From 050b427264c48d2dad54746f002806c6732d449d Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Fri, 13 Feb 2026 12:01:39 -0500 Subject: [PATCH 01/73] modified a few files so OPT_FLAGS -Os and gcc compiler will build US rom. Rom still unstable --- Makefile | 11 ++++++----- src/audio/synthesis.c | 5 +++-- src/crash_screen.c | 2 +- src/racing/math_util.h | 1 + src/update_objects.c | 4 ++-- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index e4d98c41a6..1aa9186685 100644 --- a/Makefile +++ b/Makefile @@ -24,19 +24,19 @@ TARGET_N64 ?= 1 # ido - uses the SGI IRIS Development Option compiler, which is used to build # an original matching N64 ROM # gcc - uses the GNU C Compiler -COMPILER ?= ido +COMPILER ?= gcc $(eval $(call validate-option,COMPILER,ido gcc)) # Add debug tools with 'make DEBUG=1' and modify the macros in include/debug.h # Adds crash screen enhancement and activates debug mode # Run make clean first -DEBUG ?= 0 +DEBUG ?= 1 # Avoid undefined behavior. Enables shiftability when making changes -AVOID_UB ?= 0 +AVOID_UB ?= 1 # Compile with GCC -GCC ?= 0 +GCC ?= 1 # VERSION - selects the version of the game to build # us - builds the 1997 North American version @@ -327,7 +327,7 @@ AR := $(CROSS)ar OBJDUMP := $(CROSS)objdump OBJCOPY := $(CROSS)objcopy -OPT_FLAGS := -O2 +OPT_FLAGS := -Os ifeq ($(TARGET_N64),1) TARGET_CFLAGS := -nostdinc -DTARGET_N64 -D_LANGUAGE_C @@ -655,6 +655,7 @@ $(BUILD_DIR)/%.o: %.s $(MIO0_FILES) $(RAW_TEXTURE_FILES) $(V)$(AS) $(ASFLAGS) -o $@ $< $(EUC_JP_FILES:%.c=$(BUILD_DIR)/%.jp.o): CC := $(PYTHON) $(TOOLS_DIR)/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) -- +$(EUC_JP_FILES:%.c=$(BUILD_DIR)/%.jp.o): OPT_FLAGS := -O2 $(GLOBAL_ASM_O_FILES): CC := $(PYTHON) $(TOOLS_DIR)/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) -- diff --git a/src/audio/synthesis.c b/src/audio/synthesis.c index bfb2452ae2..f3448bdecf 100644 --- a/src/audio/synthesis.c +++ b/src/audio/synthesis.c @@ -463,8 +463,9 @@ Acmd* synthesis_process_note(s32 noteIndex, struct NoteSubEu* noteSubEu, struct var_a0_2 = (temp_t6 * 9) + sampleAddr; } else { var_a0_2 = - dma_sample_data((uintptr_t) (temp_t6 * 9) + sampleAddr, ALIGN(((loopInfo_2 * 9) + 16), 4), - flags, &synthesisState->sampleDmaIndex); + dma_sample_data(((uintptr_t) sampleAddr + (uintptr_t) (temp_t6 * 9)), + ALIGN(((loopInfo_2 * 9) + 16), 4), flags, + &synthesisState->sampleDmaIndex); } var_t2 = ((uintptr_t) var_a0_2) & 0xF; diff --git a/src/crash_screen.c b/src/crash_screen.c index 18a4cab311..026a63811e 100644 --- a/src/crash_screen.c +++ b/src/crash_screen.c @@ -7,7 +7,7 @@ #include "crash_screen.h" #include "main.h" -#ifdef CRASH_SCREEN_ENHANCEMENT +#if DEBUG || defined(CRASH_SCREEN_ENHANCEMENT) #include "debug/crash_screen_enhancement.h" #endif diff --git a/src/racing/math_util.h b/src/racing/math_util.h index 6ba4d0aa30..e9f760d266 100644 --- a/src/racing/math_util.h +++ b/src/racing/math_util.h @@ -65,6 +65,7 @@ f32 sins(u16); f32 coss(u16); s32 is_between_angle(u16, u16, u16); f32 distance_if_visible(Vec3f, Vec3f, u16, f32, f32, f32); +void vec_unit_z_rotX_rotY(s16 rotY, s16 rotX, Vec3f arg2); // added function to header so gcc compiles extern s32 D_802B91C0[]; // Unused extern Vec3f D_802B91C8; diff --git a/src/update_objects.c b/src/update_objects.c index c142fd6cab..6d68895f60 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -7807,8 +7807,8 @@ void func_80085F74(s32 objectIndex) { void func_80086074(s32 objectIndex, s32 arg1) { set_obj_origin_pos(objectIndex, D_800E6734[arg1 * 3 + 0] * xOrientation, D_800E6734[arg1 * 3 + 1], D_800E6734[arg1 * 3 + 2]); - init_texture_object(objectIndex, &d_course_rainbow_road_static_tluts[arg1 * 256], - &d_course_rainbow_road_static_textures[arg1], 64, 64); + init_texture_object(objectIndex, (u8 *)&d_course_rainbow_road_static_tluts[arg1 * 256], //cast as 8bit pointer to stop gcc complaining + d_course_rainbow_road_static_textures[arg1], 64, 64); //remove & so gcc doesnt complain func_80085BB4(objectIndex); } From 15ad479e1cb3934e83addad76ea64fdeb4392f99 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Fri, 13 Feb 2026 20:48:55 -0500 Subject: [PATCH 02/73] enabled debug mode in debug.h, added build log to gitignore --- .gitignore | 3 +++ include/debug.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0057cda895..6717ace186 100644 --- a/.gitignore +++ b/.gitignore @@ -105,3 +105,6 @@ mingw64/ # torch torch.hash.yml + +# build log +build.log \ No newline at end of file diff --git a/include/debug.h b/include/debug.h index 170751147b..df4ba4c963 100644 --- a/include/debug.h +++ b/include/debug.h @@ -14,7 +14,7 @@ * Holding L + R + Z + A will start the creditis sequence. * Holding L + R + Z + B will start the ending sequence. */ -#define DVDL 0 +#define DVDL 1 #if DVDL #define CHARACTER_BUFFER_SIZE 200 // size of the string buffer From 2c68fc7aff2dadf03c2909780a3fdd1f732fb83a Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Fri, 13 Feb 2026 21:21:02 -0500 Subject: [PATCH 03/73] update makefile to include -fno-toplevel-reorder to fix rom corruption --- Makefile | 2 +- src/update_objects.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 1aa9186685..f4d56625c1 100644 --- a/Makefile +++ b/Makefile @@ -361,7 +361,7 @@ CC_CHECK_CFLAGS := -fsyntax-only -fsigned-char $(CC_CFLAGS) $(TARGET_CFLAGS) -st HIDE_WARNINGS := -woff 838,649,807 CFLAGS = -G 0 $(OPT_FLAGS) $(TARGET_CFLAGS) $(MIPSISET) $(DEF_INC_CFLAGS) ifeq ($(COMPILER),gcc) - CFLAGS += -mno-shared -march=vr4300 -mfix4300 -mabi=32 -mhard-float -mdivide-breaks -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-PIC -mno-abicalls -fno-strict-aliasing -fno-inline-functions -ffreestanding -fwrapv -Wall -Wextra + CFLAGS += -mno-shared -march=vr4300 -mfix4300 -mabi=32 -mhard-float -mdivide-breaks -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-PIC -mno-abicalls -fno-strict-aliasing -fno-inline-functions -ffreestanding -fwrapv -fno-toplevel-reorder -Wall -Wextra else CFLAGS += $(HIDE_WARNINGS) -non_shared -Wab,-r4300_mul -Xcpluscomm -fullwarn -signed -32 endif diff --git a/src/update_objects.c b/src/update_objects.c index 6d68895f60..16463a8a50 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -7807,8 +7807,8 @@ void func_80085F74(s32 objectIndex) { void func_80086074(s32 objectIndex, s32 arg1) { set_obj_origin_pos(objectIndex, D_800E6734[arg1 * 3 + 0] * xOrientation, D_800E6734[arg1 * 3 + 1], D_800E6734[arg1 * 3 + 2]); - init_texture_object(objectIndex, (u8 *)&d_course_rainbow_road_static_tluts[arg1 * 256], //cast as 8bit pointer to stop gcc complaining - d_course_rainbow_road_static_textures[arg1], 64, 64); //remove & so gcc doesnt complain + init_texture_object(objectIndex, (u8*) &d_course_rainbow_road_static_tluts[arg1 * 256], + d_course_rainbow_road_static_textures[arg1], 64, 64); func_80085BB4(objectIndex); } From 7d3689b43679d57de166a4eb326056dd6381c8c4 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sat, 14 Feb 2026 13:55:31 -0500 Subject: [PATCH 04/73] turned off annoying debug menu --- include/debug.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/debug.h b/include/debug.h index df4ba4c963..170751147b 100644 --- a/include/debug.h +++ b/include/debug.h @@ -14,7 +14,7 @@ * Holding L + R + Z + A will start the creditis sequence. * Holding L + R + Z + B will start the ending sequence. */ -#define DVDL 1 +#define DVDL 0 #if DVDL #define CHARACTER_BUFFER_SIZE 200 // size of the string buffer From 2cdea2f7cbd9fc63eb4b1e3afca15672cf5d5a60 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sun, 15 Feb 2026 10:10:31 -0500 Subject: [PATCH 05/73] added rdp and rsp display monitor to profiler. rom is unstable on console. maybe related to profiler. need to try previous commit --- src/profiler.c | 100 ++++++++++++++++++++++++++++++++++++++++++++----- src/profiler.h | 1 + 2 files changed, 92 insertions(+), 9 deletions(-) diff --git a/src/profiler.c b/src/profiler.c index eca4e9a718..8c3fa28752 100644 --- a/src/profiler.c +++ b/src/profiler.c @@ -2,7 +2,9 @@ #include #include "profiler.h" #include +#include #include "main.h" +#include "render_objects.h" struct ProfilerFrameData gProfilerFrameData[2]; @@ -45,6 +47,44 @@ void profiler_log_vblank_time(void) { } } +void profiler_get_last_gfx_times_ms(s32* rspMs, s32* rdpMs) { + struct ProfilerFrameData* profiler = &gProfilerFrameData[D_800DC66C ^ 1]; + OSTime taskQueued; + OSTime rspComplete; + OSTime rdpComplete; + s64 rspDuration; + s64 rdpDuration; + + if (rspMs == NULL || rdpMs == NULL) { + return; + } + + taskQueued = profiler->gfxTimes[TASKS_QUEUED]; + rspComplete = profiler->gfxTimes[RSP_COMPLETE]; + rdpComplete = profiler->gfxTimes[RDP_COMPLETE]; + + if (rspComplete > taskQueued) { + rspDuration = (s64) (rspComplete - taskQueued); + } else { + rspDuration = 0; + } + + if (rdpComplete > taskQueued) { + rdpDuration = (s64) (rdpComplete - taskQueued); + } else { + rdpDuration = 0; + } + + if (osClockRate == 0) { + *rspMs = 0; + *rdpMs = 0; + return; + } + + *rspMs = (s32) ((rspDuration * 1000) / (s64) osClockRate); + *rdpMs = (s32) ((rdpDuration * 1000) / (s64) osClockRate); +} + // Draw the specified profiler given the information passed. // This function is the same as the one in SM64 void draw_profiler_bar(OSTime clockBase, OSTime clockStart, OSTime clockEnd, s16 posY, u16 color) { @@ -131,6 +171,8 @@ void draw_profiler_mode_1(void) { void draw_profiler_mode_0(void) { s32 i; struct ProfilerFrameData* profiler; + s16 soundCount; + s16 vblankCount; u64 clockStart; // Does this naming apply to MK64? @@ -146,8 +188,16 @@ void draw_profiler_mode_0(void) { // xor it to get the last frame profiler. profiler = &gProfilerFrameData[D_800DC668 ^ 1]; + // like above functions, toss the odd bit. + soundCount = profiler->numSoundTimes & 0xFFFE; + vblankCount = profiler->numVblankTimes & 0xFFFE; + // was thread 5 ran before thread 4? set the lower one to be the clockStart. - clockStart = profiler->gameTimes[0] <= profiler->soundTimes[0] ? profiler->gameTimes[0] : profiler->soundTimes[0]; + if (soundCount >= 2) { + clockStart = profiler->gameTimes[0] <= profiler->soundTimes[0] ? profiler->gameTimes[0] : profiler->soundTimes[0]; + } else { + clockStart = profiler->gameTimes[0]; + } // set variables for duration of tasks. levelScriptDuration = profiler->gameTimes[1] - clockStart; @@ -157,11 +207,8 @@ void draw_profiler_mode_0(void) { rdpDuration = profiler->gfxTimes[2] - profiler->gfxTimes[0]; vblank = 0; - // like above functions, toss the odd bit. - profiler->numSoundTimes &= 0xFFFE; - // sound duration seems to be rendered with empty space and not actually drawn. - for (i = 0; i < profiler->numSoundTimes; i += 2) { + for (i = 0; i < soundCount; i += 2) { // calculate sound duration of max - min soundDuration = profiler->soundTimes[i + 1] - profiler->soundTimes[i]; taskStart += soundDuration; @@ -175,14 +222,11 @@ void draw_profiler_mode_0(void) { } } - // same as above. toss the odd bit. - profiler->numSoundTimes &= 0xFFFE; - //! wrong index used to retrieve vblankTimes, thus empty pairs can // potentially be passed to draw_profiler_bar, because it could be sending // pairs that are beyond the numVblankTimes enforced non-odd limit, due to // using the wrong num value. - for (i = 0; i < profiler->numSoundTimes; i += 2) { + for (i = 0; i < vblankCount; i += 2) { vblank += (profiler->vblankTimes[i + 1] - profiler->vblankTimes[i]); } @@ -228,4 +272,42 @@ void resource_display(void) { D_800DC664 ^= 1; } draw_profiler_mode_0(); + + if ((gModeSelection == VERSUS) && (gScreenModeSelection == SCREEN_MODE_3P_4P_SPLITSCREEN) && + (gPlayerCountSelection1 >= THREE_PLAYERS_SELECTED)) { + s32 rspMs = 0; + s32 rdpMs = 0; + char rspLabel[5]; + char rdpLabel[5]; + s32 x; + s32 y; + + rspLabel[0] = 'R'; + rspLabel[1] = 'S'; + rspLabel[2] = 'P'; + rspLabel[3] = ' '; + rspLabel[4] = '\0'; + + rdpLabel[0] = 'R'; + rdpLabel[1] = 'D'; + rdpLabel[2] = 'P'; + rdpLabel[3] = ' '; + rdpLabel[4] = '\0'; + + profiler_get_last_gfx_times_ms(&rspMs, &rdpMs); + load_debug_font(); + + x = 0; + y = 0; + debug_print_string(&x, &y, rspLabel); + debug_print_number(&x, &y, rspMs, 10); + + x = 0; + y = 8; + debug_print_string(&x, &y, rdpLabel); + debug_print_number(&x, &y, rdpMs, 10); + + + func_80057778(); + } } diff --git a/src/profiler.h b/src/profiler.h index f6b1a85346..627442cf7f 100644 --- a/src/profiler.h +++ b/src/profiler.h @@ -31,6 +31,7 @@ void profiler_log_thread5_time(enum ProfilerGameEvent eventID); void profiler_log_thread4_time(void); void profiler_log_gfx_time(enum ProfilerGfxEvent eventID); void profiler_log_vblank_time(void); +void profiler_get_last_gfx_times_ms(s32* rspMs, s32* rdpMs); void draw_profiler(void); void resource_display(void); From b14eb634ac4cfc9d5b0bb646378a8bc7c6d16c6e Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Tue, 24 Feb 2026 13:21:54 -0500 Subject: [PATCH 06/73] Recover assistant edits: menu/options/menu_items/menus --- Makefile | 10 +++--- include/options.h | 19 +++++++++++ src/main.c | 4 +++ src/menu_items.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++ src/menus.c | 62 ++++++++++++++++++++++++++++++++++ src/menus.h | 10 ++++++ 6 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 include/options.h diff --git a/Makefile b/Makefile index f4d56625c1..6fe6d47acd 100644 --- a/Makefile +++ b/Makefile @@ -24,19 +24,19 @@ TARGET_N64 ?= 1 # ido - uses the SGI IRIS Development Option compiler, which is used to build # an original matching N64 ROM # gcc - uses the GNU C Compiler -COMPILER ?= gcc +COMPILER ?= ido $(eval $(call validate-option,COMPILER,ido gcc)) # Add debug tools with 'make DEBUG=1' and modify the macros in include/debug.h # Adds crash screen enhancement and activates debug mode # Run make clean first -DEBUG ?= 1 +DEBUG ?= 0 # Avoid undefined behavior. Enables shiftability when making changes AVOID_UB ?= 1 # Compile with GCC -GCC ?= 1 +GCC ?= 0 # VERSION - selects the version of the game to build # us - builds the 1997 North American version @@ -122,7 +122,7 @@ endif # COMPARE - whether to verify the SHA-1 hash of the ROM after building # 1 - verifies the SHA-1 hash of the selected version of the game # 0 - does not verify the hash -COMPARE ?= 1 +COMPARE ?= 0 $(eval $(call validate-option,COMPARE,0 1)) @@ -327,7 +327,7 @@ AR := $(CROSS)ar OBJDUMP := $(CROSS)objdump OBJCOPY := $(CROSS)objcopy -OPT_FLAGS := -Os +OPT_FLAGS := -O2 ifeq ($(TARGET_N64),1) TARGET_CFLAGS := -nostdinc -DTARGET_N64 -D_LANGUAGE_C diff --git a/include/options.h b/include/options.h new file mode 100644 index 0000000000..3d06825bbc --- /dev/null +++ b/include/options.h @@ -0,0 +1,19 @@ +#ifndef OPTIONS_H +#define OPTIONS_H + +// Tracks option +typedef enum TracksOption { + TRACKS_DEFAULT = 0, + TRACKS_RANDOM = 1, +} TracksOption; + +// Game options struct - extendable +// Use plain C integer types to avoid depending on in cross +// toolchains that may not provide it in the include path. +typedef struct GameOptions { + unsigned char tracks; // TracksOption +} GameOptions; + +extern GameOptions gOptions; + +#endif // OPTIONS_H diff --git a/src/main.c b/src/main.c index 044cc235f0..3bef72c4f0 100644 --- a/src/main.c +++ b/src/main.c @@ -29,6 +29,7 @@ #include "code_80280000.h" #include "podium_ceremony_actors.h" #include "menu_items.h" +#include "options.h" #include "code_80057C60.h" #include "profiler.h" #include "player_controller.h" @@ -55,6 +56,9 @@ struct SPTask* sCurrentDisplaySPTask = NULL; struct SPTask* sNextAudioSPTask = NULL; struct SPTask* sNextDisplaySPTask = NULL; +// Global game options (defined here so the linker includes the symbol) +GameOptions gOptions = { TRACKS_DEFAULT }; + struct Controller gControllers[NUM_PLAYERS]; struct Controller* gControllerOne = &gControllers[0]; struct Controller* gControllerTwo = &gControllers[1]; diff --git a/src/menu_items.c b/src/menu_items.c index edf8e9ad26..97c43d0805 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -35,12 +35,15 @@ #include "spawn_players.h" #include "render_player.h" #include "decode.h" +#include //! @todo Move gGfxPool out of main.h // Unfortunately that's not a small effort due to weird import structure in this project #include "main.h" void guMtxCatL(Mtx* m, Mtx* n, Mtx* res); +void render_custom_overlay(void); + u16* gMenuTextureBuffer; u32* gMenuCompressedBuffer; u8* sTKMK00_LowResBuffer; @@ -2297,6 +2300,7 @@ void func_80094A64(struct GfxPool* pool) { case START_MENU: func_80095574(); func_80093E40(); + render_custom_overlay(); // render custom overlay in start menu break; case OPTIONS_MENU: case DATA_MENU: @@ -5740,6 +5744,87 @@ void add_menu_item(s32 type, s32 column, s32 row, s8 priority) { } } +// render custom menu over title screen +void render_custom_overlay(void) { + s32 x = 0xA0, y = 0x40; // centered horizontally; tweak + int i; + s32 rowY; + s32 valIdx; + char nameBuf[32]; + char valBuf[4]; + + /* Modifier names provided by user; if an entry is empty, fallback to "Modifier N" */ + static const char* customModifierNames[CUSTOM_MENU_ROWS] = { + "tracks", + "scaling", + "widescreen", + "mp music", + "mp train", + "mp boat", + "vs tracks", + "vs timer", + "stats", + "vs scores", + "tie logic", + "mirror", + "" /* keep last empty if CUSTOM_MENU_ROWS > 12 */ + }; + + set_text_color(TEXT_YELLOW); + + // title (centered) - smaller + print_text1_center_mode_1(x, y - 0x30, "WEATHERTON ABNEY CLIMATEE", 0, 0.80f, 0.80f); + // version / date (smaller) - left-aligned to start under 'KART' + print_text1_left(x + 0x5A, y + 0x06, "TE V2026-02-22", 0, 0.65f, 0.65f); + + // option name placeholders (second column) and values (third column) + for (i = 0; i < CUSTOM_MENU_ROWS; i++) { + /* standard row stride (single-line names) */ + rowY = y + (i * 0x10); + + /* first column: selection pointer (yellow asterisk) */ + if (i == gCustomMenuSelection) { + print_text1_left(x - 0x30, rowY, "*", 0, 0.6f, 0.6f); + } else { + /* draw empty space to keep alignment */ + print_text1_left(x - 0x50, rowY, " ", 0, 0.6f, 0.6f); + } + + /* second column: option name (single line) */ + if (customModifierNames[i][0] != '\0') { + print_text1_left(x, rowY, (char*)customModifierNames[i], 0, 0.8f, 0.8f); + } else { + /* Build "Modifier N" manually to avoid linking snprintf */ + const char* prefix = "Modifier "; + int num = i + 1; + int pos = 0; + const char* p = prefix; + while (*p && pos < (int)sizeof(nameBuf) - 1) { + nameBuf[pos++] = *p++; + } + if (num >= 10 && pos < (int)sizeof(nameBuf) - 2) { + nameBuf[pos++] = '0' + (num / 10); + nameBuf[pos++] = '0' + (num % 10); + } else if (pos < (int)sizeof(nameBuf) - 1) { + nameBuf[pos++] = '0' + (num % 10); + } + nameBuf[pos] = '\0'; + print_text1_left(x, rowY, nameBuf, 0, 0.8f, 0.8f); + } + + /* third column: current value for this row (1/2/3) */ + valIdx = gCustomMenuOptionValues[i]; + if (valIdx <= 0) + valBuf[0] = '1'; + else if (valIdx == 1) + valBuf[0] = '2'; + else + valBuf[0] = '3'; + valBuf[1] = '\0'; + print_text1_left(x + 0x40, rowY, valBuf, 0, 0.8f, 0.8f); + } +} + void render_menus(MenuItem* arg0) { s32 var_a1; s32 var_v1; diff --git a/src/menus.c b/src/menus.c index 5223158f56..306526fd1e 100644 --- a/src/menus.c +++ b/src/menus.c @@ -20,6 +20,7 @@ #include #include "spawn_players.h" #include "seq_ids.h" +#include "../include/options.h" #if ENABLE_DEBUG_MODE #define DEBUG_MODE_TOGGLE true @@ -164,6 +165,18 @@ const s8 sScreenModeIdxFromPlayerMode[4] = { 0, 1, 3, 4 }; const union GameModePack sSoundMenuPack = { { SOUND_STEREO, SOUND_HEADPHONES, SOUND_UNUSED, SOUND_MONO } }; +// end of standard var init + +// start of new var init + +s8 gCustomMenuTitle = 0; +s8 gCustomMenuDate = 0; +s8 gCustomMenuOption[CUSTOM_MENU_ROWS][2] = { 0 }; +s8 gCustomMenuSelection = 0; +s8 gCustomMenuOptionValues[CUSTOM_MENU_ROWS] = { 0 }; + +// end of new var init + /**************************/ /** @@ -1035,6 +1048,55 @@ void splash_menu_act(struct Controller* controller, u16 controllerIdx) { if (is_screen_being_faded() == 0) { if (controllerIdx == PLAYER_ONE) { gMenuDelayTimer += 1; + + // handles input to custom menu + // navigation + // works + if (btnAndStick & U_JPAD) { + gCustomMenuSelection--; + if (gCustomMenuSelection < 0) gCustomMenuSelection = CUSTOM_MENU_ROWS - 1; + play_sound2(SOUND_MENU_CURSOR_MOVE); + } + if (btnAndStick & D_JPAD) { + gCustomMenuSelection++; + if (gCustomMenuSelection >= CUSTOM_MENU_ROWS) gCustomMenuSelection = 0; + play_sound2(SOUND_MENU_CURSOR_MOVE); + } + // cycle option value with R_DPAD, L_DPAD (advance through defined value count) + // go forward one if press right dpad + if (btnAndStick & R_JPAD) { + if (gCustomMenuSelection == 0) { // tracks: only 2 values (default, random) + gCustomMenuOptionValues[0] = (gCustomMenuOptionValues[0] + 1) % 2; + gOptions.tracks = (gCustomMenuOptionValues[0] == 1) ? TRACKS_RANDOM : TRACKS_DEFAULT; + } else { + gCustomMenuOptionValues[gCustomMenuSelection] = + (gCustomMenuOptionValues[gCustomMenuSelection] + 1) % CUSTOM_MENU_VALUE_COUNT; + } + play_sound2(SOUND_MENU_OK); + } + // go backwards one if press left dpad and not at first index + else if (btnAndStick & L_JPAD && (gCustomMenuOptionValues[gCustomMenuSelection] != 0) ) { + if (gCustomMenuSelection == 0) { // tracks: only 2 values + gCustomMenuOptionValues[0] = (gCustomMenuOptionValues[0] - 1); + if (gCustomMenuOptionValues[0] < 0) gCustomMenuOptionValues[0] = 0; + gOptions.tracks = (gCustomMenuOptionValues[0] == 1) ? TRACKS_RANDOM : TRACKS_DEFAULT; + } else { + gCustomMenuOptionValues[gCustomMenuSelection] = + (gCustomMenuOptionValues[gCustomMenuSelection] - 1); + } + play_sound2(SOUND_MENU_OK); + } + // go to end if press left dpad at first index + else if (btnAndStick & L_JPAD && (gCustomMenuOptionValues[gCustomMenuSelection] == 0) ) { + if (gCustomMenuSelection == 0) { // tracks: wrap to last (1) + gCustomMenuOptionValues[0] = 1; + gOptions.tracks = TRACKS_RANDOM; + } else { + gCustomMenuOptionValues[gCustomMenuSelection] = + CUSTOM_MENU_VALUE_COUNT - 1; + } + play_sound2(SOUND_MENU_OK); + } } switch (gDebugMenuSelection) { case DEBUG_MENU_DISABLED: { diff --git a/src/menus.h b/src/menus.h index 8b16558a65..74617b38c5 100644 --- a/src/menus.h +++ b/src/menus.h @@ -265,4 +265,14 @@ extern const s16 gCupCourseOrder[NUM_CUPS][NUM_COURSES_PER_CUP]; // end of menus.c variables +// start of custom menu var +#define CUSTOM_MENU_ROWS 13 +#define CUSTOM_MENU_VALUE_COUNT 3 + +extern s8 gCustomMenuTitle; // tournament rom credits title +extern s8 gCustomMenuDate; // TE Version/date +extern s8 gCustomMenuOption[CUSTOM_MENU_ROWS][2]; // rows x (col1=name col2=unused/flags) +extern s8 gCustomMenuSelection; // menu selection index +extern s8 gCustomMenuOptionValues[CUSTOM_MENU_ROWS]; // current value index for each row + #endif /* MENUS_H */ From ce8f76c7674fb4f00261517a2ce39b72b952b9af Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Tue, 24 Feb 2026 13:25:14 -0500 Subject: [PATCH 07/73] center aligned option modifiers on menu --- src/menu_items.c | 64 ++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index 97c43d0805..f98903273c 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -2379,9 +2379,10 @@ void setup_menus(void) { add_menu_item(MENU_ITEM_TYPE_0D9, 0, 0, MENU_ITEM_PRIORITY_A); break; case START_MENU: - add_menu_item(MENU_ITEM_UI_LOGO_AND_COPYRIGHT, 0, 0, MENU_ITEM_PRIORITY_4); - add_menu_item(MENU_ITEM_UI_START_BACKGROUND, 0, 0, MENU_ITEM_PRIORITY_0); - add_menu_item(START_MENU_FLAG, 0, 0, MENU_ITEM_PRIORITY_0); + // maybe remove background from start menu + // add_menu_item(MENU_ITEM_UI_LOGO_AND_COPYRIGHT, 0, 0, MENU_ITEM_PRIORITY_4); + // add_menu_item(MENU_ITEM_UI_START_BACKGROUND, 0, 0, MENU_ITEM_PRIORITY_0); + // add_menu_item(START_MENU_FLAG, 0, 0, MENU_ITEM_PRIORITY_0); if (gControllerBits & 1) { add_menu_item(MENU_ITEM_UI_PUSH_START_BUTTON, 0, 0, MENU_ITEM_PRIORITY_2); } else { @@ -2542,8 +2543,9 @@ void func_80095574(void) { play_sound2(SOUND_INTRO_WELCOME); } if (gMenuTimingCounter > 300) { - func_8009E230(); - func_800CA0A0(); + // don't fade on title screen to demo + // func_8009E230(); + // func_800CA0A0(); } gSPDisplayList(gDisplayListHead++, D_020076E0); } @@ -5753,7 +5755,7 @@ void render_custom_overlay(void) { char nameBuf[32]; char valBuf[4]; - /* Modifier names provided by user; if an entry is empty, fallback to "Modifier N" */ + /* Menu items; if an entry is empty, fallback to "Modifier N" */ static const char* customModifierNames[CUSTOM_MENU_ROWS] = { "tracks", "scaling", @@ -5764,7 +5766,7 @@ void render_custom_overlay(void) { "vs tracks", "vs timer", "stats", - "vs scores", + "", "tie logic", "mirror", "" /* keep last empty if CUSTOM_MENU_ROWS > 12 */ @@ -5779,20 +5781,20 @@ void render_custom_overlay(void) { // option name placeholders (second column) and values (third column) for (i = 0; i < CUSTOM_MENU_ROWS; i++) { - /* standard row stride (single-line names) */ - rowY = y + (i * 0x10); + /* standard row stride (single-line names) - reduced spacing */ + rowY = y + 0x18 + (i * 0xC); - /* first column: selection pointer (yellow asterisk) */ + /* first column: selection pointer */ if (i == gCustomMenuSelection) { - print_text1_left(x - 0x30, rowY, "*", 0, 0.6f, 0.6f); + print_text_mode_1(x - 0x40, rowY, "X", 0, 0.6f, 0.6f); } else { /* draw empty space to keep alignment */ - print_text1_left(x - 0x50, rowY, " ", 0, 0.6f, 0.6f); + print_text1_left(x - 0x30, rowY, " ", 0, 0.6f, 0.6f); } /* second column: option name (single line) */ if (customModifierNames[i][0] != '\0') { - print_text1_left(x, rowY, (char*)customModifierNames[i], 0, 0.8f, 0.8f); + print_text_mode_1(x - 0x30, rowY, (char*)customModifierNames[i], 0, 0.6f, 0.6f); } else { /* Build "Modifier N" manually to avoid linking snprintf */ const char* prefix = "Modifier "; @@ -5809,19 +5811,29 @@ void render_custom_overlay(void) { nameBuf[pos++] = '0' + (num % 10); } nameBuf[pos] = '\0'; - print_text1_left(x, rowY, nameBuf, 0, 0.8f, 0.8f); - } - - /* third column: current value for this row (1/2/3) */ - valIdx = gCustomMenuOptionValues[i]; - if (valIdx <= 0) - valBuf[0] = '1'; - else if (valIdx == 1) - valBuf[0] = '2'; - else - valBuf[0] = '3'; - valBuf[1] = '\0'; - print_text1_left(x + 0x40, rowY, valBuf, 0, 0.8f, 0.8f); + // default case i guess + print_text_mode_1(x - 0x30, rowY, nameBuf, 0, 0.6f, 0.6f); + } + + /* third column: current value for this row */ + if (i == 0) { /* tracks: custom labels (default, random) */ + static const char* tracks_labels[] = {"default", "random"}; + int idx = gCustomMenuOptionValues[0]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(tracks_labels) / sizeof(tracks_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x40, rowY, (char*)tracks_labels[idx], 0, 0.6f, 0.6f); + } else { + /* fallback: numeric representation 1/2/3 to match previous behavior */ + valIdx = gCustomMenuOptionValues[i]; + if (valIdx <= 0) + valBuf[0] = '1'; + else if (valIdx == 1) + valBuf[0] = '2'; + else + valBuf[0] = '3'; + valBuf[1] = '\0'; + print_text1_left(x + 0x40, rowY, valBuf, 0, 0.6f, 0.6f); + } } } From ef45a57179537175e292fc48d00670be6cfef6c0 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Thu, 12 Mar 2026 07:29:12 -0400 Subject: [PATCH 08/73] added vs scores for 4p and 3p changed lightning behavior (color LUT) to be flashes of dark and mid blue so it's easier on the eyes --- src/menu_items.c | 300 ++++++++++++++++++++++++++++++++++++++++++----- src/menus.c | 37 +++--- 2 files changed, 289 insertions(+), 48 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index f98903273c..076e9abe10 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -716,6 +716,8 @@ const s8 gGPPointRewards[] = { 9, 6, 3, 1 }; const s8 D_800F0B1C[] = { 0, 0, 1, 0, 1, 0, 1, 2, 0, 1, 2, 3, }; + +// lightning flash pattern const s8 D_800F0B28[] = { 0, 1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -724,11 +726,12 @@ const s8 D_800F0B28[] = { const s8 D_800F0B50[] = { 0x1f, 0x0b, 0x15, 0x29 }; const s8 D_800F0B54[] = { 0x20, 0x0f, 0x18, 0x2c }; +// lightning flash color palette RGBA16 D_800E7AC8[] = { - { 0x00, 0x00, 0x00, 0x00 }, - { 0xff, 0xff, 0xff, 0xff }, - { 0x00, 0x00, 0x50, 0xff }, - { 0xff, 0xff, 0xff, 0xff }, + { 0x00, 0x00, 0x00, 0x00 }, // background, clear + { 0x00, 0x00, 0x90, 0xff }, // changed to mid blue from white + { 0x00, 0x00, 0x50, 0xff }, // dark blue + { 0xff, 0xff, 0x90, 0xff }, // changed to mid blue from white }; RGBA16 D_800E7AE8[] = { @@ -5258,7 +5261,7 @@ void func_8009E2A8(s32 arg0) { break; } } - +// lightning flash renderer void func_8009E2F0(s32 arg0) { UNUSED s32 stackPadding0; UNUSED s32 stackPadding1; @@ -5750,10 +5753,18 @@ void add_menu_item(s32 type, s32 column, s32 row, s8 priority) { void render_custom_overlay(void) { s32 x = 0xA0, y = 0x40; // centered horizontally; tweak int i; + int idx; s32 rowY; s32 valIdx; char nameBuf[32]; char valBuf[4]; + MenuItem cursorItem; + Unk_D_800E70A0 sp84; + + // // temp var for debug font + // s32 x1; + // s32 y1; + /* Menu items; if an entry is empty, fallback to "Modifier N" */ static const char* customModifierNames[CUSTOM_MENU_ROWS] = { @@ -5763,7 +5774,7 @@ void render_custom_overlay(void) { "mp music", "mp train", "mp boat", - "vs tracks", + "", "vs timer", "stats", "", @@ -5772,10 +5783,31 @@ void render_custom_overlay(void) { "" /* keep last empty if CUSTOM_MENU_ROWS > 12 */ }; + /* per-option label arrays */ + static const char* tracks_labels[] = {"TE", "kalliera", "random"}; + static const char* scaling_labels[] = {"default", "30fps", "60fps"}; + static const char* widescreen_labels[] = {"default", "enabled"}; + static const char* mpMusic_labels[] = {"default", "enabled"}; + static const char* mpTrain_labels[] = {"default", "full"}; + static const char* mpBoat_labels[] = {"default", "enabled"}; + static const char* opt6_labels[] = {"1"}; + static const char* timer_labels[] = {"default", "enabled"}; + static const char* stats_labels[] = {"all yoshi", "default"}; + static const char* opt10_labels[] = {"1"}; + static const char* tieLogic_labels[] = {"timer", "port"}; + static const char* mirror_labels[] = {"default", "enabled"}; + static const char* opt13_labels[] = {"1"}; + set_text_color(TEXT_YELLOW); // title (centered) - smaller print_text1_center_mode_1(x, y - 0x30, "WEATHERTON ABNEY CLIMATEE", 0, 0.80f, 0.80f); + + // /* use debug font helper */ + // x1 = 0; + // y1 = 0; + // func_800579B8(x1, y1, "WEATHERTON ABNEY CLIMATEE"); + // version / date (smaller) - left-aligned to start under 'KART' print_text1_left(x + 0x5A, y + 0x06, "TE V2026-02-22", 0, 0.65f, 0.65f); @@ -5786,7 +5818,13 @@ void render_custom_overlay(void) { /* first column: selection pointer */ if (i == gCustomMenuSelection) { - print_text_mode_1(x - 0x40, rowY, "X", 0, 0.6f, 0.6f); + /* build a local MenuItem for the cursor effect and set the target position */ + sp84.column = x - 0x40; + sp84.row = rowY - 0x06; + cursorItem.paramf = 2.0f; /* start scale/rotation multiplier */ + cursorItem.subState = 1; /* small non-zero rotation driver */ + func_800A66A8(&cursorItem, &sp84); + //print_text_mode_1(x - 0x40, rowY, "X", 0, 0.6f, 0.6f); } else { /* draw empty space to keep alignment */ print_text1_left(x - 0x30, rowY, " ", 0, 0.6f, 0.6f); @@ -5816,27 +5854,104 @@ void render_custom_overlay(void) { } /* third column: current value for this row */ - if (i == 0) { /* tracks: custom labels (default, random) */ - static const char* tracks_labels[] = {"default", "random"}; - int idx = gCustomMenuOptionValues[0]; + switch (i) { + case 0: + /* tracks: custom labels (TE, kalliera, random) */ + idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; if (idx >= (int)(sizeof(tracks_labels) / sizeof(tracks_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x40, rowY, (char*)tracks_labels[idx], 0, 0.6f, 0.6f); - } else { - /* fallback: numeric representation 1/2/3 to match previous behavior */ - valIdx = gCustomMenuOptionValues[i]; - if (valIdx <= 0) - valBuf[0] = '1'; - else if (valIdx == 1) - valBuf[0] = '2'; - else - valBuf[0] = '3'; - valBuf[1] = '\0'; - print_text1_left(x + 0x40, rowY, valBuf, 0, 0.6f, 0.6f); + break; + case 1: + /* scaling: labels (default, 30fps, 60fps) */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(scaling_labels) / sizeof(scaling_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x40, rowY, (char*)scaling_labels[idx], 0, 0.6f, 0.6f); + break; + case 2: + /* widescreen: labels (default, enabled) */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(widescreen_labels) / sizeof(widescreen_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x40, rowY, (char*)widescreen_labels[idx], 0, 0.6f, 0.6f); + break; + case 3: + /* mp music: labels (default, enabled) */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(mpMusic_labels) / sizeof(mpMusic_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x40, rowY, (char*)mpMusic_labels[idx], 0, 0.6f, 0.6f); + break; + case 4: + /* mp train: labels (default, full) */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(mpTrain_labels) / sizeof(mpTrain_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x40, rowY, (char*)mpTrain_labels[idx], 0, 0.6f, 0.6f); + break; + case 5: + /* mp boat: labels (default, enabled) */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(mpBoat_labels) / sizeof(mpBoat_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x40, rowY, (char*)mpBoat_labels[idx], 0, 0.6f, 0.6f); + break; + case 6: + /* */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(opt6_labels) / sizeof(opt6_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x40, rowY, (char*)opt6_labels[idx], 0, 0.6f, 0.6f); + break; + case 7: + /* vs timer: labels (default, enabled) */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(timer_labels) / sizeof(timer_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x40, rowY, (char*)timer_labels[idx], 0, 0.6f, 0.6f); + break; + case 8: + /* stats: labels (default, all yoshi) */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(stats_labels) / sizeof(stats_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x40, rowY, (char*)stats_labels[idx], 0, 0.6f, 0.6f); + break; + case 9: + /* */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(opt10_labels) / sizeof(opt10_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x40, rowY, (char*)opt10_labels[idx], 0, 0.6f, 0.6f); + break; + case 10: + /* tie logic: labels (timer, port) */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(tieLogic_labels) / sizeof(tieLogic_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x40, rowY, (char*)tieLogic_labels[idx], 0, 0.6f, 0.6f); + break; + case 11: + /* mirror: labels (default, enabled) */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(mirror_labels) / sizeof(mirror_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x40, rowY, (char*)mirror_labels[idx], 0, 0.6f, 0.6f); + break; + case 12: + /* */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(opt13_labels) / sizeof(opt13_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x40, rowY, (char*)opt13_labels[idx], 0, 0.6f, 0.6f); + break; } } } + + void render_menus(MenuItem* arg0) { s32 var_a1; s32 var_v1; @@ -6253,6 +6368,7 @@ void render_menus(MenuItem* arg0) { case MENU_ITEM_TYPE_0AF: /* switch 6 */ func_800A6034(arg0); break; + // vs results menu render case MENU_ITEM_TYPE_0B0: /* switch 6 */ func_800A638C(arg0); break; @@ -6676,7 +6792,13 @@ void func_800A1500(MenuItem* arg0) { break; } } - +/*Renders a course selection menu item by determining the course ID +from the cup/course order based on the item's type, displaying +the course image and name bar, and optionally drawing a flashing +selection highlight with a checkmark icon (from D_02004A0C) if the + course has been completed (as indicated by func_800B639C returning + a non-negative value). Note: the ^ 0 XOR on arg0->row is a deliberate + no-op used to force a specific register allocation in the compiled output.*/ void func_800A15EC(MenuItem* arg0) { s16 courseId = gCupCourseOrder[(arg0->type - 0x7C) / 4][(arg0->type - 0x7C) % 4]; gDisplayListHead = @@ -6693,7 +6815,14 @@ void func_800A15EC(MenuItem* arg0) { func_8009C204(gDisplayListHead, segmented_to_virtual_dupe(&D_02004A0C), arg0->column + 0x20, arg0->row, 2); } } - +/*This function renders a menu item by interpolating between +two consecutive colors from a color table (D_800E74D0) based on param1 +as a blend factor (0-256) and param2 as the base color index, +setting the result as the display list's primitive color, +and then drawing a menu texture at the item's column and row position. +The color interpolation cycles through three colors using modular + arithmetic, creating a smooth color transition effect for the menu + element.*/ void func_800A1780(MenuItem* arg0) { RGBA16* temp_a1; RGBA16* temp_v1; @@ -7108,7 +7237,15 @@ void func_800A1FB0(MenuItem* arg0) { } func_800A66A8(arg0, (Unk_D_800E70A0*) &spE0); } - +/*func_800A2D1C renders a screen wipe/iris transition effect +using horizontal black bars (top and bottom) that either appear + or shrink closed based on the state of D_80164A28, drawing + rectangles via func_80098FC8 to the display list and decrementing + arg0->param1 to animate the bars inward until they disappear + (setting arg0->type = 0), with a special case in the default branch + that only runs the closing animation in single-player Grand Prix mode + without controller demo, otherwise immediately disabling the menu + item.*/ void func_800A2D1C(MenuItem* arg0) { switch (D_80164A28) { case 1: @@ -7141,6 +7278,7 @@ void func_800A2D1C(MenuItem* arg0) { } } +// 1/2p gp results screen? void func_800A2EB8(MenuItem* arg0) { s8 sp70[8]; UNUSED s32 stackPadding0; @@ -7186,6 +7324,7 @@ void func_800A2EB8(MenuItem* arg0) { D_800E76CC[gGameModeSubMenuColumn[gPlayerCount - 1][gGameModeMenuColumn[gPlayerCount - 1]]], 0, 0.6f, 0.6f); } +// timer? void func_800A32B4(s32 arg0, s32 arg1, s32 characterId, s32 rank) { UNUSED s32 stackPadding0; f32 sp50; @@ -7210,7 +7349,13 @@ void func_800A32B4(s32 arg0, s32 arg1, s32 characterId, s32 rank) { print_text_mode_1(arg0 + 0x62, arg1, "\"", 0, 0.7f, 0.7f); func_800939C8(arg0 + 0x6A, arg1, sp3C, 0, 0.7f, 0.7f); } - +/*Renders the Grand Prix "Driver's Points" scoreboard UI for a MenuItem, +displaying the current round number, each player's rank and character +with animated text colors (cycling for human players, static for CPU), +the cup name, and the CC/engine class selection, with support for +both mid-race rankings (states 1-8) and final overall rankings + (state 9+), including a staggered reveal animation controlled by + param1.*/ void func_800A34A8(MenuItem* arg0) { s8 sp80[8]; UNUSED s32 stackPadding0; @@ -8053,6 +8198,15 @@ void func_800A6034(MenuItem* arg0) { } } +/*Renders a pause menu overlay by drawing a darkened background box +and displaying pause button text entries, with behavior depending on +the menu's state: when in state 0, it fades in using param1 as an +opacity factor and draws text in yellow, otherwise it draws at +full opacity with a rainbow text effect and a selection cursor +(func_800A66A8) positioned based on the current state. +Additionally, if param2 is positive, it draws horizontal +screen-wipe bars from the top and bottom edges of the + screen, used for a transition or iris effect.*/ void func_800A6154(MenuItem* arg0) { UNUSED s32 stackPadding0; UNUSED s32 stackPadding1; @@ -8087,6 +8241,7 @@ void func_800A6154(MenuItem* arg0) { } } +// 4p/3p vs results screen menu draw void func_800A638C(MenuItem* arg0) { UNUSED s32 temp_a0; s32 var_a1; @@ -8139,6 +8294,14 @@ void func_800A638C(MenuItem* arg0) { } } + /*This function animates and renders a 3D menu item with a spinning/tumbling effect + by applying cumulative rotations around all three axes + (with rotation speeds derived from arg0->paramf and arg0->subState) + and a scaling factor, while gradually decaying paramf toward a minimum of 1.5. + It constructs a composite transformation matrix (scale → Y rotation → Z rotation → X rotation + → translation to the item's grid position), pushes it to the display list, + and draws the display list D_0D003090 with cloud-surface blending and modulated + intensity-alpha combine mode.*/ void func_800A66A8(MenuItem* arg0, Unk_D_800E70A0* arg1) { Mtx* mtx; f32 tmp; @@ -8182,6 +8345,13 @@ void func_800A66A8(MenuItem* arg0, Unk_D_800E70A0* arg1) { gSPDisplayList(gDisplayListHead++, D_0D003090); } + /*Renders the win/lose results overlay for each player in + versus or battle mode by determining each player's + win/loss status, setting the text color + (cycling colors for the winner, blue for losers), + drawing each player's score and the corresponding win/lose text + at the appropriate screen positions, and finally drawing a + Japanese dash character ("ー") as a separator.*/ void func_800A69C8(UNUSED MenuItem* arg0) { Unk_D_800E70A0* thing; UNUSED s32 stackPadding1; @@ -8223,6 +8393,11 @@ void func_800A69C8(UNUSED MenuItem* arg0) { text_draw(0x0000009E, D_800E7300[0].row + 0x6D, "ー", 0, 1.0f, 1.0f); } + /*Iterates over all players and, based on the current mode selection, + calls either func_800A6E94 (for Versus mode) or func_800A6D94 + (for Battle mode) with a fixed parameter of 3 (3 PLAYER VERSUS), the current player + index, and a mode-specific global value (gNmiUnknown2 or gNmiUnknown5). + The MenuItem parameter is unused.*/ void func_800A6BEC(UNUSED MenuItem* arg0) { s32 var_s0; @@ -8238,6 +8413,12 @@ void func_800A6BEC(UNUSED MenuItem* arg0) { } } + /*Iterates over all players and, based on the current mode selection, + calls either func_800A6E94 (for Versus mode) or func_800A6D94 + (for Battle mode) with a fixed first argument of 4 (4 PLAYER VERSUS), + the current player index, and a corresponding global NMI-related + variable (gNmiUnknown3 or gNmiUnknown6). The MenuItem parameter + is unused.*/ void func_800A6CC0(UNUSED MenuItem* arg0) { s32 var_s0; @@ -8278,16 +8459,77 @@ void func_800A6D94(s32 arg0, s32 arg1, u8* arg2) { 0.75f); } -// The s/n/r/ー are not ASCII characters, they're EUC-JP characters +/*The s/n/r/ー are not ASCII characters, they're EUC-JP characters + + draws race finish tallies for versus races + additionally draws vs scores for tournament edition*/ void func_800A6E94(s32 arg0, s32 arg1, u8* arg2) { UNUSED s32 stackPadding0; u8* temp_v0; Unk_D_800E70A0* temp_s0; char sp40[3]; s32 rank; + + // var for drawing scores + s32 base_xPos_4p; + s32 base_xPos_3p; + s32 Y_pos; + s32 X_pos; + s32 draw_offset; + u8 *tally; + s32 firsts; + s32 seconds; + s32 thirds; + u8 i; + s32 points; + char pointsBuf[5]; + // Everything about this variable is bizarre s32 sp38 = -1; + // base x and y position for drawing scores + // x-coord increment will be different for 3p and 4p vs + base_xPos_4p = 0x1A; + base_xPos_3p = 0x34; + Y_pos = 0x20; + // i: player index + i = 0; + + // change tally var based off of player count + // gNmiUnknown2 for 3p, gNmiUnknown3 for 4p + tally = (gPlayerCountSelection1 == 3) ? gNmiUnknown2 : gNmiUnknown3; + + // Only draw scores on the first player call to avoid overdraw + // (func_800A6E94 is called once per player by func_800A6BEC/func_800A6CC0) + if (arg1 == 0) { + set_text_color(TEXT_YELLOW); + while(i < gPlayerCountSelection1) { + firsts = tally[i * 3 + 0]; + seconds = tally[i * 3 + 1]; + thirds = tally[i * 3 + 2]; + + // custom point calculation + points = (firsts * 3) + (seconds * 2) + (thirds * 1); + + // convert to ascii char + convert_number_to_ascii(points, pointsBuf); + + // remove zero padding in ascii conversion + if (pointsBuf[0] == '0') { + pointsBuf[0] = ' '; + } + + // calculate x-position to draw vs scores + X_pos = (gPlayerCountSelection1 == 3) ? (base_xPos_3p + (i * 0x4E)) : (base_xPos_4p + (i * 0x45)); + + // player i points - left-aligned with leftmost visible digit at same X position + // if single digit (space padded), offset X by space width so digit aligns with double-digit numbers + draw_offset = (pointsBuf[0] == ' ') ? -0x5 : 0; + text_draw(X_pos + draw_offset , Y_pos, pointsBuf, 0, 0.80f, 0.80f); + i++; + } + } + temp_s0 = &D_800E7300[((arg0 - 2) * 4) + arg1]; rank = gGPCurrentRaceRankByPlayerId[arg1]; if (rank == ++sp38) { @@ -8297,7 +8539,7 @@ void func_800A6E94(s32 arg0, s32 arg1, u8* arg2) { } text_draw(temp_s0->column + 4, temp_s0->row + 0x5A, "1 s ー", 0, 0.8f, 0.8f); temp_v0 = arg2 + (arg1 * 3); - convert_number_to_ascii(temp_v0[0], sp40); + convert_number_to_ascii(temp_v0[0], sp40); // first place tally for each player text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x5A, sp40, 0, 0.8f, 0.8f); if (rank == ++sp38) { set_text_color(gGlobalTimer % 3); @@ -8305,7 +8547,7 @@ void func_800A6E94(s32 arg0, s32 arg1, u8* arg2) { set_text_color(TEXT_BLUE); } text_draw(temp_s0->column + 4, temp_s0->row + 0x69, "2 n ー", 0, 0.8f, 0.8f); - convert_number_to_ascii(temp_v0[1], sp40); + convert_number_to_ascii(temp_v0[1], sp40); // second place tally for each player text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x69, sp40, 0, 0.8f, 0.8f); if (++sp38 == rank) { set_text_color(gGlobalTimer % 3); @@ -8313,7 +8555,7 @@ void func_800A6E94(s32 arg0, s32 arg1, u8* arg2) { set_text_color(TEXT_RED); } text_draw(temp_s0->column + 4, temp_s0->row + 0x78, "3 r ー", 0, 0.8f, 0.8f); - convert_number_to_ascii(temp_v0[2], sp40); + convert_number_to_ascii(temp_v0[2], sp40); // third place tally for each player text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x78, sp40, 0, 0.8f, 0.8f); } diff --git a/src/menus.c b/src/menus.c index 306526fd1e..1fb57591d7 100644 --- a/src/menus.c +++ b/src/menus.c @@ -175,6 +175,9 @@ s8 gCustomMenuOption[CUSTOM_MENU_ROWS][2] = { 0 }; s8 gCustomMenuSelection = 0; s8 gCustomMenuOptionValues[CUSTOM_MENU_ROWS] = { 0 }; +// Per-row number of selectable values (matches label arrays in render_custom_overlay) +static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 3, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 1 }; + // end of new var init /**************************/ @@ -1065,35 +1068,31 @@ void splash_menu_act(struct Controller* controller, u16 controllerIdx) { // cycle option value with R_DPAD, L_DPAD (advance through defined value count) // go forward one if press right dpad if (btnAndStick & R_JPAD) { - if (gCustomMenuSelection == 0) { // tracks: only 2 values (default, random) - gCustomMenuOptionValues[0] = (gCustomMenuOptionValues[0] + 1) % 2; - gOptions.tracks = (gCustomMenuOptionValues[0] == 1) ? TRACKS_RANDOM : TRACKS_DEFAULT; - } else { - gCustomMenuOptionValues[gCustomMenuSelection] = - (gCustomMenuOptionValues[gCustomMenuSelection] + 1) % CUSTOM_MENU_VALUE_COUNT; + int count = gCustomMenuValueCounts[gCustomMenuSelection]; + if (count <= 0) count = 1; + gCustomMenuOptionValues[gCustomMenuSelection] = + (gCustomMenuOptionValues[gCustomMenuSelection] + 1) % count; + if (gCustomMenuSelection == 0) { + gOptions.tracks = (gCustomMenuOptionValues[0] == 2) ? TRACKS_RANDOM : TRACKS_DEFAULT; } play_sound2(SOUND_MENU_OK); } // go backwards one if press left dpad and not at first index else if (btnAndStick & L_JPAD && (gCustomMenuOptionValues[gCustomMenuSelection] != 0) ) { - if (gCustomMenuSelection == 0) { // tracks: only 2 values - gCustomMenuOptionValues[0] = (gCustomMenuOptionValues[0] - 1); - if (gCustomMenuOptionValues[0] < 0) gCustomMenuOptionValues[0] = 0; - gOptions.tracks = (gCustomMenuOptionValues[0] == 1) ? TRACKS_RANDOM : TRACKS_DEFAULT; - } else { - gCustomMenuOptionValues[gCustomMenuSelection] = - (gCustomMenuOptionValues[gCustomMenuSelection] - 1); + gCustomMenuOptionValues[gCustomMenuSelection] = (gCustomMenuOptionValues[gCustomMenuSelection] - 1); + if (gCustomMenuOptionValues[gCustomMenuSelection] < 0) gCustomMenuOptionValues[gCustomMenuSelection] = 0; + if (gCustomMenuSelection == 0) { + gOptions.tracks = (gCustomMenuOptionValues[0] == 2) ? TRACKS_RANDOM : TRACKS_DEFAULT; } play_sound2(SOUND_MENU_OK); } // go to end if press left dpad at first index else if (btnAndStick & L_JPAD && (gCustomMenuOptionValues[gCustomMenuSelection] == 0) ) { - if (gCustomMenuSelection == 0) { // tracks: wrap to last (1) - gCustomMenuOptionValues[0] = 1; - gOptions.tracks = TRACKS_RANDOM; - } else { - gCustomMenuOptionValues[gCustomMenuSelection] = - CUSTOM_MENU_VALUE_COUNT - 1; + int count = gCustomMenuValueCounts[gCustomMenuSelection]; + if (count <= 0) count = 1; + gCustomMenuOptionValues[gCustomMenuSelection] = count - 1; + if (gCustomMenuSelection == 0) { + gOptions.tracks = (gCustomMenuOptionValues[0] == 2) ? TRACKS_RANDOM : TRACKS_DEFAULT; } play_sound2(SOUND_MENU_OK); } From 35edf19716a911c81ca885ce3cab95b75418caec Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Thu, 12 Mar 2026 10:40:27 -0400 Subject: [PATCH 09/73] fixed double finish bug on lap 3 by adding extra condition; disabled "Vs match ranking" text on vs results screen added rudimnetary "continue to (next tracK)" as placeholder --- src/menu_items.c | 29 +++++++++++++++++++++++++++-- src/menu_items.h | 2 +- src/racing/race_logic.c | 12 ++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index 076e9abe10..6ee2c40a9d 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -1507,6 +1507,7 @@ void func_800925CC(void) { } } +// 4p and 3p vs menu? void func_80092604(void) { add_menu_item(MENU_ITEM_TYPE_0B0, 0, 0, MENU_ITEM_PRIORITY_0); } @@ -8249,6 +8250,11 @@ void func_800A638C(MenuItem* arg0) { s32 var_s1; UNUSED s8** var_s2; + s32 nextIndex; + s32 nextCourseId; + f32 xOffset; + const char* continueText; + if (arg0->state == 0) { gDisplayListHead = draw_box(gDisplayListHead, 0, 0, 0x0000013F, 0x000000EF, 0, 0, 0, arg0->param1); set_text_color(TEXT_BLUE_GREEN_RED_CYCLE_2); @@ -8257,7 +8263,8 @@ void func_800A638C(MenuItem* arg0) { } else { gDisplayListHead = draw_box(gDisplayListHead, 0, 0, 0x0000013F, 0x000000EF, 0, 0, 0, 0x00000064); set_text_color(TEXT_BLUE_GREEN_RED_CYCLE_2); - print_text1_center_mode_1(0x000000A0, arg0->row + 0x1E, D_800E7778[gModeSelection / 3], 0, 1.0f, 1.0f); + // dont print vs match ranking text at the top + // print_text1_center_mode_1(0x000000A0, arg0->row + 0x1E, D_800E7778[gModeSelection / 3], 0, 1.0f, 1.0f); } switch (arg0->state) { /* irregular */ default: @@ -8287,8 +8294,25 @@ void func_800A638C(MenuItem* arg0) { } if (arg0->state >= 10) { for (var_s1 = 0; var_s1 < 4; var_s1++) { + /* For 3P/4P Versus, change the first option to "CONTINUE TO " */ text_rainbow_effect(arg0->state - 0xA, var_s1, TEXT_GREEN); - print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1), gTextPauseButton[var_s1 + 1], 0, 0.8f, 0.8f); + if ((var_s1 == 0) && (gModeSelection == VERSUS) && ((gPlayerCount == 3) || (gPlayerCount == 4))) { + continueText = "CONTINUE TO "; + + /* compute next course index in the current cup */ + nextIndex = (gCourseIndexInCup + 1) & 3; /* wrap 0-3 */ + nextCourseId = gCupCourseOrder[gCupSelection][nextIndex]; + + /* draw "CONTINUE TO " then the course name after it */ + print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1), continueText, 0, 0.8f, 0.8f); + xOffset = (get_string_width((char*)continueText) * 0.8f) + 4.0f; + print_text_mode_1((s32)(0x00000069 + xOffset), 0xAE + (0xF * var_s1), + gCourseNamesDup[nextCourseId], 0, 0.8f, 0.8f); + } else { + /* default: RETRY, COURSE CHANGE, DRIVER CHANGE, QUIT */ + print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1), gTextPauseButton[var_s1 + 1], 0, 0.8f, + 0.8f); + } } func_800A66A8(arg0, &D_800E7360[arg0->state - 10]); } @@ -11187,6 +11211,7 @@ void func_800ACA14(MenuItem* arg0) { } } +// renders VS/battle end-of-race rankings menu void func_800ACC50(MenuItem* arg0) { s32 i; diff --git a/src/menu_items.h b/src/menu_items.h index 7ed1964bc9..68cdde4547 100644 --- a/src/menu_items.h +++ b/src/menu_items.h @@ -214,7 +214,7 @@ enum MENU_ITEM_TYPE { MENU_ITEM_TYPE_0AB, MENU_ITEM_TYPE_0AC, MENU_ITEM_TYPE_0AF = 0XAF, - MENU_ITEM_TYPE_0B0, + MENU_ITEM_TYPE_0B0, // VS/battle end-of-race selection menu MENU_ITEM_TYPE_0B1, MENU_ITEM_TYPE_0B2, MENU_ITEM_TYPE_0B3, diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index 43c7048d32..f4c09eed29 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -522,10 +522,12 @@ f32 func_8028EE8C(s32 arg0) { return gCourseTimer - ((COURSE_TIMER_ITER_f * temp_f14) / (temp_f14 + temp_f16)); } +// set finish state void func_8028EEF0(s32 i) { gPlayers[i].type |= PLAYER_CINEMATIC_MODE; } +// synchronizes lap counts and awards race tallies void func_8028EF28(void) { s16 currentPosition; s32 i; @@ -533,10 +535,17 @@ void func_8028EF28(void) { for (i = 0; i < NUM_PLAYERS; i++) { Player* player = &gPlayers[i]; + // skip slots that don't have active player if ((gPlayers[i].type & PLAYER_EXISTS) == 0) { continue; } + // skip finished players (players in cinematic mode) + // added condition to prevent double finishes/Wonn from cheating + if ((gPlayers[i].type & PLAYER_CINEMATIC_MODE) != 0) { + continue; + } + if (gLapCountByPlayerId[i] < gPlayers[i].lapCount) { gPlayers[i].lapCount--; } else if (gLapCountByPlayerId[i] > gPlayers[i].lapCount) { @@ -574,6 +583,7 @@ void func_8028EF28(void) { gPlayerWinningIndex = i; } switch (gPlayerCountSelection1) { + // 2 player? case 2: if (currentPosition == 0) { *(gNmiUnknown1 + i) += 1; @@ -587,6 +597,7 @@ void func_8028EF28(void) { gPlayers[i].type |= PLAYER_CPU; func_800CA118((u8) i); break; + // 3 player? case 3: if (currentPosition < 3) { *(gNmiUnknown2 + i * 3 + currentPosition) += 1; @@ -606,6 +617,7 @@ void func_8028EF28(void) { func_800CA118((u8) i); } break; + // 4 player? case 4: if (currentPosition < 3) { *(gNmiUnknown3 + i * 3 + currentPosition) += 1; From 2f3cf169756d60f76a0a6efff780618963620b88 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Thu, 12 Mar 2026 15:16:16 -0400 Subject: [PATCH 10/73] added course progression text to vs mode results screen (no progression implemented yet) fixed vs match ranking text displaying during fade in transition --- src/menu_items.c | 81 ++++++++++++++++++++++++++++++++--------- src/menu_items.h | 9 +++++ src/menus.c | 71 ++++++++++++++++++++++++++++++++++++ src/menus.h | 1 + src/racing/race_logic.c | 1 - 5 files changed, 145 insertions(+), 18 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index 6ee2c40a9d..a818424b64 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -358,6 +358,31 @@ s8 gCupSelectionByCourseId[] = { #include "assets/course_metadata/gCupSelectionByCourseId.inc.c" }; +// Tournament course sequence mode: 0 = VA, 1 = KA, 2 = KA_MMF +s8 gTournamentCourseMode = 0; + +// Course name abbreviations for each tournament mode +char* gCourseNamesVA[] = { + "LR", "MMF", "KTB", "KD", + "DKJP", "YV", "BB", "RRd", + "WS", "SL", "RRy", "BC", + "TT", "FS", "CM", "MR" +}; + +char* gCourseNamesKA[] = { + "LR", "MMF", "KTB", "KD", + "TT", "FS", "CM", "MR", + "WS", "SL", "RRy", "BC", + "DKJP", "YV", "BB", "RRd" +}; + +char* gCourseNamesKA_MMF[] = { + "LR", "MMF", "KTB", "KD", + "TT", "FS", "CM", "MR", + "WS", "SL", "RRy", "BC", + "DKJP", "YV", "BB", "MMF" +}; + char* gCupText[] = { "none", "bronze", @@ -5785,7 +5810,7 @@ void render_custom_overlay(void) { }; /* per-option label arrays */ - static const char* tracks_labels[] = {"TE", "kalliera", "random"}; + static const char* tracks_labels[] = {"VA", "kalliera", "kalliera mmf"}; static const char* scaling_labels[] = {"default", "30fps", "60fps"}; static const char* widescreen_labels[] = {"default", "enabled"}; static const char* mpMusic_labels[] = {"default", "enabled"}; @@ -5862,6 +5887,7 @@ void render_custom_overlay(void) { if (idx < 0) idx = 0; if (idx >= (int)(sizeof(tracks_labels) / sizeof(tracks_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x40, rowY, (char*)tracks_labels[idx], 0, 0.6f, 0.6f); + gTournamentCourseMode = idx; // set track order break; case 1: /* scaling: labels (default, 30fps, 60fps) */ @@ -5952,6 +5978,32 @@ void render_custom_overlay(void) { } +// Get the next course ID based on current tournament mode +s16 getNextCourseId(void) { + s32 linearCourseIndex = (gCupSelection * 4) + gCourseIndexInCup; + s32 nextLinearIndex = (linearCourseIndex + 1) & 0xF; + s32 nextCup = nextLinearIndex / 4; + s32 nextIndexInCup = nextLinearIndex % 4; + + return get_course_id_for_tournament_cursor(nextCup, nextIndexInCup); +} + +// Get the course abbreviation string for the next course +char* getNextCourseAbbrString(void) { + s32 linearCourseIndex = (gCupSelection * 4) + gCourseIndexInCup; + s32 nextLinearIndex = (linearCourseIndex + 1) & 0xF; + + switch (gTournamentCourseMode) { + case 0: // VA mode - use VA abbreviations + return gCourseNamesVA[nextLinearIndex]; + case 1: // KA mode - use KA abbreviations + return gCourseNamesKA[nextLinearIndex]; + case 2: // KA_MMF mode - use KA_MMF abbreviations + return gCourseNamesKA_MMF[nextLinearIndex]; + default: + return gCourseNamesDup[getNextCourseId()]; + } +} void render_menus(MenuItem* arg0) { s32 var_a1; @@ -8249,23 +8301,22 @@ void func_800A638C(MenuItem* arg0) { UNUSED s32 var_s0; s32 var_s1; UNUSED s8** var_s2; - - s32 nextIndex; - s32 nextCourseId; - f32 xOffset; - const char* continueText; + f32 xOffset; + char* continueText; if (arg0->state == 0) { gDisplayListHead = draw_box(gDisplayListHead, 0, 0, 0x0000013F, 0x000000EF, 0, 0, 0, arg0->param1); set_text_color(TEXT_BLUE_GREEN_RED_CYCLE_2); gDPSetPrimColor(gDisplayListHead++, 0, 0, 0x00, 0x00, 0x00, (arg0->param1 * 0xFF) / 100); - print_text1_center_mode_2(0x000000A0, arg0->row + 0x1E, D_800E7778[gModeSelection / 3], 0, 1.0f, 1.0f); + // dont print vs match ranking text at the top during fade in transition + // print_text1_center_mode_2(0x000000A0, arg0->row + 0x1E, D_800E7778[gModeSelection / 3], 0, 1.0f, 1.0f); } else { gDisplayListHead = draw_box(gDisplayListHead, 0, 0, 0x0000013F, 0x000000EF, 0, 0, 0, 0x00000064); set_text_color(TEXT_BLUE_GREEN_RED_CYCLE_2); // dont print vs match ranking text at the top // print_text1_center_mode_1(0x000000A0, arg0->row + 0x1E, D_800E7778[gModeSelection / 3], 0, 1.0f, 1.0f); } + switch (arg0->state) { /* irregular */ default: var_a1 = 0x000000FF; @@ -8278,7 +8329,9 @@ void func_800A638C(MenuItem* arg0) { var_a1 = arg0->param1; break; } + gDPSetPrimColor(gDisplayListHead++, 0, 0, 0x00, 0x00, 0x00, var_a1); + switch (gPlayerCount) { case 2: func_800A69C8(arg0); @@ -8292,24 +8345,18 @@ void func_800A638C(MenuItem* arg0) { default: break; } + if (arg0->state >= 10) { for (var_s1 = 0; var_s1 < 4; var_s1++) { /* For 3P/4P Versus, change the first option to "CONTINUE TO " */ text_rainbow_effect(arg0->state - 0xA, var_s1, TEXT_GREEN); if ((var_s1 == 0) && (gModeSelection == VERSUS) && ((gPlayerCount == 3) || (gPlayerCount == 4))) { continueText = "CONTINUE TO "; - - /* compute next course index in the current cup */ - nextIndex = (gCourseIndexInCup + 1) & 3; /* wrap 0-3 */ - nextCourseId = gCupCourseOrder[gCupSelection][nextIndex]; - - /* draw "CONTINUE TO " then the course name after it */ print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1), continueText, 0, 0.8f, 0.8f); - xOffset = (get_string_width((char*)continueText) * 0.8f) + 4.0f; - print_text_mode_1((s32)(0x00000069 + xOffset), 0xAE + (0xF * var_s1), - gCourseNamesDup[nextCourseId], 0, 0.8f, 0.8f); + xOffset = (get_string_width(continueText) * 0.8f) + 1.0f; + print_text_mode_1((s32) (0x00000069 + xOffset), 0xAE + (0xF * var_s1), getNextCourseAbbrString(), + 0, 0.8f, 0.8f); } else { - /* default: RETRY, COURSE CHANGE, DRIVER CHANGE, QUIT */ print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1), gTextPauseButton[var_s1 + 1], 0, 0.8f, 0.8f); } diff --git a/src/menu_items.h b/src/menu_items.h index 68cdde4547..5f62f36c2c 100644 --- a/src/menu_items.h +++ b/src/menu_items.h @@ -850,4 +850,13 @@ extern f32 D_8018EDA4; extern f32 D_8018EDA8; extern f32 D_8018EDAC; +// Tournament mode and custom course order arrays +extern s8 gTournamentCourseMode; +extern const s16 gVACourseOrder[4][4]; +extern const s16 gKACourseOrder[4][4]; +extern const s16 gKAMMFCourseOrder[4][4]; +extern char* gCourseNamesVA[]; +extern char* gCourseNamesKA[]; +extern char* gCourseNamesKA_MMF[]; + #endif diff --git a/src/menus.c b/src/menus.c index 1fb57591d7..125d42f5f8 100644 --- a/src/menus.c +++ b/src/menus.c @@ -144,6 +144,7 @@ const s8 sCharacterGridOrder[] = { MARIO, LUIGI, PEACH, TOAD, YOSHI, DK, WARIO, BOWSER, }; +// default course order const s16 gCupCourseOrder[5][4] = { // mushroom cup { COURSE_LUIGI_RACEWAY, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, @@ -157,6 +158,76 @@ const s16 gCupCourseOrder[5][4] = { { COURSE_BIG_DONUT, COURSE_BLOCK_FORT, COURSE_DOUBLE_DECK, COURSE_SKYSCRAPER }, }; +// va course order +const s16 gVACourseOrder[4][4] = { + // mushroom cup + { COURSE_LUIGI_RACEWAY, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, + // special cup + { COURSE_DK_JUNGLE, COURSE_YOSHI_VALLEY, COURSE_BANSHEE_BOARDWALK, COURSE_RAINBOW_ROAD }, + // star cup + { COURSE_WARIO_STADIUM, COURSE_SHERBET_LAND, COURSE_ROYAL_RACEWAY, COURSE_BOWSER_CASTLE }, + // flower cup + { COURSE_TOADS_TURNPIKE, COURSE_FRAPPE_SNOWLAND, COURSE_CHOCO_MOUNTAIN, COURSE_MARIO_RACEWAY } +}; + +// KA course order +const s16 gKACourseOrder[4][4] = { + // mushroom cup + { COURSE_LUIGI_RACEWAY, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, + // flower cup + { COURSE_TOADS_TURNPIKE, COURSE_FRAPPE_SNOWLAND, COURSE_CHOCO_MOUNTAIN, COURSE_MARIO_RACEWAY }, + // star cup + { COURSE_WARIO_STADIUM, COURSE_SHERBET_LAND, COURSE_ROYAL_RACEWAY, COURSE_BOWSER_CASTLE }, + // special cup + { COURSE_DK_JUNGLE, COURSE_YOSHI_VALLEY, COURSE_BANSHEE_BOARDWALK, COURSE_RAINBOW_ROAD } +}; + +// KA mmf course order +const s16 gKAMMFCourseOrder[4][4] = { + // mushroom cup + { COURSE_LUIGI_RACEWAY, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, + // flower cup + { COURSE_TOADS_TURNPIKE, COURSE_FRAPPE_SNOWLAND, COURSE_CHOCO_MOUNTAIN, COURSE_MARIO_RACEWAY }, + // star cup + { COURSE_WARIO_STADIUM, COURSE_SHERBET_LAND, COURSE_ROYAL_RACEWAY, COURSE_BOWSER_CASTLE }, + // special cup modified + { COURSE_DK_JUNGLE, COURSE_YOSHI_VALLEY, COURSE_BANSHEE_BOARDWALK, COURSE_MOO_MOO_FARM } +}; + +s16 get_course_id_for_tournament_cursor(s32 cupSelection, s32 courseIndexInCup) { + s32 cup = cupSelection; + s32 course = courseIndexInCup; + + if (course < 0) { + course = 0; + } + if (course > 3) { + course &= 3; + } + + if (cup == 4) { + return gCupCourseOrder[4][course]; + } + + if (cup < 0) { + cup = 0; + } + if (cup > 3) { + cup &= 3; + } + + switch (gTournamentCourseMode) { + case 0: + return gVACourseOrder[cup][course]; + case 1: + return gKACourseOrder[cup][course]; + case 2: + return gKAMMFCourseOrder[cup][course]; + default: + return gCupCourseOrder[cup][course]; + } +} + const s8 unref_800F2BDC[4] = { 1, 0, 0, 0 }; // Uses player count to set gScreenModeListIndex, the latter variable then selects a mode diff --git a/src/menus.h b/src/menus.h index 74617b38c5..841cf8490b 100644 --- a/src/menus.h +++ b/src/menus.h @@ -262,6 +262,7 @@ extern s8 gControllerPakScrollDirection; extern const s8 gPlayerModeSelection[]; extern const s32 gGameModePlayerSelection[][3]; extern const s16 gCupCourseOrder[NUM_CUPS][NUM_COURSES_PER_CUP]; +extern s16 get_course_id_for_tournament_cursor(s32 cupSelection, s32 courseIndexInCup); // end of menus.c variables diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index f4c09eed29..10895996ea 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -144,7 +144,6 @@ void func_8028E298(void) { } void func_8028E3A0(void) { - if (D_80150120) { if (gCourseIndexInCup == COURSE_FOUR) { From 77576dbe951018a001ac9624d306b442733958b1 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Fri, 13 Mar 2026 11:30:43 -0400 Subject: [PATCH 11/73] added some annotations to functions --- src/audio/external.c | 1 + src/racing/race_logic.c | 74 ++++++++++++++++++++++++----------------- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/audio/external.c b/src/audio/external.c index 41835ae6d1..98f8a953e7 100644 --- a/src/audio/external.c +++ b/src/audio/external.c @@ -3249,6 +3249,7 @@ void func_800CA0E4(void) { func_800C5278(5); } +// animation sequence for vs mode finish transition to vs match rankings screen void func_800CA118(u8 arg0) { D_800EA0EC[arg0] = 1; D_800E9EA4[arg0] = 1; diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index 10895996ea..5d9f556053 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -66,7 +66,10 @@ void func_8028DF38(void) { controllers++; } } - +/*This function increments a tracked statistic for the winning player + by updating a specific global array based on the current player count. + Additionally, it calls a helper function using the winner's index, + updates a state variable, and initializes the demo timer.*/ void func_8028E028(void) { switch (gPlayerCountSelection1) { @@ -529,7 +532,7 @@ void func_8028EEF0(s32 i) { // synchronizes lap counts and awards race tallies void func_8028EF28(void) { s16 currentPosition; - s32 i; + s32 i; // player index for (i = 0; i < NUM_PLAYERS; i++) { Player* player = &gPlayers[i]; @@ -544,23 +547,29 @@ void func_8028EF28(void) { if ((gPlayers[i].type & PLAYER_CINEMATIC_MODE) != 0) { continue; } - + + // handles increasing and decreasing lap count + // two diff var for tracking lap counts if (gLapCountByPlayerId[i] < gPlayers[i].lapCount) { gPlayers[i].lapCount--; } else if (gLapCountByPlayerId[i] > gPlayers[i].lapCount) { gPlayers[i].lapCount++; + // if slot has an active player if ((gPlayers[i].type & PLAYER_HUMAN) != 0) { - if (gPlayers[i].lapCount == 3) { - func_8028EEF0(i); + // if player i finishes (crosses into lap 4) + if (gPlayers[i].lapCount == 3) { // 3 = lap 4 + func_8028EEF0(i); // finish sequence - currentPosition = gPlayers[i].currentRank; - gPlayers[i].type |= PLAYER_CPU; + currentPosition = gPlayers[i].currentRank; // store rank as currentPosition + gPlayers[i].type |= PLAYER_CPU; // cpu take over finishing player - if (currentPosition < 4) { + // sets flag after any player finishes lap 4 + if (currentPosition < 4) { D_80150120 = 1; } + // ? func_800CA118((u8) i); if ((D_802BA032 & PLAYER_EXISTS) == 0) { D_802BA032 |= PLAYER_EXISTS; @@ -578,58 +587,61 @@ void func_8028EF28(void) { if (gModeSelection == VERSUS) { gDemoTimer = 180; - if (currentPosition == 0) { + if (currentPosition == 0) { // winning player gPlayerWinningIndex = i; } switch (gPlayerCountSelection1) { - // 2 player? + // 2p vs case 2: - if (currentPosition == 0) { - *(gNmiUnknown1 + i) += 1; + // currentPosition = position of player i when crossing finish line + // 1st is 0, 2nd is 1, 3rd is 2, 4th is 3 + if (currentPosition == 0 ) { // when first finishes + *(gNmiUnknown1 + i) += 1; // add tally } - if (*(gNmiUnknown1 + i) > 99) { + if (*(gNmiUnknown1 + i) > 99) { // 99 tally limit? *(gNmiUnknown1 + i) = 99; } D_800DC510 = 5; - i = gPlayerPositionLUT[1]; - gPlayers[i].triggers |= SPINOUT_TRIGGER; - gPlayers[i].type |= PLAYER_CPU; - func_800CA118((u8) i); + i = gPlayerPositionLUT[1]; // get 2nd place player position + gPlayers[i].triggers |= SPINOUT_TRIGGER; // spin out 2nd place player + gPlayers[i].type |= PLAYER_CPU; // cpu control 2nd place player + func_800CA118((u8) i); // call animation sequence, pass in losing player idx as parameter? break; - // 3 player? + // 3p case 3: - if (currentPosition < 3) { + if (currentPosition < 3 ) { // when any player finishes (all players get tallies) *(gNmiUnknown2 + i * 3 + currentPosition) += 1; } if (*(gNmiUnknown2 + i * 3 + currentPosition) > 99) { *(gNmiUnknown2 + i * 3 + currentPosition) = 99; } - if (currentPosition == 1) { + if (currentPosition == 1 ) { // when 2nd finishes D_800DC510 = 5; - i = gPlayerPositionLUT[2]; + i = gPlayerPositionLUT[2]; // get 3rd place player position *(gNmiUnknown2 + i * 3 + 2) += 1; if (*(gNmiUnknown2 + i * 3 + 2) > 99) { *(gNmiUnknown2 + i * 3 + 2) = 99; } - gPlayers[i].triggers |= SPINOUT_TRIGGER; - gPlayers[i].type |= PLAYER_CPU; - func_800CA118((u8) i); + gPlayers[i].triggers |= SPINOUT_TRIGGER; // spin out 3rd place player + gPlayers[i].type |= PLAYER_CPU; // cpu control 3rd place + func_800CA118((u8) i); // call animation sequence, pass in losing player idx as parameter? } break; - // 4 player? + // 4p case 4: - if (currentPosition < 3) { + // 4th place gets no tally + if (currentPosition < 3 ) { // only when 1st, 2nd, 3rd finish *(gNmiUnknown3 + i * 3 + currentPosition) += 1; } if (*(gNmiUnknown3 + i * 3 + currentPosition) > 99) { *(gNmiUnknown3 + i * 3 + currentPosition) = 99; } - if (currentPosition == 2) { + if (currentPosition == 2 ) { // when 3rd finishes D_800DC510 = 5; - i = gPlayerPositionLUT[3]; - gPlayers[i].triggers |= SPINOUT_TRIGGER; - gPlayers[i].type |= PLAYER_CPU; - func_800CA118((u8) i); + i = gPlayerPositionLUT[3]; // get 4th place player position + gPlayers[i].triggers |= SPINOUT_TRIGGER; // spin out 4th place + gPlayers[i].type |= PLAYER_CPU; // cpu control 4th place + func_800CA118((u8) i); // call animation sequence, pass in losing player idx as parameter? } break; } From d31770b0090b814d3774237bc45037f7c242a165 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Fri, 13 Mar 2026 13:26:16 -0400 Subject: [PATCH 12/73] fixed lightning to be single white pulse --- src/menu_items.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index a818424b64..6fc1431491 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -743,9 +743,11 @@ const s8 D_800F0B1C[] = { }; // lightning flash pattern +// changed two zeros (indices 8 and 9) to 1 +// changed all twos to 1 const s8 D_800F0B28[] = { - 0, 1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 1, 2, 2, 1, 2, 2, 1, 2, 2, - 1, 2, 2, 1, 2, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, }; const s8 D_800F0B50[] = { 0x1f, 0x0b, 0x15, 0x29 }; @@ -754,9 +756,9 @@ const s8 D_800F0B54[] = { 0x20, 0x0f, 0x18, 0x2c }; // lightning flash color palette RGBA16 D_800E7AC8[] = { { 0x00, 0x00, 0x00, 0x00 }, // background, clear - { 0x00, 0x00, 0x90, 0xff }, // changed to mid blue from white + { 0xff, 0xff, 0xff, 0xff }, // white { 0x00, 0x00, 0x50, 0xff }, // dark blue - { 0xff, 0xff, 0x90, 0xff }, // changed to mid blue from white + { 0xff, 0xff, 0xff, 0xff }, // white }; RGBA16 D_800E7AE8[] = { From a3339082851b094962697bacd01bd17e0e2732f0 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sat, 14 Mar 2026 21:02:38 -0400 Subject: [PATCH 13/73] finished track order implementation, and menu toggle for it works too --- src/menu_items.c | 18 +++++++++++++++--- src/menus.c | 4 ++-- src/racing/race_logic.c | 19 ++++++++++++++++++- src/racing/race_logic.h | 1 + 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index 6fc1431491..4805a06e90 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -363,9 +363,9 @@ s8 gTournamentCourseMode = 0; // Course name abbreviations for each tournament mode char* gCourseNamesVA[] = { - "LR", "MMF", "KTB", "KD", + "WS", "MMF", "KTB", "KD", "DKJP", "YV", "BB", "RRd", - "WS", "SL", "RRy", "BC", + "LR", "SL", "RRy", "BC", "TT", "FS", "CM", "MR" }; @@ -4652,6 +4652,7 @@ void func_8009CE1C(void) { } } +// fade out transition for versus menu void func_8009CE64(s32 arg0) { s32 thing; s32 var_a1; @@ -4689,16 +4690,26 @@ void func_8009CE64(s32 arg0) { if (temp_v0 != NULL) { switch (temp_v0->state) { /* switch 8; irregular */ case 10: /* switch 8 */ - func_802903B0(); + if (gModeSelection == VERSUS) { + // custom function: go to next track + gotoNextTrack(); + } + else { + // retry (vs mode) + func_802903B0(); + } break; case 11: /* switch 8 */ + // course change (vs mode) func_80290388(); break; case 12: /* switch 8 */ + // driver change (vs mode) func_80290360(); break; default: /* switch 8 */ case 13: /* switch 8 */ + // quit (vs mode) func_80290338(); break; } @@ -11316,6 +11327,7 @@ void func_800ACC50(MenuItem* arg0) { arg0->subState = 1; } } + // input handling for versus menu if (gControllerFive->buttonPressed & 0x9000) { func_8009DFE0(0x0000001E); play_sound2(SOUND_MENU_OK_CLICKED); diff --git a/src/menus.c b/src/menus.c index 125d42f5f8..4390314ba8 100644 --- a/src/menus.c +++ b/src/menus.c @@ -161,11 +161,11 @@ const s16 gCupCourseOrder[5][4] = { // va course order const s16 gVACourseOrder[4][4] = { // mushroom cup - { COURSE_LUIGI_RACEWAY, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, + { COURSE_WARIO_STADIUM, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, // special cup { COURSE_DK_JUNGLE, COURSE_YOSHI_VALLEY, COURSE_BANSHEE_BOARDWALK, COURSE_RAINBOW_ROAD }, // star cup - { COURSE_WARIO_STADIUM, COURSE_SHERBET_LAND, COURSE_ROYAL_RACEWAY, COURSE_BOWSER_CASTLE }, + { COURSE_LUIGI_RACEWAY, COURSE_SHERBET_LAND, COURSE_ROYAL_RACEWAY, COURSE_BOWSER_CASTLE }, // flower cup { COURSE_TOADS_TURNPIKE, COURSE_FRAPPE_SNOWLAND, COURSE_CHOCO_MOUNTAIN, COURSE_MARIO_RACEWAY } }; diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index 5d9f556053..0085d30de4 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -35,6 +35,7 @@ extern u16 D_802BA048; extern s32 D_8018D2AC; extern s32 D_802B91E0; +extern s16 getNextCourseId(void); u16 D_802BA030; u16 D_802BA032; @@ -1131,13 +1132,29 @@ void func_80290388(void) { gQuitToMenuTransitionCounter = 5; gGotoMode = COURSE_SELECT_MENU_FROM_QUIT; } - +// retry function void func_802903B0(void) { gIsInQuitToMenuTransition = 1; gQuitToMenuTransitionCounter = 5; gGotoMode = RACING; } +// proceed to next track in selection (vs mode only) +void gotoNextTrack(void) { + s16 nextCourse; + s32 nextLinearIndex; + + gIsInQuitToMenuTransition = 1; + gQuitToMenuTransitionCounter = 5; + nextLinearIndex = (((s32) gCupSelection * 4) + gCourseIndexInCup + 1) & 0xF; + nextCourse = getNextCourseId(); + gCurrentCourseId = nextCourse; + gCupSelection = nextLinearIndex / 4; + D_800DC540 = gCupSelection; + gCourseIndexInCup = nextLinearIndex % 4; + gGotoMode = RACING; +} + void func_802903D8(Player* playerOne, Player* playerTwo) { f32 sp70 = (playerOne->boundingBoxSize + playerTwo->boundingBoxSize) - 5.0f; f32 temp_f0; diff --git a/src/racing/race_logic.h b/src/racing/race_logic.h index 3ab60a14ec..b10f9ce7da 100644 --- a/src/racing/race_logic.h +++ b/src/racing/race_logic.h @@ -34,6 +34,7 @@ void func_80290338(void); void func_80290360(void); void func_80290388(void); void func_802903B0(void); +void gotoNextTrack(void); void func_802909F0(void); void func_80290B14(void); From 5df0ca5d9b20a3e2f14faee2297f8ca72aba39a8 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sun, 15 Mar 2026 11:26:39 -0400 Subject: [PATCH 14/73] made the same character selectable from player select screen --- src/menus.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/menus.c b/src/menus.c index 4390314ba8..2460700d53 100644 --- a/src/menus.c +++ b/src/menus.c @@ -1619,14 +1619,15 @@ void main_menu_act(struct Controller* controller, u16 controllerIdx) { /** * Check if there is no currently selected and/or * hovered character at grid position `gridId` + * changed to always return true so that any character can be selected multiple times */ bool is_character_spot_free(s32 gridId) { - s32 i; - for (i = 0; i < ARRAY_COUNT(gCharacterGridSelections); i++) { - if (gridId == gCharacterGridSelections[i]) { - return false; - } - } + // s32 i; + // for (i = 0; i < ARRAY_COUNT(gCharacterGridSelections); i++) { + // if (gridId == gCharacterGridSelections[i]) { + // return false; + // } + // } return true; } @@ -1689,6 +1690,7 @@ void player_select_menu_act(struct Controller* controller, u16 controllerIdx) { break; } j = gCharacterGridSelections[controllerIdx]; + // navigation in character select menu if ((btnAndStick & R_JPAD) && (btnAndStick & D_JPAD)) { if ((gCharacterGridSelections[controllerIdx] == 1U) || (gCharacterGridSelections[controllerIdx] == 2U) || (gCharacterGridSelections[controllerIdx] == 3U)) { j = gCharacterGridSelections[controllerIdx] + 5; @@ -1774,7 +1776,8 @@ void player_select_menu_act(struct Controller* controller, u16 controllerIdx) { if ((btnAndStick & D_JPAD) && (gCharacterGridSelections[controllerIdx] < 5)) { j = gCharacterGridSelections[controllerIdx] + 4; } - if (is_character_spot_free(j)) { + // play SOUND_MENU_CURSOR_MOVE when the cursor index changes instead of when character is free to select + if ((j != gCharacterGridSelections[controllerIdx])) { gCharacterGridSelections[controllerIdx] = j; play_sound2(SOUND_MENU_CURSOR_MOVE); } From e247cb992f369322b109809234cd8bc445397b58 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Fri, 20 Mar 2026 11:50:16 -0400 Subject: [PATCH 15/73] disabled c-right noise when toggling progress view and map view in versus mode --- src/code_80057C60.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 9d6619977e..2a3f10691e 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -1559,7 +1559,8 @@ void func_8005A3C0(void) { break; } if (b) { - func_8006F824(1); + // this the sound for the progress view toggle + // func_8006F824(1); } } } From 6cefd2a48d2ee66323d2a246376cf3b5eaabf228 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Fri, 20 Mar 2026 12:00:48 -0400 Subject: [PATCH 16/73] disabled c-up noise when toggling between zoomed in and zoomed out --- src/cpu_vehicles_camera_path.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cpu_vehicles_camera_path.c b/src/cpu_vehicles_camera_path.c index 26fa50d4ae..97e2436a84 100644 --- a/src/cpu_vehicles_camera_path.c +++ b/src/cpu_vehicles_camera_path.c @@ -3508,19 +3508,20 @@ void func_80019B50(s32 cameraIndex, u16 arg1) { D_801646C0[cameraIndex] = (s16) var_v0; } +// plays respective camera zoom in/out sound; sounds have been disabled void func_80019C50(s32 playerIndex) { switch (D_80164678[playerIndex]) { case 0: if (D_80164608[playerIndex] == 1) { D_80164678[playerIndex] = 1; - func_800C9060(playerIndex, SOUND_ARG_LOAD(0x19, 0x00, 0x90, 0x4F)); + // func_800C9060(playerIndex, SOUND_ARG_LOAD(0x19, 0x00, 0x90, 0x4F)); D_80164670[playerIndex] = D_80164678[playerIndex]; } break; case 1: if (D_80164608[playerIndex] == 1) { D_80164678[playerIndex] = 0; - func_800C9060(playerIndex, SOUND_ARG_LOAD(0x19, 0x00, 0x90, 0x50)); + // func_800C9060(playerIndex, SOUND_ARG_LOAD(0x19, 0x00, 0x90, 0x50)); D_80164670[playerIndex] = D_80164678[playerIndex]; } break; @@ -3615,6 +3616,7 @@ void func_80019FB4(s32 cameraId) { } } +// calls functions that zoom in/out camera, playing sound void func_8001A0A4(UNUSED u16* arg0, UNUSED Camera* arg1, UNUSED Player* arg2, UNUSED s8 arg3, s32 arg4) { func_80019FB4(arg4); func_80019C50(arg4); From dbf38ec75b55bee44e455d9499c98c5d3e548a7c Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sat, 21 Mar 2026 08:25:01 -0400 Subject: [PATCH 17/73] implemented delayed pausing; players must hold down the pause button for one second in vs mode in order to pause the game --- src/racing/race_logic.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index 0085d30de4..2832f176a1 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -819,6 +819,7 @@ void func_8028F914(void) { void func_8028F970(void) { s32 i; + static u16 sPauseHoldCounter[4]; if (D_8015F890) { return; @@ -849,13 +850,15 @@ void func_8028F970(void) { func_800029B0(); } } - if ((controller->buttonPressed & START_BUTTON) && (!(controller->button & R_TRIG)) && - (!(controller->button & L_TRIG))) { + // pausing is gated by sPauseHoldCounter, which increments every frame player i holds start + if ((controller->button & START_BUTTON) && (!(controller->button & R_TRIG)) && + (!(controller->button & L_TRIG)) && (sPauseHoldCounter[i] >= 60)) { func_8028DF00(); gIsGamePaused = (controller - gControllerOne) + 1; controller->buttonPressed = 0; func_800C9F90(1); gPauseTriggered = 1; + sPauseHoldCounter[i] = 0; if (gModeSelection == TIME_TRIALS) { if (gPlayerOne->type & (PLAYER_EXISTS | PLAYER_INVISIBLE_OR_BOMB)) { func_80005AE8(gPlayerOne); @@ -869,6 +872,15 @@ void func_8028F970(void) { } return; } + // increment pause counter for player i + if ((controller->button & START_BUTTON) && (!(controller->button & R_TRIG)) && + (!(controller->button & L_TRIG)) && (sPauseHoldCounter[i] < 60)) { + ++sPauseHoldCounter[i]; + } + // reset pause counter if player i is not holding down start + if (!(controller->button & START_BUTTON)) { + sPauseHoldCounter[i] = 0; + } } if (gEnableDebugMode) { From 9f65a27e9dbda2e7372c288a03915ba35286a3ab Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 23 Mar 2026 07:41:09 -0400 Subject: [PATCH 18/73] added some annotations on where to change game tempo for emulator play --- src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 3bef72c4f0..f88a14328b 100644 --- a/src/main.c +++ b/src/main.c @@ -754,7 +754,7 @@ void race_logic_loop(void) { case COURSE_MOO_MOO_FARM: case COURSE_SKYSCRAPER: case COURSE_DK_JUNGLE: - gTickSpeed = 3; + gTickSpeed = 3; // change to 2 for emu break; default: gTickSpeed = 2; @@ -769,10 +769,10 @@ void race_logic_loop(void) { gTickSpeed = 2; break; case COURSE_DK_JUNGLE: - gTickSpeed = 4; + gTickSpeed = 4; // change to 2 for emu break; default: - gTickSpeed = 3; + gTickSpeed = 3; // change to 2 for emu break; } } From 372170b11fe5d5fe669e1c0311fbadce790b628a Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 23 Mar 2026 08:41:02 -0400 Subject: [PATCH 19/73] implemented start menu enhancements; removed press start to play; made background dimmer; updated credits and date; added rainbow effect to menu text --- src/menu_items.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index 4805a06e90..252b1d91cd 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -2410,12 +2410,12 @@ void setup_menus(void) { add_menu_item(MENU_ITEM_TYPE_0D9, 0, 0, MENU_ITEM_PRIORITY_A); break; case START_MENU: - // maybe remove background from start menu - // add_menu_item(MENU_ITEM_UI_LOGO_AND_COPYRIGHT, 0, 0, MENU_ITEM_PRIORITY_4); - // add_menu_item(MENU_ITEM_UI_START_BACKGROUND, 0, 0, MENU_ITEM_PRIORITY_0); - // add_menu_item(START_MENU_FLAG, 0, 0, MENU_ITEM_PRIORITY_0); + // comment to remove background from start menu + add_menu_item(MENU_ITEM_UI_LOGO_AND_COPYRIGHT, 0, 0, MENU_ITEM_PRIORITY_4); + add_menu_item(MENU_ITEM_UI_START_BACKGROUND, 0, 0, MENU_ITEM_PRIORITY_0); + add_menu_item(START_MENU_FLAG, 0, 0, MENU_ITEM_PRIORITY_0); if (gControllerBits & 1) { - add_menu_item(MENU_ITEM_UI_PUSH_START_BUTTON, 0, 0, MENU_ITEM_PRIORITY_2); + // add_menu_item(MENU_ITEM_UI_PUSH_START_BUTTON, 0, 0, MENU_ITEM_PRIORITY_2); } else { add_menu_item(MENU_ITEM_UI_NO_CONTROLLER, 0, 0, MENU_ITEM_PRIORITY_2); } @@ -5839,8 +5839,8 @@ void render_custom_overlay(void) { set_text_color(TEXT_YELLOW); - // title (centered) - smaller - print_text1_center_mode_1(x, y - 0x30, "WEATHERTON ABNEY CLIMATEE", 0, 0.80f, 0.80f); + // title (centered) + print_text1_center_mode_1(x, y - 0x30, "WEATHERTON ABNEY CLIMATEE ZSERF", 0, 0.80f, 0.80f); // /* use debug font helper */ // x1 = 0; @@ -5848,7 +5848,7 @@ void render_custom_overlay(void) { // func_800579B8(x1, y1, "WEATHERTON ABNEY CLIMATEE"); // version / date (smaller) - left-aligned to start under 'KART' - print_text1_left(x + 0x5A, y + 0x06, "TE V2026-02-22", 0, 0.65f, 0.65f); + print_text1_left(x + 0x5A, y + 0x06, "TE V2026-03-23", 0, 0.65f, 0.65f); // option name placeholders (second column) and values (third column) for (i = 0; i < CUSTOM_MENU_ROWS; i++) { @@ -5871,6 +5871,7 @@ void render_custom_overlay(void) { /* second column: option name (single line) */ if (customModifierNames[i][0] != '\0') { + text_rainbow_effect(gCustomMenuSelection, i, TEXT_YELLOW); print_text_mode_1(x - 0x30, rowY, (char*)customModifierNames[i], 0, 0.6f, 0.6f); } else { /* Build "Modifier N" manually to avoid linking snprintf */ @@ -5889,6 +5890,7 @@ void render_custom_overlay(void) { } nameBuf[pos] = '\0'; // default case i guess + text_rainbow_effect(gCustomMenuSelection, i, TEXT_YELLOW); print_text_mode_1(x - 0x30, rowY, nameBuf, 0, 0.6f, 0.6f); } @@ -6085,6 +6087,12 @@ void render_menus(MenuItem* arg0) { render_game_logo((arg0->column + 0xA0), (arg0->row + 0x47)); gDisplayListHead = render_menu_textures(gDisplayListHead, seg2_copyright_1996_texture, arg0->column, arg0->row); + // Full-screen dimmer (black with alpha) + gDisplayListHead = draw_box( + gDisplayListHead, + 0, 0, 320, 240, + 0, 0, 0, 120 + ); break; case MENU_ITEM_UI_PUSH_START_BUTTON: /* switch 6 */ if (((gGlobalTimer / 8) % 3) != 0) { From f3b53a041c4bd12b776f615368ef1d56cac6f6d1 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 23 Mar 2026 10:46:54 -0400 Subject: [PATCH 20/73] updated custom title menu overlay --- src/menu_items.c | 109 +++++++++++++++++++++++------------------------ src/menus.c | 10 +++-- 2 files changed, 60 insertions(+), 59 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index 252b1d91cd..bd40814549 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -5808,34 +5808,34 @@ void render_custom_overlay(void) { /* Menu items; if an entry is empty, fallback to "Modifier N" */ static const char* customModifierNames[CUSTOM_MENU_ROWS] = { "tracks", + "stats", "scaling", "widescreen", "mp music", - "mp train", - "mp boat", - "", + "mp train boat", + "AA", + "shell limit", "vs timer", - "stats", - "", - "tie logic", - "mirror", - "" /* keep last empty if CUSTOM_MENU_ROWS > 12 */ + "trophy", + "practice", + "extra", + "reverse" /* keep last empty if CUSTOM_MENU_ROWS > 12 */ }; /* per-option label arrays */ static const char* tracks_labels[] = {"VA", "kalliera", "kalliera mmf"}; + static const char* stats_labels[] = {"all yoshi", "default"}; static const char* scaling_labels[] = {"default", "30fps", "60fps"}; static const char* widescreen_labels[] = {"default", "enabled"}; static const char* mpMusic_labels[] = {"default", "enabled"}; - static const char* mpTrain_labels[] = {"default", "full"}; - static const char* mpBoat_labels[] = {"default", "enabled"}; - static const char* opt6_labels[] = {"1"}; + static const char* mpTrainBoat_labels[] = {"default", "enabled", "train", "boat"}; + static const char* AA_labels[] = {"default", "disabled"}; + static const char* shell_labels[] = {"default", "100"}; static const char* timer_labels[] = {"default", "enabled"}; - static const char* stats_labels[] = {"all yoshi", "default"}; - static const char* opt10_labels[] = {"1"}; - static const char* tieLogic_labels[] = {"timer", "port"}; - static const char* mirror_labels[] = {"default", "enabled"}; - static const char* opt13_labels[] = {"1"}; + static const char* trophy_labels[] = {"default", "enabled"}; + static const char* practice_labels[] = {"default", "enabled"}; + static const char* extra_labels[] = {"default", "enabled"}; + static const char* reverse_labels[] = {"default", "enabled"}; set_text_color(TEXT_YELLOW); @@ -5863,7 +5863,6 @@ void render_custom_overlay(void) { cursorItem.paramf = 2.0f; /* start scale/rotation multiplier */ cursorItem.subState = 1; /* small non-zero rotation driver */ func_800A66A8(&cursorItem, &sp84); - //print_text_mode_1(x - 0x40, rowY, "X", 0, 0.6f, 0.6f); } else { /* draw empty space to keep alignment */ print_text1_left(x - 0x30, rowY, " ", 0, 0.6f, 0.6f); @@ -5891,7 +5890,7 @@ void render_custom_overlay(void) { nameBuf[pos] = '\0'; // default case i guess text_rainbow_effect(gCustomMenuSelection, i, TEXT_YELLOW); - print_text_mode_1(x - 0x30, rowY, nameBuf, 0, 0.6f, 0.6f); + print_text_mode_1(x - 0x20, rowY, nameBuf, 0, 0.6f, 0.6f); } /* third column: current value for this row */ @@ -5901,92 +5900,92 @@ void render_custom_overlay(void) { idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; if (idx >= (int)(sizeof(tracks_labels) / sizeof(tracks_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x40, rowY, (char*)tracks_labels[idx], 0, 0.6f, 0.6f); + print_text1_center_mode_1(x + 0x50, rowY, (char*)tracks_labels[idx], 0, 0.6f, 0.6f); gTournamentCourseMode = idx; // set track order break; case 1: - /* scaling: labels (default, 30fps, 60fps) */ + /* stats: labels (default, all yoshi) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(scaling_labels) / sizeof(scaling_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x40, rowY, (char*)scaling_labels[idx], 0, 0.6f, 0.6f); + if (idx >= (int)(sizeof(stats_labels) / sizeof(stats_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)stats_labels[idx], 0, 0.6f, 0.6f); break; case 2: - /* widescreen: labels (default, enabled) */ + /* scaling: labels (default, 30fps, 60fps) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(widescreen_labels) / sizeof(widescreen_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x40, rowY, (char*)widescreen_labels[idx], 0, 0.6f, 0.6f); + if (idx >= (int)(sizeof(scaling_labels) / sizeof(scaling_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)scaling_labels[idx], 0, 0.6f, 0.6f); break; case 3: - /* mp music: labels (default, enabled) */ + /* widescreen: labels (default, enabled) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(mpMusic_labels) / sizeof(mpMusic_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x40, rowY, (char*)mpMusic_labels[idx], 0, 0.6f, 0.6f); + if (idx >= (int)(sizeof(widescreen_labels) / sizeof(widescreen_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)widescreen_labels[idx], 0, 0.6f, 0.6f); break; case 4: - /* mp train: labels (default, full) */ + /* mp music: labels (default, enabled) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(mpTrain_labels) / sizeof(mpTrain_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x40, rowY, (char*)mpTrain_labels[idx], 0, 0.6f, 0.6f); + if (idx >= (int)(sizeof(mpMusic_labels) / sizeof(mpMusic_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)mpMusic_labels[idx], 0, 0.6f, 0.6f); break; case 5: - /* mp boat: labels (default, enabled) */ + /* mp train boat: labels (default, both, train, boat) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(mpBoat_labels) / sizeof(mpBoat_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x40, rowY, (char*)mpBoat_labels[idx], 0, 0.6f, 0.6f); + if (idx >= (int)(sizeof(mpTrainBoat_labels) / sizeof(mpTrainBoat_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)mpTrainBoat_labels[idx], 0, 0.6f, 0.6f); break; case 6: - /* */ + /* AA */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(opt6_labels) / sizeof(opt6_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x40, rowY, (char*)opt6_labels[idx], 0, 0.6f, 0.6f); + if (idx >= (int)(sizeof(AA_labels) / sizeof(AA_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)AA_labels[idx], 0, 0.6f, 0.6f); break; case 7: - /* vs timer: labels (default, enabled) */ + /* shell limit: labels (default, 100) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(timer_labels) / sizeof(timer_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x40, rowY, (char*)timer_labels[idx], 0, 0.6f, 0.6f); + if (idx >= (int)(sizeof(shell_labels) / sizeof(shell_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)shell_labels[idx], 0, 0.6f, 0.6f); break; case 8: - /* stats: labels (default, all yoshi) */ + /* vs timer: labels (default, enabled) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(stats_labels) / sizeof(stats_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x40, rowY, (char*)stats_labels[idx], 0, 0.6f, 0.6f); + if (idx >= (int)(sizeof(timer_labels) / sizeof(timer_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)timer_labels[idx], 0, 0.6f, 0.6f); break; case 9: - /* */ + /* trophy ceremony: labels (default, enabled) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(opt10_labels) / sizeof(opt10_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x40, rowY, (char*)opt10_labels[idx], 0, 0.6f, 0.6f); + if (idx >= (int)(sizeof(trophy_labels) / sizeof(trophy_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)trophy_labels[idx], 0, 0.6f, 0.6f); break; case 10: - /* tie logic: labels (timer, port) */ + /* practice mode: labels (default, enabled) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(tieLogic_labels) / sizeof(tieLogic_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x40, rowY, (char*)tieLogic_labels[idx], 0, 0.6f, 0.6f); + if (idx >= (int)(sizeof(practice_labels) / sizeof(practice_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)practice_labels[idx], 0, 0.6f, 0.6f); break; case 11: - /* mirror: labels (default, enabled) */ + /* extra: labels (default, enabled) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(mirror_labels) / sizeof(mirror_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x40, rowY, (char*)mirror_labels[idx], 0, 0.6f, 0.6f); + if (idx >= (int)(sizeof(extra_labels) / sizeof(extra_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)extra_labels[idx], 0, 0.6f, 0.6f); break; case 12: - /* */ + /* reverse: labels (default, enabled) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(opt13_labels) / sizeof(opt13_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x40, rowY, (char*)opt13_labels[idx], 0, 0.6f, 0.6f); + if (idx >= (int)(sizeof(reverse_labels) / sizeof(reverse_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)reverse_labels[idx], 0, 0.6f, 0.6f); break; } } diff --git a/src/menus.c b/src/menus.c index 2460700d53..01d06c96f2 100644 --- a/src/menus.c +++ b/src/menus.c @@ -247,7 +247,9 @@ s8 gCustomMenuSelection = 0; s8 gCustomMenuOptionValues[CUSTOM_MENU_ROWS] = { 0 }; // Per-row number of selectable values (matches label arrays in render_custom_overlay) -static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 3, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 1 }; +// tracks, stats, scaling, widescreen, mp music, mp train boat, AA, shell limit, +// vs timer, trophy, practice, extra, reverse +static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 2, 3, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2 }; // end of new var init @@ -1146,7 +1148,7 @@ void splash_menu_act(struct Controller* controller, u16 controllerIdx) { if (gCustomMenuSelection == 0) { gOptions.tracks = (gCustomMenuOptionValues[0] == 2) ? TRACKS_RANDOM : TRACKS_DEFAULT; } - play_sound2(SOUND_MENU_OK); + play_sound2(SOUND_MENU_SELECT); } // go backwards one if press left dpad and not at first index else if (btnAndStick & L_JPAD && (gCustomMenuOptionValues[gCustomMenuSelection] != 0) ) { @@ -1155,7 +1157,7 @@ void splash_menu_act(struct Controller* controller, u16 controllerIdx) { if (gCustomMenuSelection == 0) { gOptions.tracks = (gCustomMenuOptionValues[0] == 2) ? TRACKS_RANDOM : TRACKS_DEFAULT; } - play_sound2(SOUND_MENU_OK); + play_sound2(SOUND_MENU_SELECT); } // go to end if press left dpad at first index else if (btnAndStick & L_JPAD && (gCustomMenuOptionValues[gCustomMenuSelection] == 0) ) { @@ -1165,7 +1167,7 @@ void splash_menu_act(struct Controller* controller, u16 controllerIdx) { if (gCustomMenuSelection == 0) { gOptions.tracks = (gCustomMenuOptionValues[0] == 2) ? TRACKS_RANDOM : TRACKS_DEFAULT; } - play_sound2(SOUND_MENU_OK); + play_sound2(SOUND_MENU_SELECT); } } switch (gDebugMenuSelection) { From 7514ebfb7289a0177091190853d749a2eef8173b Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 23 Mar 2026 14:27:28 -0400 Subject: [PATCH 21/73] implemented scaling menu option --- src/main.c | 106 ++++++++++++++++++++++++++++++++++++++++++++--- src/menu_items.c | 26 +++++++++++- src/menu_items.h | 14 ++++++- src/menus.c | 2 +- 4 files changed, 139 insertions(+), 9 deletions(-) diff --git a/src/main.c b/src/main.c index f88a14328b..1aed604ac7 100644 --- a/src/main.c +++ b/src/main.c @@ -469,7 +469,13 @@ void display_and_vsync(void) { osRecvMesg(&gGameVblankQueue, &gMainReceivedMesg, OS_MESG_BLOCK); osViSwapBuffer((void*) PHYSICAL_TO_VIRTUAL(gPhysicalFramebuffers[sRenderedFramebuffer])); profiler_log_thread5_time(THREAD5_END); - osRecvMesg(&gGameVblankQueue, &gMainReceivedMesg, OS_MESG_BLOCK); + + // Keep original 30 FPS sync outside of race gameplay (menus/credits/etc). + // Only skip the second vblank during racing when 60 FPS mode is selected. + if (!(gTournamentScaling == 2 && gGamestate == RACING)) { + osRecvMesg(&gGameVblankQueue, &gMainReceivedMesg, OS_MESG_BLOCK); + } + crash_screen_set_framebuffer(gPhysicalFramebuffers[sRenderedFramebuffer]); if (++sRenderedFramebuffer == 3) { @@ -478,6 +484,7 @@ void display_and_vsync(void) { if (++sRenderingFramebuffer == 3) { sRenderingFramebuffer = 0; } + gGlobalTimer++; } @@ -598,7 +605,14 @@ void race_logic_loop(void) { switch (gActiveScreenMode) { case SCREEN_MODE_1P: + // 60fps + if (gTournamentScaling == 2) { + gTickSpeed = 1; + } + // 30fps + else { gTickSpeed = 2; + } replays_loop(); if (gIsGamePaused == 0) { for (i = 0; i < gTickSpeed; i++) { @@ -657,11 +671,22 @@ void race_logic_loop(void) { break; case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: + // default + if (gTournamentScaling == 0) { if (gCurrentCourseId == COURSE_DK_JUNGLE) { gTickSpeed = 3; } else { gTickSpeed = 2; } + } + // 30 fps no lag + else if (gTournamentScaling == 1) { + gTickSpeed = 2; + } + // 60 fps + else if (gTournamentScaling == 2) { + gTickSpeed = 1; + } if (gIsGamePaused == 0) { for (i = 0; i < gTickSpeed; i++) { if (D_8015011E != 0) { @@ -702,11 +727,22 @@ void race_logic_loop(void) { case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: + // default + if (gTournamentScaling == 0) { if (gCurrentCourseId == COURSE_DK_JUNGLE) { gTickSpeed = 3; } else { gTickSpeed = 2; } + } + // 30 fps no lag + else if (gTournamentScaling == 1) { + gTickSpeed = 2; + } + // 60 fps + else if (gTournamentScaling == 2) { + gTickSpeed = 1; + } if (gIsGamePaused == 0) { for (i = 0; i < gTickSpeed; i++) { @@ -754,11 +790,37 @@ void race_logic_loop(void) { case COURSE_MOO_MOO_FARM: case COURSE_SKYSCRAPER: case COURSE_DK_JUNGLE: - gTickSpeed = 3; // change to 2 for emu + // 30 fps scaling (no lag) + if (gTournamentScaling == 1) { + gTickSpeed = 2; break; + } + // default scaling + else if (gTournamentScaling == 0) { + gTickSpeed = 3; + break; + } + else if (gTournamentScaling == 2) { + gTickSpeed = 1; + break; + } default: + // 30 fps scaling (no lag) + if (gTournamentScaling == 1) { gTickSpeed = 2; break; + } + // default + else if (gTournamentScaling == 0) { + gTickSpeed = 2; + break; + } + // 60fps + else if (gTournamentScaling == 2) { + gTickSpeed = 1; + break; + } + } } else { // Four players @@ -766,14 +828,46 @@ void race_logic_loop(void) { case COURSE_BLOCK_FORT: case COURSE_DOUBLE_DECK: case COURSE_BIG_DONUT: + if (gTournamentScaling == 2) { + gTickSpeed = 1; + break; + } + else { gTickSpeed = 2; break; + } case COURSE_DK_JUNGLE: - gTickSpeed = 4; // change to 2 for emu - break; + // 30 fps scaling (no lag) + if (gTournamentScaling == 1) { + gTickSpeed = 2; + break; + } + // default scaling + else if (gTournamentScaling == 0) { + gTickSpeed = 4; + break; + } + // 60 fps + else if (gTournamentScaling == 2) { + gTickSpeed = 1; + break; + } default: - gTickSpeed = 3; // change to 2 for emu - break; + // 30 fps scaling (no lag) + if (gTournamentScaling == 1) { + gTickSpeed = 2; + break; + } + // default scaling + else if (gTournamentScaling == 0) { + gTickSpeed = 3; + break; + } + // 60 fps + else if (gTournamentScaling == 2) { + gTickSpeed = 1; + break; + } } } if (gIsGamePaused == 0) { diff --git a/src/menu_items.c b/src/menu_items.c index bd40814549..afbea2184a 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -358,8 +358,20 @@ s8 gCupSelectionByCourseId[] = { #include "assets/course_metadata/gCupSelectionByCourseId.inc.c" }; -// Tournament course sequence mode: 0 = VA, 1 = KA, 2 = KA_MMF s8 gTournamentCourseMode = 0; +s8 gTournamentCharacterStats = 0; +s8 gTournamentScaling = 0; +s8 gTournamentWidescreen = 0; +s8 gTournamentMusic = 0; +s8 gTournamentTrainBoat = 0; +s8 gTournamentAA = 0; +s8 gTournamentShellLimit = 0; +s8 gTournamentTimer = 0; +s8 gTournamentTrophy = 0; +s8 gPracticeMode = 0; +s8 gTournamentExtraMode = 0; +s8 gTournamentReverseMode = 0; + // Course name abbreviations for each tournament mode char* gCourseNamesVA[] = { @@ -5909,6 +5921,7 @@ void render_custom_overlay(void) { if (idx < 0) idx = 0; if (idx >= (int)(sizeof(stats_labels) / sizeof(stats_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x50, rowY, (char*)stats_labels[idx], 0, 0.6f, 0.6f); + gTournamentCharacterStats = idx; break; case 2: /* scaling: labels (default, 30fps, 60fps) */ @@ -5916,6 +5929,7 @@ void render_custom_overlay(void) { if (idx < 0) idx = 0; if (idx >= (int)(sizeof(scaling_labels) / sizeof(scaling_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x50, rowY, (char*)scaling_labels[idx], 0, 0.6f, 0.6f); + gTournamentScaling = idx; break; case 3: /* widescreen: labels (default, enabled) */ @@ -5923,6 +5937,7 @@ void render_custom_overlay(void) { if (idx < 0) idx = 0; if (idx >= (int)(sizeof(widescreen_labels) / sizeof(widescreen_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x50, rowY, (char*)widescreen_labels[idx], 0, 0.6f, 0.6f); + gTournamentWidescreen = idx; break; case 4: /* mp music: labels (default, enabled) */ @@ -5930,6 +5945,7 @@ void render_custom_overlay(void) { if (idx < 0) idx = 0; if (idx >= (int)(sizeof(mpMusic_labels) / sizeof(mpMusic_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x50, rowY, (char*)mpMusic_labels[idx], 0, 0.6f, 0.6f); + gTournamentMusic = idx; break; case 5: /* mp train boat: labels (default, both, train, boat) */ @@ -5937,6 +5953,7 @@ void render_custom_overlay(void) { if (idx < 0) idx = 0; if (idx >= (int)(sizeof(mpTrainBoat_labels) / sizeof(mpTrainBoat_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x50, rowY, (char*)mpTrainBoat_labels[idx], 0, 0.6f, 0.6f); + gTournamentTrainBoat = idx; break; case 6: /* AA */ @@ -5944,6 +5961,7 @@ void render_custom_overlay(void) { if (idx < 0) idx = 0; if (idx >= (int)(sizeof(AA_labels) / sizeof(AA_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x50, rowY, (char*)AA_labels[idx], 0, 0.6f, 0.6f); + gTournamentAA = idx; break; case 7: /* shell limit: labels (default, 100) */ @@ -5951,6 +5969,7 @@ void render_custom_overlay(void) { if (idx < 0) idx = 0; if (idx >= (int)(sizeof(shell_labels) / sizeof(shell_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x50, rowY, (char*)shell_labels[idx], 0, 0.6f, 0.6f); + gTournamentShellLimit = idx; break; case 8: /* vs timer: labels (default, enabled) */ @@ -5958,6 +5977,7 @@ void render_custom_overlay(void) { if (idx < 0) idx = 0; if (idx >= (int)(sizeof(timer_labels) / sizeof(timer_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x50, rowY, (char*)timer_labels[idx], 0, 0.6f, 0.6f); + gTournamentTimer = idx; break; case 9: /* trophy ceremony: labels (default, enabled) */ @@ -5965,6 +5985,7 @@ void render_custom_overlay(void) { if (idx < 0) idx = 0; if (idx >= (int)(sizeof(trophy_labels) / sizeof(trophy_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x50, rowY, (char*)trophy_labels[idx], 0, 0.6f, 0.6f); + gTournamentTrophy = idx; break; case 10: /* practice mode: labels (default, enabled) */ @@ -5972,6 +5993,7 @@ void render_custom_overlay(void) { if (idx < 0) idx = 0; if (idx >= (int)(sizeof(practice_labels) / sizeof(practice_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x50, rowY, (char*)practice_labels[idx], 0, 0.6f, 0.6f); + gPracticeMode = idx; break; case 11: /* extra: labels (default, enabled) */ @@ -5979,6 +6001,7 @@ void render_custom_overlay(void) { if (idx < 0) idx = 0; if (idx >= (int)(sizeof(extra_labels) / sizeof(extra_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x50, rowY, (char*)extra_labels[idx], 0, 0.6f, 0.6f); + gTournamentExtraMode = idx; break; case 12: /* reverse: labels (default, enabled) */ @@ -5986,6 +6009,7 @@ void render_custom_overlay(void) { if (idx < 0) idx = 0; if (idx >= (int)(sizeof(reverse_labels) / sizeof(reverse_labels[0]))) idx = 0; print_text1_center_mode_1(x + 0x50, rowY, (char*)reverse_labels[idx], 0, 0.6f, 0.6f); + gTournamentReverseMode = idx; break; } } diff --git a/src/menu_items.h b/src/menu_items.h index 5f62f36c2c..2a8ff223d4 100644 --- a/src/menu_items.h +++ b/src/menu_items.h @@ -850,7 +850,6 @@ extern f32 D_8018EDA4; extern f32 D_8018EDA8; extern f32 D_8018EDAC; -// Tournament mode and custom course order arrays extern s8 gTournamentCourseMode; extern const s16 gVACourseOrder[4][4]; extern const s16 gKACourseOrder[4][4]; @@ -859,4 +858,17 @@ extern char* gCourseNamesVA[]; extern char* gCourseNamesKA[]; extern char* gCourseNamesKA_MMF[]; +extern s8 gTournamentCharacterStats; +extern s8 gTournamentScaling; +extern s8 gTournamentWidescreen; +extern s8 gTournamentMusic; +extern s8 gTournamentTrainBoat; +extern s8 gTournamentAA; +extern s8 gTournamentShellLimit; +extern s8 gTournamentTimer; +extern s8 gTournamentTrophy; +extern s8 gPracticeMode; +extern s8 gTournamentExtraMode; +extern s8 gTournamentReverseMode; + #endif diff --git a/src/menus.c b/src/menus.c index 01d06c96f2..34c5aa2c60 100644 --- a/src/menus.c +++ b/src/menus.c @@ -1111,7 +1111,7 @@ void controller_pak_menu_act(struct Controller* controller, UNUSED u16 controlle /** * Navigation of the main splash start screen menu - * Also handles debug menu options + * Also handles debug menu options and custom menu */ void splash_menu_act(struct Controller* controller, u16 controllerIdx) { u16 btnAndStick; From 552ad1d0885a88362a1df8e050e062072529de60 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Tue, 24 Mar 2026 15:59:34 -0400 Subject: [PATCH 22/73] implemented yoshi stats toggle (more testing on recompiler needed) --- src/effects.c | 44 ++++---- src/player_controller.c | 222 +++++++++++++++++++++------------------- src/spawn_players.c | 34 +++--- 3 files changed, 158 insertions(+), 142 deletions(-) diff --git a/src/effects.c b/src/effects.c index 33b31f625c..96aecbe401 100644 --- a/src/effects.c +++ b/src/effects.c @@ -19,6 +19,8 @@ #include "menu_items.h" #include +#define PLAYER_STATS_CHARACTER_ID(player) ((gTournamentCharacterStats == 0) ? YOSHI : (player)->characterId) + s32 D_8018D900[8]; s16 D_8018D920[8]; s32 gPlayerStarEffectStartTime[8]; @@ -197,14 +199,16 @@ void clean_effect(Player* player, s8 playerIndex) { void func_8008C528(Player* player, s8 playerIndex) { UNUSED s32 sp24; s32 temp_v1; + s32 statsCharacterId; clean_effect(player, playerIndex); func_8008C310(player); temp_v1 = player->characterId; + statsCharacterId = PLAYER_STATS_CHARACTER_ID(player); player->unk_0C2 = 0; - player->kartHopJerk = D_800E37B0[temp_v1]; + player->kartHopJerk = D_800E37B0[statsCharacterId]; player->kartHopAcceleration = 0.0f; - player->kartHopVelocity = D_800E3790[temp_v1]; + player->kartHopVelocity = D_800E3790[statsCharacterId]; player->unk_0A8 = 0; player->effects = player->effects | HIT_BY_GREEN_SHELL_EFFECT; player->effects = player->effects & ~DRIFTING_EFFECT; @@ -563,9 +567,9 @@ void func_8008D570(Player* player, s8 playerIndex) { player->effects |= UNKNOWN_EFFECT_0x80000; player->effects &= ~DRIFTING_EFFECT; player->triggers &= ~UNUSED_TRIGGER_0x1000; - player->kartHopJerk = D_800E3730[player->characterId]; + player->kartHopJerk = D_800E3730[PLAYER_STATS_CHARACTER_ID(player)]; player->kartHopAcceleration = 0.0f; - player->kartHopVelocity = (f32) D_800E3710[player->characterId]; + player->kartHopVelocity = (f32) D_800E3710[PLAYER_STATS_CHARACTER_ID(player)]; player->unk_0B2 = 1; player->unk_0C0 = 0; player->unk_07C = 0; @@ -611,7 +615,7 @@ void func_8008D760(Player* player) { player->unk_0C0 = 0; player->rotation[1] = player->unk_0AE; player->effects &= ~UNKNOWN_EFFECT_0x80000; - player->kartGravity = gKartGravityTable[player->characterId]; + player->kartGravity = gKartGravityTable[PLAYER_STATS_CHARACTER_ID(player)]; player->type &= 0xFF7F; } @@ -622,9 +626,9 @@ void func_8008D7B0(Player* player, s8 playerIndex) { player->effects |= UNKNOWN_EFFECT_0x800000; player->effects &= ~DRIFTING_EFFECT; player->triggers &= ~UNUSED_TRIGGER_0x20000; - player->kartHopJerk = D_800E3770[player->characterId]; + player->kartHopJerk = D_800E3770[PLAYER_STATS_CHARACTER_ID(player)]; player->kartHopAcceleration = 0.0f; - player->kartHopVelocity = D_800E3750[player->characterId]; + player->kartHopVelocity = D_800E3750[PLAYER_STATS_CHARACTER_ID(player)]; D_8018D920[playerIndex] = 0; player->unk_0B2 = 4; player->unk_0C0 = 0; @@ -665,7 +669,7 @@ void func_8008D97C(Player* player) { player->unk_0C0 = 0; player->rotation[1] = player->unk_0AE; player->effects &= ~UNKNOWN_EFFECT_0x800000; - player->kartGravity = gKartGravityTable[player->characterId]; + player->kartGravity = gKartGravityTable[PLAYER_STATS_CHARACTER_ID(player)]; } void func_8008D9C0(Player* player) { @@ -817,7 +821,7 @@ void apply_hit_effect(Player* player, s8 playerIndex) { player->unk_DB4.unk2 = 0; player->effects |= POST_SQUISH_EFFECT; player->size = 1.0f; - player->boundingBoxSize = gKartBoundingBoxSizeTable[player->characterId]; + player->boundingBoxSize = gKartBoundingBoxSizeTable[PLAYER_STATS_CHARACTER_ID(player)]; D_80165190[0][playerIndex] = 1; D_80165190[1][playerIndex] = 1; D_80165190[2][playerIndex] = 1; @@ -907,7 +911,7 @@ void apply_lightning_effect(Player* player, s8 playerIndex) { if ((player->unk_0B0 >= 0) && (player->unk_0B0 < 0x1CC)) { move_f32_towards(&player->size, 0.7f, 0.1f); move_f32_towards(&player->boundingBoxSize, - (f32) ((f64) gKartBoundingBoxSizeTable[player->characterId] * 0.9), 0.1f); + (f32) ((f64) gKartBoundingBoxSizeTable[PLAYER_STATS_CHARACTER_ID(player)] * 0.9), 0.1f); } else { remove_lightning_effect(player, playerIndex); if (player->type & PLAYER_HUMAN) { @@ -919,11 +923,11 @@ void apply_lightning_effect(Player* player, s8 playerIndex) { void remove_lightning_effect(Player* player, UNUSED s8 playerIndex) { move_f32_towards(&player->size, 1.0f, 0.1f); - move_f32_towards(&player->boundingBoxSize, gKartBoundingBoxSizeTable[player->characterId], 0.1f); + move_f32_towards(&player->boundingBoxSize, gKartBoundingBoxSizeTable[PLAYER_STATS_CHARACTER_ID(player)], 0.1f); player->effects &= ~LIGHTNING_EFFECT; player->size = 1.0f; - player->boundingBoxSize = gKartBoundingBoxSizeTable[player->characterId]; + player->boundingBoxSize = gKartBoundingBoxSizeTable[PLAYER_STATS_CHARACTER_ID(player)]; player->unk_DB4.unk10 = 3.0f; player->unk_DB4.unk2 = 0; player->effects |= POST_SQUISH_EFFECT; @@ -1007,8 +1011,8 @@ void trigger_vertical_tumble(Player* player, s8 playerIndex) { player->kartHopJerk = 0.0f; player->kartHopAcceleration = 0.0f; player->kartHopVelocity = 0.0f; - player->kartHopJerk = D_800E3730[player->characterId]; - player->kartHopVelocity = D_800E3710[player->characterId]; + player->kartHopJerk = D_800E3730[PLAYER_STATS_CHARACTER_ID(player)]; + player->kartHopVelocity = D_800E3710[PLAYER_STATS_CHARACTER_ID(player)]; player->unk_236 = 4; player->unk_042 = 0; player->unk_0E0 = 0; @@ -1116,8 +1120,8 @@ void trigger_high_tumble(Player* player, s8 playerIndex) { player->kartHopJerk = 0.0f; player->kartHopAcceleration = 0.0f; player->kartHopVelocity = 0.0f; - player->kartHopJerk = D_800E3730[player->characterId]; - player->kartHopVelocity = D_800E3710[player->characterId]; + player->kartHopJerk = D_800E3730[PLAYER_STATS_CHARACTER_ID(player)]; + player->kartHopVelocity = D_800E3710[PLAYER_STATS_CHARACTER_ID(player)]; player->unk_236 = 4; player->unk_042 = 0; player->unk_0E0 = 0; @@ -1220,7 +1224,7 @@ void trigger_wood_ramp_boost(Player* player, s8 playerId) { } void apply_boost_ramp_wood_effect(Player* player) { - player->currentSpeed = gTopSpeedTable[0][player->characterId]; + player->currentSpeed = gTopSpeedTable[0][PLAYER_STATS_CHARACTER_ID(player)]; if ((player->surfaceType != BOOST_RAMP_WOOD) && ((player->effects & MIDAIR_EFFECT) != MIDAIR_EFFECT)) { move_f32_towards(&player->boostPower, 0, 1.0f); @@ -1574,9 +1578,9 @@ void func_8008FDF4(Player* player, s8 playerIndex) { clean_effect(player, playerIndex); player->effects &= ~DRIFTING_EFFECT; - player->kartHopJerk = D_800E37F0[player->characterId]; + player->kartHopJerk = D_800E37F0[PLAYER_STATS_CHARACTER_ID(player)]; player->kartHopAcceleration = 0.0f; - player->kartHopVelocity = D_800E37D0[player->characterId]; + player->kartHopVelocity = D_800E37D0[PLAYER_STATS_CHARACTER_ID(player)]; player->triggers &= ~UNUSED_TRIGGER_0x10000; player->effects |= UNKNOWN_EFFECT_0x10000000; } @@ -2087,7 +2091,7 @@ void func_80091298(Player* player, s8 arg1) { player->unk_0C0 = 0; player->unk_DB4.unkC = 3.0f; player->unk_044 &= ~0x800; - player->kartGravity = gKartGravityTable[player->characterId]; + player->kartGravity = gKartGravityTable[PLAYER_STATS_CHARACTER_ID(player)]; player->unk_0D4[0] = 0; player->type |= PLAYER_START_SEQUENCE; player->speed = 0.0f; diff --git a/src/player_controller.c b/src/player_controller.c index 23f1e6feff..79a4633641 100644 --- a/src/player_controller.c +++ b/src/player_controller.c @@ -21,6 +21,9 @@ #include "code_80057C60.h" #include "cpu_vehicles_camera_path.h" #include "sounds.h" +#include "menu_items.h" + +#define PLAYER_STATS_CHARACTER_ID(player) ((gTournamentCharacterStats == 0) ? YOSHI : (player)->characterId) extern s32 D_8018D168; @@ -1181,9 +1184,9 @@ void func_8002A8A4(Player* player, s8 playerIndex) { } void kart_hop(Player* player) { - player->kartHopJerk = gKartHopJerkTable[player->characterId]; + player->kartHopJerk = gKartHopJerkTable[PLAYER_STATS_CHARACTER_ID(player)]; player->kartHopAcceleration = 0.0f; - player->kartHopVelocity = gKartHopInitialVelocityTable[player->characterId]; + player->kartHopVelocity = gKartHopInitialVelocityTable[PLAYER_STATS_CHARACTER_ID(player)]; player->effects |= HOP_EFFECT; player->unk_DAC = 3.0f; player->kartGravity = 500.0f; @@ -1237,14 +1240,14 @@ void func_8002AB70(Player* player) { move_f32_towards(&player->kartGravity, 500.0f, 1.0f); move_f32_towards(&player->unk_DAC, 3.0f, 0.05f); } else { - move_f32_towards(&player->kartGravity, gKartGravityTable[player->characterId], 0.1f); + move_f32_towards(&player->kartGravity, gKartGravityTable[PLAYER_STATS_CHARACTER_ID(player)], 0.1f); move_f32_towards(&player->unk_DAC, 1.0f, 0.07f); } } else { if (player->collision.surfaceDistance[2] >= 50.0f) { player->unk_DAC = 2.0f; } - move_f32_towards(&player->kartGravity, gKartGravityTable[player->characterId], 0.02f); + move_f32_towards(&player->kartGravity, gKartGravityTable[PLAYER_STATS_CHARACTER_ID(player)], 0.02f); if ((player->effects & HOP_EFFECT) == HOP_EFFECT) { move_f32_towards(&player->unk_DAC, 1.0f, 0.07f); } else { @@ -2382,12 +2385,12 @@ void func_8002D268(Player* player, UNUSED Camera* camera, s8 screenId, s8 player gPlayerLastVelocity[playerId][1] = newVelocity[1]; gPlayerLastVelocity[playerId][2] = newVelocity[2]; if ((player->type & PLAYER_HUMAN) == PLAYER_HUMAN) { - if (gKartTopSpeedTable[player->characterId] < player->speed) { - temp = gKartTopSpeedTable[player->characterId] / player->speed; + if (gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)] < player->speed) { + temp = gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)] / player->speed; player->velocity[0] *= temp; player->velocity[1] *= temp; player->velocity[2] *= temp; - player->speed = gKartTopSpeedTable[player->characterId]; + player->speed = gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)]; } } if ((player->unk_044 & 1) == 1) { @@ -2663,12 +2666,12 @@ void func_8002E594(Player* player, UNUSED Camera* camera, s8 screenId, s8 player player->velocity[1] = newVelocity[1]; player->velocity[2] = newVelocity[2]; if ((player->type & PLAYER_HUMAN) == PLAYER_HUMAN) { - if (gKartTopSpeedTable[player->characterId] < player->speed) { - topSpeedMultiplier = gKartTopSpeedTable[player->characterId] / player->speed; + if (gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)] < player->speed) { + topSpeedMultiplier = gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)] / player->speed; player->velocity[0] *= topSpeedMultiplier; player->velocity[1] *= topSpeedMultiplier; player->velocity[2] *= topSpeedMultiplier; - player->speed = gKartTopSpeedTable[player->characterId]; + player->speed = gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)]; } } func_8002C4F8(player, playerId); @@ -2741,12 +2744,12 @@ void control_cpu_movement(Player* player, UNUSED Camera* camera, s8 screenId, s8 gPlayerLastVelocity[playerId][0] = newVelocity[0]; gPlayerLastVelocity[playerId][1] = newVelocity[1]; gPlayerLastVelocity[playerId][2] = newVelocity[2]; - if (gKartTopSpeedTable[player->characterId] < player->speed) { - topSpeedMultiplier = gKartTopSpeedTable[player->characterId] / player->speed; + if (gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)] < player->speed) { + topSpeedMultiplier = gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)] / player->speed; player->velocity[0] *= topSpeedMultiplier; player->velocity[1] *= topSpeedMultiplier; player->velocity[2] *= topSpeedMultiplier; - player->speed = gKartTopSpeedTable[player->characterId]; + player->speed = gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)]; } } @@ -2851,12 +2854,12 @@ void func_8002F730(Player* player, UNUSED Camera* camera, UNUSED s8 screenId, s8 gPlayerLastVelocity[playerId][2] = newVelocity[2]; if ((player->type & PLAYER_HUMAN) == PLAYER_HUMAN) { - if (gKartTopSpeedTable[player->characterId] < player->speed) { - topSpeedMultiplier = gKartTopSpeedTable[player->characterId] / player->speed; + if (gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)] < player->speed) { + topSpeedMultiplier = gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)] / player->speed; player->velocity[0] *= topSpeedMultiplier; player->velocity[1] *= topSpeedMultiplier; player->velocity[2] *= topSpeedMultiplier; - player->speed = gKartTopSpeedTable[player->characterId]; + player->speed = gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)]; } } } @@ -2870,16 +2873,16 @@ void func_8002FCA8(Player* player, s8 playerIndex) { var_f0 = 0.0f; if ((player->effects & STAR_EFFECT) != STAR_EFFECT) { if ((s32) player->tyres[BACK_RIGHT].surfaceType < 0xF) { - var_f0 += D_800E2A90[player->characterId][player->tyres[BACK_RIGHT].surfaceType]; + var_f0 += D_800E2A90[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[BACK_RIGHT].surfaceType]; } if ((s32) player->tyres[BACK_LEFT].surfaceType < 0xF) { - var_f0 += D_800E2A90[player->characterId][player->tyres[BACK_LEFT].surfaceType]; + var_f0 += D_800E2A90[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[BACK_LEFT].surfaceType]; } if ((s32) player->tyres[FRONT_RIGHT].surfaceType < 0xF) { - var_f0 += D_800E2AB0[player->characterId][player->tyres[FRONT_RIGHT].surfaceType]; + var_f0 += D_800E2AB0[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[FRONT_RIGHT].surfaceType]; } if ((s32) player->tyres[FRONT_LEFT].surfaceType < 0xF) { - var_f0 += D_800E2AB0[player->characterId][player->tyres[FRONT_LEFT].surfaceType]; + var_f0 += D_800E2AB0[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[FRONT_LEFT].surfaceType]; } } if (D_801652C0[playerIndex] & 4) { @@ -2932,12 +2935,12 @@ void func_8002FE84(Player* player, f32 arg1) { } player->unk_098 = arg1 * (1.0f - var_f0); if (player->tyres[BACK_RIGHT].surfaceType == GRASS) { - var_f0 += D_800E2E90[player->characterId][player->tyres[BACK_RIGHT].surfaceType] * 0.7; + var_f0 += D_800E2E90[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[BACK_RIGHT].surfaceType] * 0.7; } if (player->tyres[BACK_LEFT].surfaceType == GRASS) { // The unecessary "* 1.0" here is to force the compiler to save this 0.7 as a separate RO value from the 0.7 // just above this comment - var_f0 += D_800E2E90[player->characterId][player->tyres[BACK_LEFT].surfaceType] * (0.7 * 1.0); + var_f0 += D_800E2E90[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[BACK_LEFT].surfaceType] * (0.7 * 1.0); } test = player->unk_0C0 / 182; if (test < 0) { @@ -2966,19 +2969,19 @@ f32 func_80030150(Player* player, s8 playerIndex) { // ??????? if (1) {} } else { - var_f0 += D_800E2E90[player->characterId][player->tyres[BACK_RIGHT].surfaceType]; + var_f0 += D_800E2E90[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[BACK_RIGHT].surfaceType]; } if ((s32) player->tyres[BACK_LEFT].surfaceType < 0xF) { - var_f0 += D_800E2E90[player->characterId][player->tyres[BACK_LEFT].surfaceType]; + var_f0 += D_800E2E90[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[BACK_LEFT].surfaceType]; } if ((s32) player->tyres[FRONT_RIGHT].surfaceType < 0xF) { - var_f0 += D_800E2EB0[player->characterId][player->tyres[FRONT_RIGHT].surfaceType]; + var_f0 += D_800E2EB0[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[FRONT_RIGHT].surfaceType]; } if ((s32) player->tyres[FRONT_LEFT].surfaceType < 0xF) { - var_f0 += D_800E2E90[player->characterId][player->tyres[FRONT_LEFT].surfaceType]; + var_f0 += D_800E2E90[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[FRONT_LEFT].surfaceType]; } } if (((player->effects & MIDAIR_EFFECT) != MIDAIR_EFFECT) && ((player->unk_0CA & 2) != 2)) { @@ -3005,9 +3008,9 @@ f32 func_80030150(Player* player, s8 playerIndex) { } else { var_v0 = (s16) player->unk_0C0 / 182; if (var_v0 < 0) { - var_f0 += -var_v0 * (0.01 + gKartTurnSpeedReductionTable0[player->characterId]); + var_f0 += -var_v0 * (0.01 + gKartTurnSpeedReductionTable0[PLAYER_STATS_CHARACTER_ID(player)]); } else { - var_f0 += var_v0 * (0.01 + gKartTurnSpeedReductionTable0[player->characterId]); + var_f0 += var_v0 * (0.01 + gKartTurnSpeedReductionTable0[PLAYER_STATS_CHARACTER_ID(player)]); } } if (((player->effects & DRIFT_OUTSIDE_EFFECT) == DRIFT_OUTSIDE_EFFECT) && (player->unk_228 < 0xA)) { @@ -3067,7 +3070,7 @@ f32 func_80030150(Player* player, s8 playerIndex) { move_f32_towards(&player->unk_0E4, 0.0f, 0.01f); } } - move_f32_towards(&player->unk_104, var_f0, gKartTurnSpeedReductionTable1[player->characterId] + 0.05); + move_f32_towards(&player->unk_104, var_f0, gKartTurnSpeedReductionTable1[PLAYER_STATS_CHARACTER_ID(player)] + 0.05); var_f2 = (player->unk_08C + player->unk_0E8 + player->boostPower + player->unk_0E4) - player->unk_0A0; if (var_f2 < 0.0f) { var_f2 = 0.0f; @@ -3263,99 +3266,101 @@ void detect_triple_a_combo_a_pressed(Player* player) { void player_accelerate_alternative(Player* player) { s32 player_index; + s32 statsCharacterId; player_index = get_player_index_for_player(player); + statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : player->characterId; if (gIsPlayerTripleAButtonCombo[player_index] == false) { if ((0.0 <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.1))) { player->currentSpeed += - gKartAccelerationTables[player->characterId][0] + (0.05 * (player->slopeAccel / 182)); + gKartAccelerationTables[statsCharacterId][0] + (0.05 * (player->slopeAccel / 182)); } if (((player->topSpeed * 0.1) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.2))) { player->currentSpeed += - gKartAccelerationTables[player->characterId][1] + (0.05 * (player->slopeAccel / 182)); + gKartAccelerationTables[statsCharacterId][1] + (0.05 * (player->slopeAccel / 182)); } if (((player->topSpeed * 0.2) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.3))) { player->currentSpeed += - gKartAccelerationTables[player->characterId][2] + (0.05 * (player->slopeAccel / 182)); + gKartAccelerationTables[statsCharacterId][2] + (0.05 * (player->slopeAccel / 182)); } if (((player->topSpeed * 0.3) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.4))) { player->currentSpeed += - gKartAccelerationTables[player->characterId][3] + (0.05 * (player->slopeAccel / 182)); + gKartAccelerationTables[statsCharacterId][3] + (0.05 * (player->slopeAccel / 182)); } if (((player->topSpeed * 0.4) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.5))) { player->currentSpeed += - gKartAccelerationTables[player->characterId][4] + (0.05 * (player->slopeAccel / 182)); + gKartAccelerationTables[statsCharacterId][4] + (0.05 * (player->slopeAccel / 182)); } if (((player->topSpeed * 0.5) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.6))) { player->currentSpeed += - gKartAccelerationTables[player->characterId][5] + (0.05 * (player->slopeAccel / 182)); + gKartAccelerationTables[statsCharacterId][5] + (0.05 * (player->slopeAccel / 182)); } if (((player->topSpeed * 0.6) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.7))) { player->currentSpeed += - gKartAccelerationTables[player->characterId][6] + (0.05 * (player->slopeAccel / 182)); + gKartAccelerationTables[statsCharacterId][6] + (0.05 * (player->slopeAccel / 182)); } if (((player->topSpeed * 0.7) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.8))) { player->currentSpeed += - gKartAccelerationTables[player->characterId][7] + (0.05 * (player->slopeAccel / 182)); + gKartAccelerationTables[statsCharacterId][7] + (0.05 * (player->slopeAccel / 182)); } if (((player->topSpeed * 0.8) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.9))) { player->currentSpeed += - gKartAccelerationTables[player->characterId][8] + (0.05 * (player->slopeAccel / 182)); + gKartAccelerationTables[statsCharacterId][8] + (0.05 * (player->slopeAccel / 182)); } if (((player->topSpeed * 0.9) <= player->currentSpeed) && (player->currentSpeed <= (player->topSpeed * 1.0))) { player->currentSpeed += - gKartAccelerationTables[player->characterId][9] + (0.05 * (player->slopeAccel / 182)); + gKartAccelerationTables[statsCharacterId][9] + (0.05 * (player->slopeAccel / 182)); } } else { if ((0.0 <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.1))) { player->currentSpeed += - (gKartAccelerationTables[player->characterId][0] + (0.05 * (player->slopeAccel / 182))) * - gKartTripleABoost[player->characterId]; + (gKartAccelerationTables[statsCharacterId][0] + (0.05 * (player->slopeAccel / 182))) * + gKartTripleABoost[statsCharacterId]; } if (((player->topSpeed * 0.1) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.2))) { player->currentSpeed += - (gKartAccelerationTables[player->characterId][1] + (0.05 * (player->slopeAccel / 182))) * - gKartTripleABoost[player->characterId]; + (gKartAccelerationTables[statsCharacterId][1] + (0.05 * (player->slopeAccel / 182))) * + gKartTripleABoost[statsCharacterId]; } if (((player->topSpeed * 0.2) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.3))) { player->currentSpeed += - (gKartAccelerationTables[player->characterId][2] + (0.05 * (player->slopeAccel / 182))) * - gKartTripleABoost[player->characterId]; + (gKartAccelerationTables[statsCharacterId][2] + (0.05 * (player->slopeAccel / 182))) * + gKartTripleABoost[statsCharacterId]; } if (((player->topSpeed * 0.3) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.4))) { player->currentSpeed += - (gKartAccelerationTables[player->characterId][3] + (0.05 * (player->slopeAccel / 182))) * - gKartTripleABoost[player->characterId]; + (gKartAccelerationTables[statsCharacterId][3] + (0.05 * (player->slopeAccel / 182))) * + gKartTripleABoost[statsCharacterId]; } if (((player->topSpeed * 0.4) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.5))) { player->currentSpeed += - (gKartAccelerationTables[player->characterId][4] + (0.05 * (player->slopeAccel / 182))) * - gKartTripleABoost[player->characterId]; + (gKartAccelerationTables[statsCharacterId][4] + (0.05 * (player->slopeAccel / 182))) * + gKartTripleABoost[statsCharacterId]; } if (((player->topSpeed * 0.5) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.6))) { player->currentSpeed += - (gKartAccelerationTables[player->characterId][5] + (0.05 * (player->slopeAccel / 182))) * - gKartTripleABoost[player->characterId]; + (gKartAccelerationTables[statsCharacterId][5] + (0.05 * (player->slopeAccel / 182))) * + gKartTripleABoost[statsCharacterId]; } if (((player->topSpeed * 0.6) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.7))) { player->currentSpeed += - (gKartAccelerationTables[player->characterId][6] + (0.05 * (player->slopeAccel / 182))) * - gKartTripleABoost[player->characterId]; + (gKartAccelerationTables[statsCharacterId][6] + (0.05 * (player->slopeAccel / 182))) * + gKartTripleABoost[statsCharacterId]; } if (((player->topSpeed * 0.7) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.8))) { player->currentSpeed += - (gKartAccelerationTables[player->characterId][7] + (0.05 * (player->slopeAccel / 182))) * - gKartTripleABoost[player->characterId]; + (gKartAccelerationTables[statsCharacterId][7] + (0.05 * (player->slopeAccel / 182))) * + gKartTripleABoost[statsCharacterId]; } if (((player->topSpeed * 0.8) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.9))) { player->currentSpeed += - (gKartAccelerationTables[player->characterId][8] + (0.05 * (player->slopeAccel / 182))) * - gKartTripleABoost[player->characterId]; + (gKartAccelerationTables[statsCharacterId][8] + (0.05 * (player->slopeAccel / 182))) * + gKartTripleABoost[statsCharacterId]; } if (((player->topSpeed * 0.9) <= player->currentSpeed) && (player->currentSpeed <= (player->topSpeed * 1.0))) { player->currentSpeed += - (gKartAccelerationTables[player->characterId][9] + (0.05 * (player->slopeAccel / 182))) * - gKartTripleABoost[player->characterId]; + (gKartAccelerationTables[statsCharacterId][9] + (0.05 * (player->slopeAccel / 182))) * + gKartTripleABoost[statsCharacterId]; } } if (player->currentSpeed < 0.0f) { @@ -3559,10 +3564,10 @@ void func_800323E4(Player* player) { player->unk_20C = var_f2; } else { if ((s32) player->tyres[BACK_RIGHT].surfaceType < 0xF) { - var_f2 += D_800E3210[player->characterId][player->tyres[BACK_RIGHT].surfaceType]; + var_f2 += D_800E3210[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[BACK_RIGHT].surfaceType]; } if ((s32) player->tyres[BACK_LEFT].surfaceType < 0xF) { - var_f2 += D_800E3210[player->characterId][player->tyres[BACK_LEFT].surfaceType]; + var_f2 += D_800E3210[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[BACK_LEFT].surfaceType]; } test = player->previousSpeed - player->speed; if (test <= 0.0f) { @@ -3594,39 +3599,41 @@ void func_800323E4(Player* player) { void player_accelerate_during_start_sequence(Player* player) { s32 playerIndex; + s32 statsCharacterId; s32 var_v0; s32 time_delta; playerIndex = get_player_index_for_player(player); + statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : player->characterId; if ((player->currentSpeed >= 0.0) && (player->currentSpeed < (player->topSpeed * 0.1))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][0] * 3.0; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][0] * 3.0; } if (((player->topSpeed * 0.1) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.2))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][1] * 3.0; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][1] * 3.0; } if (((player->topSpeed * 0.2) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.3))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][2] * 3.0; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][2] * 3.0; } if (((player->topSpeed * 0.3) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.4))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][3] * 3.0; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][3] * 3.0; } if (((player->topSpeed * 0.4) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.5))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][4] * 3.0; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][4] * 3.0; } if (((player->topSpeed * 0.5) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.6))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][5] * 3.0; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][5] * 3.0; } if (((player->topSpeed * 0.6) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.7))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][6] * 2.5; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][6] * 2.5; } if (((player->topSpeed * 0.7) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.8))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][7] * 2.5; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][7] * 2.5; } if (((player->topSpeed * 0.8) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.9))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][8] * 2.5; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][8] * 2.5; } if (((player->topSpeed * 0.9) <= player->currentSpeed) && (player->currentSpeed <= player->topSpeed * 1.0)) { - player->currentSpeed += gKartAccelerationTables[player->characterId][9] * 2.5; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][9] * 2.5; } if (D_801656F0 == 1) { time_delta = gRaceFrameCounter - D_801652E0[playerIndex]; @@ -3669,37 +3676,39 @@ void player_decelerate_during_start_sequence(Player* player, f32 speedReduction) void player_accelerate(Player* player) { UNUSED s32 player_index; + s32 statsCharacterId; player_index = get_player_index_for_player(player); + statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : player->characterId; if ((0.0 <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.1))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][0] * 3.2; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][0] * 3.2; } if (((player->topSpeed * 0.1) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.2))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][1] * 3.2; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][1] * 3.2; } if (((player->topSpeed * 0.2) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.3))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][2] * 3.2; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][2] * 3.2; } if (((player->topSpeed * 0.3) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.4))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][3] * 3.2; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][3] * 3.2; } if (((player->topSpeed * 0.4) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.5))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][4] * 3.2; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][4] * 3.2; } if (((player->topSpeed * 0.5) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.6))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][5] * 3.2; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][5] * 3.2; } if (((player->topSpeed * 0.6) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.7))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][6] * 3.2; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][6] * 3.2; } if (((player->topSpeed * 0.7) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.8))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][7] * 2.8; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][7] * 2.8; } if (((player->topSpeed * 0.8) <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.9))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][8] * 2.8; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][8] * 2.8; } if (((player->topSpeed * 0.9) <= player->currentSpeed) && (player->currentSpeed <= (player->topSpeed * 1.0))) { - player->currentSpeed += gKartAccelerationTables[player->characterId][9] * 2.8; + player->currentSpeed += gKartAccelerationTables[statsCharacterId][9] * 2.8; } if (player->currentSpeed < 0.0f) { player->currentSpeed = 0.0f; @@ -3719,38 +3728,41 @@ void player_decelerate(Player* player, f32 speedReduction) { } void player_accelerate_global(Player* player, s32 playerIndex) { + s32 statsCharacterId; + + statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : player->characterId; if ((gPlayerCurrentSpeed[playerIndex] >= 0.0) && (gPlayerCurrentSpeed[playerIndex] < ((f64) player->topSpeed * 0.1))) { - gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[player->characterId][0] * 3.2; + gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[statsCharacterId][0] * 3.2; } if (((player->topSpeed * 0.1) <= gPlayerCurrentSpeed[playerIndex]) && (gPlayerCurrentSpeed[playerIndex] < (player->topSpeed * 0.2))) { - gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[player->characterId][1] * 3.2; + gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[statsCharacterId][1] * 3.2; } if (((player->topSpeed * 0.2) <= gPlayerCurrentSpeed[playerIndex]) && (gPlayerCurrentSpeed[playerIndex] < (player->topSpeed * 0.3))) { - gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[player->characterId][2] * 3.2; + gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[statsCharacterId][2] * 3.2; } if (((player->topSpeed * 0.3) <= gPlayerCurrentSpeed[playerIndex]) && (gPlayerCurrentSpeed[playerIndex] < (player->topSpeed * 0.4))) { - gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[player->characterId][3] * 3.2; + gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[statsCharacterId][3] * 3.2; } if (((player->topSpeed * 0.4) <= gPlayerCurrentSpeed[playerIndex]) && (gPlayerCurrentSpeed[playerIndex] < (player->topSpeed * 0.5))) { - gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[player->characterId][4] * 3.2; + gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[statsCharacterId][4] * 3.2; } if (((player->topSpeed * 0.5) <= gPlayerCurrentSpeed[playerIndex]) && (gPlayerCurrentSpeed[playerIndex] < (player->topSpeed * 0.6))) { - gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[player->characterId][5] * 3.2; + gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[statsCharacterId][5] * 3.2; } if (((player->topSpeed * 0.6) <= gPlayerCurrentSpeed[playerIndex]) && (gPlayerCurrentSpeed[playerIndex] < (player->topSpeed * 0.7))) { - gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[player->characterId][6] * 3.2; + gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[statsCharacterId][6] * 3.2; } if (((player->topSpeed * 0.7) <= gPlayerCurrentSpeed[playerIndex]) && (gPlayerCurrentSpeed[playerIndex] < (player->topSpeed * 0.8))) { - gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[player->characterId][7] * 2.8; + gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[statsCharacterId][7] * 2.8; } if (((player->topSpeed * 0.8) <= gPlayerCurrentSpeed[playerIndex]) && (gPlayerCurrentSpeed[playerIndex] < (player->topSpeed * 0.9))) { - gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[player->characterId][8] * 2.8; + gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[statsCharacterId][8] * 2.8; } if (((player->topSpeed * 0.9) <= gPlayerCurrentSpeed[playerIndex]) && (gPlayerCurrentSpeed[playerIndex] <= (player->topSpeed * 1.0))) { - gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[player->characterId][9] * 2.8; + gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[statsCharacterId][9] * 2.8; } player->unk_044 |= 0x20; if (gPlayerCurrentSpeed[playerIndex] < 0.0f) { @@ -3918,10 +3930,10 @@ void func_80033AE0(Player* player, struct Controller* controller, s8 arg2) { } } if (((s32) player->tyres[BACK_RIGHT].surfaceType) < 0xF) { - var_f2 += D_800E3610[player->characterId][player->tyres[BACK_RIGHT].surfaceType]; + var_f2 += D_800E3610[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[BACK_RIGHT].surfaceType]; } if (((s32) player->tyres[BACK_LEFT].surfaceType) < 0xF) { - var_f2 += D_800E3610[player->characterId][player->tyres[BACK_LEFT].surfaceType]; + var_f2 += D_800E3610[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[BACK_LEFT].surfaceType]; } if ((player->effects & AB_SPIN_EFFECT) == AB_SPIN_EFFECT) { sp2C8 = 10; @@ -3937,9 +3949,9 @@ void func_80033AE0(Player* player, struct Controller* controller, s8 arg2) { if ((player->unk_044 & 2) == 2) { if ((sp2D0 < 36) && (sp2D0 >= 0)) { sp2C8 = - (gKartTable800E3650[player->characterId] + 1.0f) * (((f32) (var_a0 + 0xF)) * (1.0f + var_f2)); + (gKartTable800E3650[PLAYER_STATS_CHARACTER_ID(player)] + 1.0f) * (((f32) (var_a0 + 0xF)) * (1.0f + var_f2)); sp2CC = - (gKartTable800E3650[player->characterId] + 1.0f) * (((f32) (var_a0 + 0xF)) * (1.0f + var_f2)); + (gKartTable800E3650[PLAYER_STATS_CHARACTER_ID(player)] + 1.0f) * (((f32) (var_a0 + 0xF)) * (1.0f + var_f2)); } else { sp2C8 = (s32) (((f32) (var_a0 + 5)) * (1.0f + var_f2)); sp2CC = (s32) (((f32) (var_a0 + 9)) * (1.0f + var_f2)); @@ -3947,9 +3959,9 @@ void func_80033AE0(Player* player, struct Controller* controller, s8 arg2) { } else if ((player->unk_044 & 4) == 4) { if ((sp2D0 >= (-0x23)) && (sp2D0 <= 0)) { sp2C8 = - (gKartTable800E3650[player->characterId] + 1.0f) * (((f32) (var_a0 + 0xF)) * (1.0f + var_f2)); + (gKartTable800E3650[PLAYER_STATS_CHARACTER_ID(player)] + 1.0f) * (((f32) (var_a0 + 0xF)) * (1.0f + var_f2)); sp2CC = - (gKartTable800E3650[player->characterId] + 1.0f) * (((f32) (var_a0 + 0xF)) * (1.0f + var_f2)); + (gKartTable800E3650[PLAYER_STATS_CHARACTER_ID(player)] + 1.0f) * (((f32) (var_a0 + 0xF)) * (1.0f + var_f2)); } else { sp2C8 = (s32) (((f32) (var_a0 + 5)) * (1.0f + var_f2)); sp2CC = (s32) (((f32) (var_a0 + 9)) * (1.0f + var_f2)); @@ -4092,10 +4104,10 @@ void func_80033AE0(Player* player, struct Controller* controller, s8 arg2) { if (((s32) player->tyres[BACK_RIGHT].surfaceType) > 0xE) { var_f12 = var_f12; } else { - var_f12 += D_800E3410[player->characterId][player->tyres[BACK_RIGHT].surfaceType]; + var_f12 += D_800E3410[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[BACK_RIGHT].surfaceType]; } if (((s32) player->tyres[BACK_LEFT].surfaceType) < 0xF) { - var_f12 += D_800E3410[player->characterId][player->tyres[BACK_LEFT].surfaceType]; + var_f12 += D_800E3410[PLAYER_STATS_CHARACTER_ID(player)][player->tyres[BACK_LEFT].surfaceType]; } if (((player->effects & HOP_EFFECT) != HOP_EFFECT) && ((player->effects & DRIFTING_EFFECT) != DRIFTING_EFFECT)) { if ((player->effects & AB_SPIN_EFFECT) == AB_SPIN_EFFECT) { @@ -4104,10 +4116,10 @@ void func_80033AE0(Player* player, struct Controller* controller, s8 arg2) { if ((player->effects & BRAKING_EFFECT) != BRAKING_EFFECT) { if (((player->unk_07C >> 16) >= 45) || ((player->unk_07C >> 16) <= (-45))) { player->unk_078 = ((player->unk_07C >> 16) * (var_f2_2 + (var_f2_2 * var_f12))) * - (0.15 + gKartHandlingTable[player->characterId]); + (0.15 + gKartHandlingTable[PLAYER_STATS_CHARACTER_ID(player)]); } else { player->unk_078 = ((player->unk_07C >> 16) * (var_f2_2 + (var_f2_2 * var_f12))) * - gKartHandlingTable[player->characterId]; + gKartHandlingTable[PLAYER_STATS_CHARACTER_ID(player)]; } } else { if ((((player->speed / 18.0f) * 216.0f) >= 0.0f) && (((player->speed / 18.0f) * 216.0f) < 8.0f)) { @@ -4220,7 +4232,7 @@ void apply_cpu_turn(Player* player, s16 targetAngle) { if ((player->effects & DRIFTING_EFFECT) == DRIFTING_EFFECT) { var_f0 = speedTurn[(s16) ((player->speed / 18.0f) * 216.0f)] * var_f0; } else { - var_f0 = speedTurn[(s16) ((player->speed / 18.0f) * 216.0f)] * characterTurn[player->characterId] * + var_f0 = speedTurn[(s16) ((player->speed / 18.0f) * 216.0f)] * characterTurn[PLAYER_STATS_CHARACTER_ID(player)] * var_f0; } player->unk_07C = sp304; @@ -4997,12 +5009,12 @@ void func_80038C6C(Player* player, UNUSED Camera* camera, s8 screenId, s8 player gPlayerLastVelocity[playerId][2] = newVelocity[2]; if ((player->type & PLAYER_HUMAN) == PLAYER_HUMAN) { - if (gKartTopSpeedTable[player->characterId] < player->speed) { - divOptimize = gKartTopSpeedTable[player->characterId] / player->speed; + if (gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)] < player->speed) { + divOptimize = gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)] / player->speed; player->velocity[0] *= divOptimize; player->velocity[1] *= divOptimize; player->velocity[2] *= divOptimize; - player->speed = gKartTopSpeedTable[player->characterId]; + player->speed = gKartTopSpeedTable[PLAYER_STATS_CHARACTER_ID(player)]; } } if ((player->unk_044 & 1) == 1) { diff --git a/src/spawn_players.c b/src/spawn_players.c index 95605c73e7..1432afa16e 100644 --- a/src/spawn_players.c +++ b/src/spawn_players.c @@ -77,40 +77,40 @@ void spawn_player(Player* player, s8 playerIndex, f32 startingRow, f32 startingC u16 characterId, s16 playerType) { f32 ret; s8 idx; + s32 statsCharacterId; + s32 statsCCIndex; player->type = PLAYER_INACTIVE; player->unk_08C = 0; player->characterId = characterId; player->unk_0B6 = 0; - player->kartFriction = gKartFrictionTable[player->characterId]; - player->boundingBoxSize = gKartBoundingBoxSizeTable[player->characterId]; - player->kartGravity = gKartGravityTable[player->characterId]; + statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : player->characterId; + player->kartFriction = gKartFrictionTable[statsCharacterId]; + player->boundingBoxSize = gKartBoundingBoxSizeTable[statsCharacterId]; + player->kartGravity = gKartGravityTable[statsCharacterId]; switch (gModeSelection) { case GRAND_PRIX: case VERSUS: - player->unk_084 = D_800E2400[gCCSelection][player->characterId]; - player->unk_088 = D_800E24B4[gCCSelection][player->characterId]; - player->unk_210 = D_800E2568[gCCSelection][player->characterId]; - player->topSpeed = gTopSpeedTable[gCCSelection][player->characterId]; + statsCCIndex = gCCSelection; break; - // Uses 100CC values case TIME_TRIALS: - player->unk_084 = D_800E2400[CC_100][player->characterId]; - player->unk_088 = D_800E24B4[CC_100][player->characterId]; - player->unk_210 = D_800E2568[CC_100][player->characterId]; - player->topSpeed = gTopSpeedTable[CC_100][player->characterId]; + statsCCIndex = CC_100; break; - case BATTLE: - player->unk_084 = D_800E2400[CC_BATTLE][player->characterId]; - player->unk_088 = D_800E24B4[CC_BATTLE][player->characterId]; - player->unk_210 = D_800E2568[CC_BATTLE][player->characterId]; - player->topSpeed = gTopSpeedTable[CC_BATTLE][player->characterId]; + statsCCIndex = CC_BATTLE; + break; + default: + statsCCIndex = CC_100; break; } + player->unk_084 = D_800E2400[statsCCIndex][statsCharacterId]; + player->unk_088 = D_800E24B4[statsCCIndex][statsCharacterId]; + player->unk_210 = D_800E2568[statsCCIndex][statsCharacterId]; + player->topSpeed = gTopSpeedTable[statsCCIndex][statsCharacterId]; + player->pos[0] = startingRow; ret = get_surface_height(startingRow, arg4 + 50.0f, startingColumn) + player->boundingBoxSize; player->pos[2] = startingColumn; From e94b6b203bd0bbcf626381367ab070c15928a2ae Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Wed, 25 Mar 2026 07:41:44 -0400 Subject: [PATCH 23/73] added small comment for lagfix toggle --- src/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.c b/src/main.c index 1aed604ac7..98e505f7aa 100644 --- a/src/main.c +++ b/src/main.c @@ -240,6 +240,8 @@ void thread1_idle(void* arg) { osStartThread(&gVideoThread); osSetThreadPri(NULL, 0); + // uncomment for lagfix + // osViModeNtscLan1.comRegs.vSync = 3341; // Halt while (true) { ; From f163180b8fe6caa1d4311ee4f97235d958711792 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Wed, 25 Mar 2026 14:20:15 -0400 Subject: [PATCH 24/73] added annotations for enabling lagfix and no VI AA --- include/PR/os_vi.h | 2 +- src/main.c | 2 +- src/os/__osViInit.c | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/PR/os_vi.h b/include/PR/os_vi.h index 9fa8644487..9704e949f2 100644 --- a/include/PR/os_vi.h +++ b/include/PR/os_vi.h @@ -64,7 +64,7 @@ typedef struct { /* 0x20 */ u32 unk20; /* 0x24 */ f32 unk24; /* 0x28 */ u16 unk28; - /* 0x2c */ u32 unk2c; + /* 0x2c */ u32 unk2c; // 4 bytes, so 0x2C + 4 = 0x30 -> total size in bytes } OSViContext; void osCreateViManager(OSPri pri); diff --git a/src/main.c b/src/main.c index 98e505f7aa..d322e93871 100644 --- a/src/main.c +++ b/src/main.c @@ -240,7 +240,7 @@ void thread1_idle(void* arg) { osStartThread(&gVideoThread); osSetThreadPri(NULL, 0); - // uncomment for lagfix + // uncomment for lagfix (in osViData.c) // osViModeNtscLan1.comRegs.vSync = 3341; // Halt while (true) { diff --git a/src/os/__osViInit.c b/src/os/__osViInit.c index 34dff12966..d0ea66d1c7 100644 --- a/src/os/__osViInit.c +++ b/src/os/__osViInit.c @@ -3,6 +3,7 @@ extern u32 osTvType; +// for no AA, change sViContexts[0, 1].features = 12822 OSViContext sViContexts[2] = { 0 }; OSViContext* __osViCurr = &sViContexts[0]; OSViContext* __osViNext = &sViContexts[1]; From 1af1df88c78e2a7ea1edb5c80d5dc384999429a3 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Wed, 25 Mar 2026 14:24:23 -0400 Subject: [PATCH 25/73] added annotation for enabling mp music in 4p/3p versus --- src/racing/race_logic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index 2832f176a1..bba905d528 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -419,6 +419,7 @@ UNUSED void func_8028EC38(s32 arg0) { gDemoTimer = 5; } +// make edits here to enable mp music void play_music_for_current_track(s32 track) { if (gScreenModeSelection == SCREEN_MODE_3P_4P_SPLITSCREEN) { From 9bb7e8029047f3a79fc1a95b304aa11b23273ad8 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Wed, 25 Mar 2026 14:31:13 -0400 Subject: [PATCH 26/73] added annotations for enabling widescreen hack --- src/racing/race_logic.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index bba905d528..afebfff036 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -213,6 +213,8 @@ void func_8028E438(void) { if (temp_v0->screenStartX == 160) { phi_v1_4++; } + // if 1.3333, change to 1.7474 for widescreen hack + // else if 2.66667, change to 3.51042 for widescreen hack gScreenAspect = (f32) ((f32) temp_v0->screenWidth / (f32) temp_v0->screenHeight); if (phi_v1_4 == 4) { D_8015F894 = 2; @@ -293,7 +295,8 @@ void func_8028E678(void) { D_800DC5F0->screenStartX = SCREEN_HEIGHT; phi_a0_10++; } - + // if 1.3333, change to 1.7474 for widescreen hack + // else if 2.66667, change to 3.51042 for widescreen hack gScreenAspect = (f32) ((f32) D_800DC5EC->screenWidth / (f32) D_800DC5EC->screenHeight); if (phi_a0_10 == 4) { D_8015F894 = 3; @@ -327,7 +330,8 @@ void func_8028E678(void) { D_800DC5F0->screenStartY = 180; phi_a0_10++; } - + // if 1.3333, change to 1.7474 for widescreen hack + // else if 2.66667, change to 3.51042 for widescreen hack gScreenAspect = (f32) ((f32) D_800DC5EC->screenWidth / (f32) D_800DC5EC->screenHeight); if (phi_a0_10 == 4) { D_8015F894 = 3; @@ -351,6 +355,8 @@ void func_8028E678(void) { D_800DC5F0->screenStartY = D_800DC5EC->screenStartY; gActiveScreenMode = SCREEN_MODE_2P_SPLITSCREEN_VERTICAL; + // if 1.3333, change to 1.7474 for widescreen hack + // else if 2.66667, change to 3.51042 for widescreen hack gScreenAspect = 1.33333337; gPlayerCountSelection1 = 2; func_8003DB5C(); From 4b32828faf062c297259bf9ce158915a972785df Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Wed, 25 Mar 2026 14:33:39 -0400 Subject: [PATCH 27/73] more annotations for widescreen hack --- src/ending/camera_junk.c | 2 ++ src/racing/skybox_and_splitscreen.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/ending/camera_junk.c b/src/ending/camera_junk.c index 5f360ea41b..7b0bd35590 100644 --- a/src/ending/camera_junk.c +++ b/src/ending/camera_junk.c @@ -38,6 +38,8 @@ void init_camera_podium_ceremony(void) { cameras[0].up[1] = 1.0f; cameras[0].up[2] = 0.0f; gCameraZoom[0] = 40.0f; + // if 1.3333, change to 1.7474 for widescreen hack + // else if 2.66667, change to 3.51042 for widescreen hack gScreenAspect = 1.33333333f; gCourseNearPersp = 3.0f; gCourseFarPersp = 6800.0f; diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index 78f95fe7ce..b44b4b3be7 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -583,6 +583,8 @@ void set_perspective_and_aspect_ratio(void) { break; } } + // if 1.3333, change to 1.7474 for widescreen hack + // else if 2.66667, change to 3.51042 for widescreen hack switch (gScreenModeSelection) { /* switch 1; irregular */ case SCREEN_MODE_1P: /* switch 1 */ gScreenAspect = 1.33333334f; From 90cd6c7e862e5bcfad6a29e019d0b012de6946fc Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Thu, 26 Mar 2026 07:41:38 -0400 Subject: [PATCH 28/73] mp train boat implemented. may be weird visual bugs on KD. check with diff emu --- .../vehicle_utils.inc.c | 78 ++++++++++++++----- 1 file changed, 57 insertions(+), 21 deletions(-) diff --git a/src/cpu_vehicles_camera_path/vehicle_utils.inc.c b/src/cpu_vehicles_camera_path/vehicle_utils.inc.c index d359e10708..340db6e128 100644 --- a/src/cpu_vehicles_camera_path/vehicle_utils.inc.c +++ b/src/cpu_vehicles_camera_path/vehicle_utils.inc.c @@ -223,9 +223,41 @@ void init_vehicles_trains(void) { gTrainList[i].numCars = LOCOMOTIVE_ONLY; } - // Spawn all rolling stock in single player mode. - switch (gScreenModeSelection) { - case SCREEN_MODE_1P: // single player + + // default behavior + if (gTournamentTrainBoat == 0 || gTournamentTrainBoat == 3) { + // Spawn all rolling stock in single player mode. + switch (gScreenModeSelection) { + case SCREEN_MODE_1P: // single player + for (i = 0; i < NUM_TRAINS; i++) { + gTrainList[i].tender.isActive = 1; + + // clang-format off + // Same line required for matching... + for (j = 0; j < NUM_PASSENGER_CAR_ENTRIES; j++) { gTrainList[i].passengerCars[j].isActive = 1; } + // clang-format on + + gTrainList[i].numCars = NUM_TENDERS + NUM_PASSENGER_CAR_ENTRIES; + } + break; + + // Spawn locomotive, tender, and one passenger car in versus 2/3 player mode. + case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: // multiplayer fall-through + case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: + if (gModeSelection != GRAND_PRIX) { + for (i = 0; i < NUM_TRAINS; i++) { + gTrainList[i].tender.isActive = 1; + gTrainList[i].passengerCars[4].isActive = 1; + gTrainList[i].numCars = NUM_TENDERS + NUM_2P_PASSENGER_CARS; + } + } + break; + } + } + + // if train or both are selected + else if (gTournamentTrainBoat == 1 || gTournamentTrainBoat == 2){ + // Spawn all rolling stock override in all modes for (i = 0; i < NUM_TRAINS; i++) { gTrainList[i].tender.isActive = 1; @@ -236,23 +268,10 @@ void init_vehicles_trains(void) { gTrainList[i].numCars = NUM_TENDERS + NUM_PASSENGER_CAR_ENTRIES; } - break; - - // Spawn locomotive, tender, and one passenger car in versus 2/3 player mode. - case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: // multiplayer fall-through - case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: - if (gModeSelection != GRAND_PRIX) { - for (i = 0; i < NUM_TRAINS; i++) { - gTrainList[i].tender.isActive = 1; - gTrainList[i].passengerCars[4].isActive = 1; - gTrainList[i].numCars = NUM_TENDERS + NUM_2P_PASSENGER_CARS; - } - } - break; + } + gTrainSmokeTimer = 0; } - gTrainSmokeTimer = 0; -} /** * @brief sync the train components vehicle with the actor * @@ -480,11 +499,28 @@ void init_vehicles_ferry(void) { paddleBoat->pathPointIndex = i * 0xB4; paddleBoat->actorIndex = -1; - if (gPlayerCount >= 3) { - paddleBoat->isActive = 0; - } else { + // default, or if just train is selected + if (gTournamentTrainBoat == 0 || gTournamentTrainBoat == 2) { + if (gPlayerCount >= 3) { + paddleBoat->isActive = 0; + } else { + paddleBoat->isActive = 1; + } + } + // force boat to spawn + else if (gTournamentTrainBoat == 1 || gTournamentTrainBoat == 3) { paddleBoat->isActive = 1; } + // default case fallback + else { + if (gPlayerCount >= 3) { + paddleBoat->isActive = 0; + } else { + paddleBoat->isActive = 1; + } + } + + paddleBoat->velocity[0] = 0.0f; paddleBoat->velocity[1] = 0.0f; paddleBoat->velocity[2] = 0.0f; From ffae316d52ee89a1fc56b65267bdbc48240f241e Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Thu, 26 Mar 2026 08:08:43 -0400 Subject: [PATCH 29/73] no AA implemented --- src/os/__osViSwapContext.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/os/__osViSwapContext.c b/src/os/__osViSwapContext.c index c4abbd8bee..3029cf6999 100644 --- a/src/os/__osViSwapContext.c +++ b/src/os/__osViSwapContext.c @@ -1,5 +1,6 @@ #include "libultra_internal.h" #include "hardware.h" +#include "menu_items.h" extern OSViContext* __osViNext; extern OSViContext* __osViCurr; @@ -54,7 +55,14 @@ void __osViSwapContext() { HW_REG(VI_INTR_REG, u32) = s0->fldRegs[field].vIntr; HW_REG(VI_X_SCALE_REG, u32) = s1->unk20; HW_REG(VI_Y_SCALE_REG, u32) = s1->unk2c; - HW_REG(VI_CONTROL_REG, u32) = s1->features; + // gameshark code no AA refactor + if (gTournamentAA) { + HW_REG(VI_CONTROL_REG, u32) = 12822; + } + // default behavior + else { + HW_REG(VI_CONTROL_REG, u32) = s1->features; + } __osViNext = __osViCurr; __osViCurr = s1; *__osViNext = *__osViCurr; From 72e71f9e83f5fa5f7a7286aae6f5053f0e236e77 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Thu, 26 Mar 2026 08:13:16 -0400 Subject: [PATCH 30/73] mp music implemented --- src/racing/race_logic.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index afebfff036..0c88639878 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -428,10 +428,15 @@ UNUSED void func_8028EC38(s32 arg0) { // make edits here to enable mp music void play_music_for_current_track(s32 track) { - if (gScreenModeSelection == SCREEN_MODE_3P_4P_SPLITSCREEN) { - return; // If 3P/4P splitscreen mode is currently on, don't play the music for the current track. + // run default case; no music in 3p/4p vs mode + // if gTournamentMusic == 1, dont run and proceed to load music for each track + if (!gTournamentMusic) { + if (gScreenModeSelection == SCREEN_MODE_3P_4P_SPLITSCREEN) { + return; // If 3P/4P splitscreen mode is currently on, don't play the music for the current track. + } } + func_800029B0(); switch (track) { From b7ac31e602394f5869e9b279246c73cc31a459e9 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Thu, 26 Mar 2026 08:23:04 -0400 Subject: [PATCH 31/73] implemented widescreen hack toggle --- src/ending/camera_junk.c | 11 ++++++++--- src/racing/skybox_and_splitscreen.c | 24 +++++++++++++++++++++--- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/ending/camera_junk.c b/src/ending/camera_junk.c index 7b0bd35590..b661f021f2 100644 --- a/src/ending/camera_junk.c +++ b/src/ending/camera_junk.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "camera_junk.h" #include "camera.h" @@ -38,9 +39,13 @@ void init_camera_podium_ceremony(void) { cameras[0].up[1] = 1.0f; cameras[0].up[2] = 0.0f; gCameraZoom[0] = 40.0f; - // if 1.3333, change to 1.7474 for widescreen hack - // else if 2.66667, change to 3.51042 for widescreen hack - gScreenAspect = 1.33333333f; + // change to 1.7474 for widescreen hack + if (gTournamentWidescreen) { + gScreenAspect = 1.7474f; + } + else { + gScreenAspect = 1.33333333f; + } gCourseNearPersp = 3.0f; gCourseFarPersp = 6800.0f; init_cinematic_camera(); diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index b44b4b3be7..4a81dec7a0 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -587,16 +587,34 @@ void set_perspective_and_aspect_ratio(void) { // else if 2.66667, change to 3.51042 for widescreen hack switch (gScreenModeSelection) { /* switch 1; irregular */ case SCREEN_MODE_1P: /* switch 1 */ - gScreenAspect = 1.33333334f; + // set widescreen in 1p + if (gTournamentWidescreen) { + gScreenAspect = 1.7474f; + } + else { + gScreenAspect = 1.33333334f; + } return; case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: /* switch 1 */ gScreenAspect = 0.66666667f; return; case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: /* switch 1 */ - gScreenAspect = 2.66666667f; + // set widescreen in 2p + if (gTournamentWidescreen) { + gScreenAspect = 3.51042f; + } + else { + gScreenAspect = 2.66666667f; + } return; case SCREEN_MODE_3P_4P_SPLITSCREEN: /* switch 1 */ - gScreenAspect = 1.33333334f; + // set widescreen in 3p/4p + if (gTournamentWidescreen) { + gScreenAspect = 1.7474f; + } + else { + gScreenAspect = 1.33333334f; + } return; } } From 38a390b725402cf19958f12fa71ff5a981f46943 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Thu, 26 Mar 2026 08:39:34 -0400 Subject: [PATCH 32/73] implemented shell limit increase toggle; need more testing to see if it works properly --- src/racing/actors.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/racing/actors.c b/src/racing/actors.c index 42b3bd0576..87fd60824c 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -25,6 +25,7 @@ #include "courses/all_course_data.h" #include "main.h" #include "data/other_textures.h" +#include "menu_items.h" // Appears to be textures // or tluts @@ -166,19 +167,39 @@ void actor_init(struct Actor* actor, Vec3f startingPos, Vec3s startingRot, Vec3f actor->unk_04 = 0; actor->boundingBoxSize = 4.0f; actor->flags = actor->flags | 0x4000 | 0x2000 | 0x1000; - if ((s32) gNumSpawnedShells >= 0x15) { - cleanup_red_and_green_shells((struct ShellActor*) actor); + // default behavior, default shell limit + if (!gTournamentShellLimit) { + if ((s32) gNumSpawnedShells >= 0x15) { + cleanup_red_and_green_shells((struct ShellActor*) actor); + } + break; + } + // custom shell limit of 100 + else { + if ((s32) gNumSpawnedShells >= 0x64) { + cleanup_red_and_green_shells((struct ShellActor*) actor); + } + break; } - break; case ACTOR_RED_SHELL: gNumSpawnedShells += 1; actor->unk_04 = 0; actor->boundingBoxSize = 4.0f; actor->flags = actor->flags | 0x4000 | 0x2000 | 0x1000; - if ((s32) gNumSpawnedShells >= 0x15) { - cleanup_red_and_green_shells((struct ShellActor*) actor); + // default behavior, default shell limit + if (!gTournamentShellLimit) { + if ((s32) gNumSpawnedShells >= 0x15) { + cleanup_red_and_green_shells((struct ShellActor*) actor); + } + break; + } + // custom shell limit of 100 + else { + if ((s32) gNumSpawnedShells >= 0x64) { + cleanup_red_and_green_shells((struct ShellActor*) actor); + } + break; } - break; case ACTOR_TREE_MARIO_RACEWAY: gNumSpawnedShells += 1; actor->flags |= 0x4000; From 35d97ad997b7f2206ce368ea794f9cdccde68188 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Thu, 26 Mar 2026 09:05:42 -0400 Subject: [PATCH 33/73] extended pause/multipause now only works for vs mode --- src/racing/race_logic.c | 65 +++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index 0c88639878..c516eaf4a8 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -862,28 +862,57 @@ void func_8028F970(void) { func_800029B0(); } } - // pausing is gated by sPauseHoldCounter, which increments every frame player i holds start - if ((controller->button & START_BUTTON) && (!(controller->button & R_TRIG)) && - (!(controller->button & L_TRIG)) && (sPauseHoldCounter[i] >= 60)) { - func_8028DF00(); - gIsGamePaused = (controller - gControllerOne) + 1; - controller->buttonPressed = 0; - func_800C9F90(1); - gPauseTriggered = 1; - sPauseHoldCounter[i] = 0; - if (gModeSelection == TIME_TRIALS) { - if (gPlayerOne->type & (PLAYER_EXISTS | PLAYER_INVISIBLE_OR_BOMB)) { - func_80005AE8(gPlayerOne); - } - if (gPlayerTwo->type & (PLAYER_EXISTS | PLAYER_INVISIBLE_OR_BOMB)) { - func_80005AE8(gPlayerTwo); + + // only run extended pause in VS mode + if (gModeSelection == VERSUS) { + // pausing is gated by sPauseHoldCounter, which increments every frame player i holds start + if ((controller->button & START_BUTTON) && (!(controller->button & R_TRIG)) && + (!(controller->button & L_TRIG)) && (sPauseHoldCounter[i] >= 60)) { + func_8028DF00(); + gIsGamePaused = (controller - gControllerOne) + 1; + controller->buttonPressed = 0; + func_800C9F90(1); + gPauseTriggered = 1; + sPauseHoldCounter[i] = 0; + if (gModeSelection == TIME_TRIALS) { + if (gPlayerOne->type & (PLAYER_EXISTS | PLAYER_INVISIBLE_OR_BOMB)) { + func_80005AE8(gPlayerOne); + } + if (gPlayerTwo->type & (PLAYER_EXISTS | PLAYER_INVISIBLE_OR_BOMB)) { + func_80005AE8(gPlayerTwo); + } + if (gPlayerThree->type & (PLAYER_EXISTS | PLAYER_INVISIBLE_OR_BOMB)) { + func_80005AE8(gPlayerThree); + } } - if (gPlayerThree->type & (PLAYER_EXISTS | PLAYER_INVISIBLE_OR_BOMB)) { - func_80005AE8(gPlayerThree); + return; + } + } + // run default logic in other modes + else { + if ((controller->buttonPressed & START_BUTTON) && (!(controller->button & R_TRIG)) && + (!(controller->button & L_TRIG))) { + func_8028DF00(); + gIsGamePaused = (controller - gControllerOne) + 1; + controller->buttonPressed = 0; + func_800C9F90(1); + gPauseTriggered = 1; + if (gModeSelection == TIME_TRIALS) { + if (gPlayerOne->type & (PLAYER_EXISTS | PLAYER_INVISIBLE_OR_BOMB)) { + func_80005AE8(gPlayerOne); + } + if (gPlayerTwo->type & (PLAYER_EXISTS | PLAYER_INVISIBLE_OR_BOMB)) { + func_80005AE8(gPlayerTwo); + } + if (gPlayerThree->type & (PLAYER_EXISTS | PLAYER_INVISIBLE_OR_BOMB)) { + func_80005AE8(gPlayerThree); + } } + return; } - return; } + + // increment pause counter for player i if ((controller->button & START_BUTTON) && (!(controller->button & R_TRIG)) && (!(controller->button & L_TRIG)) && (sPauseHoldCounter[i] < 60)) { From 09bc0fbf861698fe87fa0498cfa7fccd2358d5a2 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Thu, 26 Mar 2026 14:56:13 -0400 Subject: [PATCH 34/73] implemented extra mode; updated build date --- src/cpu_vehicles_camera_path.c | 2 +- src/menu_items.c | 2 +- src/menus.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu_vehicles_camera_path.c b/src/cpu_vehicles_camera_path.c index 97e2436a84..40008984c4 100644 --- a/src/cpu_vehicles_camera_path.c +++ b/src/cpu_vehicles_camera_path.c @@ -2186,7 +2186,7 @@ void init_players(void) { } gIsInExtra = false; - if (gCCSelection == CC_EXTRA) { + if (gCCSelection == CC_EXTRA || gTournamentExtraMode == 1) { gIsInExtra = true; } diff --git a/src/menu_items.c b/src/menu_items.c index afbea2184a..4870239785 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -5860,7 +5860,7 @@ void render_custom_overlay(void) { // func_800579B8(x1, y1, "WEATHERTON ABNEY CLIMATEE"); // version / date (smaller) - left-aligned to start under 'KART' - print_text1_left(x + 0x5A, y + 0x06, "TE V2026-03-23", 0, 0.65f, 0.65f); + print_text1_left(x + 0x5A, y + 0x06, "TE V2026-03-26", 0, 0.65f, 0.65f); // option name placeholders (second column) and values (third column) for (i = 0; i < CUSTOM_MENU_ROWS; i++) { diff --git a/src/menus.c b/src/menus.c index 34c5aa2c60..1729f5ce8a 100644 --- a/src/menus.c +++ b/src/menus.c @@ -1383,7 +1383,7 @@ void setup_selected_game_mode(void) { case VERSUS: gCCSelection = subMenuMode; gPlaceItemBoxes = 1; - gIsMirrorMode = (subMenuMode == CC_EXTRA) ? 1 : 0; + gIsMirrorMode = ((subMenuMode == CC_EXTRA) || (gTournamentExtraMode == 1)) ? 1 : 0; break; case BATTLE: gPlaceItemBoxes = 1; From fd5a63079799537ae0d6f7dc7ab6202687e326f8 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Thu, 26 Mar 2026 15:22:41 -0400 Subject: [PATCH 35/73] added makefile to gitignore. updated defines.h so that debug mode isnt forced while using gcc --- .gitignore | 4 ++-- include/defines.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 6717ace186..be1d212415 100644 --- a/.gitignore +++ b/.gitignore @@ -106,5 +106,5 @@ mingw64/ # torch torch.hash.yml -# build log -build.log \ No newline at end of file +# makefile +Makefile diff --git a/include/defines.h b/include/defines.h index acc0f1dbfa..c210ec9591 100644 --- a/include/defines.h +++ b/include/defines.h @@ -37,7 +37,7 @@ * D-pad DOWN = MARIO * */ -#if defined(GCC) || defined(DEBUG) +#if /* defined(GCC) ||*/ defined(DEBUG) #define ENABLE_DEBUG_MODE 1 #else #define ENABLE_DEBUG_MODE 0 From 68cd12eddca7e0b9e2811b6de2ae4bda8a560f6b Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Fri, 27 Mar 2026 18:40:09 -0400 Subject: [PATCH 36/73] trees on MR no longer increment gNumSpawnedShells --- src/racing/actors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/racing/actors.c b/src/racing/actors.c index 87fd60824c..3999ee4129 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -201,7 +201,7 @@ void actor_init(struct Actor* actor, Vec3f startingPos, Vec3s startingRot, Vec3f break; } case ACTOR_TREE_MARIO_RACEWAY: - gNumSpawnedShells += 1; + // gNumSpawnedShells += 1; actor->flags |= 0x4000; actor->state = 0x0043; actor->boundingBoxSize = 3.0f; From e64fad7c4a2503740fed2a451ea793e0038a4ac2 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Tue, 7 Apr 2026 18:13:48 -0400 Subject: [PATCH 37/73] updated repo with following changes, require more testing: default: runs the regular code fo rthe shells, with all bugs bugfix: fixes the bug where mario raceway trees are counted towards the spawned number of shells, also properly decrements the shell counts in update.inc.c for red and green shells 30: same as bugfix, plus increases the shell limit by 10, utilizing increased gfx pool size (256 vs 128) --- src/actors/blue_and_red_shells/update.inc.c | 5 + src/actors/green_shell/update.inc.c | 5 + src/code_80057C60.c | 13 ++ src/code_80057C60.h | 1 + src/main.c | 1 + src/main.h | 3 +- src/menu_items.c | 4 +- src/menus.c | 2 +- src/racing/actors.c | 161 ++++++++++++++------ src/racing/math_util.c | 13 +- 10 files changed, 155 insertions(+), 53 deletions(-) diff --git a/src/actors/blue_and_red_shells/update.inc.c b/src/actors/blue_and_red_shells/update.inc.c index 4835c53efa..94a6429801 100644 --- a/src/actors/blue_and_red_shells/update.inc.c +++ b/src/actors/blue_and_red_shells/update.inc.c @@ -4,6 +4,7 @@ #include #include #include +#include "menu_items.h" void func_802B3B44(struct ShellActor* shell) { u16 currentPathPoint; @@ -459,6 +460,10 @@ void update_actor_red_blue_shell(struct ShellActor* shell) { shell->pos[1] += shell->velocity[1]; if (shell->someTimer == 0) { destroy_actor((struct Actor*) shell); + // bugfix toggle for modified shell limit modes + if (gTournamentShellLimit != 0) { + gNumSpawnedShells -= 1; + } } break; case BLUE_SHELL_LOCK_ON: diff --git a/src/actors/green_shell/update.inc.c b/src/actors/green_shell/update.inc.c index 7231af1832..c230ed0a4f 100644 --- a/src/actors/green_shell/update.inc.c +++ b/src/actors/green_shell/update.inc.c @@ -3,6 +3,7 @@ #include #include #include "collision.h" +#include "menu_items.h" /** * @brief Updates the green shell actor. @@ -191,6 +192,10 @@ void update_actor_green_shell(struct ShellActor* shell) { shell->pos[1] += shell->velocity[1]; if (shell->someTimer == 0) { destroy_actor((struct Actor*) shell); + // bugfix toggle for modified shell limit modes + if (gTournamentShellLimit != 0) { + gNumSpawnedShells -= 1; + } } break; default: diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 2a3f10691e..8f2dab1566 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -1098,6 +1098,19 @@ void render_hud_2p_horizontal_player_two(void) { } } +void render_shell_count(void) { + if (gActiveScreenMode == SCREEN_MODE_3P_4P_SPLITSCREEN) { + gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(D_802B8880)); + gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + set_matrix_hud_screen(); + gSPClearGeometryMode(gDisplayListHead++, G_ZBUFFER); + load_debug_font(); + print_str_num(0x0, 0x10, "shells ", gNumSpawnedShells); + func_80057778(); + gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER); + } +} + void draw_simplified_hud(s32 playerId) { if ((gModeSelection != BATTLE) && (D_80165800[playerId] == 0) && (gIsHUDVisible != 0)) { render_hud_timer(playerId); diff --git a/src/code_80057C60.h b/src/code_80057C60.h index 95e9e1fdba..cd4961533d 100644 --- a/src/code_80057C60.h +++ b/src/code_80057C60.h @@ -60,6 +60,7 @@ void func_80059358(void); void render_hud_2p_horizontal_player_two_horizontal_player_one(void); void func_800593F0(void); void render_hud_2p_horizontal_player_two(void); +void render_shell_count(void); void draw_simplified_hud(s32); void func_800594F0(void); void render_hud_2p_vertical_player_one(void); diff --git a/src/main.c b/src/main.c index d322e93871..906701325d 100644 --- a/src/main.c +++ b/src/main.c @@ -926,6 +926,7 @@ void race_logic_loop(void) { render_player_three_3p_4p_screen(); render_player_four_3p_4p_screen(); } + render_shell_count(); break; } diff --git a/src/main.h b/src/main.h index 6d7ac7aac2..0b43ad7d2f 100644 --- a/src/main.h +++ b/src/main.h @@ -17,6 +17,7 @@ #endif #define MTX_OBJECT_POOL_SIZE 128 +#define MTX_OBJECT_POOL_SIZE_EXTRA 256 //! @todo Verify with proper documentation // functions called by mtxShadow multiply by 8 @@ -46,7 +47,7 @@ struct GfxPool { /* 0x00180 */ Mtx mtxUnk; // Matrix unused /* 0x001C0 */ Mtx mtxLookAt[4]; // Matrix for lookat screen modes /* 0x002C0 */ Mtx mtxHud[MTX_HUD_POOL_SIZE]; // Matrix hud elements and 2D related effects - /* 0x0CAC0 */ Mtx mtxObject[MTX_OBJECT_POOL_SIZE]; // Matrix course objects + /* 0x0CAC0 */ Mtx mtxObject[MTX_OBJECT_POOL_SIZE_EXTRA]; // Matrix course objects (allocate max, limit used at runtime) /* 0x0EAC0 */ Mtx mtxShadow[MTX_SHADOW_POOL_SIZE]; // Matrix shadow characters /* 0x0F2C0 */ Mtx mtxKart[MTX_KART_POOL_SIZE]; // Matrix kart characters /* 0x0FAC0 */ Mtx mtxEffect[MTX_EFFECT_POOL_SIZE]; // Matrix misc effects diff --git a/src/menu_items.c b/src/menu_items.c index 4870239785..71bb13d9c1 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -5842,7 +5842,7 @@ void render_custom_overlay(void) { static const char* mpMusic_labels[] = {"default", "enabled"}; static const char* mpTrainBoat_labels[] = {"default", "enabled", "train", "boat"}; static const char* AA_labels[] = {"default", "disabled"}; - static const char* shell_labels[] = {"default", "100"}; + static const char* shell_labels[] = {"default", "30", "bugfix"}; static const char* timer_labels[] = {"default", "enabled"}; static const char* trophy_labels[] = {"default", "enabled"}; static const char* practice_labels[] = {"default", "enabled"}; @@ -5964,7 +5964,7 @@ void render_custom_overlay(void) { gTournamentAA = idx; break; case 7: - /* shell limit: labels (default, 100) */ + /* shell limit: labels (default, 30, bugfix) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; if (idx >= (int)(sizeof(shell_labels) / sizeof(shell_labels[0]))) idx = 0; diff --git a/src/menus.c b/src/menus.c index 1729f5ce8a..ed742b9080 100644 --- a/src/menus.c +++ b/src/menus.c @@ -249,7 +249,7 @@ s8 gCustomMenuOptionValues[CUSTOM_MENU_ROWS] = { 0 }; // Per-row number of selectable values (matches label arrays in render_custom_overlay) // tracks, stats, scaling, widescreen, mp music, mp train boat, AA, shell limit, // vs timer, trophy, practice, extra, reverse -static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 2, 3, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2 }; +static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 2, 3, 2, 2, 4, 2, 3, 2, 2, 2, 2, 2 }; // end of new var init diff --git a/src/racing/actors.c b/src/racing/actors.c index 3999ee4129..e08b47b88d 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -168,15 +168,15 @@ void actor_init(struct Actor* actor, Vec3f startingPos, Vec3s startingRot, Vec3f actor->boundingBoxSize = 4.0f; actor->flags = actor->flags | 0x4000 | 0x2000 | 0x1000; // default behavior, default shell limit - if (!gTournamentShellLimit) { + if (gTournamentShellLimit != 1) { if ((s32) gNumSpawnedShells >= 0x15) { cleanup_red_and_green_shells((struct ShellActor*) actor); } break; } - // custom shell limit of 100 + // custom shell limit of 30 else { - if ((s32) gNumSpawnedShells >= 0x64) { + if ((s32) gNumSpawnedShells >= 0x1F) { cleanup_red_and_green_shells((struct ShellActor*) actor); } break; @@ -187,21 +187,24 @@ void actor_init(struct Actor* actor, Vec3f startingPos, Vec3s startingRot, Vec3f actor->boundingBoxSize = 4.0f; actor->flags = actor->flags | 0x4000 | 0x2000 | 0x1000; // default behavior, default shell limit - if (!gTournamentShellLimit) { + if (gTournamentShellLimit != 1) { if ((s32) gNumSpawnedShells >= 0x15) { cleanup_red_and_green_shells((struct ShellActor*) actor); } break; } - // custom shell limit of 100 + // custom shell limit of 30 else { - if ((s32) gNumSpawnedShells >= 0x64) { + if ((s32) gNumSpawnedShells >= 0x1F) { cleanup_red_and_green_shells((struct ShellActor*) actor); } break; } case ACTOR_TREE_MARIO_RACEWAY: - // gNumSpawnedShells += 1; + // only run this bug if default shell behavior enabled + if (gTournamentShellLimit == 0) { + gNumSpawnedShells += 1; + } actor->flags |= 0x4000; actor->state = 0x0043; actor->boundingBoxSize = 3.0f; @@ -520,26 +523,54 @@ void render_cows(Camera* camera, Mat4 arg1, UNUSED struct Actor* actor) { arg1[3][0] = sp88[0]; arg1[3][1] = sp88[1]; arg1[3][2] = sp88[2]; - if ((gMatrixObjectCount < MTX_OBJECT_POOL_SIZE) && (render_set_position(arg1, 0) != 0)) { - switch (var_s1->someId) { - case 0: - gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow1); - break; - case 1: - gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow2); - break; - case 2: - gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow3); - break; - case 3: - gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow4); - break; - case 4: - gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow5); - break; + + // use default value for pool size when default shell limit is enabled + if (gTournamentShellLimit != 1) { + if ((gMatrixObjectCount < MTX_OBJECT_POOL_SIZE) && (render_set_position(arg1, 0) != 0)) { + switch (var_s1->someId) { + case 0: + gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow1); + break; + case 1: + gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow2); + break; + case 2: + gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow3); + break; + case 3: + gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow4); + break; + case 4: + gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow5); + break; + } + } else { + return; + } + } + // use increased pool with increased shell limit + else { + if ((gMatrixObjectCount < MTX_OBJECT_POOL_SIZE_EXTRA) && (render_set_position(arg1, 0) != 0)) { + switch (var_s1->someId) { + case 0: + gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow1); + break; + case 1: + gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow2); + break; + case 2: + gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow3); + break; + case 3: + gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow4); + break; + case 4: + gSPDisplayList(gDisplayListHead++, d_course_moo_moo_farm_dl_cow5); + break; + } + } else { + return; } - } else { - return; } } var_s1++; @@ -662,8 +693,17 @@ void render_palm_trees(Camera* camera, Mat4 arg1, UNUSED struct Actor* actor) { test = (s16) test; if (test == 6) { mtxf_rotate_zxy_translate(sp90, spD4, sp88); - if (!(gMatrixObjectCount < MTX_OBJECT_POOL_SIZE)) { - break; + // use default object pool size for default shell behavior + if (gTournamentShellLimit != 1) { + if (!(gMatrixObjectCount < MTX_OBJECT_POOL_SIZE)) { + break; + } + } + // use higher object pool size for higher shell limit + else { + if (!(gMatrixObjectCount < MTX_OBJECT_POOL_SIZE_EXTRA)) { + break; + } } render_set_position(sp90, 0); goto dummylabel; @@ -671,26 +711,53 @@ void render_palm_trees(Camera* camera, Mat4 arg1, UNUSED struct Actor* actor) { arg1[3][0] = spD4[0]; arg1[3][1] = spD4[1]; arg1[3][2] = spD4[2]; - if (gMatrixObjectCount < MTX_OBJECT_POOL_SIZE) { - render_set_position(arg1, 0); - dummylabel: - gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); - switch (test) { - case 0: - gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_tree1); - break; - case 4: - gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_tree2); - break; - case 5: - gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_tree3); - break; - case 6: - gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_palm_tree); - break; + + // use default behavior for default shell limit + if (gTournamentShellLimit != 1) { + if (gMatrixObjectCount < MTX_OBJECT_POOL_SIZE) { + render_set_position(arg1, 0); + dummylabel: + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + switch (test) { + case 0: + gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_tree1); + break; + case 4: + gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_tree2); + break; + case 5: + gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_tree3); + break; + case 6: + gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_palm_tree); + break; + } + } else { + break; } - } else { - break; + } + // use increased object pool size for increased shell limit + else { + if (gMatrixObjectCount < MTX_OBJECT_POOL_SIZE_EXTRA) { + render_set_position(arg1, 0); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + switch (test) { + case 0: + gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_tree1); + break; + case 4: + gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_tree2); + break; + case 5: + gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_tree3); + break; + case 6: + gSPDisplayList(gDisplayListHead++, d_course_dks_jungle_parkway_dl_palm_tree); + break; + } + } else { + break; + } } var_s1++; } diff --git a/src/racing/math_util.c b/src/racing/math_util.c index f677863d54..d5142826aa 100644 --- a/src/racing/math_util.c +++ b/src/racing/math_util.c @@ -8,6 +8,7 @@ #include "buffers/trig_tables.h" #include "math.h" #include "memory.h" +#include "menu_items.h" #pragma intrinsic(sqrtf, fabs) @@ -45,8 +46,16 @@ UNUSED void func_802B4FF0() { * to be performed. */ s32 render_set_position(Mat4 mtx, s32 mode) { - if (gMatrixObjectCount >= MTX_OBJECT_POOL_SIZE) { - return 0; + // default behavior run when shell limit set to default + if (gTournamentShellLimit != 1) { + if (gMatrixObjectCount >= MTX_OBJECT_POOL_SIZE) { + return 0; + } + } else { + // use extra pool size for increased shell limit + if (gMatrixObjectCount >= MTX_OBJECT_POOL_SIZE_EXTRA) { + return 0; + } } mtxf_to_mtx(&gGfxPool->mtxObject[gMatrixObjectCount], mtx); switch (mode) { /* irregular */ From c3e99a9757166b1f43d71c722c602a89e92a7c0e Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sun, 19 Apr 2026 15:46:33 -0400 Subject: [PATCH 38/73] reverted pool size change that crashes on n64 console --- src/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.h b/src/main.h index 0b43ad7d2f..0d58e71e64 100644 --- a/src/main.h +++ b/src/main.h @@ -47,7 +47,7 @@ struct GfxPool { /* 0x00180 */ Mtx mtxUnk; // Matrix unused /* 0x001C0 */ Mtx mtxLookAt[4]; // Matrix for lookat screen modes /* 0x002C0 */ Mtx mtxHud[MTX_HUD_POOL_SIZE]; // Matrix hud elements and 2D related effects - /* 0x0CAC0 */ Mtx mtxObject[MTX_OBJECT_POOL_SIZE_EXTRA]; // Matrix course objects (allocate max, limit used at runtime) + /* 0x0CAC0 */ Mtx mtxObject[MTX_OBJECT_POOL_SIZE]; // Matrix course objects (allocate max, limit used at runtime) /* 0x0EAC0 */ Mtx mtxShadow[MTX_SHADOW_POOL_SIZE]; // Matrix shadow characters /* 0x0F2C0 */ Mtx mtxKart[MTX_KART_POOL_SIZE]; // Matrix kart characters /* 0x0FAC0 */ Mtx mtxEffect[MTX_EFFECT_POOL_SIZE]; // Matrix misc effects From 1f573e80c341d93f635aa16d01b8bfbe42de0e7f Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sun, 28 Jun 2026 16:00:59 -0400 Subject: [PATCH 39/73] commented out shell debug counter. replaced shell count limiter menu option with 4p minimap forcing, and implemented. --- src/code_80057C60.c | 71 +++++++++++++++++++++++++++++++-------------- src/main.c | 2 +- src/main.h | 2 +- src/menu_items.c | 27 ++++++++--------- src/menu_items.h | 3 +- 5 files changed, 68 insertions(+), 37 deletions(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 8f2dab1566..6d0c7b031d 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -36,6 +36,7 @@ #include "spawn_players.h" #include "sounds.h" #include "data/some_data.h" +#include "menu_items.h" //! @warning this macro is undef'd at the end of this file #define MAKE_RGB(r, g, b) (((r) << 0x10) | ((g) << 0x08) | (b << 0x00)) @@ -149,17 +150,17 @@ UNUSED s8 D_801657E0; s8 D_801657E1; s8 D_801657E2; s8 D_801657E3; -s8 D_801657E4; +s8 D_801657E4; // shows character potraits when == 2 s8 D_801657E5; bool8 D_801657E6; u8 D_801657E7; bool8 D_801657E8; UNUSED s32 D_801657EC; -bool8 D_801657F0; +bool8 D_801657F0; // prog view UNUSED s32 D_801657F4; -bool8 D_801657F8; +bool8 D_801657F8; // lap count s32 D_801657FC; -s8 D_80165800[2]; +s8 D_80165800[2]; // draw minimap 3/4p vs s32 D_80165804; s8 D_80165808; s32 D_8016580C; @@ -1507,6 +1508,7 @@ void func_8005A3C0(void) { bool b = false; if ((gGamestate != ENDING) && (gGamestate != CREDITS_SEQUENCE) && !D_8018D204) { switch (gPlayerCountSelection1) { + // 1p case 1: if (gControllerOne->buttonPressed & R_CBUTTONS) { if (++D_801657E4 >= 3) { @@ -1528,6 +1530,7 @@ void func_8005A3C0(void) { b = true; } break; + // 2p case 2: if (gModeSelection != BATTLE) { if (gControllerOne->buttonPressed & R_CBUTTONS) { @@ -1548,28 +1551,54 @@ void func_8005A3C0(void) { } } break; + // 3p case 3: - if ((gControllerOne->buttonPressed & R_CBUTTONS) || (gControllerTwo->buttonPressed & R_CBUTTONS) || - (gControllerThree->buttonPressed & R_CBUTTONS)) { - if (gModeSelection != BATTLE) { - D_801657F0 = (D_801657F0 + 1) & 1; + if ((gControllerOne->buttonPressed & R_CBUTTONS) || (gControllerTwo->buttonPressed & R_CBUTTONS) || + (gControllerThree->buttonPressed & R_CBUTTONS)) { + if (gModeSelection != BATTLE) { + D_801657F0 = (D_801657F0 + 1) & 1; + } + D_801657E4 = (D_801657E4 + 1) & 1; + b = true; } - D_801657E4 = (D_801657E4 + 1) & 1; - b = true; - } - break; + break; + + // 4p case 4: - if ((gControllerOne->buttonPressed & R_CBUTTONS) || (gControllerTwo->buttonPressed & R_CBUTTONS) || - (gControllerThree->buttonPressed & R_CBUTTONS) || (gControllerFour->buttonPressed & R_CBUTTONS)) { - D_801657E4 = (D_801657E4 + 1) & 1; - D_801657F8 = (D_801657F8 + 1) & 1; - D_80165800[0] = (D_80165800[0] + 1) & 1; - if (gModeSelection != BATTLE) { - D_801657F0 = (D_801657F0 + 1) & 1; + // run default settings (togglable map/prog view) when forcemap = 0 + if (gTournamentForceMap == 0) { + if ((gControllerOne->buttonPressed & R_CBUTTONS) || (gControllerTwo->buttonPressed & R_CBUTTONS) || + (gControllerThree->buttonPressed & R_CBUTTONS) || (gControllerFour->buttonPressed & R_CBUTTONS)) { + D_801657E4 = (D_801657E4 + 1) & 1; + D_801657F8 = (D_801657F8 + 1) & 1; + D_80165800[0] = (D_80165800[0] + 1) & 1; + if (gModeSelection != BATTLE) { + D_801657F0 = (D_801657F0 + 1) & 1; + } + b = true; } - b = true; + break; + } + // force progress view at all times (N/A in battle) + else if (gTournamentForceMap == 1) { + D_801657E4 = 0; + D_801657F8 = 1; + D_80165800[0] = 0; + if (gModeSelection != BATTLE) { + D_801657F0 = 1; + } + b = true; + } + // force map view at all times + else { + D_801657E4 = 0; + D_801657F8 = 0; + D_80165800[0] = 1; + if (gModeSelection != BATTLE) { + D_801657F0 = 0; + } + b = true; } - break; } if (b) { // this the sound for the progress view toggle diff --git a/src/main.c b/src/main.c index 906701325d..4678299976 100644 --- a/src/main.c +++ b/src/main.c @@ -926,7 +926,7 @@ void race_logic_loop(void) { render_player_three_3p_4p_screen(); render_player_four_3p_4p_screen(); } - render_shell_count(); + // render_shell_count(); break; } diff --git a/src/main.h b/src/main.h index 0d58e71e64..0d8ea8d9a2 100644 --- a/src/main.h +++ b/src/main.h @@ -47,7 +47,7 @@ struct GfxPool { /* 0x00180 */ Mtx mtxUnk; // Matrix unused /* 0x001C0 */ Mtx mtxLookAt[4]; // Matrix for lookat screen modes /* 0x002C0 */ Mtx mtxHud[MTX_HUD_POOL_SIZE]; // Matrix hud elements and 2D related effects - /* 0x0CAC0 */ Mtx mtxObject[MTX_OBJECT_POOL_SIZE]; // Matrix course objects (allocate max, limit used at runtime) + /* 0x0CAC0 */ Mtx mtxObject[MTX_OBJECT_POOL_SIZE]; // Matrix course objects (allocate max, limit used at runtime; raise value to increase num of shells rendered) /* 0x0EAC0 */ Mtx mtxShadow[MTX_SHADOW_POOL_SIZE]; // Matrix shadow characters /* 0x0F2C0 */ Mtx mtxKart[MTX_KART_POOL_SIZE]; // Matrix kart characters /* 0x0FAC0 */ Mtx mtxEffect[MTX_EFFECT_POOL_SIZE]; // Matrix misc effects diff --git a/src/menu_items.c b/src/menu_items.c index 71bb13d9c1..7ae4759a5a 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -365,7 +365,8 @@ s8 gTournamentWidescreen = 0; s8 gTournamentMusic = 0; s8 gTournamentTrainBoat = 0; s8 gTournamentAA = 0; -s8 gTournamentShellLimit = 0; +s8 gTournamentForceMap = 0; +s8 gTournamentShellLimit = 0; // not currently in menu s8 gTournamentTimer = 0; s8 gTournamentTrophy = 0; s8 gPracticeMode = 0; @@ -5826,7 +5827,7 @@ void render_custom_overlay(void) { "mp music", "mp train boat", "AA", - "shell limit", + "force minimap", "vs timer", "trophy", "practice", @@ -5842,7 +5843,7 @@ void render_custom_overlay(void) { static const char* mpMusic_labels[] = {"default", "enabled"}; static const char* mpTrainBoat_labels[] = {"default", "enabled", "train", "boat"}; static const char* AA_labels[] = {"default", "disabled"}; - static const char* shell_labels[] = {"default", "30", "bugfix"}; + static const char* minimap_labels[] = {"default", "prog view", "map"}; static const char* timer_labels[] = {"default", "enabled"}; static const char* trophy_labels[] = {"default", "enabled"}; static const char* practice_labels[] = {"default", "enabled"}; @@ -5852,7 +5853,7 @@ void render_custom_overlay(void) { set_text_color(TEXT_YELLOW); // title (centered) - print_text1_center_mode_1(x, y - 0x30, "WEATHERTON ABNEY CLIMATEE ZSERF", 0, 0.80f, 0.80f); + print_text1_center_mode_1(x, y - 0x28, "WEATHERTON ABNEY CLIMATEE ZSERF", 0, 0.70f, 0.70f); // /* use debug font helper */ // x1 = 0; @@ -5860,30 +5861,30 @@ void render_custom_overlay(void) { // func_800579B8(x1, y1, "WEATHERTON ABNEY CLIMATEE"); // version / date (smaller) - left-aligned to start under 'KART' - print_text1_left(x + 0x5A, y + 0x06, "TE V2026-03-26", 0, 0.65f, 0.65f); + print_text1_left(x + 0x5A, y + 0x06, "TE V2026-06-28", 0, 0.65f, 0.65f); // option name placeholders (second column) and values (third column) for (i = 0; i < CUSTOM_MENU_ROWS; i++) { /* standard row stride (single-line names) - reduced spacing */ - rowY = y + 0x18 + (i * 0xC); + rowY = y + 0x14 + (i * 0xC); /* first column: selection pointer */ if (i == gCustomMenuSelection) { /* build a local MenuItem for the cursor effect and set the target position */ - sp84.column = x - 0x40; + sp84.column = x - 0x50; sp84.row = rowY - 0x06; cursorItem.paramf = 2.0f; /* start scale/rotation multiplier */ cursorItem.subState = 1; /* small non-zero rotation driver */ func_800A66A8(&cursorItem, &sp84); } else { /* draw empty space to keep alignment */ - print_text1_left(x - 0x30, rowY, " ", 0, 0.6f, 0.6f); + print_text1_left(x - 0x40, rowY, " ", 0, 0.6f, 0.6f); } /* second column: option name (single line) */ if (customModifierNames[i][0] != '\0') { text_rainbow_effect(gCustomMenuSelection, i, TEXT_YELLOW); - print_text_mode_1(x - 0x30, rowY, (char*)customModifierNames[i], 0, 0.6f, 0.6f); + print_text_mode_1(x - 0x40, rowY, (char*)customModifierNames[i], 0, 0.6f, 0.6f); } else { /* Build "Modifier N" manually to avoid linking snprintf */ const char* prefix = "Modifier "; @@ -5964,12 +5965,12 @@ void render_custom_overlay(void) { gTournamentAA = idx; break; case 7: - /* shell limit: labels (default, 30, bugfix) */ + /* force minimap: labels (default, progress view, map) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(shell_labels) / sizeof(shell_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x50, rowY, (char*)shell_labels[idx], 0, 0.6f, 0.6f); - gTournamentShellLimit = idx; + if (idx >= (int)(sizeof(minimap_labels) / sizeof(minimap_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)minimap_labels[idx], 0, 0.6f, 0.6f); + gTournamentForceMap = idx; break; case 8: /* vs timer: labels (default, enabled) */ diff --git a/src/menu_items.h b/src/menu_items.h index 2a8ff223d4..512ccfec31 100644 --- a/src/menu_items.h +++ b/src/menu_items.h @@ -864,7 +864,8 @@ extern s8 gTournamentWidescreen; extern s8 gTournamentMusic; extern s8 gTournamentTrainBoat; extern s8 gTournamentAA; -extern s8 gTournamentShellLimit; +extern s8 gTournamentShellLimit; // unused +extern s8 gTournamentForceMap; extern s8 gTournamentTimer; extern s8 gTournamentTrophy; extern s8 gPracticeMode; From b4c3e324de386c9729425d6ca72ca2aa4988e385 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 29 Jun 2026 06:26:54 -0400 Subject: [PATCH 40/73] fixed bug that made it so only P1 could navigate custom menu --- src/menus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/menus.c b/src/menus.c index ed742b9080..ba51a515c1 100644 --- a/src/menus.c +++ b/src/menus.c @@ -1124,7 +1124,8 @@ void splash_menu_act(struct Controller* controller, u16 controllerIdx) { if (is_screen_being_faded() == 0) { if (controllerIdx == PLAYER_ONE) { gMenuDelayTimer += 1; - + } + // handles input to custom menu // navigation // works @@ -1169,7 +1170,6 @@ void splash_menu_act(struct Controller* controller, u16 controllerIdx) { } play_sound2(SOUND_MENU_SELECT); } - } switch (gDebugMenuSelection) { case DEBUG_MENU_DISABLED: { isDebug = false; From b54390cb5cecb511980f1bbbb3a00f2a02981200 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 29 Jun 2026 07:13:37 -0400 Subject: [PATCH 41/73] added wario stats switch to custom menu. --- src/effects.c | 4 ++-- src/menu_items.c | 4 ++-- src/menus.c | 4 ++-- src/player_controller.c | 10 +++++----- src/spawn_players.c | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/effects.c b/src/effects.c index 96aecbe401..e5f398b264 100644 --- a/src/effects.c +++ b/src/effects.c @@ -19,9 +19,9 @@ #include "menu_items.h" #include -#define PLAYER_STATS_CHARACTER_ID(player) ((gTournamentCharacterStats == 0) ? YOSHI : (player)->characterId) +#define PLAYER_STATS_CHARACTER_ID(player) ((gTournamentCharacterStats == 0) ? YOSHI : (gTournamentCharacterStats == 2) ? WARIO : (player)->characterId) -s32 D_8018D900[8]; +s32 D_8018D900[8]; s16 D_8018D920[8]; s32 gPlayerStarEffectStartTime[8]; s32 gPlayerBooEffectStartTime[8]; diff --git a/src/menu_items.c b/src/menu_items.c index 7ae4759a5a..a22b00a67e 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -5837,7 +5837,7 @@ void render_custom_overlay(void) { /* per-option label arrays */ static const char* tracks_labels[] = {"VA", "kalliera", "kalliera mmf"}; - static const char* stats_labels[] = {"all yoshi", "default"}; + static const char* stats_labels[] = {"all yoshi", "default", "all wario"}; static const char* scaling_labels[] = {"default", "30fps", "60fps"}; static const char* widescreen_labels[] = {"default", "enabled"}; static const char* mpMusic_labels[] = {"default", "enabled"}; @@ -5917,7 +5917,7 @@ void render_custom_overlay(void) { gTournamentCourseMode = idx; // set track order break; case 1: - /* stats: labels (default, all yoshi) */ + /* stats: labels (all yoshi, default, all wario) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; if (idx >= (int)(sizeof(stats_labels) / sizeof(stats_labels[0]))) idx = 0; diff --git a/src/menus.c b/src/menus.c index ba51a515c1..da948e45b6 100644 --- a/src/menus.c +++ b/src/menus.c @@ -247,9 +247,9 @@ s8 gCustomMenuSelection = 0; s8 gCustomMenuOptionValues[CUSTOM_MENU_ROWS] = { 0 }; // Per-row number of selectable values (matches label arrays in render_custom_overlay) -// tracks, stats, scaling, widescreen, mp music, mp train boat, AA, shell limit, +// tracks, stats, scaling, widescreen, mp music, mp train boat, AA, force minimap, // vs timer, trophy, practice, extra, reverse -static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 2, 3, 2, 2, 4, 2, 3, 2, 2, 2, 2, 2 }; +static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 3, 3, 2, 2, 4, 2, 3, 2, 2, 2, 2, 2 }; // end of new var init diff --git a/src/player_controller.c b/src/player_controller.c index 79a4633641..8c08935cad 100644 --- a/src/player_controller.c +++ b/src/player_controller.c @@ -23,7 +23,7 @@ #include "sounds.h" #include "menu_items.h" -#define PLAYER_STATS_CHARACTER_ID(player) ((gTournamentCharacterStats == 0) ? YOSHI : (player)->characterId) +#define PLAYER_STATS_CHARACTER_ID(player) ((gTournamentCharacterStats == 0) ? YOSHI : (gTournamentCharacterStats == 2) ? WARIO : (player)->characterId) extern s32 D_8018D168; @@ -3269,7 +3269,7 @@ void player_accelerate_alternative(Player* player) { s32 statsCharacterId; player_index = get_player_index_for_player(player); - statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : player->characterId; + statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : (gTournamentCharacterStats == 2) ? WARIO : player->characterId; if (gIsPlayerTripleAButtonCombo[player_index] == false) { if ((0.0 <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.1))) { player->currentSpeed += @@ -3604,7 +3604,7 @@ void player_accelerate_during_start_sequence(Player* player) { s32 time_delta; playerIndex = get_player_index_for_player(player); - statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : player->characterId; + statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : (gTournamentCharacterStats == 2) ? WARIO : player->characterId; if ((player->currentSpeed >= 0.0) && (player->currentSpeed < (player->topSpeed * 0.1))) { player->currentSpeed += gKartAccelerationTables[statsCharacterId][0] * 3.0; } @@ -3679,7 +3679,7 @@ void player_accelerate(Player* player) { s32 statsCharacterId; player_index = get_player_index_for_player(player); - statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : player->characterId; + statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : (gTournamentCharacterStats == 2) ? WARIO : player->characterId; if ((0.0 <= player->currentSpeed) && (player->currentSpeed < (player->topSpeed * 0.1))) { player->currentSpeed += gKartAccelerationTables[statsCharacterId][0] * 3.2; } @@ -3730,7 +3730,7 @@ void player_decelerate(Player* player, f32 speedReduction) { void player_accelerate_global(Player* player, s32 playerIndex) { s32 statsCharacterId; - statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : player->characterId; + statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : (gTournamentCharacterStats == 2) ? WARIO : player->characterId; if ((gPlayerCurrentSpeed[playerIndex] >= 0.0) && (gPlayerCurrentSpeed[playerIndex] < ((f64) player->topSpeed * 0.1))) { gPlayerCurrentSpeed[playerIndex] += gKartAccelerationTables[statsCharacterId][0] * 3.2; } diff --git a/src/spawn_players.c b/src/spawn_players.c index 1432afa16e..99fdf0e936 100644 --- a/src/spawn_players.c +++ b/src/spawn_players.c @@ -84,7 +84,7 @@ void spawn_player(Player* player, s8 playerIndex, f32 startingRow, f32 startingC player->unk_08C = 0; player->characterId = characterId; player->unk_0B6 = 0; - statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : player->characterId; + statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : (gTournamentCharacterStats == 2) ? WARIO : player->characterId; player->kartFriction = gKartFrictionTable[statsCharacterId]; player->boundingBoxSize = gKartBoundingBoxSizeTable[statsCharacterId]; player->kartGravity = gKartGravityTable[statsCharacterId]; From 354d2a3b3982b18d47a5540dacce26e45e0a1873 Mon Sep 17 00:00:00 2001 From: Jed Grabman Date: Mon, 6 Jul 2026 05:01:48 -0400 Subject: [PATCH 42/73] Finish times and port priority fix --- src/code_80057C60.c | 2 + src/code_80057C60.h | 2 + src/cpu_vehicles_camera_path.c | 164 ++++++++++++++++++--------------- src/menu_items.c | 109 ++++++++++++++++------ src/racing/race_logic.c | 150 +++++++++++++++--------------- src/racing/race_logic.h | 2 +- 6 files changed, 251 insertions(+), 178 deletions(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 6d0c7b031d..773ca430dc 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -41,6 +41,8 @@ //! @warning this macro is undef'd at the end of this file #define MAKE_RGB(r, g, b) (((r) << 0x10) | ((g) << 0x08) | (b << 0x00)) +bool gFinished[8]; +f32 gFinishTime[8]; s32 D_80165590; s32 D_80165594; s32 D_80165598; diff --git a/src/code_80057C60.h b/src/code_80057C60.h index cd4961533d..edfd6a581e 100644 --- a/src/code_80057C60.h +++ b/src/code_80057C60.h @@ -257,6 +257,8 @@ void func_8006E940(Player*, s8, s8); void func_80075CA8(void); void func_80085214(); +extern bool gFinished[]; +extern f32 gFinishTime[]; extern s16 D_800E4730[]; extern u8** D_800E4770[]; extern u8** D_800E47A0[]; diff --git a/src/cpu_vehicles_camera_path.c b/src/cpu_vehicles_camera_path.c index 40008984c4..5e4b8fa426 100644 --- a/src/cpu_vehicles_camera_path.c +++ b/src/cpu_vehicles_camera_path.c @@ -706,16 +706,17 @@ void detect_wrong_player_direction(s32 playerId, Player* player) { gPreviousLapProgressScore[playerId] = gNumPathPointsTraversed[playerId]; } -void set_places(void) { - s32 temp_s2; - f32 temp_f0; - s32 rankPlayer[8]; - s32 a_really_cool_variable_name; - UNUSED s32 pad; +void set_places(void){ + s32 playerIdx; + s32 rankIdx; + s32 rankOld; s32 numPlayer; - s32 playerId; - s32 temp_a0; - s32 var_t1_3; + bool playerProcessed[8]; + bool bestIsFinished; + f32 bestFinishTime; + f32 bestCourseCompletionPercent; + s32 bestPlayerIdx; + s32 playerIdByRank[8]; switch (gModeSelection) { case BATTLE: @@ -730,71 +731,62 @@ void set_places(void) { break; } - if (D_8016348C == 0) { - for (playerId = 0; playerId < numPlayer; playerId++) { - temp_a0 = gGPCurrentRacePlayerIdByRank[playerId]; - rankPlayer[playerId] = temp_a0; - gCourseCompletionPercentByRank[playerId] = gCourseCompletionPercentByPlayerId[temp_a0]; - } - } else { - for (playerId = 0; playerId < numPlayer; playerId++) { - temp_a0 = gGPCurrentRacePlayerIdByRank[playerId]; - rankPlayer[playerId] = temp_a0; - gCourseCompletionPercentByRank[playerId] = -gTimePlayerLastTouchedFinishLine[temp_a0]; - } - } - - for (playerId = 0; playerId < numPlayer - 1; playerId++) { - if ((gPlayers[gGPCurrentRacePlayerIdByRank[playerId]].type & 0x800)) { - continue; - } - - for (var_t1_3 = playerId + 1; var_t1_3 < numPlayer; var_t1_3++) { - if (gCourseCompletionPercentByRank[playerId] < gCourseCompletionPercentByRank[var_t1_3]) { - if (!(gPlayers[gGPCurrentRacePlayerIdByRank[var_t1_3]].type & 0x800)) { - temp_s2 = rankPlayer[playerId]; - rankPlayer[playerId] = rankPlayer[var_t1_3]; - rankPlayer[var_t1_3] = temp_s2; - temp_f0 = gCourseCompletionPercentByRank[playerId]; - gCourseCompletionPercentByRank[playerId] = gCourseCompletionPercentByRank[var_t1_3]; - gCourseCompletionPercentByRank[var_t1_3] = temp_f0; + for (playerIdx = 0; playerIdx < numPlayer; playerIdx++){ + playerProcessed[playerIdx] = false; + gPreviousGPCurrentRaceRankByPlayerId[playerIdx] = gGPCurrentRaceRankByPlayerId[playerIdx]; + playerIdByRank[gGPCurrentRaceRankByPlayerId[playerIdx]] = playerIdx; + } + + // finds best player, puts them in 1st. + // Best remaining player in 2nd... + for (rankIdx = 0; rankIdx < numPlayer; rankIdx++){ + bestIsFinished = false; + // deliberately absurd value so that any player is better than it + bestFinishTime = 1000000; + bestCourseCompletionPercent = -1000000; + bestPlayerIdx = -1; + + /* uses previous ranks as tie-breaker. Only really relevant when + racers are not finished as they use course indexes, which is not very precise. + Finish times are floating point, so it's almost impossible to get a true tie + among finished players */ + for (rankOld = 0; rankOld < numPlayer; rankOld++){ + playerIdx = playerIdByRank[rankOld]; + if (playerProcessed[playerIdx]){ + continue; + } + if (bestIsFinished){ + if (gFinished[playerIdx] && gFinishTime[playerIdx] < bestFinishTime){ + bestFinishTime = gFinishTime[playerIdx]; + bestPlayerIdx = playerIdx; + } + } else { + if (gFinished[playerIdx]){ + bestIsFinished = true; + bestFinishTime = gFinishTime[playerIdx]; + bestPlayerIdx = playerIdx; + } else { + if (gCourseCompletionPercentByPlayerId[playerIdx] > bestCourseCompletionPercent){ + bestCourseCompletionPercent = gCourseCompletionPercentByPlayerId[playerIdx]; + bestPlayerIdx = playerIdx; + } } } } - } - - for (playerId = 0; playerId < NUM_PLAYERS; playerId++) { - gPreviousGPCurrentRaceRankByPlayerId[playerId] = gGPCurrentRaceRankByPlayerId[playerId]; - } - - for (playerId = 0; playerId < numPlayer; playerId++) { - gGPCurrentRacePlayerIdByRank[playerId] = rankPlayer[playerId]; - gGPCurrentRaceRankByPlayerId[rankPlayer[playerId]] = playerId; - } - - for (playerId = 0; playerId < numPlayer; playerId++) { - a_really_cool_variable_name = D_80164378[playerId]; - rankPlayer[playerId] = a_really_cool_variable_name; - gCourseCompletionPercentByRank[playerId] = gCourseCompletionPercentByPlayerId[a_really_cool_variable_name]; - } - - for (playerId = 0; playerId < numPlayer - 1; playerId++) { - for (var_t1_3 = playerId + 1; var_t1_3 < numPlayer; var_t1_3++) { - if (gCourseCompletionPercentByRank[playerId] < gCourseCompletionPercentByRank[var_t1_3]) { - temp_s2 = rankPlayer[playerId]; - rankPlayer[playerId] = rankPlayer[var_t1_3]; - rankPlayer[var_t1_3] = temp_s2; - temp_f0 = gCourseCompletionPercentByRank[playerId]; - gCourseCompletionPercentByRank[playerId] = gCourseCompletionPercentByRank[var_t1_3]; - gCourseCompletionPercentByRank[var_t1_3] = temp_f0; - } + playerProcessed[bestPlayerIdx] = true; + + gGPCurrentRaceRankByPlayerId[bestPlayerIdx] = rankIdx; + gGPCurrentRacePlayerIdByRank[rankIdx] = bestPlayerIdx; + D_80164378[rankIdx] = gGPCurrentRacePlayerIdByRank[rankIdx]; + gGPCurrentRaceRankByPlayerIdDup[rankIdx] = bestPlayerIdx; + // I am 90% sure this is unnecessary because gCourseCompletionPercentByRank is always reset when it is called, + // but I'm keeping it out of abundence of caution to be consistent with the old version of set_places + if (D_8016348C == 0) { + gCourseCompletionPercentByRank[rankIdx] = gCourseCompletionPercentByPlayerId[bestPlayerIdx]; + } else { + gCourseCompletionPercentByRank[rankIdx] = -gTimePlayerLastTouchedFinishLine[bestPlayerIdx]; } } - - for (playerId = 0; playerId < numPlayer; playerId++) { - gGPCurrentRaceRankByPlayerIdDup[rankPlayer[playerId]] = playerId; - D_80164378[playerId] = rankPlayer[playerId]; - } } void update_player_rankings(void) { @@ -1200,11 +1192,12 @@ void update_cpu_path_completion(s32 playerId, Player* player) { /** * Helps calculate time since player last touched finishline. + * Assumes constant z-speed and subtracts portion of frame where the finish line was already crossed **/ -f32 func_80009258(UNUSED s32 playerId, f32 arg1, f32 arg2) { - f32 temp_f2 = gPathStartZ - arg2; - f32 temp_f12 = arg1 - gPathStartZ; - return gCourseTimer - ((COURSE_TIMER_ITER_f * temp_f2) / (temp_f2 + temp_f12)); +f32 func_80009258(UNUSED s32 playerId, f32 previousPlayerZ, f32 playerZ) { + f32 z_change_after_cross = gPathStartZ - playerZ; + f32 z_change_before_cross = previousPlayerZ - gPathStartZ; + return gCourseTimer - ((COURSE_TIMER_ITER_f * z_change_after_cross) / (z_change_after_cross + z_change_before_cross)); } void update_player_path_completion(s32 playerId, Player* player) { @@ -1269,6 +1262,10 @@ void update_player_path_completion(s32 playerId, Player* player) { if ((var_v1 != 0) && (playerZ <= gPathStartZ)) { if (gPathStartZ < previousPlayerZ) { gLapCountByPlayerId[playerId]++; + if ((gLapCountByPlayerId[playerId] == 3) && !gFinished[playerId]){ + gFinished[playerId] = true; + gFinishTime[playerId] = func_80009258(playerId, previousPlayerZ, playerZ); + } if ((gModeSelection == GRAND_PRIX) && (gLapCountByPlayerId[playerId] == 5)) { if (gGPCurrentRaceRankByPlayerIdDup[playerId] == 7) { // clang-format off @@ -1411,6 +1408,7 @@ void update_player(s32 playerId) { UNUSED s32 pad3[10]; TrackPathPoint* pathPoint; f32 onePointFive = 1.5f; + s8 numPlayer; player = &gPlayers[playerId]; if ((s32) GET_COURSE_AIMaximumSeparation >= 0) { @@ -1460,7 +1458,22 @@ void update_player(s32 playerId) { player->unk_044 &= ~0x0001; } update_player_path_completion(playerId, player); - if ((gCurrentCourseId != COURSE_AWARD_CEREMONY) && ((D_80163240[playerId] == 1) || (playerId == 0))) { + + switch (gModeSelection) { + case BATTLE: + default: + return; // HEY! returns, not breaks + case GRAND_PRIX: + case TIME_TRIALS: + numPlayer = NUM_PLAYERS; + break; + case VERSUS: + numPlayer = gPlayerCount; + break; + } + + // checks on last player to ensure all players positions have been updated + if ((gCurrentCourseId != COURSE_AWARD_CEREMONY) && (playerId == (numPlayer - 1))) { set_places(); } if (player->type & PLAYER_CPU) { @@ -2088,6 +2101,9 @@ void init_players(void) { gLapCountByPlayerId[i] = -1; gCourseCompletionPercentByPlayerId[i] = 0.0f; gTimePlayerLastTouchedFinishLine[i] = 0.0f; + gFinished[i] = false; + // arbitrary large number to be longer than any vs race + gFinishTime[i] = 1000000.0f; if (gModeSelection == GRAND_PRIX) { if (1) {}; if (1) {}; // Maybe some debug code? diff --git a/src/menu_items.c b/src/menu_items.c index a22b00a67e..edfedbbf5d 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -213,11 +213,12 @@ Unk_D_800E70A0 D_800E7300[] = { { 0x18, 0x23, 0x00, 0x00 }, { 0x5d, 0x23, 0x00, 0x00 }, { 0xa2, 0x23, 0x00, 0x00 }, { 0xe7, 0x23, 0x00, 0x00 }, }; +// Versus menu coordinates Unk_D_800E70A0 D_800E7360[] = { - { 0x61, 0xa7, 0x00, 0x00 }, { 0x61, 0xb6, 0x00, 0x00 }, { 0x61, 0xc5, 0x00, 0x00 }, { 0x61, 0xd4, 0x00, 0x00 }, + { 0x61, 0xe3, 0x00, 0x00 }, }; Unk_D_800E70A0 D_800E7380[] = { @@ -8397,12 +8398,12 @@ void func_800A638C(MenuItem* arg0) { text_rainbow_effect(arg0->state - 0xA, var_s1, TEXT_GREEN); if ((var_s1 == 0) && (gModeSelection == VERSUS) && ((gPlayerCount == 3) || (gPlayerCount == 4))) { continueText = "CONTINUE TO "; - print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1), continueText, 0, 0.8f, 0.8f); + print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1) + 15, continueText, 0, 0.8f, 0.8f); xOffset = (get_string_width(continueText) * 0.8f) + 1.0f; - print_text_mode_1((s32) (0x00000069 + xOffset), 0xAE + (0xF * var_s1), getNextCourseAbbrString(), + print_text_mode_1((s32) (0x00000069 + xOffset), 0xAE + (0xF * var_s1) + 15, getNextCourseAbbrString(), 0, 0.8f, 0.8f); } else { - print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1), gTextPauseButton[var_s1 + 1], 0, 0.8f, + print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1) + 15, gTextPauseButton[var_s1 + 1], 0, 0.8f, 0.8f); } } @@ -8471,27 +8472,29 @@ void func_800A66A8(MenuItem* arg0, Unk_D_800E70A0* arg1) { void func_800A69C8(UNUSED MenuItem* arg0) { Unk_D_800E70A0* thing; UNUSED s32 stackPadding1; - s32 var_s0; + s32 playerId; char sp74[5]; s32 var_v1; char* temp_s3; u8* var_s4; + s32 finishTimeCopy; + char finishTimeText[8]; - for (var_s0 = 0; var_s0 < gPlayerCount; var_s0++) { + for (playerId = 0; playerId < gPlayerCount; playerId++) { var_v1 = 0; - thing = &D_800E7300[var_s0]; + thing = &D_800E7300[playerId]; switch (gModeSelection) { /* irregular */ case VERSUS: - if (gGPCurrentRaceRankByPlayerId[var_s0] != 0) { + if (gGPCurrentRaceRankByPlayerId[playerId] != 0) { var_v1 = 1; } - var_s4 = &gNmiUnknown1[var_s0]; + var_s4 = &gNmiUnknown1[playerId]; break; case BATTLE: - if (var_s0 != gPlayerWinningIndex) { + if (playerId != gPlayerWinningIndex) { var_v1 = 1; } - var_s4 = &gNmiUnknown4[var_s0]; + var_s4 = &gNmiUnknown4[playerId]; break; } temp_s3 = gWinLoseText[var_v1]; @@ -8501,12 +8504,35 @@ void func_800A69C8(UNUSED MenuItem* arg0) { set_text_color((s32) gGlobalTimer % 3); } func_800A79F4(var_s4[0], sp74); - text_draw(thing->column + 0x10, thing->row + 0x75, sp74, 0, 1.0f, 1.0f); - print_text1_center_mode_2(D_800E7380[var_s0].column, D_800E7380[var_s0].row, temp_s3, 0, 0.65f, 1.0f); + text_draw(thing->column + 0x10, thing->row + 0x75 + 15, sp74, 0, 1.0f, 1.0f); + print_text1_center_mode_2(D_800E7380[playerId].column, D_800E7380[playerId].row, temp_s3, 0, 0.65f, 1.0f); + + // show finish time if finished + if (gFinished[playerId]){ + // winner gets flashing timer + if (var_v1 != 1){ + set_text_color(gGlobalTimer % 3); + } + else{ + set_text_color(TEXT_YELLOW); + } + finishTimeCopy = (s32) (1000 * gFinishTime[playerId]); + + // 48 is the offset from digits to ASCII code string representations + finishTimeText[0] = func_8004F674(&finishTimeCopy, 60000) + 48; + finishTimeText[1] = 39; // ' + finishTimeText[2] = func_8004F674(&finishTimeCopy, 10000) + 48; + finishTimeText[3] = func_8004F674(&finishTimeCopy, 1000) + 48; + finishTimeText[4] = 34; // " + finishTimeText[5] = func_8004F674(&finishTimeCopy, 100) + 48; + finishTimeText[6] = func_8004F674(&finishTimeCopy, 10) + 48; + finishTimeText[7] = finishTimeCopy + 48; + text_draw(thing->column, thing->row + 0x75 - 25, finishTimeText, 0, 0.7f, 0.7f); + } } set_text_color(TEXT_BLUE); // Not a hyphen, that is an EUC-JP character - text_draw(0x0000009E, D_800E7300[0].row + 0x6D, "ー", 0, 1.0f, 1.0f); + text_draw(0x0000009E, D_800E7300[0].row + 0x6D + 15, "ー", 0, 1.0f, 1.0f); } /*Iterates over all players and, based on the current mode selection, @@ -8579,12 +8605,14 @@ void func_800A6D94(s32 arg0, s32 arg1, u8* arg2) { draws race finish tallies for versus races additionally draws vs scores for tournament edition*/ -void func_800A6E94(s32 arg0, s32 arg1, u8* arg2) { +void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { UNUSED s32 stackPadding0; u8* temp_v0; Unk_D_800E70A0* temp_s0; char sp40[3]; s32 rank; + s32 finishTimeCopy; + char finishTimeText[8]; // var for drawing scores s32 base_xPos_4p; @@ -8601,7 +8629,7 @@ void func_800A6E94(s32 arg0, s32 arg1, u8* arg2) { char pointsBuf[5]; // Everything about this variable is bizarre - s32 sp38 = -1; + s32 rankIdx = -1; // base x and y position for drawing scores // x-coord increment will be different for 3p and 4p vs @@ -8617,7 +8645,7 @@ void func_800A6E94(s32 arg0, s32 arg1, u8* arg2) { // Only draw scores on the first player call to avoid overdraw // (func_800A6E94 is called once per player by func_800A6BEC/func_800A6CC0) - if (arg1 == 0) { + if (playerId == 0) { set_text_color(TEXT_YELLOW); while(i < gPlayerCountSelection1) { firsts = tally[i * 3 + 0]; @@ -8646,33 +8674,56 @@ void func_800A6E94(s32 arg0, s32 arg1, u8* arg2) { } } - temp_s0 = &D_800E7300[((arg0 - 2) * 4) + arg1]; - rank = gGPCurrentRaceRankByPlayerId[arg1]; - if (rank == ++sp38) { + temp_s0 = &D_800E7300[((playerCount - 2) * 4) + playerId]; + rank = gGPCurrentRaceRankByPlayerId[playerId]; + if (rank == ++rankIdx) { set_text_color(gGlobalTimer % 3); } else { set_text_color(TEXT_YELLOW); } - text_draw(temp_s0->column + 4, temp_s0->row + 0x5A, "1 s ー", 0, 0.8f, 0.8f); - temp_v0 = arg2 + (arg1 * 3); + text_draw(temp_s0->column + 4, temp_s0->row + 0x69, "1 s ー", 0, 0.8f, 0.8f); + temp_v0 = placeAry + (playerId * 3); convert_number_to_ascii(temp_v0[0], sp40); // first place tally for each player - text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x5A, sp40, 0, 0.8f, 0.8f); - if (rank == ++sp38) { + text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x69, sp40, 0, 0.8f, 0.8f); + if (rank == ++rankIdx) { set_text_color(gGlobalTimer % 3); } else { set_text_color(TEXT_BLUE); } - text_draw(temp_s0->column + 4, temp_s0->row + 0x69, "2 n ー", 0, 0.8f, 0.8f); + text_draw(temp_s0->column + 4, temp_s0->row + 0x78, "2 n ー", 0, 0.8f, 0.8f); convert_number_to_ascii(temp_v0[1], sp40); // second place tally for each player - text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x69, sp40, 0, 0.8f, 0.8f); - if (++sp38 == rank) { + text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x78, sp40, 0, 0.8f, 0.8f); + if (++rankIdx == rank) { set_text_color(gGlobalTimer % 3); } else { set_text_color(TEXT_RED); } - text_draw(temp_s0->column + 4, temp_s0->row + 0x78, "3 r ー", 0, 0.8f, 0.8f); + text_draw(temp_s0->column + 4, temp_s0->row + 0x87, "3 r ー", 0, 0.8f, 0.8f); convert_number_to_ascii(temp_v0[2], sp40); // third place tally for each player - text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x78, sp40, 0, 0.8f, 0.8f); + text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x87, sp40, 0, 0.8f, 0.8f); + + // show time if player has finished + if (gFinished[playerId]){ + // flash timer for winner + if (rank == 0){ + set_text_color(gGlobalTimer % 3); + } + else{ + set_text_color(TEXT_YELLOW); + } + finishTimeCopy = (s32) (1000 * gFinishTime[playerId]); + + // 48 is the offset from digits to ASCII code string representations + finishTimeText[0] = func_8004F674(&finishTimeCopy, 60000) + 48; + finishTimeText[1] = 39; // ' + finishTimeText[2] = func_8004F674(&finishTimeCopy, 10000) + 48; + finishTimeText[3] = func_8004F674(&finishTimeCopy, 1000) + 48; + finishTimeText[4] = 34; // " + finishTimeText[5] = func_8004F674(&finishTimeCopy, 100) + 48; + finishTimeText[6] = func_8004F674(&finishTimeCopy, 10) + 48; + finishTimeText[7] = finishTimeCopy + 48; + text_draw(temp_s0->column + 4, temp_s0->row + 0x5A, finishTimeText, 0, 0.7f, 0.7f); + } } void func_800A70E8(MenuItem* arg0) { diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index c516eaf4a8..6274918ab5 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -538,52 +538,45 @@ f32 func_8028EE8C(s32 arg0) { } // set finish state -void func_8028EEF0(s32 i) { +void add_cinematic_mode(s32 i) { gPlayers[i].type |= PLAYER_CINEMATIC_MODE; } -// synchronizes lap counts and awards race tallies void func_8028EF28(void) { s16 currentPosition; - s32 i; // player index + s32 playerId; + s32 playerIdLast; - for (i = 0; i < NUM_PLAYERS; i++) { - Player* player = &gPlayers[i]; + for (playerId = 0; playerId < NUM_PLAYERS; playerId++) { + Player* player = &gPlayers[playerId]; // skip slots that don't have active player - if ((gPlayers[i].type & PLAYER_EXISTS) == 0) { + if ((player->type & PLAYER_EXISTS) == 0) { continue; } - // skip finished players (players in cinematic mode) - // added condition to prevent double finishes/Wonn from cheating - if ((gPlayers[i].type & PLAYER_CINEMATIC_MODE) != 0) { - continue; - } - // handles increasing and decreasing lap count // two diff var for tracking lap counts - if (gLapCountByPlayerId[i] < gPlayers[i].lapCount) { - gPlayers[i].lapCount--; - } else if (gLapCountByPlayerId[i] > gPlayers[i].lapCount) { - gPlayers[i].lapCount++; + if (gLapCountByPlayerId[playerId] < player->lapCount) { + player->lapCount--; + } else if (gLapCountByPlayerId[playerId] > player->lapCount) { + player->lapCount++; // if slot has an active player - if ((gPlayers[i].type & PLAYER_HUMAN) != 0) { - // if player i finishes (crosses into lap 4) - if (gPlayers[i].lapCount == 3) { // 3 = lap 4 - func_8028EEF0(i); // finish sequence + if ((player->type & PLAYER_HUMAN) != 0) { + // if player finishes (3 = starting 4th lap = finished) + if (player->lapCount == 3) { + add_cinematic_mode(playerId); - currentPosition = gPlayers[i].currentRank; // store rank as currentPosition - gPlayers[i].type |= PLAYER_CPU; // cpu take over finishing player + currentPosition = player->currentRank; // store rank as currentPosition + player->type |= PLAYER_CPU; // cpu take over finishing player - // sets flag after any player finishes lap 4 - if (currentPosition < 4) { + if (currentPosition < 4) { D_80150120 = 1; } // ? - func_800CA118((u8) i); + func_800CA118((u8) playerId); if ((D_802BA032 & PLAYER_EXISTS) == 0) { D_802BA032 |= PLAYER_EXISTS; } @@ -591,8 +584,15 @@ void func_8028EF28(void) { if (gModeSelection == GRAND_PRIX && gPlayerCountSelection1 == 2 && D_802BA048 == 0) { D_802BA048 = 1; } - if ((gPlayers[i].type & PLAYER_INVISIBLE_OR_BOMB) == 0) { - D_800DC510 = 4; + if ((player->type & PLAYER_INVISIBLE_OR_BOMB) == 0) { + // Inner if required for precise finish times. + // Otherwise, higher port numbers can reset the state after a lower + // port number finished 2nd to last, concluding the race + if (D_800DC510 <= 4){ + // 4 means somebody has finished the race (or something similar) + // 5 means 2nd to last has finished, concluding the race + D_800DC510 = 4; + } } if (gModeSelection == TIME_TRIALS) { func_80005AE8(player); @@ -601,76 +601,79 @@ void func_8028EF28(void) { if (gModeSelection == VERSUS) { gDemoTimer = 180; if (currentPosition == 0) { // winning player - gPlayerWinningIndex = i; + gPlayerWinningIndex = playerId; } switch (gPlayerCountSelection1) { - // 2p vs case 2: - // currentPosition = position of player i when crossing finish line - // 1st is 0, 2nd is 1, 3rd is 2, 4th is 3 + // currentPosition = position of player when crossing finish line (0 indexed) + // 0 is 1st, 1 is 2nd, 2 is 3rd, 3 is 4th if (currentPosition == 0 ) { // when first finishes - *(gNmiUnknown1 + i) += 1; // add tally - } - if (*(gNmiUnknown1 + i) > 99) { // 99 tally limit? - *(gNmiUnknown1 + i) = 99; + *(gNmiUnknown1 + playerId) += 1; // add tally + if (*(gNmiUnknown1 + playerId) > 99) { + *(gNmiUnknown1 + playerId) = 99; + } + D_800DC510 = 5; + playerIdLast = gPlayerPositionLUT[1]; // get 2nd place player position + gPlayers[playerIdLast].triggers |= SPINOUT_TRIGGER; // spin out 2nd place player + gPlayers[playerIdLast].type |= PLAYER_CPU; // cpu control 2nd place player + func_800CA118((u8) playerIdLast); // call animation sequence, pass in losing player idx as parameter? } - D_800DC510 = 5; - i = gPlayerPositionLUT[1]; // get 2nd place player position - gPlayers[i].triggers |= SPINOUT_TRIGGER; // spin out 2nd place player - gPlayers[i].type |= PLAYER_CPU; // cpu control 2nd place player - func_800CA118((u8) i); // call animation sequence, pass in losing player idx as parameter? break; - // 3p case 3: - if (currentPosition < 3 ) { // when any player finishes (all players get tallies) - *(gNmiUnknown2 + i * 3 + currentPosition) += 1; - } - if (*(gNmiUnknown2 + i * 3 + currentPosition) > 99) { - *(gNmiUnknown2 + i * 3 + currentPosition) = 99; - } - if (currentPosition == 1 ) { // when 2nd finishes - D_800DC510 = 5; - i = gPlayerPositionLUT[2]; // get 3rd place player position - *(gNmiUnknown2 + i * 3 + 2) += 1; - if (*(gNmiUnknown2 + i * 3 + 2) > 99) { - *(gNmiUnknown2 + i * 3 + 2) = 99; + if (currentPosition < 2) { + *(gNmiUnknown2 + playerId * 3 + currentPosition) += 1; + + if (*(gNmiUnknown2 + playerId * 3 + currentPosition) > 99) { + *(gNmiUnknown2 + playerId * 3 + currentPosition) = 99; + } + /* Because the last player may not finish, their score must be updated when the 2nd + to last racer finishes. */ + if (currentPosition == 1) { + D_800DC510 = 5; // triggers results screen + + playerIdLast = gPlayerPositionLUT[2]; + // update 3rd place (last) tally here because they may not cross finish line + *(gNmiUnknown2 + playerIdLast * 3 + 2) += 1; + if (*(gNmiUnknown2 + playerIdLast * 3 + 2) > 99) { + *(gNmiUnknown2 + playerIdLast * 3 + 2) = 99; + } + gPlayers[playerIdLast].triggers |= SPINOUT_TRIGGER; // spin out 3rd place player + gPlayers[playerIdLast].type |= PLAYER_CPU; // cpu control 3rd place + func_800CA118((u8) playerIdLast); // call animation sequence, pass in losing player idx as parameter? } - gPlayers[i].triggers |= SPINOUT_TRIGGER; // spin out 3rd place player - gPlayers[i].type |= PLAYER_CPU; // cpu control 3rd place - func_800CA118((u8) i); // call animation sequence, pass in losing player idx as parameter? } break; - // 4p case 4: // 4th place gets no tally - if (currentPosition < 3 ) { // only when 1st, 2nd, 3rd finish - *(gNmiUnknown3 + i * 3 + currentPosition) += 1; - } - if (*(gNmiUnknown3 + i * 3 + currentPosition) > 99) { - *(gNmiUnknown3 + i * 3 + currentPosition) = 99; + if (currentPosition < 3) { + *(gNmiUnknown3 + playerId * 3 + currentPosition) += 1; + if (*(gNmiUnknown3 + playerId * 3 + currentPosition) > 99) { + *(gNmiUnknown3 + playerId * 3 + currentPosition) = 99; + } } - if (currentPosition == 2 ) { // when 3rd finishes + // if 3rd has finished, race is over + if (currentPosition == 2) { D_800DC510 = 5; - i = gPlayerPositionLUT[3]; // get 4th place player position - gPlayers[i].triggers |= SPINOUT_TRIGGER; // spin out 4th place - gPlayers[i].type |= PLAYER_CPU; // cpu control 4th place - func_800CA118((u8) i); // call animation sequence, pass in losing player idx as parameter? + playerIdLast = gPlayerPositionLUT[3]; // get 4th place player position + gPlayers[playerIdLast].triggers |= SPINOUT_TRIGGER; // spin out 4th place + gPlayers[playerIdLast].type |= PLAYER_CPU; // cpu control 4th place + func_800CA118((u8) playerIdLast); // call animation sequence, pass in losing player idx as parameter? } break; } } - } else if (gPlayers[i].lapCount == 2) { - if ((gPlayers[i].type & 0x100) != 0) { + } else if (player->lapCount == 2) { + if ((player->type & 0x100) != 0) { return; } if ((D_802BA032 & 0x4000) == 0) { D_802BA032 |= 0x4000; - func_800CA49C((u8) i); + func_800CA49C((u8) playerId); } } - } else if (gPlayers[i].lapCount == 3) { - func_8028EEF0(i); + } else if (player->lapCount == 3) { + add_cinematic_mode(playerId); if (gModeSelection == TIME_TRIALS) { func_80005AE8(player); } @@ -692,8 +695,7 @@ void update_race_position_data(void) { s16 position; for (i = 0; i < NUM_PLAYERS; i++) { - if (((gPlayers[i].type & PLAYER_EXISTS) != 0) && ((gPlayers[i].type & PLAYER_CINEMATIC_MODE) == 0) && - ((gPlayers[i].type & PLAYER_INVISIBLE_OR_BOMB) == 0)) { + if (((gPlayers[i].type & PLAYER_EXISTS) != 0)) { position = gGPCurrentRaceRankByPlayerId[i]; gPlayers[i].currentRank = position; gPlayerPositionLUT[position] = i; diff --git a/src/racing/race_logic.h b/src/racing/race_logic.h index b10f9ce7da..c053862a86 100644 --- a/src/racing/race_logic.h +++ b/src/racing/race_logic.h @@ -16,7 +16,7 @@ void func_8028EC38(s32); void play_music_for_current_track(s32); void start_race(void); f32 func_8028EE8C(s32); -void func_8028EEF0(s32); +void add_cinematic_mode(s32); void func_8028EF28(void); void func_8028F3E8(void); void update_race_position_data(void); From 931724c7753ac76b8dfca5e07d1b0171bf532cde Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 6 Jul 2026 07:59:04 -0400 Subject: [PATCH 43/73] removed unimplemented menu options and updated menu. changed pause timer in 4p vs mode to 15 frames. Updated build date --- src/menu_items.c | 92 +++++------------------------------------ src/menu_items.h | 4 -- src/menus.c | 4 +- src/menus.h | 2 +- src/racing/race_logic.c | 2 +- src/render_objects.c | 1 + 6 files changed, 16 insertions(+), 89 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index edfedbbf5d..ef7eedb402 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -368,11 +368,8 @@ s8 gTournamentTrainBoat = 0; s8 gTournamentAA = 0; s8 gTournamentForceMap = 0; s8 gTournamentShellLimit = 0; // not currently in menu -s8 gTournamentTimer = 0; -s8 gTournamentTrophy = 0; -s8 gPracticeMode = 0; s8 gTournamentExtraMode = 0; -s8 gTournamentReverseMode = 0; + // Course name abbreviations for each tournament mode @@ -5813,11 +5810,7 @@ void render_custom_overlay(void) { char valBuf[4]; MenuItem cursorItem; Unk_D_800E70A0 sp84; - - // // temp var for debug font - // s32 x1; - // s32 y1; - + /* Menu items; if an entry is empty, fallback to "Modifier N" */ static const char* customModifierNames[CUSTOM_MENU_ROWS] = { @@ -5829,11 +5822,8 @@ void render_custom_overlay(void) { "mp train boat", "AA", "force minimap", - "vs timer", - "trophy", - "practice", - "extra", - "reverse" /* keep last empty if CUSTOM_MENU_ROWS > 12 */ + "extra" + /* keep last empty if CUSTOM_MENU_ROWS > 12 */ }; /* per-option label arrays */ @@ -5845,24 +5835,15 @@ void render_custom_overlay(void) { static const char* mpTrainBoat_labels[] = {"default", "enabled", "train", "boat"}; static const char* AA_labels[] = {"default", "disabled"}; static const char* minimap_labels[] = {"default", "prog view", "map"}; - static const char* timer_labels[] = {"default", "enabled"}; - static const char* trophy_labels[] = {"default", "enabled"}; - static const char* practice_labels[] = {"default", "enabled"}; static const char* extra_labels[] = {"default", "enabled"}; - static const char* reverse_labels[] = {"default", "enabled"}; set_text_color(TEXT_YELLOW); // title (centered) print_text1_center_mode_1(x, y - 0x28, "WEATHERTON ABNEY CLIMATEE ZSERF", 0, 0.70f, 0.70f); - // /* use debug font helper */ - // x1 = 0; - // y1 = 0; - // func_800579B8(x1, y1, "WEATHERTON ABNEY CLIMATEE"); - // version / date (smaller) - left-aligned to start under 'KART' - print_text1_left(x + 0x5A, y + 0x06, "TE V2026-06-28", 0, 0.65f, 0.65f); + print_text1_left(x + 0x78, y + 0x06, "TE V2026-07-06 BETA", 0, 0.65f, 0.65f); // option name placeholders (second column) and values (third column) for (i = 0; i < CUSTOM_MENU_ROWS; i++) { @@ -5886,25 +5867,6 @@ void render_custom_overlay(void) { if (customModifierNames[i][0] != '\0') { text_rainbow_effect(gCustomMenuSelection, i, TEXT_YELLOW); print_text_mode_1(x - 0x40, rowY, (char*)customModifierNames[i], 0, 0.6f, 0.6f); - } else { - /* Build "Modifier N" manually to avoid linking snprintf */ - const char* prefix = "Modifier "; - int num = i + 1; - int pos = 0; - const char* p = prefix; - while (*p && pos < (int)sizeof(nameBuf) - 1) { - nameBuf[pos++] = *p++; - } - if (num >= 10 && pos < (int)sizeof(nameBuf) - 2) { - nameBuf[pos++] = '0' + (num / 10); - nameBuf[pos++] = '0' + (num % 10); - } else if (pos < (int)sizeof(nameBuf) - 1) { - nameBuf[pos++] = '0' + (num % 10); - } - nameBuf[pos] = '\0'; - // default case i guess - text_rainbow_effect(gCustomMenuSelection, i, TEXT_YELLOW); - print_text_mode_1(x - 0x20, rowY, nameBuf, 0, 0.6f, 0.6f); } /* third column: current value for this row */ @@ -5974,45 +5936,13 @@ void render_custom_overlay(void) { gTournamentForceMap = idx; break; case 8: - /* vs timer: labels (default, enabled) */ - idx = gCustomMenuOptionValues[i]; - if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(timer_labels) / sizeof(timer_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x50, rowY, (char*)timer_labels[idx], 0, 0.6f, 0.6f); - gTournamentTimer = idx; - break; - case 9: - /* trophy ceremony: labels (default, enabled) */ - idx = gCustomMenuOptionValues[i]; - if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(trophy_labels) / sizeof(trophy_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x50, rowY, (char*)trophy_labels[idx], 0, 0.6f, 0.6f); - gTournamentTrophy = idx; - break; - case 10: - /* practice mode: labels (default, enabled) */ - idx = gCustomMenuOptionValues[i]; - if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(practice_labels) / sizeof(practice_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x50, rowY, (char*)practice_labels[idx], 0, 0.6f, 0.6f); - gPracticeMode = idx; - break; - case 11: /* extra: labels (default, enabled) */ - idx = gCustomMenuOptionValues[i]; - if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(extra_labels) / sizeof(extra_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x50, rowY, (char*)extra_labels[idx], 0, 0.6f, 0.6f); - gTournamentExtraMode = idx; - break; - case 12: - /* reverse: labels (default, enabled) */ - idx = gCustomMenuOptionValues[i]; - if (idx < 0) idx = 0; - if (idx >= (int)(sizeof(reverse_labels) / sizeof(reverse_labels[0]))) idx = 0; - print_text1_center_mode_1(x + 0x50, rowY, (char*)reverse_labels[idx], 0, 0.6f, 0.6f); - gTournamentReverseMode = idx; - break; + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(extra_labels) / sizeof(extra_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)extra_labels[idx], 0, 0.6f, 0.6f); + gTournamentExtraMode = idx; + break; } } } diff --git a/src/menu_items.h b/src/menu_items.h index 512ccfec31..01aceb1f66 100644 --- a/src/menu_items.h +++ b/src/menu_items.h @@ -866,10 +866,6 @@ extern s8 gTournamentTrainBoat; extern s8 gTournamentAA; extern s8 gTournamentShellLimit; // unused extern s8 gTournamentForceMap; -extern s8 gTournamentTimer; -extern s8 gTournamentTrophy; -extern s8 gPracticeMode; extern s8 gTournamentExtraMode; -extern s8 gTournamentReverseMode; #endif diff --git a/src/menus.c b/src/menus.c index da948e45b6..5f642eb676 100644 --- a/src/menus.c +++ b/src/menus.c @@ -248,8 +248,8 @@ s8 gCustomMenuOptionValues[CUSTOM_MENU_ROWS] = { 0 }; // Per-row number of selectable values (matches label arrays in render_custom_overlay) // tracks, stats, scaling, widescreen, mp music, mp train boat, AA, force minimap, -// vs timer, trophy, practice, extra, reverse -static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 3, 3, 2, 2, 4, 2, 3, 2, 2, 2, 2, 2 }; +// extra +static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 3, 3, 2, 2, 4, 2, 3, 2 }; // end of new var init diff --git a/src/menus.h b/src/menus.h index 841cf8490b..dee269ba7f 100644 --- a/src/menus.h +++ b/src/menus.h @@ -267,7 +267,7 @@ extern s16 get_course_id_for_tournament_cursor(s32 cupSelection, s32 courseIndex // end of menus.c variables // start of custom menu var -#define CUSTOM_MENU_ROWS 13 +#define CUSTOM_MENU_ROWS 9 #define CUSTOM_MENU_VALUE_COUNT 3 extern s8 gCustomMenuTitle; // tournament rom credits title diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index 6274918ab5..6ea65621bf 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -869,7 +869,7 @@ void func_8028F970(void) { if (gModeSelection == VERSUS) { // pausing is gated by sPauseHoldCounter, which increments every frame player i holds start if ((controller->button & START_BUTTON) && (!(controller->button & R_TRIG)) && - (!(controller->button & L_TRIG)) && (sPauseHoldCounter[i] >= 60)) { + (!(controller->button & L_TRIG)) && (sPauseHoldCounter[i] >= 15)) { func_8028DF00(); gIsGamePaused = (controller - gControllerOne) + 1; controller->buttonPressed = 0; diff --git a/src/render_objects.c b/src/render_objects.c index 21ac663f18..52ffc211fa 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -4793,6 +4793,7 @@ UNUSED void func_80057960(s32 arg0, s32 arg1, char* arg2, u32 arg3) { func_800573E4(arg0, arg1, D_800E5628[0x42]); } +// use debug font to print string UNUSED void func_800579B8(s32 arg0, s32 arg1, char* arg2) { load_debug_font(); debug_print_string(&arg0, &arg1, arg2); From 67a853d07156c44cc1d9b67be617f62ae56b54e4 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 6 Jul 2026 12:18:12 -0400 Subject: [PATCH 44/73] re-patched double finish bug (crossing finish line in reverse) --- src/racing/race_logic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index 6ea65621bf..c47e4fe009 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -550,8 +550,9 @@ void func_8028EF28(void) { for (playerId = 0; playerId < NUM_PLAYERS; playerId++) { Player* player = &gPlayers[playerId]; - // skip slots that don't have active player - if ((player->type & PLAYER_EXISTS) == 0) { + // skip finished players (players in cinematic mode) + // added condition to prevent double finishes/Wonn from cheating + if ((gPlayers[playerId].type & PLAYER_CINEMATIC_MODE) != 0) { continue; } From 64b4e5c4f3a0ec94fad47f220771fab26a4d6d49 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Tue, 7 Jul 2026 20:56:19 -0400 Subject: [PATCH 45/73] shifted vs mode points screen menu up by 5 units to accomodate for CRT overscan --- src/menu_items.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index ef7eedb402..f4043021e3 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -129,6 +129,7 @@ Unk_D_800E70A0 D_800E7108[][4] = { }, }; +// not character potraits Unk_D_800E70A0 D_800E7148[] = { { 0x17, 0x3b, 0x00, 0x00 }, { 0x5d, 0x3b, 0x00, 0x00 }, @@ -202,23 +203,24 @@ Unk_D_800E70A0 D_800E7278[] = { { 0xffc0, 0xf0, 0x00, 0x00 }, { 0x140, 0xf0, 0x00, 0x00 }, }; -Unk_D_800E70A0 D_800E72F8 = { 0x140, 0x23, 0x00, 0x00 }; +Unk_D_800E70A0 D_800E72F8 = { 0x140, 0x1e, 0x00, 0x00 }; // In a perfect world this would be `Unk_D_800E70A0 D_800E7300[][4]` +// character potrait position tables; used in at least VS mode Unk_D_800E70A0 D_800E7300[] = { - { 0x50, 0x23, 0x00, 0x00 }, { 0xb0, 0x23, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 }, + { 0x50, 0x1e, 0x00, 0x00 }, { 0xb0, 0x1e, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 }, - { 0x32, 0x23, 0x00, 0x00 }, { 0x80, 0x23, 0x00, 0x00 }, { 0xce, 0x23, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 }, + { 0x32, 0x1e, 0x00, 0x00 }, { 0x80, 0x1e, 0x00, 0x00 }, { 0xce, 0x1e, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 }, - { 0x18, 0x23, 0x00, 0x00 }, { 0x5d, 0x23, 0x00, 0x00 }, { 0xa2, 0x23, 0x00, 0x00 }, { 0xe7, 0x23, 0x00, 0x00 }, + { 0x18, 0x1e, 0x00, 0x00 }, { 0x5d, 0x1e, 0x00, 0x00 }, { 0xa2, 0x1e, 0x00, 0x00 }, { 0xe7, 0x1e, 0x00, 0x00 }, }; -// Versus menu coordinates +// Versus menu coordinates; used for cursor Unk_D_800E70A0 D_800E7360[] = { - { 0x61, 0xb6, 0x00, 0x00 }, - { 0x61, 0xc5, 0x00, 0x00 }, - { 0x61, 0xd4, 0x00, 0x00 }, - { 0x61, 0xe3, 0x00, 0x00 }, + { 0x61, 0xb1, 0x00, 0x00 }, + { 0x61, 0xc0, 0x00, 0x00 }, + { 0x61, 0xcf, 0x00, 0x00 }, + { 0x61, 0xde, 0x00, 0x00 }, }; Unk_D_800E70A0 D_800E7380[] = { @@ -8328,12 +8330,12 @@ void func_800A638C(MenuItem* arg0) { text_rainbow_effect(arg0->state - 0xA, var_s1, TEXT_GREEN); if ((var_s1 == 0) && (gModeSelection == VERSUS) && ((gPlayerCount == 3) || (gPlayerCount == 4))) { continueText = "CONTINUE TO "; - print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1) + 15, continueText, 0, 0.8f, 0.8f); + print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1) + 10, continueText, 0, 0.8f, 0.8f); xOffset = (get_string_width(continueText) * 0.8f) + 1.0f; - print_text_mode_1((s32) (0x00000069 + xOffset), 0xAE + (0xF * var_s1) + 15, getNextCourseAbbrString(), + print_text_mode_1((s32) (0x00000069 + xOffset), 0xAE + (0xF * var_s1) + 10, getNextCourseAbbrString(), 0, 0.8f, 0.8f); } else { - print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1) + 15, gTextPauseButton[var_s1 + 1], 0, 0.8f, + print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1) + 10, gTextPauseButton[var_s1 + 1], 0, 0.8f, 0.8f); } } @@ -8434,7 +8436,7 @@ void func_800A69C8(UNUSED MenuItem* arg0) { set_text_color((s32) gGlobalTimer % 3); } func_800A79F4(var_s4[0], sp74); - text_draw(thing->column + 0x10, thing->row + 0x75 + 15, sp74, 0, 1.0f, 1.0f); + text_draw(thing->column + 0x10, thing->row + 0x75 + 10, sp74, 0, 1.0f, 1.0f); print_text1_center_mode_2(D_800E7380[playerId].column, D_800E7380[playerId].row, temp_s3, 0, 0.65f, 1.0f); // show finish time if finished @@ -8565,7 +8567,7 @@ void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { // x-coord increment will be different for 3p and 4p vs base_xPos_4p = 0x1A; base_xPos_3p = 0x34; - Y_pos = 0x20; + Y_pos = 0x1B; // i: player index i = 0; From a4911bc0e0938143389dcb2b6c90e4cade6ecc2d Mon Sep 17 00:00:00 2001 From: "dntn31@gmail.com" Date: Wed, 8 Jul 2026 15:57:46 -0700 Subject: [PATCH 46/73] Kaillera typo fix --- src/menu_items.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index f4043021e3..59b3397825 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -5829,7 +5829,7 @@ void render_custom_overlay(void) { }; /* per-option label arrays */ - static const char* tracks_labels[] = {"VA", "kalliera", "kalliera mmf"}; + static const char* tracks_labels[] = {"VA", "kaillera", "kaillera mmf"}; static const char* stats_labels[] = {"all yoshi", "default", "all wario"}; static const char* scaling_labels[] = {"default", "30fps", "60fps"}; static const char* widescreen_labels[] = {"default", "enabled"}; @@ -5874,7 +5874,7 @@ void render_custom_overlay(void) { /* third column: current value for this row */ switch (i) { case 0: - /* tracks: custom labels (TE, kalliera, random) */ + /* tracks: custom labels (TE, kaillera, random) */ idx = gCustomMenuOptionValues[i]; if (idx < 0) idx = 0; if (idx >= (int)(sizeof(tracks_labels) / sizeof(tracks_labels[0]))) idx = 0; From c72fe91c99a0b019a82dbc457a51346e1563a9f7 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 13 Jul 2026 07:04:51 -0400 Subject: [PATCH 47/73] removed shell counter display + function --- src/code_80057C60.c | 13 ------------- src/main.c | 1 - 2 files changed, 14 deletions(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 773ca430dc..a44ca39fa3 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -1101,19 +1101,6 @@ void render_hud_2p_horizontal_player_two(void) { } } -void render_shell_count(void) { - if (gActiveScreenMode == SCREEN_MODE_3P_4P_SPLITSCREEN) { - gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(D_802B8880)); - gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - set_matrix_hud_screen(); - gSPClearGeometryMode(gDisplayListHead++, G_ZBUFFER); - load_debug_font(); - print_str_num(0x0, 0x10, "shells ", gNumSpawnedShells); - func_80057778(); - gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER); - } -} - void draw_simplified_hud(s32 playerId) { if ((gModeSelection != BATTLE) && (D_80165800[playerId] == 0) && (gIsHUDVisible != 0)) { render_hud_timer(playerId); diff --git a/src/main.c b/src/main.c index 4678299976..d322e93871 100644 --- a/src/main.c +++ b/src/main.c @@ -926,7 +926,6 @@ void race_logic_loop(void) { render_player_three_3p_4p_screen(); render_player_four_3p_4p_screen(); } - // render_shell_count(); break; } From 92aa38274babe44fa67a48454b719edf3c727b69 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 13 Jul 2026 07:14:21 -0400 Subject: [PATCH 48/73] fixed VA course progression --- src/menu_items.c | 2 +- src/menus.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index 59b3397825..8da7ff6fff 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -5845,7 +5845,7 @@ void render_custom_overlay(void) { print_text1_center_mode_1(x, y - 0x28, "WEATHERTON ABNEY CLIMATEE ZSERF", 0, 0.70f, 0.70f); // version / date (smaller) - left-aligned to start under 'KART' - print_text1_left(x + 0x78, y + 0x06, "TE V2026-07-06 BETA", 0, 0.65f, 0.65f); + print_text1_left(x + 0x78, y + 0x06, "TE V2026-07-13 BETA 4", 0, 0.65f, 0.65f); // option name placeholders (second column) and values (third column) for (i = 0; i < CUSTOM_MENU_ROWS; i++) { diff --git a/src/menus.c b/src/menus.c index 5f642eb676..52ed794006 100644 --- a/src/menus.c +++ b/src/menus.c @@ -161,11 +161,11 @@ const s16 gCupCourseOrder[5][4] = { // va course order const s16 gVACourseOrder[4][4] = { // mushroom cup - { COURSE_WARIO_STADIUM, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, + { COURSE_LUIGI_RACEWAY, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, // special cup { COURSE_DK_JUNGLE, COURSE_YOSHI_VALLEY, COURSE_BANSHEE_BOARDWALK, COURSE_RAINBOW_ROAD }, // star cup - { COURSE_LUIGI_RACEWAY, COURSE_SHERBET_LAND, COURSE_ROYAL_RACEWAY, COURSE_BOWSER_CASTLE }, + { COURSE_WARIO_STADIUM, COURSE_SHERBET_LAND, COURSE_ROYAL_RACEWAY, COURSE_BOWSER_CASTLE }, // flower cup { COURSE_TOADS_TURNPIKE, COURSE_FRAPPE_SNOWLAND, COURSE_CHOCO_MOUNTAIN, COURSE_MARIO_RACEWAY } }; From 6760c74808ee36238513393c60c55f910754f9d6 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 13 Jul 2026 10:59:54 -0400 Subject: [PATCH 49/73] updated course progression text --- src/menu_items.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index 8da7ff6fff..b698ba1c42 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -376,9 +376,9 @@ s8 gTournamentExtraMode = 0; // Course name abbreviations for each tournament mode char* gCourseNamesVA[] = { - "WS", "MMF", "KTB", "KD", + "LR", "MMF", "KTB", "KD", "DKJP", "YV", "BB", "RRd", - "LR", "SL", "RRy", "BC", + "WS", "SL", "RRy", "BC", "TT", "FS", "CM", "MR" }; From 57629d8bd503f28c14df8775a649c17ce71ec60d Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Tue, 14 Jul 2026 12:41:36 -0400 Subject: [PATCH 50/73] fixed bug where tournament character weights weren't being assigned; updated build date --- src/effects.c | 2 +- src/menu_items.c | 4 ++-- src/racing/race_logic.c | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/effects.c b/src/effects.c index e5f398b264..a92bd6db79 100644 --- a/src/effects.c +++ b/src/effects.c @@ -202,7 +202,7 @@ void func_8008C528(Player* player, s8 playerIndex) { s32 statsCharacterId; clean_effect(player, playerIndex); func_8008C310(player); - temp_v1 = player->characterId; + temp_v1 = (gTournamentCharacterStats == 0) ? YOSHI : (gTournamentCharacterStats == 2) ? WARIO : player->characterId; statsCharacterId = PLAYER_STATS_CHARACTER_ID(player); player->unk_0C2 = 0; player->kartHopJerk = D_800E37B0[statsCharacterId]; diff --git a/src/menu_items.c b/src/menu_items.c index b698ba1c42..ac7e2e2876 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -5842,10 +5842,10 @@ void render_custom_overlay(void) { set_text_color(TEXT_YELLOW); // title (centered) - print_text1_center_mode_1(x, y - 0x28, "WEATHERTON ABNEY CLIMATEE ZSERF", 0, 0.70f, 0.70f); + print_text1_center_mode_1(x, y - 0x28, "WEATHERTON ABNEY CLIMATEE ZSERF DNTN31", 0, 0.60f, 0.60f); // version / date (smaller) - left-aligned to start under 'KART' - print_text1_left(x + 0x78, y + 0x06, "TE V2026-07-13 BETA 4", 0, 0.65f, 0.65f); + print_text1_left(x + 0x78, y + 0x06, "TE V2026-07-14 BETA 5", 0, 0.65f, 0.65f); // option name placeholders (second column) and values (third column) for (i = 0; i < CUSTOM_MENU_ROWS; i++) { diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index c47e4fe009..ca25daaa52 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -1221,10 +1221,11 @@ void func_802903D8(Player* playerOne, Player* playerTwo) { f32 temp_f16; f32 temp_f2; + // kart weights! f32 gFloatArray802B8790[] = { 1.2, 1.0, 0.9, 0.7, 2.0, 1.8, 0.9, 2.3 }; - f32 sp24 = gFloatArray802B8790[playerOne->characterId]; - f32 sp20 = gFloatArray802B8790[playerTwo->characterId]; + f32 sp24 = gFloatArray802B8790[(gTournamentCharacterStats == 0) ? YOSHI : (gTournamentCharacterStats == 2) ? WARIO : playerOne->characterId]; + f32 sp20 = gFloatArray802B8790[(gTournamentCharacterStats == 0) ? YOSHI : (gTournamentCharacterStats == 2) ? WARIO : playerTwo->characterId]; sp60[0] = playerOne->pos[0] - playerTwo->pos[0]; sp60[1] = (playerOne->pos[1] - playerOne->boundingBoxSize) - (playerTwo->pos[1] - playerTwo->boundingBoxSize); From 1743d61600a31282b9f36ea51a20147aae379817 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Tue, 14 Jul 2026 16:36:18 -0400 Subject: [PATCH 51/73] reverted to default the following 1.) all custom rdp display settings + custom profiler code 2.) makefile c flags 3.) enabled non-matching rom 4.) func_80086074 in update_objects --- Makefile | 7 ++- include/debug.h | 2 +- src/profiler.c | 104 +++++-------------------------------------- src/profiler.h | 1 - src/update_objects.c | 4 +- 5 files changed, 17 insertions(+), 101 deletions(-) diff --git a/Makefile b/Makefile index 6fe6d47acd..4dd1321466 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,7 @@ endif # NON_MATCHING - whether to build a matching, identical copy of the ROM # 1 - enable some alternate, more portable code that does not produce a matching ROM # 0 - build a matching ROM -NON_MATCHING ?= 0 +NON_MATCHING ?= 1 $(eval $(call validate-option,NON_MATCHING,0 1)) ifeq ($(TARGET_N64),0) @@ -361,7 +361,7 @@ CC_CHECK_CFLAGS := -fsyntax-only -fsigned-char $(CC_CFLAGS) $(TARGET_CFLAGS) -st HIDE_WARNINGS := -woff 838,649,807 CFLAGS = -G 0 $(OPT_FLAGS) $(TARGET_CFLAGS) $(MIPSISET) $(DEF_INC_CFLAGS) ifeq ($(COMPILER),gcc) - CFLAGS += -mno-shared -march=vr4300 -mfix4300 -mabi=32 -mhard-float -mdivide-breaks -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-PIC -mno-abicalls -fno-strict-aliasing -fno-inline-functions -ffreestanding -fwrapv -fno-toplevel-reorder -Wall -Wextra + CFLAGS += -mno-shared -march=vr4300 -mfix4300 -mabi=32 -mhard-float -mdivide-breaks -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-PIC -mno-abicalls -fno-strict-aliasing -fno-inline-functions -ffreestanding -fwrapv -Wall -Wextra else CFLAGS += $(HIDE_WARNINGS) -non_shared -Wab,-r4300_mul -Xcpluscomm -fullwarn -signed -32 endif @@ -655,7 +655,6 @@ $(BUILD_DIR)/%.o: %.s $(MIO0_FILES) $(RAW_TEXTURE_FILES) $(V)$(AS) $(ASFLAGS) -o $@ $< $(EUC_JP_FILES:%.c=$(BUILD_DIR)/%.jp.o): CC := $(PYTHON) $(TOOLS_DIR)/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) -- -$(EUC_JP_FILES:%.c=$(BUILD_DIR)/%.jp.o): OPT_FLAGS := -O2 $(GLOBAL_ASM_O_FILES): CC := $(PYTHON) $(TOOLS_DIR)/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) -- @@ -790,4 +789,4 @@ MAKEFLAGS += --no-builtin-rules -include $(DEP_FILES) -print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true +print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true \ No newline at end of file diff --git a/include/debug.h b/include/debug.h index 170751147b..9ade139b9a 100644 --- a/include/debug.h +++ b/include/debug.h @@ -73,4 +73,4 @@ void display_dvdl(void); #endif -#endif +#endif \ No newline at end of file diff --git a/src/profiler.c b/src/profiler.c index 8c3fa28752..1d16bd6c7e 100644 --- a/src/profiler.c +++ b/src/profiler.c @@ -2,9 +2,7 @@ #include #include "profiler.h" #include -#include #include "main.h" -#include "render_objects.h" struct ProfilerFrameData gProfilerFrameData[2]; @@ -47,44 +45,6 @@ void profiler_log_vblank_time(void) { } } -void profiler_get_last_gfx_times_ms(s32* rspMs, s32* rdpMs) { - struct ProfilerFrameData* profiler = &gProfilerFrameData[D_800DC66C ^ 1]; - OSTime taskQueued; - OSTime rspComplete; - OSTime rdpComplete; - s64 rspDuration; - s64 rdpDuration; - - if (rspMs == NULL || rdpMs == NULL) { - return; - } - - taskQueued = profiler->gfxTimes[TASKS_QUEUED]; - rspComplete = profiler->gfxTimes[RSP_COMPLETE]; - rdpComplete = profiler->gfxTimes[RDP_COMPLETE]; - - if (rspComplete > taskQueued) { - rspDuration = (s64) (rspComplete - taskQueued); - } else { - rspDuration = 0; - } - - if (rdpComplete > taskQueued) { - rdpDuration = (s64) (rdpComplete - taskQueued); - } else { - rdpDuration = 0; - } - - if (osClockRate == 0) { - *rspMs = 0; - *rdpMs = 0; - return; - } - - *rspMs = (s32) ((rspDuration * 1000) / (s64) osClockRate); - *rdpMs = (s32) ((rdpDuration * 1000) / (s64) osClockRate); -} - // Draw the specified profiler given the information passed. // This function is the same as the one in SM64 void draw_profiler_bar(OSTime clockBase, OSTime clockStart, OSTime clockEnd, s16 posY, u16 color) { @@ -171,8 +131,6 @@ void draw_profiler_mode_1(void) { void draw_profiler_mode_0(void) { s32 i; struct ProfilerFrameData* profiler; - s16 soundCount; - s16 vblankCount; u64 clockStart; // Does this naming apply to MK64? @@ -188,16 +146,8 @@ void draw_profiler_mode_0(void) { // xor it to get the last frame profiler. profiler = &gProfilerFrameData[D_800DC668 ^ 1]; - // like above functions, toss the odd bit. - soundCount = profiler->numSoundTimes & 0xFFFE; - vblankCount = profiler->numVblankTimes & 0xFFFE; - // was thread 5 ran before thread 4? set the lower one to be the clockStart. - if (soundCount >= 2) { - clockStart = profiler->gameTimes[0] <= profiler->soundTimes[0] ? profiler->gameTimes[0] : profiler->soundTimes[0]; - } else { - clockStart = profiler->gameTimes[0]; - } + clockStart = profiler->gameTimes[0] <= profiler->soundTimes[0] ? profiler->gameTimes[0] : profiler->soundTimes[0]; // set variables for duration of tasks. levelScriptDuration = profiler->gameTimes[1] - clockStart; @@ -207,8 +157,11 @@ void draw_profiler_mode_0(void) { rdpDuration = profiler->gfxTimes[2] - profiler->gfxTimes[0]; vblank = 0; + // like above functions, toss the odd bit. + profiler->numSoundTimes &= 0xFFFE; + // sound duration seems to be rendered with empty space and not actually drawn. - for (i = 0; i < soundCount; i += 2) { + for (i = 0; i < profiler->numSoundTimes; i += 2) { // calculate sound duration of max - min soundDuration = profiler->soundTimes[i + 1] - profiler->soundTimes[i]; taskStart += soundDuration; @@ -222,11 +175,14 @@ void draw_profiler_mode_0(void) { } } + // same as above. toss the odd bit. + profiler->numSoundTimes &= 0xFFFE; + //! wrong index used to retrieve vblankTimes, thus empty pairs can // potentially be passed to draw_profiler_bar, because it could be sending // pairs that are beyond the numVblankTimes enforced non-odd limit, due to // using the wrong num value. - for (i = 0; i < vblankCount; i += 2) { + for (i = 0; i < profiler->numSoundTimes; i += 2) { vblank += (profiler->vblankTimes[i + 1] - profiler->vblankTimes[i]); } @@ -268,46 +224,8 @@ void resource_display(void) { gDPSetCycleType(gDisplayListHead++, G_CYC_FILL); gDPSetFillColor(gDisplayListHead++, GPACK_RGBA5551(0, 0, 0, 0) << 16 | GPACK_RGBA5551(0, 0, 0, 0)); - if ((gControllerOne->buttonPressed & 0x20) != 0) { + if ((gControllerOne->buttonPressed & L_TRIG) != 0) { D_800DC664 ^= 1; } draw_profiler_mode_0(); - - if ((gModeSelection == VERSUS) && (gScreenModeSelection == SCREEN_MODE_3P_4P_SPLITSCREEN) && - (gPlayerCountSelection1 >= THREE_PLAYERS_SELECTED)) { - s32 rspMs = 0; - s32 rdpMs = 0; - char rspLabel[5]; - char rdpLabel[5]; - s32 x; - s32 y; - - rspLabel[0] = 'R'; - rspLabel[1] = 'S'; - rspLabel[2] = 'P'; - rspLabel[3] = ' '; - rspLabel[4] = '\0'; - - rdpLabel[0] = 'R'; - rdpLabel[1] = 'D'; - rdpLabel[2] = 'P'; - rdpLabel[3] = ' '; - rdpLabel[4] = '\0'; - - profiler_get_last_gfx_times_ms(&rspMs, &rdpMs); - load_debug_font(); - - x = 0; - y = 0; - debug_print_string(&x, &y, rspLabel); - debug_print_number(&x, &y, rspMs, 10); - - x = 0; - y = 8; - debug_print_string(&x, &y, rdpLabel); - debug_print_number(&x, &y, rdpMs, 10); - - - func_80057778(); - } -} +} \ No newline at end of file diff --git a/src/profiler.h b/src/profiler.h index 627442cf7f..f6b1a85346 100644 --- a/src/profiler.h +++ b/src/profiler.h @@ -31,7 +31,6 @@ void profiler_log_thread5_time(enum ProfilerGameEvent eventID); void profiler_log_thread4_time(void); void profiler_log_gfx_time(enum ProfilerGfxEvent eventID); void profiler_log_vblank_time(void); -void profiler_get_last_gfx_times_ms(s32* rspMs, s32* rdpMs); void draw_profiler(void); void resource_display(void); diff --git a/src/update_objects.c b/src/update_objects.c index 16463a8a50..c142fd6cab 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -7807,8 +7807,8 @@ void func_80085F74(s32 objectIndex) { void func_80086074(s32 objectIndex, s32 arg1) { set_obj_origin_pos(objectIndex, D_800E6734[arg1 * 3 + 0] * xOrientation, D_800E6734[arg1 * 3 + 1], D_800E6734[arg1 * 3 + 2]); - init_texture_object(objectIndex, (u8*) &d_course_rainbow_road_static_tluts[arg1 * 256], - d_course_rainbow_road_static_textures[arg1], 64, 64); + init_texture_object(objectIndex, &d_course_rainbow_road_static_tluts[arg1 * 256], + &d_course_rainbow_road_static_textures[arg1], 64, 64); func_80085BB4(objectIndex); } From 03509a12f41b5f785325dc223eeec9f2f09756ed Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Tue, 14 Jul 2026 16:50:30 -0400 Subject: [PATCH 52/73] fixed bug where speedometer/map view would reset upon retry in time trails --- src/code_80057C60.c | 3 +-- src/code_8006E9C0.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index a44ca39fa3..d155fec35b 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -1590,8 +1590,7 @@ void func_8005A3C0(void) { } } if (b) { - // this the sound for the progress view toggle - // func_8006F824(1); + func_8006F824(1); } } } diff --git a/src/code_8006E9C0.c b/src/code_8006E9C0.c index 03073c1e3a..7581852bd9 100644 --- a/src/code_8006E9C0.c +++ b/src/code_8006E9C0.c @@ -369,7 +369,7 @@ void func_8006F824(s32 arg0) { D_80165832[0] = D_80165800[0]; D_80165832[1] = D_80165800[1]; if ((arg0 != 0) && (gIsGamePaused == 0)) { - play_sound2(SOUND_ACTION_PING); + // play_sound2(SOUND_ACTION_PING); } } From 0371d70b5f963d3ef008b691a3e508c9c5192bdd Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 20 Jul 2026 17:38:03 -0400 Subject: [PATCH 53/73] added ability to adjust scores and made tournament course progression more robust (now based off of current track), and removed code for old implementation --- src/menu_items.c | 309 +++++++++++++++++++++++++++++++++++++--- src/menus.c | 70 --------- src/menus.h | 2 - src/racing/race_logic.c | 5 - 4 files changed, 288 insertions(+), 98 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index ac7e2e2876..0f5907cb38 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -5950,31 +5950,245 @@ void render_custom_overlay(void) { } -// Get the next course ID based on current tournament mode s16 getNextCourseId(void) { - s32 linearCourseIndex = (gCupSelection * 4) + gCourseIndexInCup; - s32 nextLinearIndex = (linearCourseIndex + 1) & 0xF; - s32 nextCup = nextLinearIndex / 4; - s32 nextIndexInCup = nextLinearIndex % 4; + switch (gTournamentCourseMode) { + // va track order + case 0: + switch(gCurrentCourseId) { + case COURSE_LUIGI_RACEWAY: + return COURSE_MOO_MOO_FARM; + case COURSE_MOO_MOO_FARM: + return COURSE_KOOPA_BEACH; + case COURSE_KOOPA_BEACH: + return COURSE_KALAMARI_DESERT; + case COURSE_KALAMARI_DESERT: + return COURSE_DK_JUNGLE; + case COURSE_DK_JUNGLE: + return COURSE_YOSHI_VALLEY; + case COURSE_YOSHI_VALLEY: + return COURSE_BANSHEE_BOARDWALK; + case COURSE_BANSHEE_BOARDWALK: + return COURSE_RAINBOW_ROAD; + case COURSE_RAINBOW_ROAD: + return COURSE_WARIO_STADIUM; + case COURSE_WARIO_STADIUM: + return COURSE_SHERBET_LAND; + case COURSE_SHERBET_LAND: + return COURSE_ROYAL_RACEWAY; + case COURSE_ROYAL_RACEWAY: + return COURSE_BOWSER_CASTLE; + case COURSE_BOWSER_CASTLE: + return COURSE_TOADS_TURNPIKE; + case COURSE_TOADS_TURNPIKE: + return COURSE_FRAPPE_SNOWLAND; + case COURSE_FRAPPE_SNOWLAND: + return COURSE_CHOCO_MOUNTAIN; + case COURSE_CHOCO_MOUNTAIN: + return COURSE_MARIO_RACEWAY; + case COURSE_MARIO_RACEWAY: + return COURSE_LUIGI_RACEWAY; + default: + break; + } + // kaillera track order + case 1: + switch(gCurrentCourseId) { + case COURSE_LUIGI_RACEWAY: + return COURSE_MOO_MOO_FARM; + case COURSE_MOO_MOO_FARM: + return COURSE_KOOPA_BEACH; + case COURSE_KOOPA_BEACH: + return COURSE_KALAMARI_DESERT; + case COURSE_KALAMARI_DESERT: + return COURSE_TOADS_TURNPIKE; + case COURSE_TOADS_TURNPIKE: + return COURSE_FRAPPE_SNOWLAND; + case COURSE_FRAPPE_SNOWLAND: + return COURSE_CHOCO_MOUNTAIN; + case COURSE_CHOCO_MOUNTAIN: + return COURSE_MARIO_RACEWAY; + case COURSE_MARIO_RACEWAY: + return COURSE_WARIO_STADIUM; + case COURSE_WARIO_STADIUM: + return COURSE_SHERBET_LAND; + case COURSE_SHERBET_LAND: + return COURSE_ROYAL_RACEWAY; + case COURSE_ROYAL_RACEWAY: + return COURSE_BOWSER_CASTLE; + case COURSE_BOWSER_CASTLE: + return COURSE_DK_JUNGLE; + case COURSE_DK_JUNGLE: + return COURSE_YOSHI_VALLEY; + case COURSE_YOSHI_VALLEY: + return COURSE_BANSHEE_BOARDWALK; + case COURSE_BANSHEE_BOARDWALK: + return COURSE_RAINBOW_ROAD; + case COURSE_RAINBOW_ROAD: + return COURSE_LUIGI_RACEWAY; + default: + break; + } + // kaillera mmf track order + case 2: + switch(gCurrentCourseId) { + case COURSE_LUIGI_RACEWAY: + return COURSE_MOO_MOO_FARM; + case COURSE_MOO_MOO_FARM: + return COURSE_KOOPA_BEACH; + case COURSE_KOOPA_BEACH: + return COURSE_KALAMARI_DESERT; + case COURSE_KALAMARI_DESERT: + return COURSE_TOADS_TURNPIKE; + case COURSE_TOADS_TURNPIKE: + return COURSE_FRAPPE_SNOWLAND; + case COURSE_FRAPPE_SNOWLAND: + return COURSE_CHOCO_MOUNTAIN; + case COURSE_CHOCO_MOUNTAIN: + return COURSE_MARIO_RACEWAY; + case COURSE_MARIO_RACEWAY: + return COURSE_WARIO_STADIUM; + case COURSE_WARIO_STADIUM: + return COURSE_SHERBET_LAND; + case COURSE_SHERBET_LAND: + return COURSE_ROYAL_RACEWAY; + case COURSE_ROYAL_RACEWAY: + return COURSE_BOWSER_CASTLE; + case COURSE_BOWSER_CASTLE: + return COURSE_DK_JUNGLE; + case COURSE_DK_JUNGLE: + return COURSE_YOSHI_VALLEY; + case COURSE_YOSHI_VALLEY: + return COURSE_BANSHEE_BOARDWALK; + case COURSE_BANSHEE_BOARDWALK: + return COURSE_MOO_MOO_FARM; + default: + break; + } + default: + break; + } - return get_course_id_for_tournament_cursor(nextCup, nextIndexInCup); } // Get the course abbreviation string for the next course char* getNextCourseAbbrString(void) { - s32 linearCourseIndex = (gCupSelection * 4) + gCourseIndexInCup; - s32 nextLinearIndex = (linearCourseIndex + 1) & 0xF; - switch (gTournamentCourseMode) { - case 0: // VA mode - use VA abbreviations - return gCourseNamesVA[nextLinearIndex]; - case 1: // KA mode - use KA abbreviations - return gCourseNamesKA[nextLinearIndex]; - case 2: // KA_MMF mode - use KA_MMF abbreviations - return gCourseNamesKA_MMF[nextLinearIndex]; + // va track order + case 0: + switch(gCurrentCourseId) { + case COURSE_LUIGI_RACEWAY: + return "MMF"; + case COURSE_MOO_MOO_FARM: + return "KTB"; + case COURSE_KOOPA_BEACH: + return "KD"; + case COURSE_KALAMARI_DESERT: + return "DKJP"; + case COURSE_DK_JUNGLE: + return "YV"; + case COURSE_YOSHI_VALLEY: + return "BB"; + case COURSE_BANSHEE_BOARDWALK: + return "RRd"; + case COURSE_RAINBOW_ROAD: + return "WS"; + case COURSE_WARIO_STADIUM: + return "SL"; + case COURSE_SHERBET_LAND: + return "RRy"; + case COURSE_ROYAL_RACEWAY: + return "BC"; + case COURSE_BOWSER_CASTLE: + return "TT"; + case COURSE_TOADS_TURNPIKE: + return "FS"; + case COURSE_FRAPPE_SNOWLAND: + return "CM"; + case COURSE_CHOCO_MOUNTAIN: + return "MR"; + case COURSE_MARIO_RACEWAY: + return "LR"; + default: + break; + } + // kaillera track order + case 1: + switch(gCurrentCourseId) { + case COURSE_LUIGI_RACEWAY: + return "MMF"; + case COURSE_MOO_MOO_FARM: + return "KTB"; + case COURSE_KOOPA_BEACH: + return "KTB"; + case COURSE_KALAMARI_DESERT: + return "TT"; + case COURSE_TOADS_TURNPIKE: + return "FS"; + case COURSE_FRAPPE_SNOWLAND: + return "CM"; + case COURSE_CHOCO_MOUNTAIN: + return "MR"; + case COURSE_MARIO_RACEWAY: + return "WS"; + case COURSE_WARIO_STADIUM: + return "SL"; + case COURSE_SHERBET_LAND: + return "RRy"; + case COURSE_ROYAL_RACEWAY: + return "BC"; + case COURSE_BOWSER_CASTLE: + return "DKJP"; + case COURSE_DK_JUNGLE: + return "YV"; + case COURSE_YOSHI_VALLEY: + return "BB"; + case COURSE_BANSHEE_BOARDWALK: + return "RRd"; + case COURSE_RAINBOW_ROAD: + return "LR"; + default: + break; + } + // kaillera mmf track order + case 2: + switch(gCurrentCourseId) { + case COURSE_LUIGI_RACEWAY: + return "MMF"; + case COURSE_MOO_MOO_FARM: + return "KTB"; + case COURSE_KOOPA_BEACH: + return "KD"; + case COURSE_KALAMARI_DESERT: + return "TT"; + case COURSE_TOADS_TURNPIKE: + return "FS"; + case COURSE_FRAPPE_SNOWLAND: + return "CM"; + case COURSE_CHOCO_MOUNTAIN: + return "MR"; + case COURSE_MARIO_RACEWAY: + return "WS"; + case COURSE_WARIO_STADIUM: + return "SL"; + case COURSE_SHERBET_LAND: + return "RRy"; + case COURSE_ROYAL_RACEWAY: + return "BC"; + case COURSE_BOWSER_CASTLE: + return "DKJP"; + case COURSE_DK_JUNGLE: + return "YV"; + case COURSE_YOSHI_VALLEY: + return "BB"; + case COURSE_BANSHEE_BOARDWALK: + return "MMF"; + default: + break; + } default: - return gCourseNamesDup[getNextCourseId()]; + break; } + } void render_menus(MenuItem* arg0) { @@ -8558,11 +8772,17 @@ void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { s32 thirds; u8 i; s32 points; - char pointsBuf[5]; + char pointsBuf[5]; + + // tally override initially zero + static s32 tally_overrides[4] = {0, 0, 0, 0}; // Everything about this variable is bizarre s32 rankIdx = -1; + // flag that checks if manual point override is active + s32 isComboActive = 0; + // base x and y position for drawing scores // x-coord increment will be different for 3p and 4p vs base_xPos_4p = 0x1A; @@ -8578,15 +8798,62 @@ void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { // Only draw scores on the first player call to avoid overdraw // (func_800A6E94 is called once per player by func_800A6BEC/func_800A6CC0) if (playerId == 0) { + if (gPlayerCountSelection1 == 3) { + if ((gControllerOne->button & L_TRIG) && (gControllerOne->button & R_TRIG) && + (gControllerTwo->button & L_TRIG) && (gControllerTwo->button & R_TRIG) && + (gControllerThree->button & L_TRIG) && (gControllerThree->button & R_TRIG)) { + isComboActive = 1; + } + } else if (gPlayerCountSelection1 == 4) { + if ((gControllerOne->button & L_TRIG) && (gControllerOne->button & R_TRIG) && + (gControllerTwo->button & L_TRIG) && (gControllerTwo->button & R_TRIG) && + (gControllerThree->button & L_TRIG) && (gControllerThree->button & R_TRIG) && + (gControllerFour->button & L_TRIG) && (gControllerFour->button & R_TRIG)) { + isComboActive = 1; + } + } + + if (isComboActive) { + // p1 adjust points + if (gControllerOne->buttonPressed & U_CBUTTONS) { + tally_overrides[0] += 1; + } else if (gControllerOne->buttonPressed & D_CBUTTONS) { + tally_overrides[0] -= 1; + } + + // p2 adjust points + if (gControllerTwo->buttonPressed & U_CBUTTONS) { + tally_overrides[1] += 1; + } else if (gControllerTwo->buttonPressed & D_CBUTTONS) { + tally_overrides[1] -= 1; + } + + // p3 adjust points + if (gControllerThree->buttonPressed & U_CBUTTONS) { + tally_overrides[2] += 1; + } else if (gControllerThree->buttonPressed & D_CBUTTONS) { + tally_overrides[2] -= 1; + } + + // p4 adjust points (check if in 4-player mode) + if (gPlayerCountSelection1 == 4) { + if (gControllerFour->buttonPressed & U_CBUTTONS) { + tally_overrides[3] += 1; + } else if (gControllerFour->buttonPressed & D_CBUTTONS) { + tally_overrides[3] -= 1; + } + } + } + set_text_color(TEXT_YELLOW); while(i < gPlayerCountSelection1) { firsts = tally[i * 3 + 0]; seconds = tally[i * 3 + 1]; thirds = tally[i * 3 + 2]; - // custom point calculation - points = (firsts * 3) + (seconds * 2) + (thirds * 1); - + // custom point calculation; wraps around to 0 after hitting 49 + points = (u8)((( (firsts * 3) + (seconds * 2) + (thirds * 1) + tally_overrides[i] ) % 49 + 49) % 49); + // convert to ascii char convert_number_to_ascii(points, pointsBuf); @@ -8603,8 +8870,8 @@ void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { draw_offset = (pointsBuf[0] == ' ') ? -0x5 : 0; text_draw(X_pos + draw_offset , Y_pos, pointsBuf, 0, 0.80f, 0.80f); i++; - } } +} temp_s0 = &D_800E7300[((playerCount - 2) * 4) + playerId]; rank = gGPCurrentRaceRankByPlayerId[playerId]; diff --git a/src/menus.c b/src/menus.c index 52ed794006..eca8a28aa8 100644 --- a/src/menus.c +++ b/src/menus.c @@ -158,76 +158,6 @@ const s16 gCupCourseOrder[5][4] = { { COURSE_BIG_DONUT, COURSE_BLOCK_FORT, COURSE_DOUBLE_DECK, COURSE_SKYSCRAPER }, }; -// va course order -const s16 gVACourseOrder[4][4] = { - // mushroom cup - { COURSE_LUIGI_RACEWAY, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, - // special cup - { COURSE_DK_JUNGLE, COURSE_YOSHI_VALLEY, COURSE_BANSHEE_BOARDWALK, COURSE_RAINBOW_ROAD }, - // star cup - { COURSE_WARIO_STADIUM, COURSE_SHERBET_LAND, COURSE_ROYAL_RACEWAY, COURSE_BOWSER_CASTLE }, - // flower cup - { COURSE_TOADS_TURNPIKE, COURSE_FRAPPE_SNOWLAND, COURSE_CHOCO_MOUNTAIN, COURSE_MARIO_RACEWAY } -}; - -// KA course order -const s16 gKACourseOrder[4][4] = { - // mushroom cup - { COURSE_LUIGI_RACEWAY, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, - // flower cup - { COURSE_TOADS_TURNPIKE, COURSE_FRAPPE_SNOWLAND, COURSE_CHOCO_MOUNTAIN, COURSE_MARIO_RACEWAY }, - // star cup - { COURSE_WARIO_STADIUM, COURSE_SHERBET_LAND, COURSE_ROYAL_RACEWAY, COURSE_BOWSER_CASTLE }, - // special cup - { COURSE_DK_JUNGLE, COURSE_YOSHI_VALLEY, COURSE_BANSHEE_BOARDWALK, COURSE_RAINBOW_ROAD } -}; - -// KA mmf course order -const s16 gKAMMFCourseOrder[4][4] = { - // mushroom cup - { COURSE_LUIGI_RACEWAY, COURSE_MOO_MOO_FARM, COURSE_KOOPA_BEACH, COURSE_KALAMARI_DESERT }, - // flower cup - { COURSE_TOADS_TURNPIKE, COURSE_FRAPPE_SNOWLAND, COURSE_CHOCO_MOUNTAIN, COURSE_MARIO_RACEWAY }, - // star cup - { COURSE_WARIO_STADIUM, COURSE_SHERBET_LAND, COURSE_ROYAL_RACEWAY, COURSE_BOWSER_CASTLE }, - // special cup modified - { COURSE_DK_JUNGLE, COURSE_YOSHI_VALLEY, COURSE_BANSHEE_BOARDWALK, COURSE_MOO_MOO_FARM } -}; - -s16 get_course_id_for_tournament_cursor(s32 cupSelection, s32 courseIndexInCup) { - s32 cup = cupSelection; - s32 course = courseIndexInCup; - - if (course < 0) { - course = 0; - } - if (course > 3) { - course &= 3; - } - - if (cup == 4) { - return gCupCourseOrder[4][course]; - } - - if (cup < 0) { - cup = 0; - } - if (cup > 3) { - cup &= 3; - } - - switch (gTournamentCourseMode) { - case 0: - return gVACourseOrder[cup][course]; - case 1: - return gKACourseOrder[cup][course]; - case 2: - return gKAMMFCourseOrder[cup][course]; - default: - return gCupCourseOrder[cup][course]; - } -} - const s8 unref_800F2BDC[4] = { 1, 0, 0, 0 }; // Uses player count to set gScreenModeListIndex, the latter variable then selects a mode diff --git a/src/menus.h b/src/menus.h index dee269ba7f..8d81966500 100644 --- a/src/menus.h +++ b/src/menus.h @@ -262,8 +262,6 @@ extern s8 gControllerPakScrollDirection; extern const s8 gPlayerModeSelection[]; extern const s32 gGameModePlayerSelection[][3]; extern const s16 gCupCourseOrder[NUM_CUPS][NUM_COURSES_PER_CUP]; -extern s16 get_course_id_for_tournament_cursor(s32 cupSelection, s32 courseIndexInCup); - // end of menus.c variables // start of custom menu var diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index ca25daaa52..e67ea84d47 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -1198,16 +1198,11 @@ void func_802903B0(void) { // proceed to next track in selection (vs mode only) void gotoNextTrack(void) { s16 nextCourse; - s32 nextLinearIndex; gIsInQuitToMenuTransition = 1; gQuitToMenuTransitionCounter = 5; - nextLinearIndex = (((s32) gCupSelection * 4) + gCourseIndexInCup + 1) & 0xF; nextCourse = getNextCourseId(); gCurrentCourseId = nextCourse; - gCupSelection = nextLinearIndex / 4; - D_800DC540 = gCupSelection; - gCourseIndexInCup = nextLinearIndex % 4; gGotoMode = RACING; } From 0ce03f7b41f7c9dce3a52181954fe152608fd2f3 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 20 Jul 2026 17:40:47 -0400 Subject: [PATCH 54/73] updated comments --- src/menu_items.c | 2 +- src/racing/race_logic.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/menu_items.c b/src/menu_items.c index 0f5907cb38..a0587c09fe 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -8851,7 +8851,7 @@ void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { seconds = tally[i * 3 + 1]; thirds = tally[i * 3 + 2]; - // custom point calculation; wraps around to 0 after hitting 49 + // custom point calculation; wraps around to 0 after hitting 48 points = (u8)((( (firsts * 3) + (seconds * 2) + (thirds * 1) + tally_overrides[i] ) % 49 + 49) % 49); // convert to ascii char diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index e67ea84d47..903e8ac293 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -1206,6 +1206,7 @@ void gotoNextTrack(void) { gGotoMode = RACING; } +// has to do with collision when two players hit each other void func_802903D8(Player* playerOne, Player* playerTwo) { f32 sp70 = (playerOne->boundingBoxSize + playerTwo->boundingBoxSize) - 5.0f; f32 temp_f0; From 6ed1343ae62d0e89e37f9fe1b2c9d7b9211289d3 Mon Sep 17 00:00:00 2001 From: Jed Grabman Date: Mon, 20 Jul 2026 23:37:21 -0400 Subject: [PATCH 55/73] Update places, even while held by Lakitu --- src/cpu_vehicles_camera_path.c | 35 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/cpu_vehicles_camera_path.c b/src/cpu_vehicles_camera_path.c index 5e4b8fa426..02673fa0b3 100644 --- a/src/cpu_vehicles_camera_path.c +++ b/src/cpu_vehicles_camera_path.c @@ -1459,23 +1459,6 @@ void update_player(s32 playerId) { } update_player_path_completion(playerId, player); - switch (gModeSelection) { - case BATTLE: - default: - return; // HEY! returns, not breaks - case GRAND_PRIX: - case TIME_TRIALS: - numPlayer = NUM_PLAYERS; - break; - case VERSUS: - numPlayer = gPlayerCount; - break; - } - - // checks on last player to ensure all players positions have been updated - if ((gCurrentCourseId != COURSE_AWARD_CEREMONY) && (playerId == (numPlayer - 1))) { - set_places(); - } if (player->type & PLAYER_CPU) { if ((gIsPlayerNewPathPoint == true) && (gCurrentCourseId != COURSE_AWARD_CEREMONY)) { cpu_behaviour(playerId); @@ -1759,6 +1742,24 @@ void update_player(s32 playerId) { regulate_cpu_speed(playerId, gCurrentCpuTargetSpeed, player); } } + + switch (gModeSelection) { + case BATTLE: + default: + return; // HEY! returns, not breaks + case GRAND_PRIX: + case TIME_TRIALS: + numPlayer = NUM_PLAYERS; + break; + case VERSUS: + numPlayer = gPlayerCount; + break; + } + + // checks on last player to ensure all players positions have been updated + if ((gCurrentCourseId != COURSE_AWARD_CEREMONY) && (playerId == (numPlayer - 1))) { + set_places(); + } } } From 4e9dc5c6e9e725b90ef8f1bdb67a620dc19d6109 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Tue, 21 Jul 2026 19:08:47 -0400 Subject: [PATCH 56/73] Release candidate 1; updated UI to reflect version --- src/menu_items.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/menu_items.c b/src/menu_items.c index a0587c09fe..7e4ed388d1 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -5845,7 +5845,7 @@ void render_custom_overlay(void) { print_text1_center_mode_1(x, y - 0x28, "WEATHERTON ABNEY CLIMATEE ZSERF DNTN31", 0, 0.60f, 0.60f); // version / date (smaller) - left-aligned to start under 'KART' - print_text1_left(x + 0x78, y + 0x06, "TE V2026-07-14 BETA 5", 0, 0.65f, 0.65f); + print_text1_left(x + 0x78, y + 0x06, "TE V2026-07-21 RELEASE 1", 0, 0.65f, 0.65f); // option name placeholders (second column) and values (third column) for (i = 0; i < CUSTOM_MENU_ROWS; i++) { From c45b920a0ca7551da3a0afd88b7e33df59891e5f Mon Sep 17 00:00:00 2001 From: Jed Grabman Date: Thu, 23 Jul 2026 00:48:34 -0400 Subject: [PATCH 57/73] Update globals and functions from base decomp project --- assets/blueshell.json | 16 +-- assets/course_outlines.json | 40 +++--- assets/greenshell.json | 16 +-- assets/include/blueshell.mk | 16 +-- assets/include/course_outlines.mk | 40 +++--- assets/include/greenshell.mk | 16 +-- data/course_player_selection.s | 2 +- data/other_textures.h | 78 +++++------ data/other_textures.s | 150 ++++++++++---------- data/texture_data_2.s | 4 +- src/code_800029B0.c | 8 +- src/code_800029B0.h | 6 +- src/code_80057C60.c | 218 +++++++++++++++--------------- src/code_80057C60.h | 36 ++--- src/code_80057C60_var.c | 22 +-- src/code_8006E9C0.c | 2 +- src/cpu_vehicles_camera_path.c | 22 +-- src/cpu_vehicles_camera_path.h | 6 +- src/data/some_data.c | 14 +- src/data/textures.c | 108 +++++++-------- src/effects.c | 36 ++--- src/effects.h | 16 +-- src/main.c | 12 +- src/main.h | 8 +- src/menu_items.c | 184 ++++++++++++------------- src/menu_items.h | 14 +- src/menus.c | 2 +- src/player_controller.c | 218 +++++++++++++++--------------- src/player_controller.h | 10 +- src/racing/actors.c | 32 ++--- src/racing/race_logic.c | 68 +++++----- src/render_objects.c | 2 +- src/render_player.c | 8 +- src/spawn_players.c | 2 +- src/textures.h | 102 +++++++------- 35 files changed, 767 insertions(+), 767 deletions(-) diff --git a/assets/blueshell.json b/assets/blueshell.json index c75ccf5efd..6a18323292 100644 --- a/assets/blueshell.json +++ b/assets/blueshell.json @@ -1,11 +1,11 @@ { "common_tlut_blue_shell": {"output_dir": "blueshell", "rom_offset": "0x132B50", "block_offset": "0x05038", "width": 16, "height": 16, "type": "rgba16"}, -"gTextureBlueShell0": {"output_dir": "blueshell", "rom_offset": "0x68FE20", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, -"gTextureBlueShell1": {"output_dir": "blueshell", "rom_offset": "0x69004C", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, -"gTextureBlueShell2": {"output_dir": "blueshell", "rom_offset": "0x690284", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, -"gTextureBlueShell3": {"output_dir": "blueshell", "rom_offset": "0x6904C4", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, -"gTextureBlueShell4": {"output_dir": "blueshell", "rom_offset": "0x690708", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, -"gTextureBlueShell5": {"output_dir": "blueshell", "rom_offset": "0x690960", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, -"gTextureBlueShell6": {"output_dir": "blueshell", "rom_offset": "0x690BBC", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, -"gTextureBlueShell7": {"output_dir": "blueshell", "rom_offset": "0x690DF8", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"} +"texture_blue_shell_0": {"output_dir": "blueshell", "rom_offset": "0x68FE20", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, +"texture_blue_shell_1": {"output_dir": "blueshell", "rom_offset": "0x69004C", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, +"texture_blue_shell_2": {"output_dir": "blueshell", "rom_offset": "0x690284", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, +"texture_blue_shell_3": {"output_dir": "blueshell", "rom_offset": "0x6904C4", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, +"texture_blue_shell_4": {"output_dir": "blueshell", "rom_offset": "0x690708", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, +"texture_blue_shell_5": {"output_dir": "blueshell", "rom_offset": "0x690960", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, +"texture_blue_shell_6": {"output_dir": "blueshell", "rom_offset": "0x690BBC", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"}, +"texture_blue_shell_7": {"output_dir": "blueshell", "rom_offset": "0x690DF8", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_blue_shell"} } \ No newline at end of file diff --git a/assets/course_outlines.json b/assets/course_outlines.json index 48877d202f..7a208a6842 100644 --- a/assets/course_outlines.json +++ b/assets/course_outlines.json @@ -1,22 +1,22 @@ { -"gTextureCourseOutlineMarioRaceway": {"output_dir": "course_outlines", "rom_offset": "0x720C0C", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineChocoMountain": {"output_dir": "course_outlines", "rom_offset": "0x720ED0", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineBowsersCastle": {"output_dir": "course_outlines", "rom_offset": "0x7211D8", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineBansheeBoardwalk": {"output_dir": "course_outlines", "rom_offset": "0x72143C", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineYoshiValley": {"output_dir": "course_outlines", "rom_offset": "0x721634", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineFrappeSnowland": {"output_dir": "course_outlines", "rom_offset": "0x721A58", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineKoopaTroopaBeach": {"output_dir": "course_outlines", "rom_offset": "0x721CD0", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineRoyalRaceway": {"output_dir": "course_outlines", "rom_offset": "0x721F38", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineLuigiRaceway": {"output_dir": "course_outlines", "rom_offset": "0x722210", "width": 64, "height": 96, "type": "i4"}, -"gTextureCourseOutlineMooMooFarm": {"output_dir": "course_outlines", "rom_offset": "0x72248C", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineToadsTurnpike": {"output_dir": "course_outlines", "rom_offset": "0x7226C4", "width": 128, "height": 64, "type": "i4"}, -"gTextureCourseOutlineKalimariDesert": {"output_dir": "course_outlines", "rom_offset": "0x7229C0", "width": 64, "height": 96, "type": "i4"}, -"gTextureCourseOutlineSherbetLand": {"output_dir": "course_outlines", "rom_offset": "0x722D2C", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineRainbowRoad": {"output_dir": "course_outlines", "rom_offset": "0x723034", "width": 64, "height": 96, "type": "i4"}, -"gTextureCourseOutlineWarioStadium": {"output_dir": "course_outlines", "rom_offset": "0x723370", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineBlockFort": {"output_dir": "course_outlines", "rom_offset": "0x723644", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineSkyscraper": {"output_dir": "course_outlines", "rom_offset": "0x7238E4", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineDoubleDeck": {"output_dir": "course_outlines", "rom_offset": "0x723B18", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineDksJungleParkway": {"output_dir": "course_outlines", "rom_offset": "0x723C9C", "width": 64, "height": 64, "type": "i4"}, -"gTextureCourseOutlineBigDonut": {"output_dir": "course_outlines", "rom_offset": "0x723F84", "width": 64, "height": 64, "type": "i4"} +"minimap_mario_raceway": {"output_dir": "course_outlines", "rom_offset": "0x720C0C", "width": 64, "height": 64, "type": "i4"}, +"minimap_choco_mountain": {"output_dir": "course_outlines", "rom_offset": "0x720ED0", "width": 64, "height": 64, "type": "i4"}, +"minimap_bowsers_castle": {"output_dir": "course_outlines", "rom_offset": "0x7211D8", "width": 64, "height": 64, "type": "i4"}, +"minimap_banshee_boardwalk": {"output_dir": "course_outlines", "rom_offset": "0x72143C", "width": 64, "height": 64, "type": "i4"}, +"minimap_yoshi_valley": {"output_dir": "course_outlines", "rom_offset": "0x721634", "width": 64, "height": 64, "type": "i4"}, +"minimap_frappe_snowland": {"output_dir": "course_outlines", "rom_offset": "0x721A58", "width": 64, "height": 64, "type": "i4"}, +"minimap_koopa_troopa_beach": {"output_dir": "course_outlines", "rom_offset": "0x721CD0", "width": 64, "height": 64, "type": "i4"}, +"minimap_royal_raceway": {"output_dir": "course_outlines", "rom_offset": "0x721F38", "width": 64, "height": 64, "type": "i4"}, +"minimap_luigi_raceway": {"output_dir": "course_outlines", "rom_offset": "0x722210", "width": 64, "height": 96, "type": "i4"}, +"minimap_moo_moo_farm": {"output_dir": "course_outlines", "rom_offset": "0x72248C", "width": 64, "height": 64, "type": "i4"}, +"minimap_toads_turnpike": {"output_dir": "course_outlines", "rom_offset": "0x7226C4", "width": 128, "height": 64, "type": "i4"}, +"minimap_kalimari_desert": {"output_dir": "course_outlines", "rom_offset": "0x7229C0", "width": 64, "height": 96, "type": "i4"}, +"minimap_sherbet_land": {"output_dir": "course_outlines", "rom_offset": "0x722D2C", "width": 64, "height": 64, "type": "i4"}, +"minimap_rainbow_road": {"output_dir": "course_outlines", "rom_offset": "0x723034", "width": 64, "height": 96, "type": "i4"}, +"minimap_wario_stadium": {"output_dir": "course_outlines", "rom_offset": "0x723370", "width": 64, "height": 64, "type": "i4"}, +"minimap_block_fort": {"output_dir": "course_outlines", "rom_offset": "0x723644", "width": 64, "height": 64, "type": "i4"}, +"minimap_skyscraper": {"output_dir": "course_outlines", "rom_offset": "0x7238E4", "width": 64, "height": 64, "type": "i4"}, +"minimap_double_deck": {"output_dir": "course_outlines", "rom_offset": "0x723B18", "width": 64, "height": 64, "type": "i4"}, +"minimap_dks_jungle_parkway": {"output_dir": "course_outlines", "rom_offset": "0x723C9C", "width": 64, "height": 64, "type": "i4"}, +"minimap_big_donut": {"output_dir": "course_outlines", "rom_offset": "0x723F84", "width": 64, "height": 64, "type": "i4"} } diff --git a/assets/greenshell.json b/assets/greenshell.json index d6feea7345..cf07a68221 100644 --- a/assets/greenshell.json +++ b/assets/greenshell.json @@ -1,11 +1,11 @@ { "common_tlut_green_shell": {"output_dir": "greenshell", "rom_offset": "0x132B50", "block_offset": "0x04E38", "width": 16, "height": 16, "type": "rgba16"}, -"gTextureGreenShell0": {"output_dir": "greenshell", "rom_offset": "0x68EB50", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, -"gTextureGreenShell1": {"output_dir": "greenshell", "rom_offset": "0x68EDA0", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, -"gTextureGreenShell2": {"output_dir": "greenshell", "rom_offset": "0x68EFF0", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, -"gTextureGreenShell3": {"output_dir": "greenshell", "rom_offset": "0x68F248", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, -"gTextureGreenShell4": {"output_dir": "greenshell", "rom_offset": "0x68F4A8", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, -"gTextureGreenShell5": {"output_dir": "greenshell", "rom_offset": "0x68F700", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, -"gTextureGreenShell6": {"output_dir": "greenshell", "rom_offset": "0x68F96C", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, -"gTextureGreenShell7": {"output_dir": "greenshell", "rom_offset": "0x68FBCC", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"} +"texture_green_shell_0": {"output_dir": "greenshell", "rom_offset": "0x68EB50", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, +"texture_green_shell_1": {"output_dir": "greenshell", "rom_offset": "0x68EDA0", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, +"texture_green_shell_2": {"output_dir": "greenshell", "rom_offset": "0x68EFF0", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, +"texture_green_shell_3": {"output_dir": "greenshell", "rom_offset": "0x68F248", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, +"texture_green_shell_4": {"output_dir": "greenshell", "rom_offset": "0x68F4A8", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, +"texture_green_shell_5": {"output_dir": "greenshell", "rom_offset": "0x68F700", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, +"texture_green_shell_6": {"output_dir": "greenshell", "rom_offset": "0x68F96C", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"}, +"texture_green_shell_7": {"output_dir": "greenshell", "rom_offset": "0x68FBCC", "width": 32, "height": 32, "type": "ci8", "tlut": "common_tlut_green_shell"} } diff --git a/assets/include/blueshell.mk b/assets/include/blueshell.mk index c344726ff4..81efb56c39 100644 --- a/assets/include/blueshell.mk +++ b/assets/include/blueshell.mk @@ -3,14 +3,14 @@ BLUESHELL_DIR := assets/blueshell BLUESHELL_PALETTE := $(BLUESHELL_DIR)/common_tlut_blue_shell.png BLUESHELL_FRAMES := \ -$(BLUESHELL_DIR)/gTextureBlueShell0.png \ -$(BLUESHELL_DIR)/gTextureBlueShell1.png \ -$(BLUESHELL_DIR)/gTextureBlueShell2.png \ -$(BLUESHELL_DIR)/gTextureBlueShell3.png \ -$(BLUESHELL_DIR)/gTextureBlueShell4.png \ -$(BLUESHELL_DIR)/gTextureBlueShell5.png \ -$(BLUESHELL_DIR)/gTextureBlueShell6.png \ -$(BLUESHELL_DIR)/gTextureBlueShell7.png +$(BLUESHELL_DIR)/texture_blue_shell_0.png \ +$(BLUESHELL_DIR)/texture_blue_shell_1.png \ +$(BLUESHELL_DIR)/texture_blue_shell_2.png \ +$(BLUESHELL_DIR)/texture_blue_shell_3.png \ +$(BLUESHELL_DIR)/texture_blue_shell_4.png \ +$(BLUESHELL_DIR)/texture_blue_shell_5.png \ +$(BLUESHELL_DIR)/texture_blue_shell_6.png \ +$(BLUESHELL_DIR)/texture_blue_shell_7.png BLUESHELL_EXPORT_SENTINEL := $(BLUESHELL_DIR)/.export diff --git a/assets/include/course_outlines.mk b/assets/include/course_outlines.mk index 067e7b4e3c..9e799ce085 100644 --- a/assets/include/course_outlines.mk +++ b/assets/include/course_outlines.mk @@ -1,26 +1,26 @@ COURSE_OUTLINE_DIR := assets/course_outlines COURSE_OUTLINE_PNG := \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineMarioRaceway.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineChocoMountain.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineBowsersCastle.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineBansheeBoardwalk.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineYoshiValley.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineFrappeSnowland.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineKoopaTroopaBeach.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineRoyalRaceway.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineLuigiRaceway.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineMooMooFarm.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineToadsTurnpike.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineKalimariDesert.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineSherbetLand.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineRainbowRoad.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineWarioStadium.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineBlockFort.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineSkyscraper.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineDoubleDeck.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineDksJungleParkway.png \ -$(COURSE_OUTLINE_DIR)/gTextureCourseOutlineBigDonut.png +$(COURSE_OUTLINE_DIR)/minimap_mario_raceway.png \ +$(COURSE_OUTLINE_DIR)/minimap_choco_mountain.png \ +$(COURSE_OUTLINE_DIR)/minimap_bowsers_castle.png \ +$(COURSE_OUTLINE_DIR)/minimap_banshee_boardwalk.png \ +$(COURSE_OUTLINE_DIR)/minimap_yoshi_valley.png \ +$(COURSE_OUTLINE_DIR)/minimap_frappe_snowland.png \ +$(COURSE_OUTLINE_DIR)/minimap_koopa_troopa_beach.png \ +$(COURSE_OUTLINE_DIR)/minimap_royal_raceway.png \ +$(COURSE_OUTLINE_DIR)/minimap_luigi_raceway.png \ +$(COURSE_OUTLINE_DIR)/minimap_moo_moo_farm.png \ +$(COURSE_OUTLINE_DIR)/minimap_toads_turnpike.png \ +$(COURSE_OUTLINE_DIR)/minimap_kalimari_desert.png \ +$(COURSE_OUTLINE_DIR)/minimap_sherbet_land.png \ +$(COURSE_OUTLINE_DIR)/minimap_rainbow_road.png \ +$(COURSE_OUTLINE_DIR)/minimap_wario_stadium.png \ +$(COURSE_OUTLINE_DIR)/minimap_block_fort.png \ +$(COURSE_OUTLINE_DIR)/minimap_skyscraper.png \ +$(COURSE_OUTLINE_DIR)/minimap_double_deck.png \ +$(COURSE_OUTLINE_DIR)/minimap_dks_jungle_parkway.png \ +$(COURSE_OUTLINE_DIR)/minimap_big_donut.png COURSE_OUTLINE_EXPORT_SENTINEL := $(COURSE_OUTLINE_DIR)/.export diff --git a/assets/include/greenshell.mk b/assets/include/greenshell.mk index 870962eb59..0dd8a5b0bc 100644 --- a/assets/include/greenshell.mk +++ b/assets/include/greenshell.mk @@ -3,14 +3,14 @@ GREENSHELL_DIR := assets/greenshell GREENSHELL_PALETTE := $(GREENSHELL_DIR)/common_tlut_green_shell.png GREENSHELL_FRAMES := \ -$(GREENSHELL_DIR)/gTextureGreenShell0.png \ -$(GREENSHELL_DIR)/gTextureGreenShell1.png \ -$(GREENSHELL_DIR)/gTextureGreenShell2.png \ -$(GREENSHELL_DIR)/gTextureGreenShell3.png \ -$(GREENSHELL_DIR)/gTextureGreenShell4.png \ -$(GREENSHELL_DIR)/gTextureGreenShell5.png \ -$(GREENSHELL_DIR)/gTextureGreenShell6.png \ -$(GREENSHELL_DIR)/gTextureGreenShell7.png +$(GREENSHELL_DIR)/texture_green_shell_0.png \ +$(GREENSHELL_DIR)/texture_green_shell_1.png \ +$(GREENSHELL_DIR)/texture_green_shell_2.png \ +$(GREENSHELL_DIR)/texture_green_shell_3.png \ +$(GREENSHELL_DIR)/texture_green_shell_4.png \ +$(GREENSHELL_DIR)/texture_green_shell_5.png \ +$(GREENSHELL_DIR)/texture_green_shell_6.png \ +$(GREENSHELL_DIR)/texture_green_shell_7.png GREENSHELL_EXPORT_SENTINEL := $(GREENSHELL_DIR)/.export diff --git a/data/course_player_selection.s b/data/course_player_selection.s index bf868d526e..1c8c8a0834 100644 --- a/data/course_player_selection.s +++ b/data/course_player_selection.s @@ -822,7 +822,7 @@ glabel gTextureP4BorderGreen .incbin "textures/raw/p4_border_green.rgba16" .align 2, 0x00 -glabel gTextureSmallGreenTriangle +glabel texture_small_green_triangle .incbin "textures/raw/small_green_triangle.rgba16" .align 2, 0x00 diff --git a/data/other_textures.h b/data/other_textures.h index 5e8d4d9d72..b23e626a38 100644 --- a/data/other_textures.h +++ b/data/other_textures.h @@ -286,22 +286,22 @@ extern u8 gTexture68D834[]; extern u8 gTexture68D940[]; extern u8 gTexture68DEC0[]; extern u8 gTexture68E2D0[]; -extern u8 gTextureGreenShell0[]; -extern u8 gTextureGreenShell1[]; -extern u8 gTextureGreenShell2[]; -extern u8 gTextureGreenShell3[]; -extern u8 gTextureGreenShell4[]; -extern u8 gTextureGreenShell5[]; -extern u8 gTextureGreenShell6[]; -extern u8 gTextureGreenShell7[]; -extern u8 gTextureBlueShell0[]; -extern u8 gTextureBlueShell1[]; -extern u8 gTextureBlueShell2[]; -extern u8 gTextureBlueShell3[]; -extern u8 gTextureBlueShell4[]; -extern u8 gTextureBlueShell5[]; -extern u8 gTextureBlueShell6[]; -extern u8 gTextureBlueShell7[]; +extern u8 texture_green_shell_0[]; +extern u8 texture_green_shell_1[]; +extern u8 texture_green_shell_2[]; +extern u8 texture_green_shell_3[]; +extern u8 texture_green_shell_4[]; +extern u8 texture_green_shell_5[]; +extern u8 texture_green_shell_6[]; +extern u8 texture_green_shell_7[]; +extern u8 texture_blue_shell_0[]; +extern u8 texture_blue_shell_1[]; +extern u8 texture_blue_shell_2[]; +extern u8 texture_blue_shell_3[]; +extern u8 texture_blue_shell_4[]; +extern u8 texture_blue_shell_5[]; +extern u8 texture_blue_shell_6[]; +extern u8 texture_blue_shell_7[]; extern u8 gTextureQuestionMarkYellow[]; extern u8 gTextureTrees1[]; extern u8 gTextureTrees2[]; @@ -354,7 +354,7 @@ extern u8 gTextureDksJungleParkwayKiwanoFruit3[]; extern u8 gTextureKartShadow[]; extern u8 gTexture69B03C[]; extern u8 gTexture69B140[]; -extern u8 gTexture69B378[]; +extern u8 gGrassParticle[]; extern u8 gTextureMusicNote[]; extern u8 gTextureSpeechBubble[]; extern u8 gTextureBoingExclamation[]; @@ -363,7 +363,7 @@ extern u8 gTexture69BF54[]; extern u8 gTexture69C090[]; extern u8 gTexture69C1E8[]; extern u8 gTextureSmokePuff[]; -extern u8 gTexture69C4E4[]; +extern u8 gGroundDust[]; extern u8 gTexture69C80C[]; extern u8 gTexture69C9C4[]; extern u8 gTexture69CB84[]; @@ -514,26 +514,26 @@ extern u8 gTextureExhaust2[]; extern u8 gTextureExhaust3[]; extern u8 gTextureExhaust4[]; extern u8 gTextureExhaust5[]; -extern u8 gTextureLogoMarioKart64[]; -extern u8 gTextureCourseOutlineMarioRaceway[]; -extern u8 gTextureCourseOutlineChocoMountain[]; -extern u8 gTextureCourseOutlineBowsersCastle[]; -extern u8 gTextureCourseOutlineBansheeBoardwalk[]; -extern u8 gTextureCourseOutlineYoshiValley[]; -extern u8 gTextureCourseOutlineFrappeSnowland[]; -extern u8 gTextureCourseOutlineKoopaTroopaBeach[]; -extern u8 gTextureCourseOutlineRoyalRaceway[]; -extern u8 gTextureCourseOutlineLuigiRaceway[]; -extern u8 gTextureCourseOutlineMooMooFarm[]; -extern u8 gTextureCourseOutlineToadsTurnpike[]; -extern u8 gTextureCourseOutlineKalimariDesert[]; -extern u8 gTextureCourseOutlineSherbetLand[]; -extern u8 gTextureCourseOutlineRainbowRoad[]; -extern u8 gTextureCourseOutlineWarioStadium[]; -extern u8 gTextureCourseOutlineBlockFort[]; -extern u8 gTextureCourseOutlineSkyscraper[]; -extern u8 gTextureCourseOutlineDoubleDeck[]; -extern u8 gTextureCourseOutlineDksJungleParkway[]; -extern u8 gTextureCourseOutlineBigDonut[]; +extern u8 logo_mario_kart_64[]; +extern u8 minimap_mario_raceway[]; +extern u8 minimap_choco_mountain[]; +extern u8 minimap_bowsers_castle[]; +extern u8 minimap_banshee_boardwalk[]; +extern u8 minimap_yoshi_valley[]; +extern u8 minimap_frappe_snowland[]; +extern u8 minimap_koopa_troopa_beach[]; +extern u8 minimap_royal_raceway[]; +extern u8 minimap_luigi_raceway[]; +extern u8 minimap_moo_moo_farm[]; +extern u8 minimap_toads_turnpike[]; +extern u8 minimap_kalimari_desert[]; +extern u8 minimap_sherbet_land[]; +extern u8 minimap_rainbow_road[]; +extern u8 minimap_wario_stadium[]; +extern u8 minimap_block_fort[]; +extern u8 minimap_skyscraper[]; +extern u8 minimap_double_deck[]; +extern u8 minimap_dks_jungle_parkway[]; +extern u8 minimap_big_donut[]; #endif diff --git a/data/other_textures.s b/data/other_textures.s index 233a44b1ae..d56b02a33c 100644 --- a/data/other_textures.s +++ b/data/other_textures.s @@ -1148,68 +1148,68 @@ glabel gTexture68E2D0 .incbin "textures/standalone/texture_68E2D0.rgba16.mio0" .balign 4, 0x00 -glabel gTextureGreenShell0 -.incbin "assets/greenshell/gTextureGreenShell0.mio0" +glabel texture_green_shell_0 +.incbin "assets/greenshell/texture_green_shell_0.mio0" .balign 4, 0x00 -glabel gTextureGreenShell1 -.incbin "assets/greenshell/gTextureGreenShell1.mio0" +glabel texture_green_shell_1 +.incbin "assets/greenshell/texture_green_shell_1.mio0" .balign 4, 0x00 -glabel gTextureGreenShell2 -.incbin "assets/greenshell/gTextureGreenShell2.mio0" +glabel texture_green_shell_2 +.incbin "assets/greenshell/texture_green_shell_2.mio0" .balign 4, 0x00 -glabel gTextureGreenShell3 -.incbin "assets/greenshell/gTextureGreenShell3.mio0" +glabel texture_green_shell_3 +.incbin "assets/greenshell/texture_green_shell_3.mio0" .balign 4, 0x00 -glabel gTextureGreenShell4 -.incbin "assets/greenshell/gTextureGreenShell4.mio0" +glabel texture_green_shell_4 +.incbin "assets/greenshell/texture_green_shell_4.mio0" .balign 4, 0x00 -glabel gTextureGreenShell5 -.incbin "assets/greenshell/gTextureGreenShell5.mio0" +glabel texture_green_shell_5 +.incbin "assets/greenshell/texture_green_shell_5.mio0" .balign 4, 0x00 -glabel gTextureGreenShell6 -.incbin "assets/greenshell/gTextureGreenShell6.mio0" +glabel texture_green_shell_6 +.incbin "assets/greenshell/texture_green_shell_6.mio0" .balign 4, 0x00 -glabel gTextureGreenShell7 -.incbin "assets/greenshell/gTextureGreenShell7.mio0" +glabel texture_green_shell_7 +.incbin "assets/greenshell/texture_green_shell_7.mio0" .balign 4, 0x00 -glabel gTextureBlueShell0 -.incbin "assets/blueshell/gTextureBlueShell0.mio0" +glabel texture_blue_shell_0 +.incbin "assets/blueshell/texture_blue_shell_0.mio0" .balign 4, 0x00 -glabel gTextureBlueShell1 -.incbin "assets/blueshell/gTextureBlueShell1.mio0" +glabel texture_blue_shell_1 +.incbin "assets/blueshell/texture_blue_shell_1.mio0" .balign 4, 0x00 -glabel gTextureBlueShell2 -.incbin "assets/blueshell/gTextureBlueShell2.mio0" +glabel texture_blue_shell_2 +.incbin "assets/blueshell/texture_blue_shell_2.mio0" .balign 4, 0x00 -glabel gTextureBlueShell3 -.incbin "assets/blueshell/gTextureBlueShell3.mio0" +glabel texture_blue_shell_3 +.incbin "assets/blueshell/texture_blue_shell_3.mio0" .balign 4, 0x00 -glabel gTextureBlueShell4 -.incbin "assets/blueshell/gTextureBlueShell4.mio0" +glabel texture_blue_shell_4 +.incbin "assets/blueshell/texture_blue_shell_4.mio0" .balign 4, 0x00 -glabel gTextureBlueShell5 -.incbin "assets/blueshell/gTextureBlueShell5.mio0" +glabel texture_blue_shell_5 +.incbin "assets/blueshell/texture_blue_shell_5.mio0" .balign 4, 0x00 -glabel gTextureBlueShell6 -.incbin "assets/blueshell/gTextureBlueShell6.mio0" +glabel texture_blue_shell_6 +.incbin "assets/blueshell/texture_blue_shell_6.mio0" .balign 4, 0x00 -glabel gTextureBlueShell7 -.incbin "assets/blueshell/gTextureBlueShell7.mio0" +glabel texture_blue_shell_7 +.incbin "assets/blueshell/texture_blue_shell_7.mio0" .balign 4, 0x00 glabel gTextureQuestionMarkYellow @@ -1420,7 +1420,7 @@ glabel gTexture69B140 .incbin "textures/standalone/texture_69B140.i8.mio0" .balign 4, 0x00 -glabel gTexture69B378 +glabel gGrassParticle .incbin "textures/standalone/texture_69B378.rgba16.mio0" .balign 4, 0x00 @@ -1456,7 +1456,7 @@ glabel gTextureSmokePuff .incbin "textures/standalone/texture_69C354.ia8.mio0" .balign 4, 0x00 -glabel gTexture69C4E4 +glabel gGroundDust .incbin "textures/standalone/texture_69C4E4.i8.mio0" .balign 4, 0x00 @@ -2060,85 +2060,85 @@ glabel gTextureExhaust5 .incbin "textures/standalone/exhaust_5.ia8.mio0" .balign 4, 0x00 -glabel gTextureLogoMarioKart64 +glabel logo_mario_kart_64 .incbin "textures/standalone/logo_mario_kart_64.rgba32.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineMarioRaceway -.incbin "assets/course_outlines/gTextureCourseOutlineMarioRaceway.mio0" +glabel minimap_mario_raceway +.incbin "assets/course_outlines/minimap_mario_raceway.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineChocoMountain -.incbin "assets/course_outlines/gTextureCourseOutlineChocoMountain.mio0" +glabel minimap_choco_mountain +.incbin "assets/course_outlines/minimap_choco_mountain.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineBowsersCastle -.incbin "assets/course_outlines/gTextureCourseOutlineBowsersCastle.mio0" +glabel minimap_bowsers_castle +.incbin "assets/course_outlines/minimap_bowsers_castle.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineBansheeBoardwalk -.incbin "assets/course_outlines/gTextureCourseOutlineBansheeBoardwalk.mio0" +glabel minimap_banshee_boardwalk +.incbin "assets/course_outlines/minimap_banshee_boardwalk.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineYoshiValley -.incbin "assets/course_outlines/gTextureCourseOutlineYoshiValley.mio0" +glabel minimap_yoshi_valley +.incbin "assets/course_outlines/minimap_yoshi_valley.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineFrappeSnowland -.incbin "assets/course_outlines/gTextureCourseOutlineFrappeSnowland.mio0" +glabel minimap_frappe_snowland +.incbin "assets/course_outlines/minimap_frappe_snowland.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineKoopaTroopaBeach -.incbin "assets/course_outlines/gTextureCourseOutlineKoopaTroopaBeach.mio0" +glabel minimap_koopa_troopa_beach +.incbin "assets/course_outlines/minimap_koopa_troopa_beach.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineRoyalRaceway -.incbin "assets/course_outlines/gTextureCourseOutlineRoyalRaceway.mio0" +glabel minimap_royal_raceway +.incbin "assets/course_outlines/minimap_royal_raceway.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineLuigiRaceway -.incbin "assets/course_outlines/gTextureCourseOutlineLuigiRaceway.mio0" +glabel minimap_luigi_raceway +.incbin "assets/course_outlines/minimap_luigi_raceway.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineMooMooFarm -.incbin "assets/course_outlines/gTextureCourseOutlineMooMooFarm.mio0" +glabel minimap_moo_moo_farm +.incbin "assets/course_outlines/minimap_moo_moo_farm.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineToadsTurnpike -.incbin "assets/course_outlines/gTextureCourseOutlineToadsTurnpike.mio0" +glabel minimap_toads_turnpike +.incbin "assets/course_outlines/minimap_toads_turnpike.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineKalimariDesert -.incbin "assets/course_outlines/gTextureCourseOutlineKalimariDesert.mio0" +glabel minimap_kalimari_desert +.incbin "assets/course_outlines/minimap_kalimari_desert.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineSherbetLand -.incbin "assets/course_outlines/gTextureCourseOutlineSherbetLand.mio0" +glabel minimap_sherbet_land +.incbin "assets/course_outlines/minimap_sherbet_land.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineRainbowRoad -.incbin "assets/course_outlines/gTextureCourseOutlineRainbowRoad.mio0" +glabel minimap_rainbow_road +.incbin "assets/course_outlines/minimap_rainbow_road.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineWarioStadium -.incbin "assets/course_outlines/gTextureCourseOutlineWarioStadium.mio0" +glabel minimap_wario_stadium +.incbin "assets/course_outlines/minimap_wario_stadium.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineBlockFort -.incbin "assets/course_outlines/gTextureCourseOutlineBlockFort.mio0" +glabel minimap_block_fort +.incbin "assets/course_outlines/minimap_block_fort.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineSkyscraper -.incbin "assets/course_outlines/gTextureCourseOutlineSkyscraper.mio0" +glabel minimap_skyscraper +.incbin "assets/course_outlines/minimap_skyscraper.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineDoubleDeck -.incbin "assets/course_outlines/gTextureCourseOutlineDoubleDeck.mio0" +glabel minimap_double_deck +.incbin "assets/course_outlines/minimap_double_deck.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineDksJungleParkway -.incbin "assets/course_outlines/gTextureCourseOutlineDksJungleParkway.mio0" +glabel minimap_dks_jungle_parkway +.incbin "assets/course_outlines/minimap_dks_jungle_parkway.mio0" .balign 4, 0x00 -glabel gTextureCourseOutlineBigDonut -.incbin "assets/course_outlines/gTextureCourseOutlineBigDonut.mio0" +glabel minimap_big_donut +.incbin "assets/course_outlines/minimap_big_donut.mio0" diff --git a/data/texture_data_2.s b/data/texture_data_2.s index 5b61729d77..c4a1aba53a 100644 --- a/data/texture_data_2.s +++ b/data/texture_data_2.s @@ -1738,7 +1738,7 @@ glabel gTexture7F9FC4 .incbin "textures/raw/7F9FC4.i4" .align 2, 0x00 -glabel gTexture7FA044 +glabel font_apostrophe .incbin "textures/raw/7FA044.i4" .align 2, 0x00 @@ -1754,5 +1754,5 @@ glabel gTexture7FA264 .incbin "textures/raw/7FA264.i4" .align 2, 0x00 -glabel gTexture7FA334 +glabel font_comma .incbin "textures/raw/7FA334.i4" diff --git a/src/code_800029B0.c b/src/code_800029B0.c index a351de8ece..08d485d90e 100644 --- a/src/code_800029B0.c +++ b/src/code_800029B0.c @@ -130,9 +130,9 @@ u16 D_8015F894; // Indexed by Player ID. Track time in seconds since player has last crossed the finish line f32 gTimePlayerLastTouchedFinishLine[8]; -u8* gNmiUnknown1; -u8* gNmiUnknown2; -u8* gNmiUnknown3; +u8* nmi_gVersusResults2P; +u8* nmi_gVersusResults3P; +u8* nmi_gVersusResults4P; u8* gNmiUnknown4; u8* gNmiUnknown5; u8* gNmiUnknown6; @@ -204,7 +204,7 @@ void setup_race(void) { func_80005310(); func_8003D080(); init_hud(); - D_800DC510 = 0; + gRaceState = 0; gNumSpawnedShells = 0; D_800DC5B8 = 0; D_80152308 = 0; diff --git a/src/code_800029B0.h b/src/code_800029B0.h index 0b7335383a..3b98ab7404 100644 --- a/src/code_800029B0.h +++ b/src/code_800029B0.h @@ -118,9 +118,9 @@ extern u16 D_8015F892; extern u16 D_8015F894; extern f32 gTimePlayerLastTouchedFinishLine[]; -extern u8* gNmiUnknown1; -extern u8* gNmiUnknown2; -extern u8* gNmiUnknown3; +extern u8* nmi_gVersusResults2P; +extern u8* nmi_gVersusResults3P; +extern u8* nmi_gVersusResults4P; extern u8* gNmiUnknown4; extern u8* gNmiUnknown5; extern u8* gNmiUnknown6; diff --git a/src/code_80057C60.c b/src/code_80057C60.c index d155fec35b..654f7a9c8d 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -2777,26 +2777,26 @@ void func_8005D1F4(s32 arg0) { // Appears to load GP Mode race staging balloons and kart shadows. void func_8005D290(void) { D_8018D488 = dma_textures(gTexture69C80C, 0x400, 0x400); - D_8018D474 = dma_textures(gTextureKartShadow, 0x1000, 0x1000); + gLoadedTextureKartShadow = dma_textures(gTextureKartShadow, 0x1000, 0x1000); D_8018D420 = dma_textures(gTexture69B03C, 0x100, 0x100); D_8018D424 = dma_textures(gTexture69B140, 0x400, 0x400); D_8018D478 = dma_textures(gTexture69C1E8, 0x200, 0x200); D_8018D480 = dma_textures(gTextureSpeechBubble, 0x400, 0x400); D_8018D484 = dma_textures(gTextureMusicNote, 0x400, 0x400); D_8018D48C = dma_textures(gTextureSmokePuff, 0x400, 0x400); - D_8018D494 = dma_textures(gTexture69C4E4, 0x400, 0x400); + gLoadedGroundDust = dma_textures(gGroundDust, 0x400, 0x400); D_8018D490 = D_8018D48C; - D_8018D498 = dma_textures(gTexture69B378, 0x1000, 0x1000); + gLoadedGrassParticle = dma_textures(gGrassParticle, 0x1000, 0x1000); D_8018D4BC = dma_textures(gTextureBalloon1, 0x800, 0x800); D_8018D4C0 = dma_textures(gTextureBalloon2, 0x800, 0x800); D_8018D49C = dma_textures(gTexture69C9C4, 0x200, 0x200); D_8018D4A0 = dma_textures(gTextureBoingExclamation, 0x800, 0x800); - D_8018D4A4 = dma_textures(gTextureOnomatopoeiaPoomp1, 0x800, 0x800); - D_8018D4A8 = dma_textures(gTextureOnomatopoeiaPoomp2, 0x800, 0x800); - D_8018D4AC = dma_textures(gTextureOnomatopoeiaWhrrrr1, 0x800, 0x800); - D_8018D4B0 = dma_textures(gTextureOnomatopoeiaWhrrrr2, 0x800, 0x800); - D_8018D4B4 = dma_textures(gTextureOnomatopoeiaCrash1, 0x800, 0x800); - D_8018D4B8 = dma_textures(gTextureOnomatopoeiaCrash2, 0x800, 0x800); + gTextureLoadedOnomatopoeiaPoomp1 = dma_textures(gTextureOnomatopoeiaPoomp1, 0x800, 0x800); + gTextureLoadedOnomatopoeiaPoomp2 = dma_textures(gTextureOnomatopoeiaPoomp2, 0x800, 0x800); + gTextureLoadedOnomatopoeiaWhrrrr1 = dma_textures(gTextureOnomatopoeiaWhrrrr1, 0x800, 0x800); + gTextureLoadedOnomatopoeiaWhrrrr2 = dma_textures(gTextureOnomatopoeiaWhrrrr2, 0x800, 0x800); + gTextureLoadedOnomatopoeiaCrash1 = dma_textures(gTextureOnomatopoeiaCrash1, 0x800, 0x800); + gTextureLoadedOnomatopoeiaCrash2 = dma_textures(gTextureOnomatopoeiaCrash2, 0x800, 0x800); D_8018D438 = dma_textures(gTexture69CB84, 0x800, 0x800); D_8018D43C = dma_textures(gTexture69CCEC, 0x800, 0x800); D_8018D440 = dma_textures(gTexture69CEB8, 0x800, 0x800); @@ -2812,11 +2812,11 @@ void func_8005D290(void) { D_8018D468 = dma_textures(gTexture69EC54, 0x800, 0x800); D_8018D46C = dma_textures(gTexture69EE38, 0x800, 0x800); D_8018D470 = dma_textures(gTexture69EFE0, 0x800, 0x800); - D_8018D4C4 = dma_textures(gTextureLightningBolt0, 0x800, 0x800); - D_8018D4C8 = dma_textures(gTextureLightningBolt1, 0x800, 0x800); + gTextureLoadedLightningBolt0 = dma_textures(gTextureLightningBolt0, 0x800, 0x800); + gTextureLoadedLightningBolt1 = dma_textures(gTextureLightningBolt1, 0x800, 0x800); } -void func_8005D6C0(Player* player) { +void reset_player_particle_pool(Player* player) { s32 temp_v0; for (temp_v0 = 0; temp_v0 < 10; ++temp_v0) { @@ -2853,7 +2853,7 @@ void set_particle_position_and_rotation(Player* player, Particle* particle, f32 particle->unk_010 = arg6; } -s32 init_new_particle_player(Particle* particle, s8 arg1, f32 scale) { +s32 init_particle_player(Particle* particle, s8 arg1, f32 scale) { particle->IsAlive = 1; particle->type = arg1; particle->timer = 0; @@ -2892,7 +2892,7 @@ void set_drift_particles(Player* player, s16 arg1, UNUSED s32 arg2, UNUSED s8 ar temp_lo = player->unk_0C0 / 182; if ((temp_lo >= 7) || (temp_lo < -6)) { - init_new_particle_player(&player->particles[10 + arg1], 1, 0.35f); + init_particle_player(&player->particles[10 + arg1], 1, 0.35f); if (player->driftState == 0) { set_particle_colour(&player->particles[10 + arg1], 0xFFFFFF, 0x70); } @@ -2965,7 +2965,7 @@ void setup_tyre_particles(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UN if (((player->speed / 18.0f) * 216.0f) >= 10.0f) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); if ((gCurrentCourseId == COURSE_CHOCO_MOUNTAIN) || (gCurrentCourseId == COURSE_ROYAL_RACEWAY)) { func_8005DAD8(&player->particles[10 + arg1], 1, 0, 0x0080); } @@ -2989,7 +2989,7 @@ void setup_tyre_particles(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UN } else if ((player->particles[10 + arg2].timer > 0) && (((player->speed / 18.0f) * 216.0f) >= 10.0f)) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); if ((gCurrentCourseId == COURSE_CHOCO_MOUNTAIN) || (gCurrentCourseId == COURSE_ROYAL_RACEWAY)) { func_8005DAD8(&player->particles[10 + arg1], 1, 0, 0x0080); } @@ -3017,7 +3017,7 @@ void setup_tyre_particles(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UN if (((player->speed / 18.0f) * 216.0f) >= 10.0f) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 3, 1.0f); + init_particle_player(&player->particles[10 + arg1], 3, 1.0f); set_particle_colour(&player->particles[10 + arg1], 0x00FFFFFF, 0x00FF); player->particles[10 + arg1].red -= arg1 * 8; player->particles[10 + arg1].green -= arg1 * 8; @@ -3026,7 +3026,7 @@ void setup_tyre_particles(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UN } else if ((player->particles[10 + arg2].timer > 0) && (((player->speed / 18.0f) * 216.0f) >= 10.0f)) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 3, 1.0f); + init_particle_player(&player->particles[10 + arg1], 3, 1.0f); set_particle_colour(&player->particles[10 + arg1], 0x00FFFFFF, 0x00FF); player->particles[10 + arg1].red -= arg1 * 8; player->particles[10 + arg1].green -= arg1 * 8; @@ -3040,14 +3040,14 @@ void setup_tyre_particles(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UN if (((player->speed / 18.0f) * 216.0f) >= 10.0f) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 2, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } } else if ((player->particles[10 + arg2].timer > 0) && (((player->speed / 18.0f) * 216.0f) >= 10.0f)) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 2, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3058,14 +3058,14 @@ void setup_tyre_particles(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UN if (((player->speed / 18.0f) * 216.0f) >= 10.0f) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 3, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } } else if ((player->particles[10 + arg2].timer > 0) && (((player->speed / 18.0f) * 216.0f) >= 10.0f)) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 3, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3076,14 +3076,14 @@ void setup_tyre_particles(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UN if (((player->speed / 18.0f) * 216.0f) >= 10.0f) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 4, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } } else if ((player->particles[10 + arg2].timer > 0) && (((player->speed / 18.0f) * 216.0f) >= 10.0f)) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 4, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3094,14 +3094,14 @@ void setup_tyre_particles(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UN if (((player->speed / 18.0f) * 216.0f) >= 10.0f) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 5, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } } else if ((player->particles[10 + arg2].timer > 0) && (((player->speed / 18.0f) * 216.0f) >= 10.0f)) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); set_particle_colour_randomly_varried(&player->particles[10 + arg1], 0x00FFA54F, 0x00AF); func_8005DAD8(&player->particles[10 + arg1], 5, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); @@ -3114,14 +3114,14 @@ void setup_tyre_particles(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UN if (((player->speed / 18.0f) * 216.0f) >= 10.0f) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 6, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } } else if ((player->particles[10 + arg2].timer > 0) && (((player->speed / 18.0f) * 216.0f) >= 10.0f)) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 6, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3136,7 +3136,7 @@ void setup_tyre_particles(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UN ((player->previousSpeed - player->speed) >= 0.04)) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 0, 0, 0x0080); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3146,7 +3146,7 @@ void setup_tyre_particles(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UN ((player->previousSpeed - player->speed) >= 0.04))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], tyre_x, tyre_y, tyre_z, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 2, 0.46f); + init_particle_player(&player->particles[10 + arg1], 2, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 0, 0, 0x0080); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3190,12 +3190,12 @@ void func_8005EA94(Player* player, s16 arg1, s32 arg2, s8 arg3, UNUSED s8 arg4) if ((arg1 == 0) && ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { if (((player->speed / 18.0f) * 216.0f) >= 10.0f) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f2, var_f12, var_f14, var_t0, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 9, 0.8f); + init_particle_player(&player->particles[10 + arg1], 9, 0.8f); set_particle_colour(&player->particles[10 + arg1], 0x00FFFFFF, 0x00AF); } } else if ((player->particles[10 + arg2].timer > 0) && (((player->speed / 18.0f) * 216.0f) >= 10.0f)) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f2, var_f12, var_f14, var_t0, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 9, 0.8f); + init_particle_player(&player->particles[10 + arg1], 9, 0.8f); set_particle_colour(&player->particles[10 + arg1], 0x00FFFFFF, 0x00AF); } } @@ -3231,7 +3231,7 @@ void func_8005ED48(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 if ((arg1 == 0) && ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); if ((gCurrentCourseId == COURSE_CHOCO_MOUNTAIN) || (gCurrentCourseId == COURSE_ROYAL_RACEWAY)) { func_8005DAD8(&player->particles[10 + arg1], 1, 0, 0x0080); } @@ -3253,7 +3253,7 @@ void func_8005ED48(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); if ((gCurrentCourseId == COURSE_CHOCO_MOUNTAIN) || (gCurrentCourseId == COURSE_ROYAL_RACEWAY)) { func_8005DAD8(&player->particles[10 + arg1], 1, 0, 0x0080); } @@ -3280,7 +3280,7 @@ void func_8005ED48(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.1f); + init_particle_player(&player->particles[10 + arg1], 5, 0.1f); set_particle_colour(&player->particles[10 + arg1], 0x00FFFFFF, 0x00FF); player->particles[10 + arg1].red -= arg1 * 8; player->particles[10 + arg1].green -= arg1 * 8; @@ -3288,7 +3288,7 @@ void func_8005ED48(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.1f); + init_particle_player(&player->particles[10 + arg1], 5, 0.1f); set_particle_colour(&player->particles[10 + arg1], 0x00FFFFFF, 0x00FF); player->particles[10 + arg1].red -= arg1 * 8; player->particles[10 + arg1].green -= arg1 * 8; @@ -3301,13 +3301,13 @@ void func_8005ED48(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 2, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 2, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3317,13 +3317,13 @@ void func_8005ED48(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 3, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 3, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3333,13 +3333,13 @@ void func_8005ED48(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 4, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 4, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3349,13 +3349,13 @@ void func_8005ED48(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 5, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 5, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3366,13 +3366,13 @@ void func_8005ED48(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 6, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 6, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3384,13 +3384,13 @@ void func_8005ED48(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 0, 0, 0x0080); player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, (s8) surfaceType, (s8) var_t3); - init_new_particle_player(&player->particles[10 + arg1], 5, 0.46f); + init_particle_player(&player->particles[10 + arg1], 5, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 0, 0, 0x0080); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3425,7 +3425,7 @@ void func_8005F90C(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 if ((arg1 == 0) && ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); if ((gCurrentCourseId == COURSE_CHOCO_MOUNTAIN) || (gCurrentCourseId == COURSE_ROYAL_RACEWAY)) { func_8005DAD8(&player->particles[10 + arg1], 1, 0, 0x0080); } @@ -3447,7 +3447,7 @@ void func_8005F90C(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); if ((gCurrentCourseId == COURSE_CHOCO_MOUNTAIN) || (gCurrentCourseId == COURSE_ROYAL_RACEWAY)) { func_8005DAD8(&player->particles[10 + arg1], 1, 0, 0x0080); } @@ -3473,14 +3473,14 @@ void func_8005F90C(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 if ((arg1 == 0) && ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.1f); + init_particle_player(&player->particles[10 + arg1], 4, 0.1f); set_particle_colour(&player->particles[10 + arg1], 0x00FFFFFF, 0x00FF); player->particles[10 + arg1].red -= arg1 * 8; player->particles[10 + arg1].green -= arg1 * 8; player->particles[10 + arg1].blue -= arg1 * 8; } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.1f); + init_particle_player(&player->particles[10 + arg1], 4, 0.1f); set_particle_colour(&player->particles[10 + arg1], 0x00FFFFFF, 0x00FF); player->particles[10 + arg1].red -= arg1 * 8; player->particles[10 + arg1].green -= arg1 * 8; @@ -3492,12 +3492,12 @@ void func_8005F90C(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 if ((arg1 == 0) && ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 2, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 2, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3506,12 +3506,12 @@ void func_8005F90C(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 if ((arg1 == 0) && ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 3, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 3, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3520,12 +3520,12 @@ void func_8005F90C(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 if ((arg1 == 0) && ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 4, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 4, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3534,12 +3534,12 @@ void func_8005F90C(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 if ((arg1 == 0) && ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 5, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 5, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3549,12 +3549,12 @@ void func_8005F90C(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 if ((arg1 == 0) && ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 6, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 6, 1, 0x00A8); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3565,12 +3565,12 @@ void func_8005F90C(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 if ((arg1 == 0) && ((player->particles[10 + arg2].timer > 0) || (player->particles[10 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 0, 0, 0x0080); player->particles[10 + arg1].green = random_int(0x0010U); } else if (player->particles[10 + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1); - init_new_particle_player(&player->particles[10 + arg1], 4, 0.46f); + init_particle_player(&player->particles[10 + arg1], 4, 0.46f); func_8005DAD8(&player->particles[10 + arg1], 0, 0, 0x0080); player->particles[10 + arg1].green = random_int(0x0010U); } @@ -3604,13 +3604,13 @@ void func_80060504(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 sp48 = player->pos[2]; sp50 = player->pos[0]; set_particle_position_and_rotation(player, &player->particles[arg1], sp50, sp4C, sp48, 0, 0); - init_new_particle_player(&player->particles[arg1], 1, 0.5f); + init_particle_player(&player->particles[arg1], 1, 0.5f); } else if (player->particles[arg2].timer > 0) { sp4C = player->pos[1] - 2.5; sp48 = player->pos[2]; sp50 = player->pos[0]; set_particle_position_and_rotation(player, &player->particles[arg1], sp50, sp4C, sp48, 0, 0); - init_new_particle_player(&player->particles[arg1], 1, 0.5f); + init_particle_player(&player->particles[arg1], 1, 0.5f); } } player->particles[arg1].unk_024 = 0.0f; @@ -3664,7 +3664,7 @@ void func_800608E0(Player* player, s16 arg1, UNUSED s32 arg2, s8 arg3, UNUSED s8 sp4C = (f32) ((f64) (D_801652A0[arg3] - player->pos[1]) + 0.1); } set_particle_position_and_rotation(player, &player->particles[arg1], 0.0f, 0.0f, 0.0f, (s8) 0, (s8) 0); - init_new_particle_player(&player->particles[arg1], 3, var_f0); + init_particle_player(&player->particles[arg1], 3, var_f0); if ((gCurrentCourseId == COURSE_BOWSER_CASTLE) || (gCurrentCourseId == COURSE_BIG_DONUT)) { set_particle_colour(&player->particles[arg1], 0, 0x00AF); } else { @@ -3710,7 +3710,7 @@ void func_80060BCC(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 } if ((arg1 == 0) && ((player->particles[arg2 + 10].timer > 0) || (player->particles[arg2 + 10].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[arg1 + 10], 0.0f, 0.0f, 0.0f, (s8) 0, (s8) 0); - init_new_particle_player(&player->particles[arg1 + 10], 0x0B, 0.4f); + init_particle_player(&player->particles[arg1 + 10], 0x0B, 0.4f); set_particle_colour(&player->particles[arg1 + 10], 0x00FFFFFF, 0x00FF); player->particles[arg1 + 10].pos[2] = player->pos[2] + (coss(sp54 * 0xB6) * -1.8); player->particles[arg1 + 10].pos[0] = player->pos[0] + (sins(sp54 * 0xB6) * -1.8); @@ -3719,7 +3719,7 @@ void func_80060BCC(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 player->particles[arg1 + 10].scale = (sp48 + 2.0f) / 10.0f; } else if (player->particles[arg2 + 10].timer > 0) { set_particle_position_and_rotation(player, &player->particles[arg1 + 10], 0.0f, 0.0f, 0.0f, (s8) 0, (s8) 0); - init_new_particle_player(&player->particles[arg1 + 10], 0x0B, 0.4f); + init_particle_player(&player->particles[arg1 + 10], 0x0B, 0.4f); set_particle_colour(&player->particles[arg1 + 10], 0x00FFFFFF, 0x00FF); player->particles[arg1 + 10].pos[2] = player->pos[2] + (coss(sp54 * 0xB6) * -1.8); player->particles[arg1 + 10].pos[0] = player->pos[0] + (sins(sp54 * 0xB6) * -1.8); @@ -3731,7 +3731,7 @@ void func_80060BCC(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 void func_80060F50(Player* player, s16 arg1, UNUSED s32 arg2, s8 arg3, UNUSED s8 arg4) { set_particle_position_and_rotation(player, &player->particles[arg1], 0.0f, 0.0f, 0.0f, 0, 0); - init_new_particle_player(&player->particles[arg1], 5, 4.0f); + init_particle_player(&player->particles[arg1], 5, 4.0f); if ((gCurrentCourseId == COURSE_BOWSER_CASTLE) || (gCurrentCourseId == COURSE_BIG_DONUT)) { set_particle_colour(&player->particles[arg1], 0xFF0000, 0xFF); @@ -3748,7 +3748,7 @@ void func_80060F50(Player* player, s16 arg1, UNUSED s32 arg2, s8 arg3, UNUSED s8 void func_80061094(Player* player, s16 arg1, UNUSED s32 arg2, UNUSED s8 arg3, UNUSED s8 arg4) { if (arg1 == 0) { set_particle_position_and_rotation(player, &player->particles[arg1], 0.0f, 0.0f, 0.0f, 0, 0); - init_new_particle_player(&player->particles[arg1], 6, 3.8f); + init_particle_player(&player->particles[arg1], 6, 3.8f); set_particle_colour(&player->particles[arg1], 0xFFFFFF, 0xFF); player->particles[arg1].red = 0; player->particles[arg1].green = 0; @@ -3758,7 +3758,7 @@ void func_80061094(Player* player, s16 arg1, UNUSED s32 arg2, UNUSED s8 arg3, UN void func_80061130(Player* player, s16 arg1, UNUSED s32 arg2, UNUSED s8 arg3, UNUSED s8 arg4) { set_particle_position_and_rotation(player, &player->particles[arg1], 0.0f, 0.0f, 0.0f, 0, 0); - init_new_particle_player(&player->particles[arg1], 7, 0.6f); + init_particle_player(&player->particles[arg1], 7, 0.6f); set_particle_colour(&player->particles[arg1], 0xFFFFFF, 0xD0); player->particles[arg1].pos[2] = player->pos[2] + (coss(player->particles[arg1].rotation) * 6.0f); @@ -3855,7 +3855,7 @@ void func_80061754(Player* player, s16 arg1, UNUSED s32 arg2, UNUSED s32 arg3, U sp44 = random_int(6U); sp48 = random_int(2U); set_particle_position_and_rotation(player, &player->particles[0x1E + arg1], 0.0f, 0.0f, 0.0f, (s8) 0, (s8) 0); - init_new_particle_player(&player->particles[0x1E + arg1], 6, 1.0f); + init_particle_player(&player->particles[0x1E + arg1], 6, 1.0f); if ((player->effects & HIT_BY_STAR_EFFECT) || ((player->effects) & EXPLOSION_CRASH_EFFECT) || ((player->effects) & HIT_BY_GREEN_SHELL_EFFECT) || ((player->effects) & BOO_EFFECT)) { set_particle_colour(&player->particles[0x1E + arg1], 0x00FFFFFF, 0x00A0); @@ -3896,7 +3896,7 @@ void func_80061A34(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 sp48 = (f32) random_int(3U); if ((arg1 == 0) && ((player->particles[0x1E + arg2].timer > 0) || (player->particles[0x1E + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[0x1E + arg1], 0.0f, 0.0f, 0.0f, (s8) 0, (s8) 0); - init_new_particle_player(&player->particles[0x1E + arg1], 7, 1.0f); + init_particle_player(&player->particles[0x1E + arg1], 7, 1.0f); set_particle_colour(&player->particles[0x1E + arg1], 0x00FFFFFF, 0x00FF); player->particles[0x1E + arg1].pos[2] = player->pos[2] + (coss(sp54 * 0xB6) * -2.0); player->particles[0x1E + arg1].pos[0] = player->pos[0] + (sins(sp54 * 0xB6) * -2.0); @@ -3904,7 +3904,7 @@ void func_80061A34(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 player->particles[0x1E + arg1].scale = (sp48 + 2.0f) / 10.0f; } else if (player->particles[0x1E + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[0x1E + arg1], 0.0f, 0.0f, 0.0f, (s8) 0, (s8) 0); - init_new_particle_player(&player->particles[0x1E + arg1], 7, 1.0f); + init_particle_player(&player->particles[0x1E + arg1], 7, 1.0f); set_particle_colour(&player->particles[0x1E + arg1], 0x00FFFFFF, 0x00FF); player->particles[0x1E + arg1].pos[2] = player->pos[2] + (coss(sp54 * 0xB6) * -2.0); player->particles[0x1E + arg1].pos[0] = player->pos[0] + (sins(sp54 * 0xB6) * -2.0); @@ -3960,7 +3960,7 @@ void func_80061EF4(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 if ((arg1 == 0) && ((player->particles[0x1E + arg2].timer > 0) || (player->particles[0x1E + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[0x1E + arg1], 0.0f, var_f2, 0.0f, (s8) var_t0, (s8) var_t1); - init_new_particle_player(&player->particles[0x1E + arg1], 3, 0.5f); + init_particle_player(&player->particles[0x1E + arg1], 3, 0.5f); set_particle_colour(&player->particles[0x1E + arg1], 0x00FFFFFF, 0x0060); player->particles[0x1E + arg1].rotation = 0; if (player->particles[0x1E + arg1].unk_010 == 1) { @@ -3976,7 +3976,7 @@ void func_80061EF4(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 (sins(player->particles[0x1E + arg1].rotation - player->rotation[1] - player->unk_0C0) * 5.0f); } else if (player->particles[0x1E + arg2].timer > 0) { set_particle_position_and_rotation(player, &player->particles[0x1E + arg1], 0.0f, var_f2, 0.0f, (s8) var_t0, (s8) var_t1); - init_new_particle_player(&player->particles[0x1E + arg1], 3, 0.5f); + init_particle_player(&player->particles[0x1E + arg1], 3, 0.5f); set_particle_colour(&player->particles[0x1E + arg1], 0x00FFFFFF, 0x0060); player->particles[0x1E + arg1].rotation = 0; if (player->particles[0x1E + arg1].unk_010 == 1) { @@ -4021,7 +4021,7 @@ void func_800621BC(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 if (phi_t0 == 0) { if ((arg1 == 0) && ((player->particles[30 + arg2].timer > 0) || (player->particles[30 + arg2].IsAlive == 0))) { set_particle_position_and_rotation(player, &player->particles[30 + arg1], 0.0f, phi_f2, 0.0f, phi_t0, phi_t1); - init_new_particle_player(&player->particles[30 + arg1], 8, 1.0f); + init_particle_player(&player->particles[30 + arg1], 8, 1.0f); set_particle_colour(&player->particles[30 + arg1], 0xFFFF20, 0xFF); player->particles[30 + arg1].rotation = 0; @@ -4043,7 +4043,7 @@ void func_800621BC(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8 new_var2 = player; if (new_var2->particles[30 + arg2].timer > 0) { set_particle_position_and_rotation(new_var2, &new_var2->particles[30 + arg1], 0.0f, phi_f2, 0.0f, phi_t0, phi_t1); - init_new_particle_player(&new_var2->particles[30 + arg1], 8, 1.0f); + init_particle_player(&new_var2->particles[30 + arg1], 8, 1.0f); set_particle_colour(&new_var2->particles[30 + arg1], 0xFFFF20, 0xFF); new_var2->particles[30 + arg1].rotation = 0; if (new_var2->particles[30 + arg1].unk_010 == 1) { @@ -5093,7 +5093,7 @@ void func_800658A0(Player* player, UNUSED s8 playerIndex, s16 arg2, s8 arg3) { } } -void func_80065AB0(Player* player, UNUSED s8 playerIndex, s16 arg2, s8 arg3) { +void render_player_drift_particles(Player* player, UNUSED s8 playerIndex, s16 arg2, s8 arg3) { Vec3f spB4; Vec3s spAC; s32 var_s0; @@ -5146,7 +5146,7 @@ void func_80065AB0(Player* player, UNUSED s8 playerIndex, s16 arg2, s8 arg3) { } } -void func_80065F0C(Player* player, UNUSED s8 playerIndex, s16 arg2, s8 arg3) { +void render_player_ground_particles(Player* player, UNUSED s8 playerIndex, s16 arg2, s8 arg3) { Vec3f spDC; Vec3s spD4; s16 primRed; @@ -5174,12 +5174,12 @@ void func_80065F0C(Player* player, UNUSED s8 playerIndex, s16 arg2, s8 arg3) { primAlpha = player->particles[10 + arg2].alpha; if (player->particles[10 + arg2].unk_040 == 0) { gSPDisplayList(gDisplayListHead++, D_0D008DB8); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D494, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + gDPLoadTextureBlock(gDisplayListHead++, gLoadedGroundDust, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); func_8004B72C(primRed, primGreen, primBlue, envRed, envGreen, envBlue, primAlpha); gSPDisplayList(gDisplayListHead++, D_0D008E48); } else { gSPDisplayList(gDisplayListHead++, D_0D008DB8); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D494, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + gDPLoadTextureBlock(gDisplayListHead++, gLoadedGroundDust, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); func_8004B72C(primRed, primGreen, primBlue, envRed, envGreen, envBlue, primAlpha); gDPSetAlphaCompare(gDisplayListHead++, G_AC_DITHER); gSPDisplayList(gDisplayListHead++, D_0D008E48); @@ -5190,7 +5190,7 @@ void func_80065F0C(Player* player, UNUSED s8 playerIndex, s16 arg2, s8 arg3) { primBlue = player->particles[10 + arg2].blue; gSPDisplayList(gDisplayListHead++, D_0D008C90); gDPSetTextureLUT(gDisplayListHead++, G_TT_NONE); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D498, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 64, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + gDPLoadTextureBlock(gDisplayListHead++, gLoadedGrassParticle, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 64, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); func_8004B35C(primRed, primGreen, primBlue, 0x000000FF); gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2); gSPVertex(gDisplayListHead++, D_800E8C00, 4, 0); @@ -5320,12 +5320,12 @@ void func_80066BAC(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3) { gSPDisplayList(gDisplayListHead++, D_0D008DB8); gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); gDPSetRenderMode(gDisplayListHead++, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4C4, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 64, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureLoadedLightningBolt0, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 64, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, &D_800E8900[0][player->particles[arg2].red], 4, 0); gSPDisplayList(gDisplayListHead++, common_square_plain_render); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4C8, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 64, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureLoadedLightningBolt1, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 64, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, &D_800E8900[1][player->particles[arg2].red], 4, 0); @@ -5334,12 +5334,12 @@ void func_80066BAC(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3) { gSPDisplayList(gDisplayListHead++, D_0D008DB8); gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); gDPSetRenderMode(gDisplayListHead++, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4C8, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 64, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureLoadedLightningBolt1, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 64, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, &D_800E8900[0][player->particles[arg2].red], 4, 0); gSPDisplayList(gDisplayListHead++, common_square_plain_render); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4C4, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 64, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureLoadedLightningBolt0, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 64, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, &D_800E8900[1][player->particles[arg2].red], 4, 0); @@ -5439,12 +5439,12 @@ void render_player_onomatopoeia_whrrrr(Player* player, UNUSED s8 arg1, f32 arg2, gSPClearGeometryMode(gDisplayListHead++, G_CULL_BOTH); gDPLoadTLUT_pal256(gDisplayListHead++, D_800E52D0); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4AC, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureLoadedOnomatopoeiaWhrrrr1, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, D_800E8840, 4, 0); gSPDisplayList(gDisplayListHead++, common_square_plain_render); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4B0, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureLoadedOnomatopoeiaWhrrrr2, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, D_800E8800, 4, 0); @@ -5509,7 +5509,7 @@ void render_music_note(Player* player, s8 arg1, u8* texture, s8 arg3, f32 arg4, } } -void func_80068310(Player* player, UNUSED s8 arg1, UNUSED f32 arg2, s8 arg3, s8 arg4) { +void render_player_onomatopoeia_crash(Player* player, UNUSED s8 arg1, UNUSED f32 arg2, s8 arg3, s8 arg4) { UNUSED s32 stackPadding[16]; // huh? Vec3f sp9C; Vec3s sp94; @@ -5525,12 +5525,12 @@ void func_80068310(Player* player, UNUSED s8 arg1, UNUSED f32 arg2, s8 arg3, s8 gSPDisplayList(gDisplayListHead++, D_0D008C90); gDPLoadTLUT_pal256(gDisplayListHead++, D_800E52D0); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4B4, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureLoadedOnomatopoeiaCrash1, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, D_800E8880, 4, 0); gSPDisplayList(gDisplayListHead++, common_square_plain_render); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4B8, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureLoadedOnomatopoeiaCrash2, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, D_800E88C0, 4, 0); @@ -5555,12 +5555,12 @@ void func_80068724(Player* player, UNUSED s8 arg1, UNUSED f32 arg2, s8 arg3, s8 gSPDisplayList(gDisplayListHead++, D_0D008DB8); gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA); gDPSetRenderMode(gDisplayListHead++, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4C4, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 64, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureLoadedLightningBolt0, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 64, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, D_800E8A00, 4, 0); gSPDisplayList(gDisplayListHead++, common_square_plain_render); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4C8, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 64, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureLoadedLightningBolt1, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 64, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, D_800E8A40, 4, 0); @@ -5609,12 +5609,12 @@ void render_player_onomatopoeia_pomp(Player* player, UNUSED s8 arg1, UNUSED f32 gSPDisplayList(gDisplayListHead++, D_0D008C90); gDPLoadTLUT_pal256(gDisplayListHead++, D_800E52D0); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4A4, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureLoadedOnomatopoeiaPoomp1, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, D_800E8B80, 4, 0); gSPDisplayList(gDisplayListHead++, common_square_plain_render); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D4A8, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, gTextureLoadedOnomatopoeiaPoomp2, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, D_800E8BC0, 4, 0); @@ -5680,7 +5680,7 @@ void func_80069444(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3) { sp6C[2] = 0; func_800652D4(sp74, sp6C, player->size * 1.5); gSPDisplayList(gDisplayListHead++, D_0D008DB8); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D494, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, gLoadedGroundDust, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); // `test` MUST be a u16 @@ -5885,7 +5885,7 @@ void init_balloon(Player* player, f32 arg1, f32 arg2, s8 playerIndex, s8 balloon D_8018D890[playerIndex][balloonIndex] = 0; } -void func_8006A7C0(Player* player, f32 arg1, f32 arg2, s8 playerIndex, s8 balloonIndex) { +void update_player_one_balloon_position(Player* player, f32 arg1, f32 arg2, s8 playerIndex, s8 balloonIndex) { f32 sp80[] = { 9.0f, 10.0f, 9.0f, 8.0f, 10.0f, 9.5f, 9.5f, 11.0f, }; @@ -6089,18 +6089,18 @@ void set_player_balloon_to_gone(UNUSED s32 arg0, s8 playerIndex, s8 balloonIndex } } -void func_8006B9CC(Player* player, s8 playerIndex) { +void update_player_balloons_position(Player* player, s8 playerIndex) { if (gPlayerBalloonStatus[playerIndex][0] != BALLOON_STATUS_GONE) { - func_8006A7C0(player, 0.0f, 0.0f, playerIndex, 0); + update_player_one_balloon_position(player, 0.0f, 0.0f, playerIndex, 0); } if (gPlayerBalloonStatus[playerIndex][1] != BALLOON_STATUS_GONE) { - func_8006A7C0(player, 1.8f, 2.6f, playerIndex, 1); + update_player_one_balloon_position(player, 1.8f, 2.6f, playerIndex, 1); } if (gPlayerBalloonStatus[playerIndex][2] != BALLOON_STATUS_GONE) { - func_8006A7C0(player, -1.8f, 2.6f, playerIndex, 2); + update_player_one_balloon_position(player, -1.8f, 2.6f, playerIndex, 2); } } @@ -6622,10 +6622,10 @@ void func_8006D474(Player* player, s8 playerId, s8 screenId) { case 1: if (gActiveScreenMode == SCREEN_MODE_3P_4P_SPLITSCREEN) { if (screenId == playerId) { - func_80065AB0(player, playerId, var_s2, screenId); + render_player_drift_particles(player, playerId, var_s2, screenId); } } else { - func_80065AB0(player, playerId, var_s2, screenId); + render_player_drift_particles(player, playerId, var_s2, screenId); } break; case 2: @@ -6634,10 +6634,10 @@ void func_8006D474(Player* player, s8 playerId, s8 screenId) { case 5: if (gActiveScreenMode == SCREEN_MODE_3P_4P_SPLITSCREEN) { if (screenId == playerId) { - func_80065F0C(player, playerId, var_s2, screenId); + render_player_ground_particles(player, playerId, var_s2, screenId); } } else { - func_80065F0C(player, playerId, var_s2, screenId); + render_player_ground_particles(player, playerId, var_s2, screenId); } break; case 9: @@ -6704,7 +6704,7 @@ void func_8006DD3C(Player* arg0, s8 arg1, s8 arg2) { if (((arg0->type & 0x4000) == 0x4000) && (arg2 == arg1)) { switch (arg0->particles[20].type) { case 2: - func_80068310(arg0, arg1, arg0->particles[20].scale, arg2, 0); + render_player_onomatopoeia_crash(arg0, arg1, arg0->particles[20].scale, arg2, 0); break; case 3: render_player_onomatopoeia_whrrrr(arg0, arg1, arg0->particles[20].scale, arg2, 0); @@ -6838,7 +6838,7 @@ void func_8006E420(Player* player, s8 playerIndex, s8 arg2) { } if (gModeSelection == BATTLE) { - func_8006B9CC(player, playerIndex); + update_player_balloons_position(player, playerIndex); } } } diff --git a/src/code_80057C60.h b/src/code_80057C60.h index edfd6a581e..690b558bcc 100644 --- a/src/code_80057C60.h +++ b/src/code_80057C60.h @@ -117,9 +117,9 @@ void func_8005D18C(void); void func_8005D1F4(s32); void func_8005D290(void); -void func_8005D6C0(Player*); +void reset_player_particle_pool(Player*); void set_particle_position_and_rotation(Player*, Particle*, f32, f32, f32, s8, s8); -s32 init_new_particle_player(Particle*, s8, f32); +s32 init_particle_player(Particle*, s8, f32); s32 set_particle_colour(Particle*, s32, s16); s32 set_particle_colour_randomly_varried(Particle*, s32, s16); void set_drift_particles(Player*, s16, s32, s8, s8); @@ -193,8 +193,8 @@ void func_800651F4(Player*, s8, s8, s8); void func_800652D4(Vec3f, Vec3s, f32); void func_8006538C(Player*, s8, s16, s8); void func_800658A0(Player*, s8, s16, s8); -void func_80065AB0(Player*, s8, s16, s8); -void func_80065F0C(Player*, s8, s16, s8); +void render_player_drift_particles(Player*, s8, s16, s8); +void render_player_ground_particles(Player*, s8, s16, s8); void func_800664E0(Player*, s8, s16, s8); void func_80066998(Player*, s8, s16, s8); @@ -206,7 +206,7 @@ void render_player_onomatopoeia_whrrrr(Player*, s8, f32, s8, s8); void render_player_speech_bubble(Player*, s8, u8*, s8, f32, s32); void render_music_note(Player*, s8, u8*, s8, f32, s32); -void func_80068310(Player*, s8, f32, s8, s8); +void render_player_onomatopoeia_crash(Player*, s8, f32, s8, s8); void func_80068724(Player*, s8, f32, s8, s8); void render_player_onomatopoeia_boing(Player*, s8, f32, s8, s8); void render_player_onomatopoeia_pomp(Player*, s8, f32, s8, s8); @@ -221,14 +221,14 @@ void func_80069DB8(Player*, s8, s16, s8); void func_8006A01C(Player*, s8, s16, s8); void func_8006A280(Player*, s8, s16, s8); void init_balloon(Player*, f32, f32, s8, s8, s16); -void func_8006A7C0(Player*, f32, f32, s8, s8); +void update_player_one_balloon_position(Player*, f32, f32, s8, s8); void render_battle_balloon(Player*, s8, s16, s8); void init_all_player_balloons(Player*, s8); void clear_all_player_balloons(Player*, s8); void pop_player_balloon(Player*, s8); void set_player_balloon_to_gone(s32, s8, s8); -void func_8006B9CC(Player*, s8); +void update_player_balloons_position(Player*, s8); void render_remaining_battle_balloons(Player*, s8, s8); void render_balloon(Vec3f, f32, s16, s16); @@ -609,27 +609,27 @@ extern u8* D_8018D464; extern u8* D_8018D468; extern u8* D_8018D46C; extern u8* D_8018D470; -extern u8* D_8018D474; +extern u8* gLoadedTextureKartShadow; extern u8* D_8018D478; extern u8* D_8018D480; extern u8* D_8018D484; extern u8* D_8018D488; extern u8* D_8018D48C; extern u8* D_8018D490; -extern u8* D_8018D494; -extern u8* D_8018D498; +extern u8* gLoadedGroundDust; +extern u8* gLoadedGrassParticle; extern u8* D_8018D49C; extern u8* D_8018D4A0; -extern u8* D_8018D4A4; -extern u8* D_8018D4A8; -extern u8* D_8018D4AC; -extern u8* D_8018D4B0; -extern u8* D_8018D4B4; -extern u8* D_8018D4B8; +extern u8* gTextureLoadedOnomatopoeiaPoomp1; +extern u8* gTextureLoadedOnomatopoeiaPoomp2; +extern u8* gTextureLoadedOnomatopoeiaWhrrrr1; +extern u8* gTextureLoadedOnomatopoeiaWhrrrr2; +extern u8* gTextureLoadedOnomatopoeiaCrash1; +extern u8* gTextureLoadedOnomatopoeiaCrash2; extern u8* D_8018D4BC; extern u8* D_8018D4C0; -extern u8* D_8018D4C4; -extern u8* D_8018D4C8; +extern u8* gTextureLoadedLightningBolt0; +extern u8* gTextureLoadedLightningBolt1; extern Vec3f gPlayerBalloonPosX[]; extern Vec3f gPlayerBalloonPosY[]; extern Vec3f gPlayerBalloonPosZ[]; diff --git a/src/code_80057C60_var.c b/src/code_80057C60_var.c index 7052d494c5..72ace331af 100644 --- a/src/code_80057C60_var.c +++ b/src/code_80057C60_var.c @@ -191,7 +191,7 @@ u8* D_8018D464; u8* D_8018D468; u8* D_8018D46C; u8* D_8018D470; -u8* D_8018D474; +u8* gLoadedTextureKartShadow; u8* D_8018D478; UNUSED u8* D_8018D47C; u8* D_8018D480; @@ -199,20 +199,20 @@ u8* D_8018D484; u8* D_8018D488; u8* D_8018D48C; u8* D_8018D490; -u8* D_8018D494; -u8* D_8018D498; +u8* gLoadedGroundDust; +u8* gLoadedGrassParticle; u8* D_8018D49C; u8* D_8018D4A0; -u8* D_8018D4A4; -u8* D_8018D4A8; -u8* D_8018D4AC; -u8* D_8018D4B0; -u8* D_8018D4B4; -u8* D_8018D4B8; +u8* gTextureLoadedOnomatopoeiaPoomp1; +u8* gTextureLoadedOnomatopoeiaPoomp2; +u8* gTextureLoadedOnomatopoeiaWhrrrr1; +u8* gTextureLoadedOnomatopoeiaWhrrrr2; +u8* gTextureLoadedOnomatopoeiaCrash1; +u8* gTextureLoadedOnomatopoeiaCrash2; u8* D_8018D4BC; u8* D_8018D4C0; -u8* D_8018D4C4; -u8* D_8018D4C8; +u8* gTextureLoadedLightningBolt0; +u8* gTextureLoadedLightningBolt1; Vec3f gPlayerBalloonPosX[8]; Vec3f gPlayerBalloonPosY[8]; Vec3f gPlayerBalloonPosZ[8]; diff --git a/src/code_8006E9C0.c b/src/code_8006E9C0.c index 7581852bd9..c33c397ad9 100644 --- a/src/code_8006E9C0.c +++ b/src/code_8006E9C0.c @@ -131,7 +131,7 @@ u8* dma_copy_base_misc_textures(u8* devAddr, u8* baseAddress, u32 size, u32 offs void load_mario_kart_64_logo(void) { gGameLogoAddress = - dma_copy_base_misc_textures((u8*) &gTextureLogoMarioKart64, (u8*) gMenuTextureBuffer, 0x79E1, 0x20000); + dma_copy_base_misc_textures((u8*) &logo_mario_kart_64, (u8*) gMenuTextureBuffer, 0x79E1, 0x20000); } // Some kind of initalization for the Item Window part of the HUD diff --git a/src/cpu_vehicles_camera_path.c b/src/cpu_vehicles_camera_path.c index 02673fa0b3..6abe997cd9 100644 --- a/src/cpu_vehicles_camera_path.c +++ b/src/cpu_vehicles_camera_path.c @@ -88,7 +88,7 @@ u16 D_801631F8[10]; f32 gCurrentCpuTargetSpeed; f32 gPreviousCpuTargetSpeed[10]; s32 D_80163238; -u16 D_80163240[12]; +u16 gCrossedFinishLine[12]; u16 gWrongDirectionCounter[12]; u16 gIsPlayerWrongDirection[12]; s32 gPreviousLapProgressScore[10]; @@ -154,7 +154,7 @@ s16 D_80164358; s16 D_8016435A; s16 D_8016435C; s16 gGPCurrentRacePlayerIdByRank[12]; // D_80164360 -s16 D_80164378[12]; +s16 gPrevPlayerIdByRank[12]; s32 gLapCountByPlayerId[10]; // D_80164390 s32 gGPCurrentRaceRankByPlayerId[10]; // D_801643B8 s32 gPreviousGPCurrentRaceRankByPlayerId[10]; @@ -777,7 +777,7 @@ void set_places(void){ gGPCurrentRaceRankByPlayerId[bestPlayerIdx] = rankIdx; gGPCurrentRacePlayerIdByRank[rankIdx] = bestPlayerIdx; - D_80164378[rankIdx] = gGPCurrentRacePlayerIdByRank[rankIdx]; + gPrevPlayerIdByRank[rankIdx] = gGPCurrentRacePlayerIdByRank[rankIdx]; gGPCurrentRaceRankByPlayerIdDup[rankIdx] = bestPlayerIdx; // I am 90% sure this is unnecessary because gCourseCompletionPercentByRank is always reset when it is called, // but I'm keeping it out of abundence of caution to be consistent with the old version of set_places @@ -984,7 +984,7 @@ bool func_800088D8(s32 playerId, s16 arg1, s16 arg2) { if (arg2 == 0) { if (gDemoMode == 1) { STEMP_V0 = gNumPathPointsTraversed[playerId]; - STEMP_V1 = gNumPathPointsTraversed[D_80164378[7]]; + STEMP_V1 = gNumPathPointsTraversed[gPrevPlayerIdByRank[7]]; progress = STEMP_V0 - STEMP_V1; if (progress < 0) { progress = -progress; @@ -1010,7 +1010,7 @@ bool func_800088D8(s32 playerId, s16 arg1, s16 arg2) { rank = gGPCurrentRaceRankByPlayerId[gBestRankedHumanPlayer]; if (((((gPathCountByPathIndex[0] * 2) / 3)) < progress) && ((rank) >= 6)) { STEMP_V0 = gNumPathPointsTraversed[playerId]; - STEMP_V1 = temp = gNumPathPointsTraversed[D_80164378[rank - 1]]; + STEMP_V1 = temp = gNumPathPointsTraversed[gPrevPlayerIdByRank[rank - 1]]; progress = STEMP_V0 - STEMP_V1; } if (progress < 0) { @@ -1194,7 +1194,7 @@ void update_cpu_path_completion(s32 playerId, Player* player) { * Helps calculate time since player last touched finishline. * Assumes constant z-speed and subtracts portion of frame where the finish line was already crossed **/ -f32 func_80009258(UNUSED s32 playerId, f32 previousPlayerZ, f32 playerZ) { +f32 time_crossed_finish_line(UNUSED s32 playerId, f32 previousPlayerZ, f32 playerZ) { f32 z_change_after_cross = gPathStartZ - playerZ; f32 z_change_before_cross = previousPlayerZ - gPathStartZ; return gCourseTimer - ((COURSE_TIMER_ITER_f * z_change_after_cross) / (z_change_after_cross + z_change_before_cross)); @@ -1213,7 +1213,7 @@ void update_player_path_completion(s32 playerId, Player* player) { playerZ = player->pos[2]; previousPlayerZ = gPreviousPlayerZ[playerId]; gIsPlayerNewPathPoint = false; - D_80163240[playerId] = 0; + gCrossedFinishLine[playerId] = 0; sSomeNearestPathPoint = update_player_path(playerX, playerY, playerZ, gNearestPathPointByPlayerId[playerId], player, playerId, gPlayerPathIndex); gCurrentNearestPathPoint = sSomeNearestPathPoint; @@ -1264,7 +1264,7 @@ void update_player_path_completion(s32 playerId, Player* player) { gLapCountByPlayerId[playerId]++; if ((gLapCountByPlayerId[playerId] == 3) && !gFinished[playerId]){ gFinished[playerId] = true; - gFinishTime[playerId] = func_80009258(playerId, previousPlayerZ, playerZ); + gFinishTime[playerId] = time_crossed_finish_line(playerId, previousPlayerZ, playerZ); } if ((gModeSelection == GRAND_PRIX) && (gLapCountByPlayerId[playerId] == 5)) { if (gGPCurrentRaceRankByPlayerIdDup[playerId] == 7) { @@ -1273,12 +1273,12 @@ void update_player_path_completion(s32 playerId, Player* player) { // clang-format on } } - D_80163240[playerId] = 1; + gCrossedFinishLine[playerId] = 1; update_player_completion(playerId); reset_cpu_behaviour(playerId); cpu_ItemStrategy[playerId].numItemUse = 0; if ((D_8016348C == 0) && !(player->type & PLAYER_CINEMATIC_MODE)) { - gTimePlayerLastTouchedFinishLine[playerId] = func_80009258(playerId, previousPlayerZ, playerZ); + gTimePlayerLastTouchedFinishLine[playerId] = time_crossed_finish_line(playerId, previousPlayerZ, playerZ); } } } @@ -2116,7 +2116,7 @@ void init_players(void) { } temp_v0_3 = gGPCurrentRaceRankByPlayerId[i]; gGPCurrentRacePlayerIdByRank[temp_v0_3] = (s16) i; - D_80164378[temp_v0_3] = (s16) i; + gPrevPlayerIdByRank[temp_v0_3] = (s16) i; gGPCurrentRaceRankByPlayerIdDup[i] = temp_v0_3; gWrongDirectionCounter[i] = 0; gIsPlayerWrongDirection[i] = 0; diff --git a/src/cpu_vehicles_camera_path.h b/src/cpu_vehicles_camera_path.h index ae46283e80..7b6fba533b 100644 --- a/src/cpu_vehicles_camera_path.h +++ b/src/cpu_vehicles_camera_path.h @@ -115,7 +115,7 @@ void update_player_completion(s32); void yoshi_valley_cpu_path(s32); void update_cpu_path_completion(s32, Player*); -f32 func_80009258(s32, f32, f32); +f32 time_crossed_finish_line(s32, f32, f32); void update_player_path_completion(s32, Player*); void update_vehicles(void); void play_cpu_sound_effect(s32, Player*); @@ -323,7 +323,7 @@ extern u16 D_801631F8[]; extern f32 gCurrentCpuTargetSpeed; extern f32 gPreviousCpuTargetSpeed[]; extern s32 D_80163238; -extern u16 D_80163240[]; +extern u16 gCrossedFinishLine[]; extern u16 gWrongDirectionCounter[]; extern u16 gIsPlayerWrongDirection[]; extern s32 gPreviousLapProgressScore[]; @@ -383,7 +383,7 @@ extern s16 D_80164358; extern s16 D_8016435A; extern s16 D_8016435C; extern s16 gGPCurrentRacePlayerIdByRank[]; // D_80164360 -extern s16 D_80164378[]; +extern s16 gPrevPlayerIdByRank[]; extern s32 gLapCountByPlayerId[]; // D_80164390 extern s32 gGPCurrentRaceRankByPlayerId[]; // D_801643B8 extern s32 gPreviousGPCurrentRaceRankByPlayerId[]; diff --git a/src/data/some_data.c b/src/data/some_data.c index 88bff8bf63..d12f89323e 100644 --- a/src/data/some_data.c +++ b/src/data/some_data.c @@ -186,13 +186,13 @@ u8 D_800E52D0[] = { }; u8* gCourseOutlineTextures[] = { - gTextureCourseOutlineMarioRaceway, gTextureCourseOutlineChocoMountain, gTextureCourseOutlineBowsersCastle, - gTextureCourseOutlineBansheeBoardwalk, gTextureCourseOutlineYoshiValley, gTextureCourseOutlineFrappeSnowland, - gTextureCourseOutlineKoopaTroopaBeach, gTextureCourseOutlineRoyalRaceway, gTextureCourseOutlineLuigiRaceway, - gTextureCourseOutlineMooMooFarm, gTextureCourseOutlineToadsTurnpike, gTextureCourseOutlineKalimariDesert, - gTextureCourseOutlineSherbetLand, gTextureCourseOutlineRainbowRoad, gTextureCourseOutlineWarioStadium, - gTextureCourseOutlineBlockFort, gTextureCourseOutlineSkyscraper, gTextureCourseOutlineDoubleDeck, - gTextureCourseOutlineDksJungleParkway, gTextureCourseOutlineBigDonut, + minimap_mario_raceway, minimap_choco_mountain, minimap_bowsers_castle, + minimap_banshee_boardwalk, minimap_yoshi_valley, minimap_frappe_snowland, + minimap_koopa_troopa_beach, minimap_royal_raceway, minimap_luigi_raceway, + minimap_moo_moo_farm, minimap_toads_turnpike, minimap_kalimari_desert, + minimap_sherbet_land, minimap_rainbow_road, minimap_wario_stadium, + minimap_block_fort, minimap_skyscraper, minimap_double_deck, + minimap_dks_jungle_parkway, minimap_big_donut, }; s16 D_800E5520[] = { diff --git a/src/data/textures.c b/src/data/textures.c index 76d6409702..03d632c377 100644 --- a/src/data/textures.c +++ b/src/data/textures.c @@ -2045,7 +2045,7 @@ MkAnimation D_0200210C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200211C[2] = { +MenuTexture seg2_textureFontLetterA[2] = { { 5, gTexture7F2094, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2054,7 +2054,7 @@ MenuTexture D_0200211C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002144[2] = { +MenuTexture seg2_textureFontLetterB[2] = { { 5, gTexture7F2164, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2063,7 +2063,7 @@ MenuTexture D_02002144[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200216C[2] = { +MenuTexture seg2_textureFontLetterC[2] = { { 5, gTexture7F2234, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2072,7 +2072,7 @@ MenuTexture D_0200216C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002194[2] = { +MenuTexture seg2_textureFontLetterD[2] = { { 5, gTexture7F2304, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2081,7 +2081,7 @@ MenuTexture D_02002194[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020021BC[2] = { +MenuTexture seg2_textureFontLetterE[2] = { { 5, gTexture7F23D4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2090,7 +2090,7 @@ MenuTexture D_020021BC[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020021E4[2] = { +MenuTexture seg2_textureFontLetterF[2] = { { 5, gTexture7F24A4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2099,7 +2099,7 @@ MenuTexture D_020021E4[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200220C[2] = { +MenuTexture seg2_textureFontLetterG[2] = { { 5, gTexture7F2574, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2108,7 +2108,7 @@ MenuTexture D_0200220C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002234[2] = { +MenuTexture seg2_textureFontLetterH[2] = { { 5, gTexture7F2644, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2117,7 +2117,7 @@ MenuTexture D_02002234[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200225C[2] = { +MenuTexture seg2_textureFontLetterI[2] = { { 5, gTexture7F2714, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2126,7 +2126,7 @@ MenuTexture D_0200225C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002284[2] = { +MenuTexture seg2_textureFontLetterJ[2] = { { 5, gTexture7F27E4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2135,7 +2135,7 @@ MenuTexture D_02002284[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020022AC[2] = { +MenuTexture seg2_textureFontLetterK[2] = { { 5, gTexture7F28B4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2144,7 +2144,7 @@ MenuTexture D_020022AC[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020022D4[2] = { +MenuTexture seg2_textureFontLetterL[2] = { { 5, gTexture7F2984, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2153,7 +2153,7 @@ MenuTexture D_020022D4[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020022FC[2] = { +MenuTexture seg2_textureFontLetterM[2] = { { 5, gTexture7F2A54, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2162,7 +2162,7 @@ MenuTexture D_020022FC[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002324[2] = { +MenuTexture seg2_textureFontLetterN[2] = { { 5, gTexture7F2B24, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2171,7 +2171,7 @@ MenuTexture D_02002324[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200234C[2] = { +MenuTexture seg2_textureFontLetterO[2] = { { 5, gTexture7F2BF4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2180,7 +2180,7 @@ MenuTexture D_0200234C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002374[2] = { +MenuTexture seg2_textureFontLetterP[2] = { { 5, gTexture7F2CC4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2189,7 +2189,7 @@ MenuTexture D_02002374[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200239C[2] = { +MenuTexture seg2_textureFontLetterQ[2] = { { 5, gTexture7F2D94, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2198,7 +2198,7 @@ MenuTexture D_0200239C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020023C4[2] = { +MenuTexture seg2_textureFontLetterR[2] = { { 5, gTexture7F2E64, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2207,7 +2207,7 @@ MenuTexture D_020023C4[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020023EC[2] = { +MenuTexture seg2_textureFontLetterS[2] = { { 5, gTexture7F2F34, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2216,7 +2216,7 @@ MenuTexture D_020023EC[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002414[2] = { +MenuTexture seg2_textureFontLetterT[2] = { { 5, gTexture7F3004, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2225,7 +2225,7 @@ MenuTexture D_02002414[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200243C[2] = { +MenuTexture seg2_textureFontLetterU[2] = { { 5, gTexture7F30D4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2234,7 +2234,7 @@ MenuTexture D_0200243C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002464[2] = { +MenuTexture seg2_textureFontLetterV[2] = { { 5, gTexture7F31A4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2243,7 +2243,7 @@ MenuTexture D_02002464[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200248C[2] = { +MenuTexture seg2_textureFontLetterW[2] = { { 5, gTexture7F3274, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2252,7 +2252,7 @@ MenuTexture D_0200248C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020024B4[2] = { +MenuTexture seg2_textureFontLetterX[2] = { { 5, gTexture7F3344, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2261,7 +2261,7 @@ MenuTexture D_020024B4[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020024DC[2] = { +MenuTexture seg2_textureFontLetterY[2] = { { 5, gTexture7F3414, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2270,7 +2270,7 @@ MenuTexture D_020024DC[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002504[2] = { +MenuTexture seg2_textureFontLetterZ[2] = { { 5, gTexture7F34E4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2279,7 +2279,7 @@ MenuTexture D_02002504[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200252C[2] = { +MenuTexture seg2_textureFontExclamationMark[2] = { { 5, gTexture7F1394, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2288,7 +2288,7 @@ MenuTexture D_0200252C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002554[2] = { +MenuTexture seg2_textureFontMinus[2] = { { 5, gTexture7F1464, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2297,7 +2297,7 @@ MenuTexture D_02002554[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200257C[2] = { +MenuTexture seg2_textureFontInterogationMark[2] = { { 5, gTexture7F16D4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2306,7 +2306,7 @@ MenuTexture D_0200257C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020025A4[2] = { +MenuTexture seg2_textureFontSimpleQuote[2] = { { 5, gTexture7F17A4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2315,7 +2315,7 @@ MenuTexture D_020025A4[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020025CC[2] = { +MenuTexture seg2_textureFontDoubleQuote[2] = { { 5, gTexture7F12C4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2324,7 +2324,7 @@ MenuTexture D_020025CC[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020025F4[2] = { +MenuTexture seg2_textureFontPlus[2] = { { 5, gTexture7F1604, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2333,7 +2333,7 @@ MenuTexture D_020025F4[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200261C[2] = { +MenuTexture seg2_textureFontDot[2] = { { 5, gTexture7F1534, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2342,7 +2342,7 @@ MenuTexture D_0200261C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002644[2] = { +MenuTexture seg2_textureFontFourDote[2] = { { 5, gTexture7F1124, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2351,7 +2351,7 @@ MenuTexture D_02002644[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200266C[2] = { +MenuTexture seg2_textureFontCC[2] = { { 5, gTexture7F11F4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2360,7 +2360,7 @@ MenuTexture D_0200266C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002694[2] = { +MenuTexture seg2_textureFontNumberZero[2] = { { 5, gTexture7F1874, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2369,7 +2369,7 @@ MenuTexture D_02002694[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020026BC[2] = { +MenuTexture seg2_textureFontNumberOne[2] = { { 5, gTexture7F1944, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2378,7 +2378,7 @@ MenuTexture D_020026BC[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020026E4[2] = { +MenuTexture seg2_textureFontNumberTwo[2] = { { 5, gTexture7F1A14, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2387,7 +2387,7 @@ MenuTexture D_020026E4[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200270C[2] = { +MenuTexture seg2_textureFontNumberThree[2] = { { 5, gTexture7F1AE4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2396,7 +2396,7 @@ MenuTexture D_0200270C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002734[2] = { +MenuTexture seg2_textureFontNumberFour[2] = { { 5, gTexture7F1BB4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2405,7 +2405,7 @@ MenuTexture D_02002734[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_0200275C[2] = { +MenuTexture seg2_textureFontNumberFive[2] = { { 5, gTexture7F1C84, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2414,7 +2414,7 @@ MenuTexture D_0200275C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02002784[2] = { +MenuTexture seg2_textureFontNumberSix[2] = { { 5, gTexture7F1D54, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2423,7 +2423,7 @@ MenuTexture D_02002784[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020027AC[2] = { +MenuTexture seg2_textureFontNumberSeven[2] = { { 5, gTexture7F1E24, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2432,7 +2432,7 @@ MenuTexture D_020027AC[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020027D4[2] = { +MenuTexture seg2_textureFontNumberEight[2] = { { 5, gTexture7F1EF4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -2441,7 +2441,7 @@ MenuTexture D_020027D4[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_020027FC[2] = { +MenuTexture seg2_textureFontNumberNine[2] = { { 5, gTexture7F1FC4, 26, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -4071,7 +4071,7 @@ MenuTexture D_0200441C[2] = { * */ MenuTexture D_02004444[2] = { - { 5, gTexture7FA044, 16, 16, 0, 0, 0x0, 0 }, + { 5, font_apostrophe, 16, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -4124,8 +4124,8 @@ MenuTexture D_0200450C[2] = { * @brief unknown MenuTexture * */ -MenuTexture D_02004534[2] = { - { 5, gTexture7FA334, 16, 16, 0, 0, 0x0, 0 }, +MenuTexture seg2_textureFontComma[2] = { + { 5, font_comma, 16, 16, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -4142,7 +4142,7 @@ MenuTexture D_0200455C[2] = { * @brief unknown empty MenuTexture * */ -MenuTexture D_02004584[1] = { +MenuTexture seg2_textureFontEmpty[1] = { { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -4250,7 +4250,7 @@ MenuTexture seg2_menu_4p_column[4] = { * */ MenuTexture D_020047DC[2] = { - { 1, gTextureSmallGreenTriangle, 12, 7, 27, 56, 0x0, 0 }, + { 1, texture_small_green_triangle, 12, 7, 27, 56, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -4259,7 +4259,7 @@ MenuTexture D_020047DC[2] = { * */ MenuTexture D_02004804[2] = { - { 1, gTextureSmallGreenTriangle, 12, 7, 27, 56, 0x0, 0 }, + { 1, texture_small_green_triangle, 12, 7, 27, 56, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -4268,7 +4268,7 @@ MenuTexture D_02004804[2] = { * */ MenuTexture D_0200482C[2] = { - { 1, gTextureSmallGreenTriangle, 12, 7, 27, 56, 0x0, 0 }, + { 1, texture_small_green_triangle, 12, 7, 27, 56, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -4277,7 +4277,7 @@ MenuTexture D_0200482C[2] = { * */ MenuTexture D_02004854[2] = { - { 1, gTextureSmallGreenTriangle, 12, 7, 27, 56, 0x0, 0 }, + { 1, texture_small_green_triangle, 12, 7, 27, 56, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; @@ -4303,7 +4303,7 @@ MenuTexture D_020048A4[2] = { * @brief MenuTexture for Menu R Option * */ -MenuTexture D_020048CC[2] = { +MenuTexture seg2_textureMenuRData[2] = { { 1, gTextureMenuRData, 58, 19, 0, 0, 0x0, 0 }, { 0, NULL, 0, 0, 0, 0, 0, 0 }, }; diff --git a/src/effects.c b/src/effects.c index a92bd6db79..9ef102c10d 100644 --- a/src/effects.c +++ b/src/effects.c @@ -154,13 +154,13 @@ void clean_effect(Player* player, s8 playerIndex) { if (((player->effects & BANANA_SPINOUT_EFFECT) == BANANA_SPINOUT_EFFECT) || (player->effects & DRIVING_SPINOUT_EFFECT) == DRIVING_SPINOUT_EFFECT) { - func_8008C8C4(player, playerIndex); + remove_spinout_effects(player, playerIndex); } if ((player->effects & BANANA_NEAR_SPINOUT_EFFECT) == BANANA_NEAR_SPINOUT_EFFECT) { - func_8008D0E4(player, playerIndex); + remove_banana_near_spinout_effect(player, playerIndex); } if ((player->unk_044 & 0x4000) != 0) { - func_8008D3B0(player, playerIndex); + remove_driving_near_spinout_effect(player, playerIndex); } if ((player->effects & MUSHROOM_EFFECT) == MUSHROOM_EFFECT) { remove_mushroom_effect(player); @@ -261,7 +261,7 @@ void func_8008C6D0(Player* player, s8 playerIndex) { player->unk_042 = 0; } -void func_8008C73C(Player* player, s8 playerIndex) { +void add_spinout_effect(Player* player, s8 playerIndex) { clean_effect(player, playerIndex); if (((player->effects & BANANA_SPINOUT_EFFECT) != BANANA_SPINOUT_EFFECT) && ((player->effects & DRIVING_SPINOUT_EFFECT) != DRIVING_SPINOUT_EFFECT)) { @@ -297,7 +297,7 @@ void func_8008C73C(Player* player, s8 playerIndex) { } } -void func_8008C8C4(Player* player, s8 playerId) { +void remove_spinout_effects(Player* player, s8 playerId) { player->effects &= ~BANANA_SPINOUT_EFFECT; player->effects &= ~DRIVING_SPINOUT_EFFECT; player->unk_0A8 = 0; @@ -351,7 +351,7 @@ void func_8008C9EC(Player* player, s8 playerIndex) { if (gModeSelection == BATTLE) { pop_player_balloon(player, playerIndex); } - func_8008C8C4(player, playerIndex); + remove_spinout_effects(player, playerIndex); } } } else { @@ -361,7 +361,7 @@ void func_8008C9EC(Player* player, s8 playerIndex) { if (stackPadding2 == 0) { player->unk_0B2--; if (player->unk_0B2 <= 0) { - func_8008C8C4(player, playerIndex); + remove_spinout_effects(player, playerIndex); if (gModeSelection == BATTLE) { pop_player_balloon(player, playerIndex); } @@ -376,7 +376,7 @@ void func_8008C9EC(Player* player, s8 playerIndex) { } } -void func_8008CDC0(Player* player, s8 playerIndex) { +void trigger_hit_banana(Player* player, s8 playerIndex) { clean_effect(player, playerIndex); player->triggers &= ~HIT_BANANA_TRIGGER; @@ -388,13 +388,13 @@ void func_8008CDC0(Player* player, s8 playerIndex) { if (((player->unk_07C >> 0x10) >= 0x14) || ((player->unk_07C >> 0x10) < -0x13) || (((player->speed / 18.0f) * 216.0f) <= 30.0f) || ((player->effects & MIDAIR_EFFECT) != 0) || (((player->type & PLAYER_HUMAN) == 0) && ((player->effects & LOST_RACE_EFFECT) == 0))) { - func_8008C73C(player, playerIndex); + add_spinout_effect(player, playerIndex); } else { player->effects |= BANANA_NEAR_SPINOUT_EFFECT; } } -void func_8008CEB0(Player* player, s8 playerIndex) { +void apply_banana_near_spinout_effect(Player* player, s8 playerIndex) { f32 var_f0; s16 var_v1; s16 var_a3; @@ -415,7 +415,7 @@ void func_8008CEB0(Player* player, s8 playerIndex) { if (var_f0 <= 1.0f) { player->effects &= ~BANANA_NEAR_SPINOUT_EFFECT; if ((player->effects & BANANA_SPINOUT_SAVE_EFFECT) != BANANA_SPINOUT_SAVE_EFFECT) { - func_8008C73C(player, playerIndex); + add_spinout_effect(player, playerIndex); var_v1 = 0; } else { player->unk_0B6 |= 0x20; @@ -439,16 +439,16 @@ void func_8008CEB0(Player* player, s8 playerIndex) { player->unk_0B4 = var_v1; player->unk_0AC = var_a3; if (player->effects & MIDAIR_EFFECT) { - func_8008C73C(player, playerIndex); + add_spinout_effect(player, playerIndex); player->effects &= ~BANANA_NEAR_SPINOUT_EFFECT; } } -void func_8008D0E4(Player* player, UNUSED s8 playerIndex) { +void remove_banana_near_spinout_effect(Player* player, UNUSED s8 playerIndex) { player->effects &= ~BANANA_NEAR_SPINOUT_EFFECT; } -void func_8008D0FC(Player* player, s8 playerIndex) { +void trigger_driving_spinout(Player* player, s8 playerIndex) { clean_effect(player, playerIndex); player->triggers &= ~DRIVING_SPINOUT_TRIGGER; @@ -459,7 +459,7 @@ void func_8008D0FC(Player* player, s8 playerIndex) { player->unk_044 |= 0x4000; } -void func_8008D170(Player* player, s8 playerIndex) { +void apply_driving_near_spinout_effect(Player* player, s8 playerIndex) { f32 var_f0; s16 var_v1; s16 var_a3; @@ -480,7 +480,7 @@ void func_8008D170(Player* player, s8 playerIndex) { if (var_f0 <= 1.3) { player->unk_044 &= ~0x4000; if ((player->effects & BANANA_SPINOUT_SAVE_EFFECT) != BANANA_SPINOUT_SAVE_EFFECT) { - func_8008C73C(player, playerIndex); + add_spinout_effect(player, playerIndex); var_v1 = 0; } else { player->unk_0B6 |= 0x20; @@ -504,12 +504,12 @@ void func_8008D170(Player* player, s8 playerIndex) { player->unk_0B4 = var_v1; player->unk_0AC = var_a3; if (player->effects & MIDAIR_EFFECT) { - func_8008C73C(player, playerIndex); + add_spinout_effect(player, playerIndex); player->unk_044 &= ~0x4000; } } -void func_8008D3B0(Player* player, UNUSED s8 playerIndex) { +void remove_driving_near_spinout_effect(Player* player, UNUSED s8 playerIndex) { player->unk_044 &= 0xBFFF; } diff --git a/src/effects.h b/src/effects.h index 5649359d5d..dfae0fc7c8 100644 --- a/src/effects.h +++ b/src/effects.h @@ -50,15 +50,15 @@ void clean_effect(Player*, s8); void func_8008C528(Player*, s8); void func_8008C62C(Player*, s8); void func_8008C6D0(Player*, s8); -void func_8008C73C(Player*, s8); -void func_8008C8C4(Player*, s8); +void add_spinout_effect(Player*, s8); +void remove_spinout_effects(Player*, s8); void func_8008C9EC(Player*, s8); -void func_8008CDC0(Player*, s8); -void func_8008CEB0(Player*, s8); -void func_8008D0E4(Player*, s8); -void func_8008D0FC(Player*, s8); -void func_8008D170(Player*, s8); -void func_8008D3B0(Player*, s8); +void trigger_hit_banana(Player*, s8); +void apply_banana_near_spinout_effect(Player*, s8); +void remove_banana_near_spinout_effect(Player*, s8); +void trigger_driving_spinout(Player*, s8); +void apply_driving_near_spinout_effect(Player*, s8); +void remove_driving_near_spinout_effect(Player*, s8); void trigger_shroom(Player*, s8); void apply_mushroom_effect(Player*); void remove_mushroom_effect(Player*); diff --git a/src/main.c b/src/main.c index d322e93871..a7254ce591 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,5 @@ #ifndef GCC -#define D_800DC510_AS_U16 +#define gRaceState_AS_U16 #endif #include #include @@ -166,8 +166,8 @@ OSMesg gPIMesgBuf[32]; OSMesgQueue gPIMesgQueue; s32 gGamestate = 0xFFFF; -// D_800DC510 is externed as an s32 in other files. D_800DC514 is only used in main.c, likely a developer mistake. -u16 D_800DC510 = 0; +// gRaceState is externed as an s32 in other files. D_800DC514 is only used in main.c, likely a developer mistake. +u16 gRaceState = 0; u16 D_800DC514 = 0; u16 creditsRenderMode = 0; // Renders the whole track. Displays red if used in normal race mode. u16 gDemoMode = DEMO_MODE_INACTIVE; @@ -1279,10 +1279,10 @@ void thread5_game_loop(UNUSED void* arg) { set_vblank_handler(2, &gGameVblankHandler, &gGameVblankQueue, (OSMesg) OS_EVENT_SW2); // These variables track stats such as player wins. // In the event of a console reset, it remembers them. - gNmiUnknown1 = &pAppNmiBuffer[0]; // 2 u8's, tracks number of times player 1/2 won a VS race - gNmiUnknown2 = + nmi_gVersusResults2P = &pAppNmiBuffer[0]; // 2 u8's, tracks number of times player 1/2 won a VS race + nmi_gVersusResults3P = &pAppNmiBuffer[2]; // 9 u8's, 3x3, tracks number of times player 1/2/3 has placed in 1st/2nd/3rd in a VS race - gNmiUnknown3 = &pAppNmiBuffer[11]; // 12 u8's, 4x3, tracks number of times player 1/2/3/4 has placed in 1st/2nd/3rd + nmi_gVersusResults4P = &pAppNmiBuffer[11]; // 12 u8's, 4x3, tracks number of times player 1/2/3/4 has placed in 1st/2nd/3rd // in a VS race gNmiUnknown4 = &pAppNmiBuffer[23]; // 2 u8's, tracking number of Battle mode wins by player 1/2 gNmiUnknown5 = &pAppNmiBuffer[25]; // 3 u8's, tracking number of Battle mode wins by player 1/2/3 diff --git a/src/main.h b/src/main.h index 0d8ea8d9a2..dbe8b6339e 100644 --- a/src/main.h +++ b/src/main.h @@ -199,13 +199,13 @@ extern OSMesg gPIMesgBuf[]; extern OSMesgQueue gPIMesgQueue; void race_logic_loop(void); extern s32 gGamestate; -#ifndef D_800DC510_AS_U16 +#ifndef gRaceState_AS_U16 // Prevent overlapping writes in gcc -// Whether D_800DC510 was intended to be a separate variable in main.c from the rest of the game is unknown +// Whether gRaceState was intended to be a separate variable in main.c from the rest of the game is unknown #ifdef GCC -extern u16 D_800DC510; +extern u16 gRaceState; #else -extern s32 D_800DC510; +extern s32 gRaceState; #endif #endif diff --git a/src/menu_items.c b/src/menu_items.c index 7e4ed388d1..833ed5bf73 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -70,9 +70,9 @@ Gfx* sGfxPtr; s32 gNumD_8018E768Entries; struct_8018E768_entry D_8018E768[D_8018E768_SIZE]; s32 gCycleFlashMenu; -s8 D_8018E7AC[5]; -u32 D_8018E7B8[5]; -u32 D_8018E7D0[4]; +s8 gTransitionType[5]; +u32 gTransitionDuration[5]; +u32 gCurrentTransitionTime[4]; s32 D_8018E7E0; struct UnkStruct_8018E7E8 D_8018E7E8[D_8018E7E8_SIZE]; struct UnkStruct_8018E7E8 D_8018E810[D_8018E810_SIZE]; @@ -284,7 +284,7 @@ RGBA16 D_800E74D0[] = { { 0xff, 0xff, 0x00, 0xff }, }; -RGBA16 D_800E74E8[] = { +RGBA16 gBackgroundColor[] = { { 0xff, 0xaf, 0xaf, 0xff }, { 0xaf, 0xff, 0xaf, 0xff }, { 0xaf, 0xaf, 0xff, 0xff }, @@ -879,12 +879,12 @@ MkAnimation* D_800E7E34[] = { }; MenuTexture* gGlyphTextureLUT[] = { - D_0200211C, D_02002144, D_0200216C, D_02002194, D_020021BC, D_020021E4, D_0200220C, D_02002234, D_0200225C, - D_02002284, D_020022AC, D_020022D4, D_020022FC, D_02002324, D_0200234C, D_02002374, D_0200239C, D_020023C4, - D_020023EC, D_02002414, D_0200243C, D_02002464, D_0200248C, D_020024B4, D_020024DC, D_02002504, D_0200252C, - D_02002554, D_0200257C, D_020025A4, D_02004584, D_0200261C, D_02002694, D_020026BC, D_020026E4, D_0200270C, - D_02002734, D_0200275C, D_02002784, D_020027AC, D_020027D4, D_020027FC, D_020025CC, D_02002644, D_020025F4, - D_0200266C, D_02004534, D_02004584, D_02002824, D_0200284C, D_02002874, D_0200289C, D_020028C4, D_020028EC, + seg2_textureFontLetterA, seg2_textureFontLetterB, seg2_textureFontLetterC, seg2_textureFontLetterD, seg2_textureFontLetterE, seg2_textureFontLetterF, seg2_textureFontLetterG, seg2_textureFontLetterH, seg2_textureFontLetterI, + seg2_textureFontLetterJ, seg2_textureFontLetterK, seg2_textureFontLetterL, seg2_textureFontLetterM, seg2_textureFontLetterN, seg2_textureFontLetterO, seg2_textureFontLetterP, seg2_textureFontLetterQ, seg2_textureFontLetterR, + seg2_textureFontLetterS, seg2_textureFontLetterT, seg2_textureFontLetterU, seg2_textureFontLetterV, seg2_textureFontLetterW, seg2_textureFontLetterX, seg2_textureFontLetterY, seg2_textureFontLetterZ, seg2_textureFontExclamationMark, + seg2_textureFontMinus, seg2_textureFontInterogationMark, seg2_textureFontSimpleQuote, seg2_textureFontEmpty, seg2_textureFontDot, seg2_textureFontNumberZero, seg2_textureFontNumberOne, seg2_textureFontNumberTwo, seg2_textureFontNumberThree, + seg2_textureFontNumberFour, seg2_textureFontNumberFive, seg2_textureFontNumberSix, seg2_textureFontNumberSeven, seg2_textureFontNumberEight, seg2_textureFontNumberNine, seg2_textureFontDoubleQuote, seg2_textureFontFourDote, seg2_textureFontPlus, + seg2_textureFontCC, seg2_textureFontComma, seg2_textureFontEmpty, D_02002824, D_0200284C, D_02002874, D_0200289C, D_020028C4, D_020028EC, D_02002F54, D_02002914, D_02002F7C, D_0200293C, D_02002FA4, D_02002964, D_02002FCC, D_0200298C, D_02002FF4, D_020029B4, D_0200301C, D_020029DC, D_02003044, D_02002A04, D_0200306C, D_02002A2C, D_02003094, D_02002A54, D_020030BC, D_02002A7C, D_020030E4, D_02002AA4, D_0200310C, D_020033B4, D_02002ACC, D_02003134, D_02002AF4, @@ -930,7 +930,7 @@ MenuTexture* D_800E81E4[] = { }; MenuTexture* D_800E822C[] = { - D_02004534, + seg2_textureFontComma, D_0200455C, }; @@ -942,7 +942,7 @@ MenuTexture* D_800E8234[] = { MenuTexture* D_800E8254[] = { seg2_game_select_texture, seg2_menu_1p_column, seg2_menu_2p_column, seg2_menu_3p_column, - seg2_menu_4p_column, D_0200487C, D_020048A4, D_020048CC, + seg2_menu_4p_column, D_0200487C, D_020048A4, seg2_textureMenuRData, }; // CC textures @@ -1292,7 +1292,7 @@ void func_80091B78(void) { unref_8018EE0C = 0; for (i = 0; i < 5; i++) { - D_8018E7AC[i] = 0; + gTransitionType[i] = 0; } for (i = 0; i < 4; i++) { @@ -1388,7 +1388,7 @@ void func_80091FA4(void) { sGPPointsCopy = get_next_available_memory_addr(4); for (i = 0; i < 5; i++) { - D_8018E7AC[i] = 0; + gTransitionType[i] = 0; } for (i = 0; i < 4; i++) { @@ -2199,7 +2199,7 @@ void func_80093E60(void) { sGPPointsCopy = get_next_available_memory_addr(4U); for (i = 0; i < 5; i++) { - D_8018E7AC[i] = 0; + gTransitionType[i] = 0; } for (i = 0; i < 4; i++) { @@ -2526,7 +2526,7 @@ void setup_menus(void) { void func_80095574(void) { s32 var_v0; - if ((unref_8018EE0C < 3) || (D_8018E7AC[4] != 0)) { + if ((unref_8018EE0C < 3) || (gTransitionType[4] != 0)) { handle_menus_default(); } if (gDebugMenuSelection > DEBUG_MENU_DISABLED) { // If not disabled @@ -3275,12 +3275,12 @@ Gfx* func_800987D0(Gfx* displayListHead, u32 arg1, u32 arg2, u32 width, u32 heig f32 temp_f18; f32 temp_f24; - if (D_8018E7B8[0] == 0) { - D_8018E7B8[0] = 1; + if (gTransitionDuration[0] == 0) { + gTransitionDuration[0] = 1; } - temp_f24 = sins(((D_8018E7D0[0] * 0x4E20) / D_8018E7B8[0]) % 20000U); - temp_f0 = coss(((D_8018E7D0[0] * 0x4E20) / D_8018E7B8[0]) % 20000U); - temp_f18 = (((f32) D_8018E7D0[0] * 0.5) / D_8018E7B8[0]) + 1.0; + temp_f24 = sins(((gCurrentTransitionTime[0] * 0x4E20) / gTransitionDuration[0]) % 20000U); + temp_f0 = coss(((gCurrentTransitionTime[0] * 0x4E20) / gTransitionDuration[0]) % 20000U); + temp_f18 = (((f32) gCurrentTransitionTime[0] * 0.5) / gTransitionDuration[0]) + 1.0; columnCopy = column; for (var_v0_2 = arg2; (u32) var_v0_2 < height; var_v0_2 += 0x20) { for (var_a2 = arg1; (u32) var_a2 < width; var_a2 += 0x20) { @@ -4303,7 +4303,7 @@ Gfx* render_menu_textures(Gfx* arg0, MenuTexture* arg1, s32 column, s32 row) { } temp_v0_3 = (u8*) func_8009B8C4(temp_v0->textureData); if (temp_v0_3 != 0) { - if (D_8018E7AC[4] != 4) { + if (gTransitionType[4] != 4) { arg0 = func_80095E10(arg0, var_s4, 0x00000400, 0x00000400, 0, 0, temp_v0->width, temp_v0->height, temp_v0->dX + column, temp_v0->dY + row, temp_v0_3, temp_v0->width, temp_v0->height); @@ -4580,9 +4580,9 @@ void func_8009CA6C(s32 arg0) { if ((arg0 != 4) && (gIsGamePaused != 0)) { var_a1 = 1; } - switch (D_8018E7AC[arg0]) { + switch (gTransitionType[arg0]) { case 1: - func_8009CDDC(arg0, var_a1); + draw_black_fade_in(arg0, var_a1); return; case 2: func_8009D958(arg0, var_a1); @@ -4600,7 +4600,7 @@ void func_8009CA6C(s32 arg0) { func_8009D978(arg0, var_a1); return; case 8: - func_8009CDFC(arg0, var_a1); + draw_white_fade_in(arg0, var_a1); break; case 0: default: @@ -4609,7 +4609,7 @@ void func_8009CA6C(s32 arg0) { } } -void func_8009CBE4(s32 arg0, s32 arg1, s32 arg2) { +void draw_fade_in(s32 arg0, s32 arg1, s32 arg2) { RGBA16* color; s16 x, y, w, h; UNUSED s32 pad[3]; @@ -4639,24 +4639,24 @@ void func_8009CBE4(s32 arg0, s32 arg1, s32 arg2) { } color = &D_800E7AE8[arg2]; gDisplayListHead = draw_box(gDisplayListHead, x - (w / 2), y - (h / 2), (w / 2) + x, (h / 2) + y, color->red, - color->green, color->blue, 0xFF - (D_8018E7D0[arg0] * 0xFF / D_8018E7B8[arg0])); + color->green, color->blue, 0xFF - (gCurrentTransitionTime[arg0] * 0xFF / gTransitionDuration[arg0])); - if ((arg1 == 0) && (D_8018E7D0[arg0] += 1, (D_8018E7D0[arg0] >= D_8018E7B8[arg0]))) { + if ((arg1 == 0) && (gCurrentTransitionTime[arg0] += 1, (gCurrentTransitionTime[arg0] >= gTransitionDuration[arg0]))) { if (gGamestate == RACING) { - D_8018E7AC[arg0] = 6; + gTransitionType[arg0] = 6; return; } - D_8018E7AC[arg0] = 0; + gTransitionType[arg0] = 0; unref_8018EE0C = 0; } } -void func_8009CDDC(s32 arg0, s32 arg1) { - func_8009CBE4(arg0, arg1, 0); +void draw_black_fade_in(s32 arg0, s32 arg1) { + draw_fade_in(arg0, arg1, 0); } -void func_8009CDFC(s32 arg0, s32 arg1) { - func_8009CBE4(arg0, arg1, 1); +void draw_white_fade_in(s32 arg0, s32 arg1) { + draw_fade_in(arg0, arg1, 1); } void func_8009CE1C(void) { @@ -4694,9 +4694,9 @@ void func_8009CE64(s32 arg0) { gMenuSelection = 0x0000000B; } } else if (gGamestate == RACING) { - if (D_8018E7AC[arg0] == 2) { + if (gTransitionType[arg0] == 2) { if (arg0 != 4) { - D_8018E7AC[arg0] = 5; + gTransitionType[arg0] = 5; } else { var_a1 = 0; temp_v0 = find_menu_items(0x000000B0); @@ -4769,7 +4769,7 @@ void func_8009CE64(s32 arg0) { var_a1 = 1; break; default: - D_8018E7AC[arg0] = 5; + gTransitionType[arg0] = 5; break; } if (var_a1 != 0) { @@ -4808,14 +4808,14 @@ void func_8009CE64(s32 arg0) { break; } } else { - D_8018E7AC[arg0] = 5; + gTransitionType[arg0] = 5; } } } } } } else { - D_8018E7AC[arg0] = 0; + gTransitionType[arg0] = 0; if (gDebugMenuSelection != DEBUG_MENU_OPTION_SELECTED) { switch (gMenuFadeType) { /* switch 3 */ case MENU_FADE_TYPE_MAIN: /* switch 3 */ @@ -5031,7 +5031,7 @@ void func_8009D77C(s32 arg0, s32 arg1, s32 arg2) { var_ra = D_8015F480[arg0].screenWidth; sp44 = D_8015F480[arg0].screenHeight; } - var_t2 = (D_8018E7D0[arg0] * 0xFF) / D_8018E7B8[arg0]; + var_t2 = (gCurrentTransitionTime[arg0] * 0xFF) / gTransitionDuration[arg0]; if (var_t2 >= 0x100) { var_t2 = 0x000000FF; } @@ -5046,8 +5046,8 @@ void func_8009D77C(s32 arg0, s32 arg1, s32 arg2) { gDisplayListHead = draw_box(gDisplayListHead, var_t3 - temp_v1, var_t4 - temp_t8, someMath0, someMath1, temp_v0_2->red, temp_v0_2->green, temp_v0_2->blue, var_t2); if (arg1 == 0) { - D_8018E7D0[arg0]++; - if ((D_8018E7B8[arg0] + 1) < D_8018E7D0[arg0]) { + gCurrentTransitionTime[arg0]++; + if ((gTransitionDuration[arg0] + 1) < gCurrentTransitionTime[arg0]) { func_8009CE64(arg0); } } @@ -5101,12 +5101,12 @@ void func_8009D998(s32 arg0) { void func_8009DAA8(void) { u32 var_t0; - D_8018E7D0[4]++; - if (D_8018E7D0[4] >= (D_8018E7B8[4] + 1)) { + gCurrentTransitionTime[4]++; + if (gCurrentTransitionTime[4] >= (gTransitionDuration[4] + 1)) { func_8009CE64(4); } gDPPipeSync(gDisplayListHead++); - var_t0 = (D_8018E7D0[4] * 255) / D_8018E7B8[4]; + var_t0 = (gCurrentTransitionTime[4] * 255) / gTransitionDuration[4]; if ((s32) var_t0 >= 0x100) { var_t0 = 0x000000FF; } @@ -5120,11 +5120,11 @@ void func_8009DB8C(void) { u32 var_s3; s32 var_v1; - D_8018E7D0[4]++; + gCurrentTransitionTime[4]++; // why? - var_v1 = D_8018E7D0[4]; - if ((u32) var_v1 >= D_8018E7B8[4]) { - if ((u32) var_v1 == D_8018E7B8[4]) { + var_v1 = gCurrentTransitionTime[4]; + if ((u32) var_v1 >= gTransitionDuration[4]) { + if ((u32) var_v1 == gTransitionDuration[4]) { for (var_s0 = 0; var_s0 < 0x4B0; var_s0++) { sTKMK00_LowResBuffer[var_s0] = 1; } @@ -5134,8 +5134,8 @@ void func_8009DB8C(void) { } else { var_s0 = 0; var_s3 = 0; - while (var_s3 < (0x4B0U / D_8018E7B8[4])) { - if ((sTKMK00_LowResBuffer[var_s0] == 0) && (random_int((0x4B0U - D_8018E7D0[4]) / D_8018E7B8[4]) == 0)) { + while (var_s3 < (0x4B0U / gTransitionDuration[4])) { + if ((sTKMK00_LowResBuffer[var_s0] == 0) && (random_int((0x4B0U - gCurrentTransitionTime[4]) / gTransitionDuration[4]) == 0)) { var_s3 += 1; sTKMK00_LowResBuffer[var_s0] = 1; } @@ -5157,7 +5157,7 @@ void func_8009DB8C(void) { } } gDPPipeSync(gDisplayListHead++); - var_v1 = (D_8018E7D0[4] * 255) / D_8018E7B8[4]; + var_v1 = (gCurrentTransitionTime[4] * 255) / gTransitionDuration[4]; if (var_v1 >= 0x100) { var_v1 = 0x000000FF; } @@ -5168,11 +5168,11 @@ void func_8009DEF8(u32 arg0, u32 arg1) { if (arg0 == 0) { arg0 = 1; } - if ((D_8018E7AC[4] != 1) && (D_8018E7AC[4] != 6)) { - D_8018E7AC[4] = arg1; - D_8018E7B8[4] = arg0; - if (D_8018E7B8[4] >= 0x100U) { - D_8018E7B8[4] = 0xFFU; + if ((gTransitionType[4] != 1) && (gTransitionType[4] != 6)) { + gTransitionType[4] = arg1; + gTransitionDuration[4] = arg0; + if (gTransitionDuration[4] >= 0x100U) { + gTransitionDuration[4] = 0xFFU; } D_8018E7E0 = 0; } @@ -5190,11 +5190,11 @@ void func_8009DF8C(u32 arg0, u32 arg1) { if (arg0 == 0) { arg0 = 1; } - if ((D_8018E7AC[4] != 2) && (D_8018E7AC[4] != 5)) { - D_8018E7AC[4] = arg1; - D_8018E7B8[4] = arg0; - if (D_8018E7B8[4] >= 0x100U) { - D_8018E7B8[4] = 0xFFU; + if ((gTransitionType[4] != 2) && (gTransitionType[4] != 5)) { + gTransitionType[4] = arg1; + gTransitionDuration[4] = arg0; + if (gTransitionDuration[4] >= 0x100U) { + gTransitionDuration[4] = 0xFFU; } D_8018E7E0 = 0; } @@ -5215,14 +5215,14 @@ void func_8009E020(s32 arg0, s32 arg1) { arg1 = 1; } - temp = D_8018E7AC[arg0]; + temp = gTransitionType[arg0]; if ((temp != 1) && (temp != 6)) { - D_8018E7AC[arg0] = 1; - D_8018E7B8[arg0] = arg1; + gTransitionType[arg0] = 1; + gTransitionDuration[arg0] = arg1; if ((u32) arg1 >= 0x100U) { - D_8018E7B8[arg0] = 0xFF; + gTransitionDuration[arg0] = 0xFF; } - D_8018E7D0[arg0] = 0; + gCurrentTransitionTime[arg0] = 0; } } @@ -5233,25 +5233,25 @@ void func_8009E088(s32 arg0, s32 arg1) { arg1 = 1; } - temp = D_8018E7AC[arg0]; + temp = gTransitionType[arg0]; if ((temp != 2) && (temp != 5)) { - D_8018E7AC[arg0] = 2; - D_8018E7B8[arg0] = arg1; + gTransitionType[arg0] = 2; + gTransitionDuration[arg0] = arg1; if ((u32) arg1 >= 0x100U) { - D_8018E7B8[arg0] = 0xFF; + gTransitionDuration[arg0] = 0xFF; } - D_8018E7D0[arg0] = 0; + gCurrentTransitionTime[arg0] = 0; } } void func_8009E0F0(s32 arg0) { s32 var_v0; - if (D_8018E7AC[4] != 3) { - D_8018E7AC[4] = 3; - D_8018E7B8[4] = arg0; - if (D_8018E7B8[4] >= 0x100U) { - D_8018E7B8[4] = 0x000000FF; + if (gTransitionType[4] != 3) { + gTransitionType[4] = 3; + gTransitionDuration[4] = arg0; + if (gTransitionDuration[4] >= 0x100U) { + gTransitionDuration[4] = 0x000000FF; } D_8018E7E0 = 0; for (var_v0 = 0; var_v0 < 0x4B0; var_v0++) { @@ -5261,11 +5261,11 @@ void func_8009E0F0(s32 arg0) { } void func_8009E17C(u32 arg0) { - if (D_8018E7AC[4] != 4) { - D_8018E7AC[4] = 4; - D_8018E7B8[4] = arg0; - if (D_8018E7B8[4] >= 0x100U) { - D_8018E7B8[4] = 0x000000FFU; + if (gTransitionType[4] != 4) { + gTransitionType[4] = 4; + gTransitionDuration[4] = arg0; + if (gTransitionDuration[4] >= 0x100U) { + gTransitionDuration[4] = 0x000000FFU; } D_8018E7E0 = 0; } @@ -5493,9 +5493,9 @@ void add_menu_item(s32 type, s32 column, s32 row, s8 priority) { load_menu_img_comp_type(gMenuTexturesBackground[has_unlocked_extra_mode()], LOAD_MENU_IMG_TKMK00_ONCE); load_menu_img_comp_type(D_02004B74, LOAD_MENU_IMG_TKMK00_ONCE); convert_img_to_greyscale(0, 0x00000019); - adjust_img_colour(0, SCREEN_WIDTH * SCREEN_HEIGHT, D_800E74E8[type - MAIN_MENU_BACKGROUND].red, - D_800E74E8[type - MAIN_MENU_BACKGROUND].green, - D_800E74E8[type - MAIN_MENU_BACKGROUND].blue); + adjust_img_colour(0, SCREEN_WIDTH * SCREEN_HEIGHT, gBackgroundColor[type - MAIN_MENU_BACKGROUND].red, + gBackgroundColor[type - MAIN_MENU_BACKGROUND].green, + gBackgroundColor[type - MAIN_MENU_BACKGROUND].blue); break; case MENU_ITEM_UI_OK: menuItem->param1 = 0x20; @@ -8634,7 +8634,7 @@ void func_800A69C8(UNUSED MenuItem* arg0) { if (gGPCurrentRaceRankByPlayerId[playerId] != 0) { var_v1 = 1; } - var_s4 = &gNmiUnknown1[playerId]; + var_s4 = &nmi_gVersusResults2P[playerId]; break; case BATTLE: if (playerId != gPlayerWinningIndex) { @@ -8684,7 +8684,7 @@ void func_800A69C8(UNUSED MenuItem* arg0) { /*Iterates over all players and, based on the current mode selection, calls either func_800A6E94 (for Versus mode) or func_800A6D94 (for Battle mode) with a fixed parameter of 3 (3 PLAYER VERSUS), the current player - index, and a mode-specific global value (gNmiUnknown2 or gNmiUnknown5). + index, and a mode-specific global value (nmi_gVersusResults3P or gNmiUnknown5). The MenuItem parameter is unused.*/ void func_800A6BEC(UNUSED MenuItem* arg0) { s32 var_s0; @@ -8692,7 +8692,7 @@ void func_800A6BEC(UNUSED MenuItem* arg0) { for (var_s0 = 0; var_s0 < gPlayerCount; var_s0++) { switch (gModeSelection) { /* irregular */ case VERSUS: - func_800A6E94(3, var_s0, gNmiUnknown2); + func_800A6E94(3, var_s0, nmi_gVersusResults3P); break; case BATTLE: func_800A6D94(3, var_s0, gNmiUnknown5); @@ -8705,7 +8705,7 @@ void func_800A6BEC(UNUSED MenuItem* arg0) { calls either func_800A6E94 (for Versus mode) or func_800A6D94 (for Battle mode) with a fixed first argument of 4 (4 PLAYER VERSUS), the current player index, and a corresponding global NMI-related - variable (gNmiUnknown3 or gNmiUnknown6). The MenuItem parameter + variable (nmi_gVersusResults4P or gNmiUnknown6). The MenuItem parameter is unused.*/ void func_800A6CC0(UNUSED MenuItem* arg0) { s32 var_s0; @@ -8713,7 +8713,7 @@ void func_800A6CC0(UNUSED MenuItem* arg0) { for (var_s0 = 0; var_s0 < gPlayerCount; var_s0++) { switch (gModeSelection) { /* irregular */ case VERSUS: - func_800A6E94(4, var_s0, gNmiUnknown3); + func_800A6E94(4, var_s0, nmi_gVersusResults4P); break; case BATTLE: func_800A6D94(4, var_s0, gNmiUnknown6); @@ -8792,8 +8792,8 @@ void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { i = 0; // change tally var based off of player count - // gNmiUnknown2 for 3p, gNmiUnknown3 for 4p - tally = (gPlayerCountSelection1 == 3) ? gNmiUnknown2 : gNmiUnknown3; + // nmi_gVersusResults3P for 3p, nmi_gVersusResults4P for 4p + tally = (gPlayerCountSelection1 == 3) ? nmi_gVersusResults3P : nmi_gVersusResults4P; // Only draw scores on the first player call to avoid overdraw // (func_800A6E94 is called once per player by func_800A6BEC/func_800A6CC0) diff --git a/src/menu_items.h b/src/menu_items.h index 01aceb1f66..a1e32bd075 100644 --- a/src/menu_items.h +++ b/src/menu_items.h @@ -455,9 +455,9 @@ Gfx* func_8009C708(Gfx*, struct_8018DEE0_entry*, s32, s32, s32, s32); void func_8009C918(void); void func_8009CA2C(void); void func_8009CA6C(s32); -void func_8009CBE4(s32, s32, s32); -void func_8009CDDC(s32, s32); -void func_8009CDFC(s32, s32); +void draw_fade_in(s32, s32, s32); +void draw_black_fade_in(s32, s32); +void draw_white_fade_in(s32, s32); void func_8009CE1C(void); void func_8009CE64(s32); void func_8009D77C(s32, s32, s32); @@ -676,9 +676,9 @@ extern Gfx* sGfxPtr; extern s32 gNumD_8018E768Entries; extern struct_8018E768_entry D_8018E768[D_8018E768_SIZE]; extern s32 gCycleFlashMenu; -extern s8 D_8018E7AC[]; -extern u32 D_8018E7B8[]; -extern u32 D_8018E7D0[]; +extern s8 gTransitionType[]; +extern u32 gTransitionDuration[]; +extern u32 gCurrentTransitionTime[]; extern s32 D_8018E7E0; extern struct UnkStruct_8018E7E8 D_8018E7E8[D_8018E7E8_SIZE]; extern struct UnkStruct_8018E7E8 D_8018E810[D_8018E810_SIZE]; @@ -721,7 +721,7 @@ extern Unk_D_800E70A0 D_800E7458[]; extern Unk_D_800E70A0 D_800E7480[]; extern RGBA16 D_800E74A8[]; extern RGBA16 D_800E74D0[]; -extern RGBA16 D_800E74E8[]; +extern RGBA16 gBackgroundColor[]; extern const s16 gGlyphDisplayWidth[]; extern char* gCupNames[]; extern char* gCourseNamesDup2[]; diff --git a/src/menus.c b/src/menus.c index eca8a28aa8..4655d352b4 100644 --- a/src/menus.c +++ b/src/menus.c @@ -2063,7 +2063,7 @@ void set_sound_mode(void) { * interacted while a fade transition is active */ bool is_screen_being_faded(void) { - if ((D_8018E7AC[4] == 2) || (D_8018E7AC[4] == 3) || (D_8018E7AC[4] == 4) || (D_8018E7AC[4] == 7)) { + if ((gTransitionType[4] == 2) || (gTransitionType[4] == 3) || (gTransitionType[4] == 4) || (gTransitionType[4] == 7)) { return true; } return false; diff --git a/src/player_controller.c b/src/player_controller.c index 8c08935cad..4c7d02aa66 100644 --- a/src/player_controller.c +++ b/src/player_controller.c @@ -591,7 +591,7 @@ void func_80028C44(Player* player, Camera* camera, s8 playerId, s8 screenId) { } void func_80028D3C(Player* player, Camera* camera, s8 playerId, s8 screenId) { - if ((((player->type & PLAYER_START_SEQUENCE) == 0) && (D_800DC510 != 5)) || (player->unk_0CA & 2) != 0 || + if ((((player->type & PLAYER_START_SEQUENCE) == 0) && (gRaceState != 5)) || (player->unk_0CA & 2) != 0 || (player->unk_0CA & 8) != 0 || (player->effects & (LIGHTNING_EFFECT | EXPLOSION_CRASH_EFFECT | HIT_BY_STAR_EFFECT | SQUISH_EFFECT | POST_SQUISH_EFFECT | TERRAIN_TUMBLE_EFFECT | 0xC00 | 0xC0)) != 0) { @@ -1139,7 +1139,7 @@ void func_8002A79C(Player* player, s8 playerIndex) { } } -void func_8002A8A4(Player* player, s8 playerIndex) { +void update_drift_state_counter(Player* player, s8 playerIndex) { if (((s16) player->unk_0C0 / 182) > 0) { if (((s32) player->unk_07C >> 0x10) < -9) { if (player->unk_228 < 0x65) { @@ -1378,7 +1378,7 @@ void apply_triggers(Player* player, s8 playerId, UNUSED s8 screenId) { func_8008C528(player, playerId); } if ((player->triggers & HIT_BANANA_TRIGGER) == HIT_BANANA_TRIGGER) { - func_8008CDC0(player, playerId); + trigger_hit_banana(player, playerId); } if ((player->triggers & SHROOM_TRIGGER) == SHROOM_TRIGGER) { trigger_shroom(player, playerId); @@ -1399,7 +1399,7 @@ void apply_triggers(Player* player, s8 playerId, UNUSED s8 screenId) { trigger_lightning_strike(player, playerId); } if ((player->triggers & SPINOUT_TRIGGER) == SPINOUT_TRIGGER) { - func_8008C73C(player, playerId); + add_spinout_effect(player, playerId); } if ((player->triggers & VERTICAL_TUMBLE_TRIGGER) == VERTICAL_TUMBLE_TRIGGER) { trigger_vertical_tumble(player, playerId); @@ -1420,7 +1420,7 @@ void apply_triggers(Player* player, s8 playerId, UNUSED s8 screenId) { trigger_boo(player, playerId); } if (player->triggers & DRIVING_SPINOUT_TRIGGER) { - func_8008D0FC(player, playerId); + trigger_driving_spinout(player, playerId); } if (player->triggers & HIT_PADDLE_BOAT_TRIGGER) { trigger_vertical_tumble(player, playerId); @@ -1570,7 +1570,7 @@ void func_8002B9CC(Player* player, s8 playerIndex, UNUSED s32 arg2) { player->unk_08C /= 4; player->currentSpeed /= 4; if (!(player->effects & BANANA_SPINOUT_EFFECT) && !(player->effects & DRIVING_SPINOUT_EFFECT)) { - func_8008C73C(player, playerIndex); + add_spinout_effect(player, playerIndex); } } } else { @@ -1581,7 +1581,7 @@ void func_8002B9CC(Player* player, s8 playerIndex, UNUSED s32 arg2) { player->unk_08C /= 4; player->currentSpeed /= 4; if (!(player->effects & BANANA_SPINOUT_EFFECT) && !(player->effects & DRIVING_SPINOUT_EFFECT)) { - func_8008C73C(player, playerIndex); + add_spinout_effect(player, playerIndex); } } temp = (-(s16) get_xz_angle_between_points(player->pos, &player->oldPos[0])); @@ -1732,7 +1732,7 @@ void func_8002BF4C(Player* player, s8 playerIndex) { } } -void func_8002C11C(Player* player) { +void update_player_drift_duration(Player* player) { if ((player->effects & DRIFTING_EFFECT) == DRIFTING_EFFECT) { player->unk_204 += 1; if (player->unk_204 >= 0x65) { @@ -1961,10 +1961,10 @@ void apply_effect(Player* player, s8 playerIndex, s8 arg2) { func_80090970(player, playerIndex, arg2); } if ((player->effects & BANANA_NEAR_SPINOUT_EFFECT) == BANANA_NEAR_SPINOUT_EFFECT) { - func_8008CEB0(player, playerIndex); + apply_banana_near_spinout_effect(player, playerIndex); } if (player->unk_044 & 0x4000) { - func_8008D170(player, playerIndex); + apply_driving_near_spinout_effect(player, playerIndex); } if ((player->effects & MUSHROOM_EFFECT) == MUSHROOM_EFFECT) { apply_mushroom_effect(player); @@ -2016,7 +2016,7 @@ void apply_effect(Player* player, s8 playerIndex, s8 arg2) { func_8008D8B4(player, playerIndex); player_decelerate_alternative(player, 10.0f); } - if (D_800DC510 != 5) { + if (gRaceState != 5) { if (player->triggers & LOSE_BATTLE_EFFECT) { func_8008FC64(player, playerIndex); } @@ -2112,7 +2112,7 @@ void func_8002D268(Player* player, UNUSED Camera* camera, s8 screenId, s8 player UNUSED s32 pad4[6]; func_80027EDC(player, playerId); - func_8002C11C(player); + update_player_drift_duration(player); if ((player->type & PLAYER_HUMAN) == PLAYER_HUMAN) { func_8002A79C(player, playerId); } @@ -3790,7 +3790,7 @@ void func_80033850(Player* arg0, f32 arg1) { } } -void func_80033884(Player* player, s32* arg1, s32* arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6) { +void update_steering_large(Player* player, s32* arg1, s32* arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6) { s32 temp_v1; if ((*arg1 >= arg4) || (-arg4 >= *arg1)) { @@ -3847,7 +3847,7 @@ void func_800339C4(Player* player, s32* arg1, s32 arg2, s32 arg3, f32 arg4) { func_80033850(player, arg4); } -void func_80033A40(Player* player, s32* arg1, s32* arg2, s32 arg3, s32 arg4, s32 arg5, f32 arg6) { +void update_steering_small(Player* player, s32* arg1, s32* arg2, s32 arg3, s32 arg4, s32 arg5, f32 arg6) { s32 temp_v1; if ((*arg1 >= arg4) || (-arg4 >= *arg1)) { @@ -3895,7 +3895,7 @@ void func_80033AE0(Player* player, struct Controller* controller, s8 arg2) { ((controller->button & R_TRIG) != R_TRIG))) || (((player->speed / 18.0f) * 216.0f) <= 20.0f)) || ((player->effects & ENEMY_BONK_EFFECT) == ENEMY_BONK_EFFECT)) { - func_80036CB4(player); + cancel_drift_effect(player); } if ((player->unk_0C0 / 182) < (-5)) { player->unk_044 |= 4; @@ -3989,96 +3989,96 @@ void func_80033AE0(Player* player, struct Controller* controller, s8 arg2) { sp2CC *= 1.05; } } - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000005A, 0x78000 / sp2C8, 0x000001C2); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000059, 0x76000 / sp2C8, 0x000001B8); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000058, 0x74000 / sp2C8, 0x000001AE); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000057, 0x72000 / sp2C8, 0x000001A4); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000056, 0x70000 / sp2C8, 0x0000019A); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000055, 0x58000 / sp2C8, 0x00000190); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000054, 0x56000 / sp2C8, 0x0000018B); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000053, 0x50000 / sp2C8, 0x00000186); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000052, 0x4F000 / sp2C8, 0x00000186); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000051, 0x4E000 / sp2C8, 0x0000017C); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000050, 0x4D000 / sp2C8, 0x00000172); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000004F, 0x4C000 / sp2C8, 0x00000168); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000004E, 0x4C000 / sp2C8, 0x00000168); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000004D, 0x4B000 / sp2C8, 0x0000015E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000004C, 0x4A000 / sp2C8, 0x00000154); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000004B, 0x49000 / sp2C8, 0x0000014A); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000004A, 0x49000 / sp2C8, 0x0000014A); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000049, 0x49000 / sp2C8, 0x0000014A); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000048, 0x48000 / sp2C8, 0x00000140); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000047, 0x47000 / sp2C8, 0x0000013B); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000046, 0x47000 / sp2C8, 0x0000013B); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000045, 0x46000 / sp2C8, 0x00000131); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000044, 0x46000 / sp2C8, 0x00000131); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000043, 0x45000 / sp2C8, 0x00000118); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000042, 0x46000 / sp2C8, 0x0000010E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000041, 0x45000 / sp2C8, 0x0000010E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000040, 0x44000 / sp2C8, 0x00000104); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000003F, 0x43000 / sp2C8, 0x000000FA); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000003E, 0x43000 / sp2C8, 0x000000FA); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000003D, 0x43000 / sp2C8, 0x000000FA); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000003C, 0x3D000 / sp2C8, 0x000000F5); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000003B, 0x3C000 / sp2C8, 0x000000F5); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000003A, 0x3B000 / sp2C8, 0x000000F5); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000039, 0x3A000 / sp2C8, 0x000000F5); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000038, 0x38000 / sp2C8, 0x000000F5); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000037, 0x38000 / sp2C8, 0x000000E6); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000036, 0x38000 / sp2C8, 0x000000E6); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000035, 0x38000 / sp2C8, 0x000000E6); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000034, 0x38000 / sp2C8, 0x000000E6); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000033, 0x38000 / sp2C8, 0x000000E6); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000032, 0x32000 / sp2C8, 0x000000DC); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000031, 0x32000 / sp2C8, 0x000000DC); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000030, 0x32000 / sp2C8, 0x000000DC); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000002F, 0x32000 / sp2C8, 0x000000DC); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000002E, 0x32000 / sp2C8, 0x000000DC); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000002D, 0x30000 / sp2C8, 0x0000006E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000002C, 0x2E000 / sp2C8, 0x0000006E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000002B, 0x2E000 / sp2C8, 0x0000006E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000002A, 0x2E000 / sp2C8, 0x0000006E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000029, 0x2E000 / sp2C8, 0x0000006E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000028, 0x2E000 / sp2C8, 0x0000006E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000027, 0x2C000 / sp2C8, 0x0000006E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000026, 0x28000 / sp2C8, 0x0000006E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000025, 0x28000 / sp2C8, 0x0000006E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000024, 0x24000 / sp2C8, 0x0000006E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000023, 0x24000 / sp2C8, 0x0000006E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000022, 0x22000 / sp2C8, 0x0000006E); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000020, 0x20000 / sp2C8, 0x00000064); - func_80033884(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000001F, 0x20000 / sp2C8, 0x00000064); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000001E, 0x1F000 / sp2CC, 0.9f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000001D, 0x1E000 / sp2CC, 0.9f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000001C, 0x1D000 / sp2CC, 0.9f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000001B, 0x1C000 / sp2CC, 0.9f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000001A, 0x1B000 / sp2CC, 0.9f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000019, 0x1A000 / sp2CC, 1.0f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000018, 0x19000 / sp2CC, 1.0f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000017, 0x18000 / sp2CC, 1.0f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000016, 0x17000 / sp2CC, 1.0f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000015, 0x16000 / sp2CC, 1.0f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000014, 0x15000 / sp2CC, 1.05f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000013, 0x14000 / sp2CC, 1.05f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000012, 0x13000 / sp2CC, 1.05f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000011, 0x12000 / sp2CC, 1.05f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000010, 0x11000 / sp2CC, 1.05f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000000F, 0x10000 / sp2CC, 1.2f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000000E, 0xF000 / sp2CC, 1.2f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000000D, 0xE000 / sp2CC, 1.2f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000000C, 0xD000 / sp2CC, 1.2f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000000B, 0xC000 / sp2CC, 1.2f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000000A, 0xE000 / sp2CC, 1.6f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 9, 0xD000 / sp2CC, 1.6f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 8, 0xC000 / sp2CC, 1.6f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 7, 0xB000 / sp2CC, 1.6f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 6, 0xA000 / sp2CC, 1.6f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 5, 0x9000 / sp2CC, 1.9f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 4, 0x8000 / sp2CC, 1.9f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 3, 0x7000 / sp2CC, 1.9f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 2, 0x6000 / sp2CC, 1.9f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 1, 0x5000 / sp2CC, 1.9f); - func_80033A40(player, &sp2D0, &sp2E4, player->unk_07C, 0, 0 / sp2CC, 1.9f); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000005A, 0x78000 / sp2C8, 0x000001C2); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000059, 0x76000 / sp2C8, 0x000001B8); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000058, 0x74000 / sp2C8, 0x000001AE); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000057, 0x72000 / sp2C8, 0x000001A4); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000056, 0x70000 / sp2C8, 0x0000019A); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000055, 0x58000 / sp2C8, 0x00000190); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000054, 0x56000 / sp2C8, 0x0000018B); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000053, 0x50000 / sp2C8, 0x00000186); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000052, 0x4F000 / sp2C8, 0x00000186); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000051, 0x4E000 / sp2C8, 0x0000017C); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000050, 0x4D000 / sp2C8, 0x00000172); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000004F, 0x4C000 / sp2C8, 0x00000168); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000004E, 0x4C000 / sp2C8, 0x00000168); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000004D, 0x4B000 / sp2C8, 0x0000015E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000004C, 0x4A000 / sp2C8, 0x00000154); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000004B, 0x49000 / sp2C8, 0x0000014A); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000004A, 0x49000 / sp2C8, 0x0000014A); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000049, 0x49000 / sp2C8, 0x0000014A); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000048, 0x48000 / sp2C8, 0x00000140); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000047, 0x47000 / sp2C8, 0x0000013B); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000046, 0x47000 / sp2C8, 0x0000013B); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000045, 0x46000 / sp2C8, 0x00000131); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000044, 0x46000 / sp2C8, 0x00000131); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000043, 0x45000 / sp2C8, 0x00000118); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000042, 0x46000 / sp2C8, 0x0000010E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000041, 0x45000 / sp2C8, 0x0000010E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000040, 0x44000 / sp2C8, 0x00000104); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000003F, 0x43000 / sp2C8, 0x000000FA); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000003E, 0x43000 / sp2C8, 0x000000FA); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000003D, 0x43000 / sp2C8, 0x000000FA); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000003C, 0x3D000 / sp2C8, 0x000000F5); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000003B, 0x3C000 / sp2C8, 0x000000F5); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000003A, 0x3B000 / sp2C8, 0x000000F5); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000039, 0x3A000 / sp2C8, 0x000000F5); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000038, 0x38000 / sp2C8, 0x000000F5); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000037, 0x38000 / sp2C8, 0x000000E6); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000036, 0x38000 / sp2C8, 0x000000E6); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000035, 0x38000 / sp2C8, 0x000000E6); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000034, 0x38000 / sp2C8, 0x000000E6); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000033, 0x38000 / sp2C8, 0x000000E6); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000032, 0x32000 / sp2C8, 0x000000DC); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000031, 0x32000 / sp2C8, 0x000000DC); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000030, 0x32000 / sp2C8, 0x000000DC); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000002F, 0x32000 / sp2C8, 0x000000DC); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000002E, 0x32000 / sp2C8, 0x000000DC); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000002D, 0x30000 / sp2C8, 0x0000006E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000002C, 0x2E000 / sp2C8, 0x0000006E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000002B, 0x2E000 / sp2C8, 0x0000006E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000002A, 0x2E000 / sp2C8, 0x0000006E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000029, 0x2E000 / sp2C8, 0x0000006E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000028, 0x2E000 / sp2C8, 0x0000006E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000027, 0x2C000 / sp2C8, 0x0000006E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000026, 0x28000 / sp2C8, 0x0000006E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000025, 0x28000 / sp2C8, 0x0000006E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000024, 0x24000 / sp2C8, 0x0000006E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000023, 0x24000 / sp2C8, 0x0000006E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000022, 0x22000 / sp2C8, 0x0000006E); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000020, 0x20000 / sp2C8, 0x00000064); + update_steering_large(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000001F, 0x20000 / sp2C8, 0x00000064); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000001E, 0x1F000 / sp2CC, 0.9f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000001D, 0x1E000 / sp2CC, 0.9f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000001C, 0x1D000 / sp2CC, 0.9f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000001B, 0x1C000 / sp2CC, 0.9f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000001A, 0x1B000 / sp2CC, 0.9f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000019, 0x1A000 / sp2CC, 1.0f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000018, 0x19000 / sp2CC, 1.0f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000017, 0x18000 / sp2CC, 1.0f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000016, 0x17000 / sp2CC, 1.0f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000015, 0x16000 / sp2CC, 1.0f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000014, 0x15000 / sp2CC, 1.05f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000013, 0x14000 / sp2CC, 1.05f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000012, 0x13000 / sp2CC, 1.05f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000011, 0x12000 / sp2CC, 1.05f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x00000010, 0x11000 / sp2CC, 1.05f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000000F, 0x10000 / sp2CC, 1.2f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000000E, 0xF000 / sp2CC, 1.2f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000000D, 0xE000 / sp2CC, 1.2f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000000C, 0xD000 / sp2CC, 1.2f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000000B, 0xC000 / sp2CC, 1.2f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0x0000000A, 0xE000 / sp2CC, 1.6f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 9, 0xD000 / sp2CC, 1.6f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 8, 0xC000 / sp2CC, 1.6f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 7, 0xB000 / sp2CC, 1.6f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 6, 0xA000 / sp2CC, 1.6f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 5, 0x9000 / sp2CC, 1.9f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 4, 0x8000 / sp2CC, 1.9f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 3, 0x7000 / sp2CC, 1.9f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 2, 0x6000 / sp2CC, 1.9f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 1, 0x5000 / sp2CC, 1.9f); + update_steering_small(player, &sp2D0, &sp2E4, player->unk_07C, 0, 0 / sp2CC, 1.9f); if ((player->effects & DRIFTING_EFFECT) == DRIFTING_EFFECT) { var_f2_2 = (f32) (((s32) (sp2E4 >> 16)) / 8); } else if (((player->speed / 18.0f) * 216.0f) <= 25.0f) { @@ -4146,7 +4146,7 @@ void func_80033AE0(Player* player, struct Controller* controller, s8 arg2) { player->effects |= DRIFT_OUTSIDE_EFFECT; } } - func_8002A8A4(player, arg2); + update_drift_state_counter(player, arg2); } else { var_s1_2 = (((s32) (((player->unk_07C >> 0x10) * 0xD) + 0x2B1)) / 106) - 0x35; if ((player->unk_07C >> 0x10) >= 0x28) { @@ -4155,7 +4155,7 @@ void func_80033AE0(Player* player, struct Controller* controller, s8 arg2) { player->effects |= DRIFT_OUTSIDE_EFFECT; } } - func_8002A8A4(player, arg2); + update_drift_state_counter(player, arg2); } if ((((player->speed / 18.0f) * 216.0f) >= 0.0f) && (((player->speed / 18.0f) * 216.0f) < 8.0f)) { player->unk_078 = (s16) ((s32) (var_s1_2 * ((var_f2_2 + 2.0f) + (var_f2_2 * var_f12)))); @@ -4260,7 +4260,7 @@ void apply_cpu_turn(Player* player, s16 targetAngle) { } if ((((player->effects & HOP_EFFECT) != HOP_EFFECT) && (player->unk_0C0 < 0x3D) && (player->unk_0C0 > -0x3D)) || (((player->speed / 18.0f) * 216.0f) <= 20.0f) || ((player->effects & ENEMY_BONK_EFFECT) == ENEMY_BONK_EFFECT)) { - func_80036CB4(player); + cancel_drift_effect(player); } } } @@ -4275,7 +4275,7 @@ void func_80036C5C(Player* player) { } } -void func_80036CB4(Player* player) { +void cancel_drift_effect(Player* player) { s32 test; if (((player->effects & DRIFTING_EFFECT) == DRIFTING_EFFECT) && ((player->type & PLAYER_HUMAN) == PLAYER_HUMAN)) { diff --git a/src/player_controller.h b/src/player_controller.h index a0c55cec2b..457d323245 100644 --- a/src/player_controller.h +++ b/src/player_controller.h @@ -35,7 +35,7 @@ void func_8002A194(Player*, f32, f32, f32); void func_8002A5F4(Vec3f, f32, Vec3f, f32, f32); void func_8002A704(Player*, s8); void func_8002A79C(Player*, s8); -void func_8002A8A4(Player*, s8); +void update_drift_state_counter(Player*, s8); void kart_hop(Player*); void func_8002AAC0(Player*); void func_8002AB70(Player*); @@ -53,7 +53,7 @@ void func_8002B9CC(Player*, s8, s32); void func_8002BD58(Player*); void func_8002BF4C(Player*, s8); -void func_8002C11C(Player*); +void update_player_drift_duration(Player*); void func_8002C17C(Player*, s8); void func_8002C4F8(Player*, s8); void func_8002C7E4(Player*, s8, s8); @@ -85,15 +85,15 @@ void player_decelerate(Player*, f32); void player_accelerate_global(Player*, s32); void player_decelerate_global(Player*, f32, s32); void func_80033850(Player*, f32); -void func_80033884(Player*, s32*, s32*, s32, s32, s32, s32); +void update_steering_large(Player*, s32*, s32*, s32, s32, s32, s32); void func_80033940(Player*, s32*, s32, s32, f32); void func_800339C4(Player*, s32*, s32, s32, f32); -void func_80033A40(Player*, s32*, s32*, s32, s32, s32, f32); +void update_steering_small(Player*, s32*, s32*, s32, s32, s32, f32); void func_80033AE0(Player*, struct Controller*, s8); void apply_cpu_turn(Player*, s16); void func_80036C5C(Player*); -void func_80036CB4(Player*); +void cancel_drift_effect(Player*); void func_80036DB4(Player*, Vec3f, Vec3f); void func_800371F4(Player*, Vec3f, Vec3f); diff --git a/src/racing/actors.c b/src/racing/actors.c index e08b47b88d..7f03fabf6a 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -1274,22 +1274,22 @@ void spawn_course_actors(void) { */ void init_actors_and_load_textures(void) { set_segment_base_addr(3, (void*) gNextFreeMemoryAddress); - D_802BA050 = dma_textures(gTextureGreenShell0, 0x00000257U, 0x00000400U); - dma_textures(gTextureGreenShell1, 0x00000242U, 0x00000400U); - dma_textures(gTextureGreenShell2, 0x00000259U, 0x00000400U); - dma_textures(gTextureGreenShell3, 0x00000256U, 0x00000400U); - dma_textures(gTextureGreenShell4, 0x00000246U, 0x00000400U); - dma_textures(gTextureGreenShell5, 0x0000025EU, 0x00000400U); - dma_textures(gTextureGreenShell6, 0x0000025CU, 0x00000400U); - dma_textures(gTextureGreenShell7, 0x00000254U, 0x00000400U); - D_802BA054 = dma_textures(gTextureBlueShell0, 0x0000022AU, 0x00000400U); - dma_textures(gTextureBlueShell1, 0x00000237U, 0x00000400U); - dma_textures(gTextureBlueShell2, 0x0000023EU, 0x00000400U); - dma_textures(gTextureBlueShell3, 0x00000243U, 0x00000400U); - dma_textures(gTextureBlueShell4, 0x00000255U, 0x00000400U); - dma_textures(gTextureBlueShell5, 0x00000259U, 0x00000400U); - dma_textures(gTextureBlueShell6, 0x00000239U, 0x00000400U); - dma_textures(gTextureBlueShell7, 0x00000236U, 0x00000400U); + D_802BA050 = dma_textures(texture_green_shell_0, 0x00000257U, 0x00000400U); + dma_textures(texture_green_shell_1, 0x00000242U, 0x00000400U); + dma_textures(texture_green_shell_2, 0x00000259U, 0x00000400U); + dma_textures(texture_green_shell_3, 0x00000256U, 0x00000400U); + dma_textures(texture_green_shell_4, 0x00000246U, 0x00000400U); + dma_textures(texture_green_shell_5, 0x0000025EU, 0x00000400U); + dma_textures(texture_green_shell_6, 0x0000025CU, 0x00000400U); + dma_textures(texture_green_shell_7, 0x00000254U, 0x00000400U); + D_802BA054 = dma_textures(texture_blue_shell_0, 0x0000022AU, 0x00000400U); + dma_textures(texture_blue_shell_1, 0x00000237U, 0x00000400U); + dma_textures(texture_blue_shell_2, 0x0000023EU, 0x00000400U); + dma_textures(texture_blue_shell_3, 0x00000243U, 0x00000400U); + dma_textures(texture_blue_shell_4, 0x00000255U, 0x00000400U); + dma_textures(texture_blue_shell_5, 0x00000259U, 0x00000400U); + dma_textures(texture_blue_shell_6, 0x00000239U, 0x00000400U); + dma_textures(texture_blue_shell_7, 0x00000236U, 0x00000400U); dma_textures(gTextureFinishLineBanner1, 0x0000028EU, 0x00000800U); dma_textures(gTextureFinishLineBanner2, 0x000002FBU, 0x00000800U); dma_textures(gTextureFinishLineBanner3, 0x00000302U, 0x00000800U); diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index 903e8ac293..c3ca7b8297 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -85,7 +85,7 @@ void func_8028E028(void) { break; } func_800CA118((u8) gPlayerWinningIndex); - D_800DC510 = 5; + gRaceState = 5; gDemoTimer = 10; } @@ -230,7 +230,7 @@ void func_8028E438(void) { func_80019DF4(); } else { func_80092564(); - D_800DC510 = 7; + gRaceState = 7; } } break; @@ -408,7 +408,7 @@ void func_8028E678(void) { case 4: gIsInQuitToMenuTransition = 1; gQuitToMenuTransitionCounter = 5; - D_800DC510 = 7; + gRaceState = 7; func_8028E3A0(); break; } @@ -416,7 +416,7 @@ void func_8028E678(void) { UNUSED void func_8028EC38(s32 arg0) { gGotoMode = arg0; - D_800DC510 = 6; + gRaceState = 6; func_800CA330(25); func_800CA388(25); D_800DC5B4 = 1; @@ -512,8 +512,8 @@ void start_race(void) { play_music_for_current_track(gCurrentCourseId); } - if (D_800DC510 == 2) { - D_800DC510 = 3; + if (gRaceState == 2) { + gRaceState = 3; } for (i = 0; i < NUM_PLAYERS; i++) { @@ -589,10 +589,10 @@ void func_8028EF28(void) { // Inner if required for precise finish times. // Otherwise, higher port numbers can reset the state after a lower // port number finished 2nd to last, concluding the race - if (D_800DC510 <= 4){ + if (gRaceState <= 4){ // 4 means somebody has finished the race (or something similar) // 5 means 2nd to last has finished, concluding the race - D_800DC510 = 4; + gRaceState = 4; } } if (gModeSelection == TIME_TRIALS) { @@ -609,11 +609,11 @@ void func_8028EF28(void) { // currentPosition = position of player when crossing finish line (0 indexed) // 0 is 1st, 1 is 2nd, 2 is 3rd, 3 is 4th if (currentPosition == 0 ) { // when first finishes - *(gNmiUnknown1 + playerId) += 1; // add tally - if (*(gNmiUnknown1 + playerId) > 99) { - *(gNmiUnknown1 + playerId) = 99; + *(nmi_gVersusResults2P + playerId) += 1; // add tally + if (*(nmi_gVersusResults2P + playerId) > 99) { + *(nmi_gVersusResults2P + playerId) = 99; } - D_800DC510 = 5; + gRaceState = 5; playerIdLast = gPlayerPositionLUT[1]; // get 2nd place player position gPlayers[playerIdLast].triggers |= SPINOUT_TRIGGER; // spin out 2nd place player gPlayers[playerIdLast].type |= PLAYER_CPU; // cpu control 2nd place player @@ -622,21 +622,21 @@ void func_8028EF28(void) { break; case 3: if (currentPosition < 2) { - *(gNmiUnknown2 + playerId * 3 + currentPosition) += 1; + *(nmi_gVersusResults3P + playerId * 3 + currentPosition) += 1; - if (*(gNmiUnknown2 + playerId * 3 + currentPosition) > 99) { - *(gNmiUnknown2 + playerId * 3 + currentPosition) = 99; + if (*(nmi_gVersusResults3P + playerId * 3 + currentPosition) > 99) { + *(nmi_gVersusResults3P + playerId * 3 + currentPosition) = 99; } /* Because the last player may not finish, their score must be updated when the 2nd to last racer finishes. */ if (currentPosition == 1) { - D_800DC510 = 5; // triggers results screen + gRaceState = 5; // triggers results screen playerIdLast = gPlayerPositionLUT[2]; // update 3rd place (last) tally here because they may not cross finish line - *(gNmiUnknown2 + playerIdLast * 3 + 2) += 1; - if (*(gNmiUnknown2 + playerIdLast * 3 + 2) > 99) { - *(gNmiUnknown2 + playerIdLast * 3 + 2) = 99; + *(nmi_gVersusResults3P + playerIdLast * 3 + 2) += 1; + if (*(nmi_gVersusResults3P + playerIdLast * 3 + 2) > 99) { + *(nmi_gVersusResults3P + playerIdLast * 3 + 2) = 99; } gPlayers[playerIdLast].triggers |= SPINOUT_TRIGGER; // spin out 3rd place player gPlayers[playerIdLast].type |= PLAYER_CPU; // cpu control 3rd place @@ -647,14 +647,14 @@ void func_8028EF28(void) { case 4: // 4th place gets no tally if (currentPosition < 3) { - *(gNmiUnknown3 + playerId * 3 + currentPosition) += 1; - if (*(gNmiUnknown3 + playerId * 3 + currentPosition) > 99) { - *(gNmiUnknown3 + playerId * 3 + currentPosition) = 99; + *(nmi_gVersusResults4P + playerId * 3 + currentPosition) += 1; + if (*(nmi_gVersusResults4P + playerId * 3 + currentPosition) > 99) { + *(nmi_gVersusResults4P + playerId * 3 + currentPosition) = 99; } } // if 3rd has finished, race is over if (currentPosition == 2) { - D_800DC510 = 5; + gRaceState = 5; playerIdLast = gPlayerPositionLUT[3]; // get 4th place player position gPlayers[playerIdLast].triggers |= SPINOUT_TRIGGER; // spin out 4th place gPlayers[playerIdLast].type |= PLAYER_CPU; // cpu control 4th place @@ -707,7 +707,7 @@ void update_race_position_data(void) { void func_8028F474(void) { s32 i; - switch (D_800DC510) { + switch (gRaceState) { case 3: case 4: case 5: @@ -730,7 +730,7 @@ void func_8028F4E8(void) { func_800CA330(0x19); func_800CA388(0x19); gGotoMode = START_MENU_FROM_QUIT; - D_800DC510 = 6; + gRaceState = 6; D_800DC5B4 = 1; D_800DC5B0 = 1; D_800DC5B8 = 0; @@ -954,7 +954,7 @@ void func_8028F970(void) { void func_8028FBD4(void) { gGotoMode = START_MENU_FROM_QUIT; - D_800DC510 = 6; + gRaceState = 6; func_800CA330(25); func_800CA388(25); D_800DC5B4 = 1; @@ -994,7 +994,7 @@ void func_8028FCBC(void) { if (gDemoUseController) { end_demo_update(); } - switch (D_800DC510) { + switch (gRaceState) { case 0: if (!gDemoMode) { // If we're not in the demo mode, play the starting fanfare for the current mode (Grand Prix / Time Trials / VS / Battle) if (gModeSelection == GRAND_PRIX) { @@ -1006,7 +1006,7 @@ void func_8028FCBC(void) { } } func_80002DAC(); - D_800DC510 = 1; + gRaceState = 1; D_80150118 = 3.0f; creditsRenderMode = 0; D_802BA032 = 0; @@ -1039,7 +1039,7 @@ void func_8028FCBC(void) { func_802A7728(); } } - D_800DC510 = 2; + gRaceState = 2; D_800DC5B0 = 0; D_800DC5B8 = 1; func_80078F64(); @@ -1090,7 +1090,7 @@ void func_8028FCBC(void) { switch (gScreenModeSelection) { case SCREEN_MODE_1P: gDemoTimer = 690; - D_800DC510 = 5; + gRaceState = 5; func_8028E298(); break; case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: @@ -1106,7 +1106,7 @@ void func_8028FCBC(void) { func_8028E298(); gDemoTimer = 600; - D_800DC510 = 5; + gRaceState = 5; } break; } @@ -1120,9 +1120,9 @@ void func_8028FCBC(void) { case TIME_TRIALS: gDemoTimer = 360; if (D_8015F890 != 0) { - D_800DC510 = 7; + gRaceState = 7; } else { - D_800DC510 = 5; + gRaceState = 5; } break; } @@ -1137,7 +1137,7 @@ void func_8028FCBC(void) { func_8028E678(); } else if (gScreenModeSelection == SCREEN_MODE_1P) { func_80092564(); - D_800DC510 = 7; + gRaceState = 7; } else { func_8028E438(); } diff --git a/src/render_objects.c b/src/render_objects.c index 52ffc211fa..3f9aaf4187 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -2847,7 +2847,7 @@ void func_800508C0(void) { u16 var_s2; if (gModeSelection == TIME_TRIALS) { - var_s0 = D_80164378[0]; + var_s0 = gPrevPlayerIdByRank[0]; } else { var_s0 = gGPCurrentRacePlayerIdByRank[0]; } diff --git a/src/render_player.c b/src/render_player.c index ca979a9775..b3af9c91d8 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -1340,14 +1340,14 @@ void render_player_shadow(Player* player, s8 playerId, s8 screenId) { gSPDisplayList(gDisplayListHead++, D_0D008D58); gDPSetTextureLUT(gDisplayListHead++, G_TT_NONE); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D474, G_IM_FMT_I, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, + gDPLoadTextureBlock(gDisplayListHead++, gLoadedTextureKartShadow, G_IM_FMT_I, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); func_8004B414(0, 0, 0, 0xFF); gDPSetRenderMode(gDisplayListHead++, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2); gSPVertex(gDisplayListHead++, &D_800E51D0[0], 4, 0); gSPDisplayList(gDisplayListHead++, common_square_plain_render); - gDPLoadTextureBlock(gDisplayListHead++, (D_8018D474 + SOME_TEXTURE_POINTER_MATH), G_IM_FMT_I, G_IM_SIZ_8b, 64, 32, + gDPLoadTextureBlock(gDisplayListHead++, (gLoadedTextureKartShadow + SOME_TEXTURE_POINTER_MATH), G_IM_FMT_I, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); func_8004B414(0, 0, 0, 0xFF); @@ -1394,14 +1394,14 @@ void render_player_shadow_credits(Player* player, s8 playerId, s8 arg2) { gSPDisplayList(gDisplayListHead++, D_0D008D58); gDPSetTextureLUT(gDisplayListHead++, G_TT_NONE); - gDPLoadTextureBlock(gDisplayListHead++, D_8018D474, G_IM_FMT_I, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, + gDPLoadTextureBlock(gDisplayListHead++, gLoadedTextureKartShadow, G_IM_FMT_I, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); func_8004B414(0, 0, 0, 0x000000D0); gDPSetRenderMode(gDisplayListHead++, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2); gSPVertex(gDisplayListHead++, &D_800E51D0[0], 4, 0); gSPDisplayList(gDisplayListHead++, common_square_plain_render); - gDPLoadTextureBlock(gDisplayListHead++, (D_8018D474 + SOME_TEXTURE_POINTER_MATH), G_IM_FMT_I, G_IM_SIZ_8b, 64, 32, + gDPLoadTextureBlock(gDisplayListHead++, (gLoadedTextureKartShadow + SOME_TEXTURE_POINTER_MATH), G_IM_FMT_I, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); func_8004B414(0, 0, 0, 0x000000D0); diff --git a/src/spawn_players.c b/src/spawn_players.c index 99fdf0e936..019ae736c2 100644 --- a/src/spawn_players.c +++ b/src/spawn_players.c @@ -355,7 +355,7 @@ void spawn_player(Player* player, s8 playerIndex, f32 startingRow, f32 startingC D_8018CE10[playerIndex].unk_04[0] = 0.0f; D_8018CE10[playerIndex].unk_04[2] = 0.0f; func_80295BF8(playerIndex); - func_8005D6C0(player); + reset_player_particle_pool(player); clear_all_player_balloons(player, playerIndex); if (gModeSelection == BATTLE) { init_all_player_balloons(player, playerIndex); diff --git a/src/textures.h b/src/textures.h index ac23a4b78b..1fa36a62be 100644 --- a/src/textures.h +++ b/src/textures.h @@ -253,51 +253,51 @@ extern MkAnimation D_020020DC[2]; extern MkAnimation D_020020EC[2]; extern MkAnimation D_020020FC[2]; extern MkAnimation D_0200210C[2]; -extern MenuTexture D_0200211C[2]; -extern MenuTexture D_02002144[2]; -extern MenuTexture D_0200216C[2]; -extern MenuTexture D_02002194[2]; -extern MenuTexture D_020021BC[2]; -extern MenuTexture D_020021E4[2]; -extern MenuTexture D_0200220C[2]; -extern MenuTexture D_02002234[2]; -extern MenuTexture D_0200225C[2]; -extern MenuTexture D_02002284[2]; -extern MenuTexture D_020022AC[2]; -extern MenuTexture D_020022D4[2]; -extern MenuTexture D_020022FC[2]; -extern MenuTexture D_02002324[2]; -extern MenuTexture D_0200234C[2]; -extern MenuTexture D_02002374[2]; -extern MenuTexture D_0200239C[2]; -extern MenuTexture D_020023C4[2]; -extern MenuTexture D_020023EC[2]; -extern MenuTexture D_02002414[2]; -extern MenuTexture D_0200243C[2]; -extern MenuTexture D_02002464[2]; -extern MenuTexture D_0200248C[2]; -extern MenuTexture D_020024B4[2]; -extern MenuTexture D_020024DC[2]; -extern MenuTexture D_02002504[2]; -extern MenuTexture D_0200252C[2]; -extern MenuTexture D_02002554[2]; -extern MenuTexture D_0200257C[2]; -extern MenuTexture D_020025A4[2]; -extern MenuTexture D_020025CC[2]; -extern MenuTexture D_020025F4[2]; -extern MenuTexture D_0200261C[2]; -extern MenuTexture D_02002644[2]; -extern MenuTexture D_0200266C[2]; -extern MenuTexture D_02002694[2]; -extern MenuTexture D_020026BC[2]; -extern MenuTexture D_020026E4[2]; -extern MenuTexture D_0200270C[2]; -extern MenuTexture D_02002734[2]; -extern MenuTexture D_0200275C[2]; -extern MenuTexture D_02002784[2]; -extern MenuTexture D_020027AC[2]; -extern MenuTexture D_020027D4[2]; -extern MenuTexture D_020027FC[2]; +extern MenuTexture seg2_textureFontLetterA[2]; +extern MenuTexture seg2_textureFontLetterB[2]; +extern MenuTexture seg2_textureFontLetterC[2]; +extern MenuTexture seg2_textureFontLetterD[2]; +extern MenuTexture seg2_textureFontLetterE[2]; +extern MenuTexture seg2_textureFontLetterF[2]; +extern MenuTexture seg2_textureFontLetterG[2]; +extern MenuTexture seg2_textureFontLetterH[2]; +extern MenuTexture seg2_textureFontLetterI[2]; +extern MenuTexture seg2_textureFontLetterJ[2]; +extern MenuTexture seg2_textureFontLetterK[2]; +extern MenuTexture seg2_textureFontLetterL[2]; +extern MenuTexture seg2_textureFontLetterM[2]; +extern MenuTexture seg2_textureFontLetterN[2]; +extern MenuTexture seg2_textureFontLetterO[2]; +extern MenuTexture seg2_textureFontLetterP[2]; +extern MenuTexture seg2_textureFontLetterQ[2]; +extern MenuTexture seg2_textureFontLetterR[2]; +extern MenuTexture seg2_textureFontLetterS[2]; +extern MenuTexture seg2_textureFontLetterT[2]; +extern MenuTexture seg2_textureFontLetterU[2]; +extern MenuTexture seg2_textureFontLetterV[2]; +extern MenuTexture seg2_textureFontLetterW[2]; +extern MenuTexture seg2_textureFontLetterX[2]; +extern MenuTexture seg2_textureFontLetterY[2]; +extern MenuTexture seg2_textureFontLetterZ[2]; +extern MenuTexture seg2_textureFontExclamationMark[2]; +extern MenuTexture seg2_textureFontMinus[2]; +extern MenuTexture seg2_textureFontInterogationMark[2]; +extern MenuTexture seg2_textureFontSimpleQuote[2]; +extern MenuTexture seg2_textureFontDoubleQuote[2]; +extern MenuTexture seg2_textureFontPlus[2]; +extern MenuTexture seg2_textureFontDot[2]; +extern MenuTexture seg2_textureFontFourDote[2]; +extern MenuTexture seg2_textureFontCC[2]; +extern MenuTexture seg2_textureFontNumberZero[2]; +extern MenuTexture seg2_textureFontNumberOne[2]; +extern MenuTexture seg2_textureFontNumberTwo[2]; +extern MenuTexture seg2_textureFontNumberThree[2]; +extern MenuTexture seg2_textureFontNumberFour[2]; +extern MenuTexture seg2_textureFontNumberFive[2]; +extern MenuTexture seg2_textureFontNumberSix[2]; +extern MenuTexture seg2_textureFontNumberSeven[2]; +extern MenuTexture seg2_textureFontNumberEight[2]; +extern MenuTexture seg2_textureFontNumberNine[2]; extern MenuTexture D_02002824[2]; extern MenuTexture D_0200284C[2]; extern MenuTexture D_02002874[2]; @@ -484,9 +484,9 @@ extern MenuTexture D_02004494[2]; extern MenuTexture D_020044BC[2]; extern MenuTexture D_020044E4[2]; extern MenuTexture D_0200450C[2]; -extern MenuTexture D_02004534[2]; +extern MenuTexture seg2_textureFontComma[2]; extern MenuTexture D_0200455C[2]; -extern MenuTexture D_02004584[1]; +extern MenuTexture seg2_textureFontEmpty[1]; extern MenuTexture seg2_blue_sky_background_texture[2]; extern MenuTexture seg2_sunset_background_texture[2]; extern MenuTexture seg2_copyright_1996_texture[2]; @@ -503,7 +503,7 @@ extern MenuTexture D_0200482C[2]; extern MenuTexture D_02004854[2]; extern MenuTexture D_0200487C[2]; extern MenuTexture D_020048A4[2]; -extern MenuTexture D_020048CC[2]; +extern MenuTexture seg2_textureMenuRData[2]; extern MenuTexture seg2_50_CC_texture[2]; extern MenuTexture seg2_100_CC_texture[2]; extern MenuTexture seg2_150_CC_texture[2]; @@ -1084,11 +1084,11 @@ extern u64 gTexture7F9CF4[]; extern u64 gTexture7F9DC4[]; extern u64 gTexture7F9E44[]; extern u64 gTexture7F9EC4[]; -extern u64 gTexture7FA044[]; +extern u64 font_apostrophe[]; extern u64 gTexture7FA0C4[]; extern u64 gTexture7FA194[]; extern u64 gTexture7FA264[]; -extern u64 gTexture7FA334[]; +extern u64 font_comma[]; extern u64 gTextureBackgroundBlueSky[]; extern u64 gTextureBackgroundSunset[]; extern u64 gTextureBowserFace00[]; @@ -1242,7 +1242,7 @@ extern u64 gTextureSmallFont6[]; extern u64 gTextureSmallFont7[]; extern u64 gTextureSmallFont8[]; extern u64 gTextureSmallFont9[]; -extern u64 gTextureSmallGreenTriangle[]; +extern u64 texture_small_green_triangle[]; extern u64 gTextureTableOfContents[]; extern u64 gTextureTextEnd[]; extern u64 gTextureTextErase[]; From 20913141d20ae9ccb9fc8bb98f0c12a718c7d13b Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sun, 26 Jul 2026 12:55:20 -0400 Subject: [PATCH 58/73] bot stuff --- src/menus.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/menus.c b/src/menus.c index 4655d352b4..7c584d55ff 100644 --- a/src/menus.c +++ b/src/menus.c @@ -185,6 +185,45 @@ static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 3, 3, 2, 2, 4, 2 /**************************/ +void checkPlayersAndSelectComputers(void) { + s32 i; + s32 allHumansReady = 1; + + // 1. First, verify all HUMAN players have locked in their characters + for (i = 0; i < gPlayerCount; i++) { + // If the controller bit is set (1 << i checks bits 1, 2, 4, 8) + if ((gControllerBits & (1 << i)) != 0) { + // It's a human player. Have they picked a character? + if (!gCharacterGridIsSelected[i]) { + allHumansReady = 0; + break; // Stop checking, we are still waiting on a human + } + } + } + + // 2. Once humans are done, fill the UNPLUGGED slots with bots + if (allHumansReady) { + for (i = 0; i < gPlayerCount; i++) { + // If the controller bit is 0 (Unplugged) + if ((gControllerBits & (1 << i)) == 0) { + + // If the bot hasn't been locked in yet + if (!gCharacterGridIsSelected[i]) { + + // 1. Assign the bot's choice to the grid cursor array + gCharacterGridSelections[i] = (random_u16() % 8) +1; + + // 2. Lock it in (this perfectly mimics pressing the A button) + gCharacterGridIsSelected[i] = true; + + // 3. Play the character's selection voice line + func_800C90F4(i, ((sCharacterGridOrder - 1)[gCharacterGridSelections[i]] * 0x10) + 0x2900800E); + } + } + } + } +} + /** * General menu main handler * Includes opening logo and splash screens @@ -246,6 +285,9 @@ void update_menus(void) { case PLAYER_SELECT_MENU_FROM_QUIT: case CHARACTER_SELECT_MENU: player_select_menu_act(&gControllers[controllerIdx], controllerIdx); + if (/*gPracticeMode &&*/ (gModeSelection == VERSUS)) { + checkPlayersAndSelectComputers(); + } break; case COURSE_SELECT_MENU_FROM_QUIT: case COURSE_SELECT_MENU: @@ -1598,7 +1640,7 @@ void player_select_menu_act(struct Controller* controller, u16 controllerIdx) { play_sound2(SOUND_MENU_GO_BACK); } } - + // pressing A to select character on character select screen + playing character audio if ((btnAndStick & A_BUTTON) && (gCharacterGridIsSelected[controllerIdx] == 0)) { gCharacterGridIsSelected[controllerIdx] = true; func_800C90F4(controllerIdx, ((sCharacterGridOrder - 1)[gCharacterGridSelections[controllerIdx]] * 0x10) + 0x2900800E); @@ -1844,6 +1886,7 @@ void course_select_menu_act(struct Controller* arg0, u16 controllerIdx) { play_sound2(SOUND_MENU_GO_BACK); return; } + // if all characters have been selected, any player can press A to continue to course select if ((btnAndStick & A_BUTTON) != 0) { func_8009E1C0(); func_800CA330(0x19); From d9bc30fa72e42fc197da31d6f89c1b34e059fa2a Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sun, 26 Jul 2026 17:15:44 -0400 Subject: [PATCH 59/73] implemented vs practice mode with bots; removed old, unused code --- .../cpu_speed_control.inc.c | 7 ++++ src/menu_items.c | 39 +++++++------------ src/menu_items.h | 8 +--- src/menus.c | 26 ++++++++++--- src/menus.h | 2 +- src/racing/race_logic.c | 7 +++- src/spawn_players.c | 14 +++++++ 7 files changed, 61 insertions(+), 42 deletions(-) diff --git a/src/cpu_vehicles_camera_path/cpu_speed_control.inc.c b/src/cpu_vehicles_camera_path/cpu_speed_control.inc.c index 1ba70abfc2..c82320425f 100644 --- a/src/cpu_vehicles_camera_path/cpu_speed_control.inc.c +++ b/src/cpu_vehicles_camera_path/cpu_speed_control.inc.c @@ -145,6 +145,13 @@ void regulate_cpu_speed(s32 playerId, f32 targetSpeed, Player* player) { player->velocity[2] = 0.0f; } } else { + if (gPracticeMode) { + if ((gModeSelection == VERSUS) && (player->type & PLAYER_CPU)) { + player->effects |= CPU_FAST_EFFECT; + player_accelerate_alternative(player); + return; + } + } var_f0 = 3.3333333f; switch (gCCSelection) { /* irregular */ case CC_100: diff --git a/src/menu_items.c b/src/menu_items.c index 833ed5bf73..1b7b6f8e42 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -371,30 +371,7 @@ s8 gTournamentAA = 0; s8 gTournamentForceMap = 0; s8 gTournamentShellLimit = 0; // not currently in menu s8 gTournamentExtraMode = 0; - - - -// Course name abbreviations for each tournament mode -char* gCourseNamesVA[] = { - "LR", "MMF", "KTB", "KD", - "DKJP", "YV", "BB", "RRd", - "WS", "SL", "RRy", "BC", - "TT", "FS", "CM", "MR" -}; - -char* gCourseNamesKA[] = { - "LR", "MMF", "KTB", "KD", - "TT", "FS", "CM", "MR", - "WS", "SL", "RRy", "BC", - "DKJP", "YV", "BB", "RRd" -}; - -char* gCourseNamesKA_MMF[] = { - "LR", "MMF", "KTB", "KD", - "TT", "FS", "CM", "MR", - "WS", "SL", "RRy", "BC", - "DKJP", "YV", "BB", "MMF" -}; +s8 gPracticeMode = 0; char* gCupText[] = { "none", @@ -5824,7 +5801,8 @@ void render_custom_overlay(void) { "mp train boat", "AA", "force minimap", - "extra" + "extra", + "practice mode" /* keep last empty if CUSTOM_MENU_ROWS > 12 */ }; @@ -5838,6 +5816,7 @@ void render_custom_overlay(void) { static const char* AA_labels[] = {"default", "disabled"}; static const char* minimap_labels[] = {"default", "prog view", "map"}; static const char* extra_labels[] = {"default", "enabled"}; + static const char* practice_labels[] = {"default", "enabled"}; set_text_color(TEXT_YELLOW); @@ -5845,7 +5824,7 @@ void render_custom_overlay(void) { print_text1_center_mode_1(x, y - 0x28, "WEATHERTON ABNEY CLIMATEE ZSERF DNTN31", 0, 0.60f, 0.60f); // version / date (smaller) - left-aligned to start under 'KART' - print_text1_left(x + 0x78, y + 0x06, "TE V2026-07-21 RELEASE 1", 0, 0.65f, 0.65f); + print_text1_left(x + 0x78, y + 0x06, "TE V2026-07-26 RELEASE 1.1b", 0, 0.65f, 0.65f); // option name placeholders (second column) and values (third column) for (i = 0; i < CUSTOM_MENU_ROWS; i++) { @@ -5945,6 +5924,14 @@ void render_custom_overlay(void) { print_text1_center_mode_1(x + 0x50, rowY, (char*)extra_labels[idx], 0, 0.6f, 0.6f); gTournamentExtraMode = idx; break; + case 9: + /* practice: labels (default, enabled) */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + if (idx >= (int)(sizeof(practice_labels) / sizeof(practice_labels[0]))) idx = 0; + print_text1_center_mode_1(x + 0x50, rowY, (char*)practice_labels[idx], 0, 0.6f, 0.6f); + gPracticeMode = idx; + break; } } } diff --git a/src/menu_items.h b/src/menu_items.h index a1e32bd075..4573c76d82 100644 --- a/src/menu_items.h +++ b/src/menu_items.h @@ -851,13 +851,6 @@ extern f32 D_8018EDA8; extern f32 D_8018EDAC; extern s8 gTournamentCourseMode; -extern const s16 gVACourseOrder[4][4]; -extern const s16 gKACourseOrder[4][4]; -extern const s16 gKAMMFCourseOrder[4][4]; -extern char* gCourseNamesVA[]; -extern char* gCourseNamesKA[]; -extern char* gCourseNamesKA_MMF[]; - extern s8 gTournamentCharacterStats; extern s8 gTournamentScaling; extern s8 gTournamentWidescreen; @@ -867,5 +860,6 @@ extern s8 gTournamentAA; extern s8 gTournamentShellLimit; // unused extern s8 gTournamentForceMap; extern s8 gTournamentExtraMode; +extern s8 gPracticeMode; #endif diff --git a/src/menus.c b/src/menus.c index 7c584d55ff..dac775f906 100644 --- a/src/menus.c +++ b/src/menus.c @@ -178,21 +178,35 @@ s8 gCustomMenuOptionValues[CUSTOM_MENU_ROWS] = { 0 }; // Per-row number of selectable values (matches label arrays in render_custom_overlay) // tracks, stats, scaling, widescreen, mp music, mp train boat, AA, force minimap, -// extra -static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 3, 3, 2, 2, 4, 2, 3, 2 }; +// extra, practice mode +static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 3, 3, 2, 2, 4, 2, 3, 2, 2 }; // end of new var init /**************************/ +extern OSContPad gControllerPads[4]; + +u8 getLiveControllerBits(void) { + u8 bits = 0; + s32 i; + for (i=0; i<4; i++) { + if (gControllerPads[i].errno == 0) { + bits |= (1 << i); + } + } + return bits; +} + void checkPlayersAndSelectComputers(void) { s32 i; s32 allHumansReady = 1; + u8 physicalBits = getLiveControllerBits(); // 1. First, verify all HUMAN players have locked in their characters for (i = 0; i < gPlayerCount; i++) { // If the controller bit is set (1 << i checks bits 1, 2, 4, 8) - if ((gControllerBits & (1 << i)) != 0) { + if ((physicalBits & (1 << i)) != 0) { // It's a human player. Have they picked a character? if (!gCharacterGridIsSelected[i]) { allHumansReady = 0; @@ -205,13 +219,13 @@ void checkPlayersAndSelectComputers(void) { if (allHumansReady) { for (i = 0; i < gPlayerCount; i++) { // If the controller bit is 0 (Unplugged) - if ((gControllerBits & (1 << i)) == 0) { + if ((physicalBits & (1 << i)) == 0) { // If the bot hasn't been locked in yet if (!gCharacterGridIsSelected[i]) { // 1. Assign the bot's choice to the grid cursor array - gCharacterGridSelections[i] = (random_u16() % 8) +1; + gCharacterGridSelections[i] = (random_u16() % 8) + 1; // 2. Lock it in (this perfectly mimics pressing the A button) gCharacterGridIsSelected[i] = true; @@ -285,7 +299,7 @@ void update_menus(void) { case PLAYER_SELECT_MENU_FROM_QUIT: case CHARACTER_SELECT_MENU: player_select_menu_act(&gControllers[controllerIdx], controllerIdx); - if (/*gPracticeMode &&*/ (gModeSelection == VERSUS)) { + if (gPracticeMode && (gModeSelection == VERSUS)) { checkPlayersAndSelectComputers(); } break; diff --git a/src/menus.h b/src/menus.h index 8d81966500..f08d29f556 100644 --- a/src/menus.h +++ b/src/menus.h @@ -265,7 +265,7 @@ extern const s16 gCupCourseOrder[NUM_CUPS][NUM_COURSES_PER_CUP]; // end of menus.c variables // start of custom menu var -#define CUSTOM_MENU_ROWS 9 +#define CUSTOM_MENU_ROWS 10 #define CUSTOM_MENU_VALUE_COUNT 3 extern s8 gCustomMenuTitle; // tournament rom credits title diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index c3ca7b8297..a7ef790b21 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -24,6 +24,7 @@ #include "math.h" #include "menus.h" #include "seq_ids.h" +#include "spawn_players.h" #pragma intrinsic(sqrtf) @@ -48,6 +49,8 @@ UNUSED s32 D_802BA03C; s16 D_802BA040[4]; u16 D_802BA048; +bool gPracticeCPU[4]; + void func_8028DF00(void) { struct Controller* controllers = &gControllers[0]; s32 i; @@ -563,8 +566,8 @@ void func_8028EF28(void) { } else if (gLapCountByPlayerId[playerId] > player->lapCount) { player->lapCount++; - // if slot has an active player - if ((player->type & PLAYER_HUMAN) != 0) { + // if slot has an active player or practice CPU + if ((player->type & PLAYER_HUMAN) || gPracticeCPU[playerId]) { // if player finishes (3 = starting 4th lap = finished) if (player->lapCount == 3) { add_cinematic_mode(playerId); diff --git a/src/spawn_players.c b/src/spawn_players.c index 019ae736c2..58a1597299 100644 --- a/src/spawn_players.c +++ b/src/spawn_players.c @@ -72,6 +72,9 @@ s16 D_8016557E; s16 D_80165580; s16 D_80165582; +extern u8 getLiveControllerBits(void); +extern bool gPracticeCPU[4]; + // arg4 is height? Or something like that? void spawn_player(Player* player, s8 playerIndex, f32 startingRow, f32 startingColumn, f32 arg4, f32 arg5, u16 characterId, s16 playerType) { @@ -80,6 +83,17 @@ void spawn_player(Player* player, s8 playerIndex, f32 startingRow, f32 startingC s32 statsCharacterId; s32 statsCCIndex; + /* empty-port human in VS -> spawn CPU in all versus modes */ + if (gPracticeMode) { + if ((gModeSelection == VERSUS) && !gDemoMode + && (playerType & PLAYER_HUMAN) + && !(playerType & PLAYER_INVISIBLE_OR_BOMB) + && !(getLiveControllerBits() & (1 << playerIndex))) { + playerType = (playerType & ~PLAYER_HUMAN | PLAYER_CPU); + gPracticeCPU[playerIndex] = true; + } + } + player->type = PLAYER_INACTIVE; player->unk_08C = 0; player->characterId = characterId; From 538c9b51adc196c46c9d404ce360562e07f66bd6 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Mon, 27 Jul 2026 17:42:11 -0400 Subject: [PATCH 60/73] added important documentation regarding netplay builds --- asm/rom_header.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asm/rom_header.s b/asm/rom_header.s index 119f217f32..7c6dec7008 100644 --- a/asm/rom_header.s +++ b/asm/rom_header.s @@ -14,7 +14,7 @@ .word 0x2E92DA52 /* Checksum 2 */ .word 0x00000000 /* Unknown */ .word 0x00000000 /* Unknown */ -.ascii "MARIOKART64 " /* Internal ROM name */ +.ascii "MARIOKART64 " /* Internal ROM name. Change to MK64 NETPLAY for netplay builds */ .word 0x00000000 /* Unknown */ .word 0x0000004E /* Cartridge */ .ascii "KT" /* Cartridge ID */ From 345c0e69f0de169b62dbe3634dea9ff583ac8a72 Mon Sep 17 00:00:00 2001 From: Jed Grabman Date: Thu, 30 Jul 2026 05:15:13 -0400 Subject: [PATCH 61/73] Show non-winning times as offsets Show non-winning times as offsets If a player finishes 2 seconds behind the leader, their time will now show as +2"000 instead of their finish time Dev notes: New function `time_to_ascii` for formatting times as text, with various options --- include/defines.h | 3 ++ src/code_80057C60.c | 1 + src/code_80057C60.h | 1 + src/cpu_vehicles_camera_path.c | 4 ++ src/menu_items.c | 69 ++++++++++++-------------------- src/render_objects.c | 73 ++++++++++++++++++++++++++-------- src/render_objects.h | 3 +- 7 files changed, 93 insertions(+), 61 deletions(-) diff --git a/include/defines.h b/include/defines.h index c210ec9591..5467517e3e 100644 --- a/include/defines.h +++ b/include/defines.h @@ -442,3 +442,6 @@ enum PLACE { FIRST_PLACE, SECOND_PLACE, THIRD_PLACE, FOURTH_PLACE }; #define FACING_Y_AXIS 0x4000 #define FACING_X_AXIS 0x8000 #define FACING_Z_AXIS 0x2000 + +// offset between digits and their ascii representations +#define NUM_TO_ASCII_OFFSET 48 diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 654f7a9c8d..d52249346e 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -43,6 +43,7 @@ bool gFinished[8]; f32 gFinishTime[8]; +f32 gWinnerTime; s32 D_80165590; s32 D_80165594; s32 D_80165598; diff --git a/src/code_80057C60.h b/src/code_80057C60.h index 690b558bcc..49adf9feb8 100644 --- a/src/code_80057C60.h +++ b/src/code_80057C60.h @@ -259,6 +259,7 @@ void func_80085214(); extern bool gFinished[]; extern f32 gFinishTime[]; +extern f32 gWinnerTime; extern s16 D_800E4730[]; extern u8** D_800E4770[]; extern u8** D_800E47A0[]; diff --git a/src/cpu_vehicles_camera_path.c b/src/cpu_vehicles_camera_path.c index 6abe997cd9..c4692572de 100644 --- a/src/cpu_vehicles_camera_path.c +++ b/src/cpu_vehicles_camera_path.c @@ -1265,6 +1265,9 @@ void update_player_path_completion(s32 playerId, Player* player) { if ((gLapCountByPlayerId[playerId] == 3) && !gFinished[playerId]){ gFinished[playerId] = true; gFinishTime[playerId] = time_crossed_finish_line(playerId, previousPlayerZ, playerZ); + if (gFinishTime[playerId] < gWinnerTime){ + gWinnerTime = gFinishTime[playerId]; + } } if ((gModeSelection == GRAND_PRIX) && (gLapCountByPlayerId[playerId] == 5)) { if (gGPCurrentRaceRankByPlayerIdDup[playerId] == 7) { @@ -2105,6 +2108,7 @@ void init_players(void) { gFinished[i] = false; // arbitrary large number to be longer than any vs race gFinishTime[i] = 1000000.0f; + gWinnerTime = 1000000.0f; if (gModeSelection == GRAND_PRIX) { if (1) {}; if (1) {}; // Maybe some debug code? diff --git a/src/menu_items.c b/src/menu_items.c index 1b7b6f8e42..138a62eb63 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -8610,8 +8610,7 @@ void func_800A69C8(UNUSED MenuItem* arg0) { s32 var_v1; char* temp_s3; u8* var_s4; - s32 finishTimeCopy; - char finishTimeText[8]; + char* finishTimeText; for (playerId = 0; playerId < gPlayerCount; playerId++) { var_v1 = 0; @@ -8637,7 +8636,7 @@ void func_800A69C8(UNUSED MenuItem* arg0) { set_text_color((s32) gGlobalTimer % 3); } func_800A79F4(var_s4[0], sp74); - text_draw(thing->column + 0x10, thing->row + 0x75 + 10, sp74, 0, 1.0f, 1.0f); + text_draw(thing->column + 16, thing->row + 127, sp74, 0, 1.0f, 1.0f); print_text1_center_mode_2(D_800E7380[playerId].column, D_800E7380[playerId].row, temp_s3, 0, 0.65f, 1.0f); // show finish time if finished @@ -8645,27 +8644,18 @@ void func_800A69C8(UNUSED MenuItem* arg0) { // winner gets flashing timer if (var_v1 != 1){ set_text_color(gGlobalTimer % 3); + finishTimeText = time_to_ascii(gFinishTime[playerId], 3, true, false); } else{ set_text_color(TEXT_YELLOW); + finishTimeText = time_to_ascii(gFinishTime[playerId] - gWinnerTime, 3, false, true); } - finishTimeCopy = (s32) (1000 * gFinishTime[playerId]); - - // 48 is the offset from digits to ASCII code string representations - finishTimeText[0] = func_8004F674(&finishTimeCopy, 60000) + 48; - finishTimeText[1] = 39; // ' - finishTimeText[2] = func_8004F674(&finishTimeCopy, 10000) + 48; - finishTimeText[3] = func_8004F674(&finishTimeCopy, 1000) + 48; - finishTimeText[4] = 34; // " - finishTimeText[5] = func_8004F674(&finishTimeCopy, 100) + 48; - finishTimeText[6] = func_8004F674(&finishTimeCopy, 10) + 48; - finishTimeText[7] = finishTimeCopy + 48; - text_draw(thing->column, thing->row + 0x75 - 25, finishTimeText, 0, 0.7f, 0.7f); + print_text1_right(thing->column + 60, thing->row + 92, finishTimeText, 0, 0.7f, 0.7f); } } set_text_color(TEXT_BLUE); // Not a hyphen, that is an EUC-JP character - text_draw(0x0000009E, D_800E7300[0].row + 0x6D + 15, "ー", 0, 1.0f, 1.0f); + text_draw(0x0000009E, D_800E7300[0].row + 124, "ー", 0, 1.0f, 1.0f); } /*Iterates over all players and, based on the current mode selection, @@ -8744,8 +8734,7 @@ void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { Unk_D_800E70A0* temp_s0; char sp40[3]; s32 rank; - s32 finishTimeCopy; - char finishTimeText[8]; + char* finishTimeText; // var for drawing scores s32 base_xPos_4p; @@ -8772,9 +8761,9 @@ void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { // base x and y position for drawing scores // x-coord increment will be different for 3p and 4p vs - base_xPos_4p = 0x1A; - base_xPos_3p = 0x34; - Y_pos = 0x1B; + base_xPos_4p = 26; + base_xPos_3p = 52; + Y_pos = 27; // i: player index i = 0; @@ -8850,15 +8839,15 @@ void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { } // calculate x-position to draw vs scores - X_pos = (gPlayerCountSelection1 == 3) ? (base_xPos_3p + (i * 0x4E)) : (base_xPos_4p + (i * 0x45)); + X_pos = (gPlayerCountSelection1 == 3) ? (base_xPos_3p + (i * 78)) : (base_xPos_4p + (i * 69)); // player i points - left-aligned with leftmost visible digit at same X position // if single digit (space padded), offset X by space width so digit aligns with double-digit numbers - draw_offset = (pointsBuf[0] == ' ') ? -0x5 : 0; + draw_offset = (pointsBuf[0] == ' ') ? -5 : 0; text_draw(X_pos + draw_offset , Y_pos, pointsBuf, 0, 0.80f, 0.80f); i++; + } } -} temp_s0 = &D_800E7300[((playerCount - 2) * 4) + playerId]; rank = gGPCurrentRaceRankByPlayerId[playerId]; @@ -8867,48 +8856,40 @@ void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { } else { set_text_color(TEXT_YELLOW); } - text_draw(temp_s0->column + 4, temp_s0->row + 0x69, "1 s ー", 0, 0.8f, 0.8f); + text_draw(temp_s0->column + 4, temp_s0->row + 105, "1 s ー", 0, 0.8f, 0.8f); temp_v0 = placeAry + (playerId * 3); convert_number_to_ascii(temp_v0[0], sp40); // first place tally for each player - text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x69, sp40, 0, 0.8f, 0.8f); + text_draw(temp_s0->column + 45, temp_s0->row + 105, sp40, 0, 0.8f, 0.8f); if (rank == ++rankIdx) { set_text_color(gGlobalTimer % 3); } else { set_text_color(TEXT_BLUE); } - text_draw(temp_s0->column + 4, temp_s0->row + 0x78, "2 n ー", 0, 0.8f, 0.8f); + text_draw(temp_s0->column + 4, temp_s0->row + 120, "2 n ー", 0, 0.8f, 0.8f); convert_number_to_ascii(temp_v0[1], sp40); // second place tally for each player - text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x78, sp40, 0, 0.8f, 0.8f); + text_draw(temp_s0->column + 45, temp_s0->row + 120, sp40, 0, 0.8f, 0.8f); if (++rankIdx == rank) { set_text_color(gGlobalTimer % 3); } else { set_text_color(TEXT_RED); } - text_draw(temp_s0->column + 4, temp_s0->row + 0x87, "3 r ー", 0, 0.8f, 0.8f); + text_draw(temp_s0->column + 4, temp_s0->row + 135, "3 r ー", 0, 0.8f, 0.8f); convert_number_to_ascii(temp_v0[2], sp40); // third place tally for each player - text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x87, sp40, 0, 0.8f, 0.8f); + text_draw(temp_s0->column + 45, temp_s0->row + 135, sp40, 0, 0.8f, 0.8f); // show time if player has finished if (gFinished[playerId]){ // flash timer for winner if (rank == 0){ + finishTimeText = time_to_ascii(gFinishTime[playerId], 3, true, false); set_text_color(gGlobalTimer % 3); } else{ set_text_color(TEXT_YELLOW); + finishTimeText = time_to_ascii(gFinishTime[playerId] - gWinnerTime, 3, false, true); } - finishTimeCopy = (s32) (1000 * gFinishTime[playerId]); - - // 48 is the offset from digits to ASCII code string representations - finishTimeText[0] = func_8004F674(&finishTimeCopy, 60000) + 48; - finishTimeText[1] = 39; // ' - finishTimeText[2] = func_8004F674(&finishTimeCopy, 10000) + 48; - finishTimeText[3] = func_8004F674(&finishTimeCopy, 1000) + 48; - finishTimeText[4] = 34; // " - finishTimeText[5] = func_8004F674(&finishTimeCopy, 100) + 48; - finishTimeText[6] = func_8004F674(&finishTimeCopy, 10) + 48; - finishTimeText[7] = finishTimeCopy + 48; - text_draw(temp_s0->column + 4, temp_s0->row + 0x5A, finishTimeText, 0, 0.7f, 0.7f); + // right aligned to keep digit significance consistent + print_text1_right(temp_s0->column + 60, temp_s0->row + 90, finishTimeText, 0, 0.7f, 0.7f); } } @@ -9036,8 +9017,8 @@ void menu_item_credits_render(MenuItem* arg0) { // Originally func_800A7894 // Presumes that "number" is a 2 digit number. Convert it to a string void convert_number_to_ascii(s32 number, char* buffer) { - buffer[0] = (number / 0xA) + 0x30; - buffer[1] = (number % 0xA) + 0x30; + buffer[0] = (number / 10) + NUM_TO_ASCII_OFFSET; + buffer[1] = (number % 10) + NUM_TO_ASCII_OFFSET; // Terminator buffer[2] = 0; } diff --git a/src/render_objects.c b/src/render_objects.c index 3f9aaf4187..909aad19f3 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -2539,19 +2539,60 @@ void func_8004F3E4(s32 arg0) { } } -s32 func_8004F674(s32* arg0, s32 arg1) { - s32 temp_v0; - s32 ret; - - temp_v0 = *arg0; - if (temp_v0 != 0) { - ret = temp_v0 / arg1; - *arg0 = temp_v0 % arg1; +// The numerator is modified and becomes the remainder +s32 div_s32(s32 *numerator, s32 denominator) { + s32 num_init; + s32 quotient; + + num_init = *numerator; + if (num_init != 0) { + quotient = num_init / denominator; + *numerator = num_init % denominator; } else { - *arg0 = 0; - ret = 0; + *numerator = 0; + quotient = 0; + } + return quotient; +} + +// time: in seconds +// decimal_places: decimal places right of the decimal to show +// keep_leading_zeroes: If true, shows e.g. 0"01"234 instead of 1"234 +// is_offset_value: Adds a "+" before the time. + +// Shows times under 10 minutes +char* time_to_ascii(f32 time, s32 decimal_places, bool keep_leading_zeroes, bool is_offset_value){ + s32 time_copy; + s8 string_idx = 0; + s32 i; + s32 decimal_mult = 1; + char* time_string = ""; + s8 foo; + for (i = 0; i < decimal_places; i++){ + decimal_mult = decimal_mult * 10; + } + time_copy = (s32) (time * decimal_mult); + if (is_offset_value){ + time_string[0] = 0x2B; // + + string_idx = 1; + } + if ((time > 60) | keep_leading_zeroes){ + time_string[string_idx++] = (div_s32(&time_copy, 60 * decimal_mult) + NUM_TO_ASCII_OFFSET); + time_string[string_idx++] = 39; // ' + } + if ((time > 10) | keep_leading_zeroes){ + time_string[string_idx++] = (div_s32(&time_copy, 10 * decimal_mult) + NUM_TO_ASCII_OFFSET); + } + time_string[string_idx++] = (div_s32(&time_copy, decimal_mult) + NUM_TO_ASCII_OFFSET); + if (decimal_places > 0){ + time_string[string_idx++] = 34; + } + for (i = 0; i < decimal_places; i++){ + decimal_mult /= 10; + time_string[string_idx++] = (div_s32(&time_copy, decimal_mult) + NUM_TO_ASCII_OFFSET); } - return ret; + time_string[string_idx++] = '\0'; + return time_string; } void func_8004F6D0(s32 arg0) { @@ -2563,11 +2604,11 @@ void func_8004F6D0(s32 arg0) { if (arg0 >= 599999) { sp24 = 599999; } - D_801657D0[0] = func_8004F674(&sp24, 60000); - D_801657D0[1] = func_8004F674(&sp24, 6000); - D_801657D0[3] = func_8004F674(&sp24, 1000); - D_801657D0[4] = func_8004F674(&sp24, 100); - D_801657D0[6] = func_8004F674(&sp24, 10); + D_801657D0[0] = div_s32(&sp24, 60000); + D_801657D0[1] = div_s32(&sp24, 6000); + D_801657D0[3] = div_s32(&sp24, 1000); + D_801657D0[4] = div_s32(&sp24, 100); + D_801657D0[6] = div_s32(&sp24, 10); D_801657D0[7] = sp24; D_801657D0[2] = 10; D_801657D0[5] = 11; diff --git a/src/render_objects.h b/src/render_objects.h index 05b65f2a5f..6b624e9221 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -297,7 +297,8 @@ void func_8004EF9C(s32); void render_mini_map_finish_line(s32); void draw_minimap_character(s32, s32, s32); void func_8004F3E4(s32); -s32 func_8004F674(s32*, s32); +s32 div_s32(s32*, s32); +char* time_to_ascii(f32, s32, bool, bool); void print_timer(s32, s32, s32); void func_8004F950(s32, s32, s32, s32); void print_timer_rainbow(s32, s32, s32); From 8963c166a5649bc56dfaeebb4400b328a8459d6f Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sun, 2 Aug 2026 10:51:55 -0400 Subject: [PATCH 62/73] implemented random (no repeats) track order --- src/menu_items.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++- src/menus.c | 2 +- 2 files changed, 128 insertions(+), 3 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index 1b7b6f8e42..918de0f003 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -373,6 +373,109 @@ s8 gTournamentShellLimit = 0; // not currently in menu s8 gTournamentExtraMode = 0; s8 gPracticeMode = 0; +static const COURSES rand_courses[] = { + COURSE_MARIO_RACEWAY, // 0x00 + COURSE_CHOCO_MOUNTAIN, // 0x01 + COURSE_BOWSER_CASTLE, // 0x02 + COURSE_BANSHEE_BOARDWALK,// 0x03 + COURSE_YOSHI_VALLEY, // 0x04 + COURSE_FRAPPE_SNOWLAND, // 0x05 + COURSE_KOOPA_BEACH, // 0x06 + COURSE_ROYAL_RACEWAY, // 0x07 + COURSE_LUIGI_RACEWAY, // 0x08 + COURSE_MOO_MOO_FARM, // 0x09 + COURSE_TOADS_TURNPIKE, // 0x0A + COURSE_KALAMARI_DESERT, // 0x0B + COURSE_SHERBET_LAND, // 0x0C + COURSE_RAINBOW_ROAD, // 0x0D + COURSE_DK_JUNGLE, // 0x12 + COURSE_WARIO_STADIUM // 0x0E +}; + +static COURSES sRandomTrackOrder[16]; +static s32 sRandomTrackOrderInitialized; +static s8 sRandomTrackOrderMode; + +void shuffle_tracks(COURSES *track_order); + +static char* getCourseAbbrFromId(COURSES courseId) { + switch (courseId) { + case COURSE_LUIGI_RACEWAY: + return "LR"; + case COURSE_MOO_MOO_FARM: + return "MMF"; + case COURSE_KOOPA_BEACH: + return "KTB"; + case COURSE_KALAMARI_DESERT: + return "KD"; + case COURSE_DK_JUNGLE: + return "DKJP"; + case COURSE_YOSHI_VALLEY: + return "YV"; + case COURSE_BANSHEE_BOARDWALK: + return "BB"; + case COURSE_RAINBOW_ROAD: + return "RRd"; + case COURSE_WARIO_STADIUM: + return "WS"; + case COURSE_SHERBET_LAND: + return "SL"; + case COURSE_ROYAL_RACEWAY: + return "RRy"; + case COURSE_BOWSER_CASTLE: + return "BC"; + case COURSE_TOADS_TURNPIKE: + return "TT"; + case COURSE_FRAPPE_SNOWLAND: + return "FS"; + case COURSE_CHOCO_MOUNTAIN: + return "CM"; + case COURSE_MARIO_RACEWAY: + return "MR"; + default: + return ""; + } +} + +static void initRandomTrackOrder(void) { + int i; + + for (i = 0; i < 16; i++) { + sRandomTrackOrder[i] = rand_courses[i]; + } + shuffle_tracks(sRandomTrackOrder); + sRandomTrackOrderInitialized = 1; + sRandomTrackOrderMode = gTournamentCourseMode; +} + +static s32 getRandomTrackOrderIndex(COURSES courseId) { + s32 i; + + for (i = 0; i < 16; i++) { + if (sRandomTrackOrder[i] == courseId) { + return i; + } + } + + return -1; +} + +static COURSES getRandomNextCourseId(void) { + s32 currentIndex; + + if (!sRandomTrackOrderInitialized || (sRandomTrackOrderMode != gTournamentCourseMode)) { + initRandomTrackOrder(); + } + + currentIndex = getRandomTrackOrderIndex(gCurrentCourseId); + if (currentIndex < 0) { + return sRandomTrackOrder[0]; + } + + return sRandomTrackOrder[(currentIndex + 1) % 16]; +} + + char* gCupText[] = { "none", "bronze", @@ -1096,6 +1199,21 @@ Unk_D_800E70A0 D_800E8600[] = { { 0x28, 0x28, 0x00, 0x00 }, { 0xb2, 0x28, 0x00, 0x00 }, { 0x28, 0xa0, 0x00, 0x00 }, { 0xb2, 0xa0, 0x00, 0x00 }, }; +void shuffle_tracks(COURSES *track_order) { + int i; + int j; + COURSES temp; + + // Fisher-Yates shuffle on the pool + for (i = 16 - 1; i > 0; i--) { + j = random_u16() % (i + 1); + temp = track_order[i]; + track_order[i] = track_order[j]; + track_order[j] = temp; + + } +} + f64 exponent_by_squaring(f64 base, s32 exponent) { s32 positive_exponent; f64 result; @@ -5807,7 +5925,7 @@ void render_custom_overlay(void) { }; /* per-option label arrays */ - static const char* tracks_labels[] = {"VA", "kaillera", "kaillera mmf"}; + static const char* tracks_labels[] = {"VA", "kaillera", "kaillera mmf", "random"}; static const char* stats_labels[] = {"all yoshi", "default", "all wario"}; static const char* scaling_labels[] = {"default", "30fps", "60fps"}; static const char* widescreen_labels[] = {"default", "enabled"}; @@ -5824,7 +5942,7 @@ void render_custom_overlay(void) { print_text1_center_mode_1(x, y - 0x28, "WEATHERTON ABNEY CLIMATEE ZSERF DNTN31", 0, 0.60f, 0.60f); // version / date (smaller) - left-aligned to start under 'KART' - print_text1_left(x + 0x78, y + 0x06, "TE V2026-07-26 RELEASE 1.1b", 0, 0.65f, 0.65f); + print_text1_left(x + 0x78, y + 0x06, "TE V2026-08-02 RELEASE 1.2b", 0, 0.65f, 0.65f); // option name placeholders (second column) and values (third column) for (i = 0; i < CUSTOM_MENU_ROWS; i++) { @@ -6051,6 +6169,9 @@ s16 getNextCourseId(void) { default: break; } + // randomized track order + case 3: + return getRandomNextCourseId(); default: break; } @@ -6172,10 +6293,14 @@ char* getNextCourseAbbrString(void) { default: break; } + case 3: + return getCourseAbbrFromId(getRandomNextCourseId()); default: break; } + return ""; + } void render_menus(MenuItem* arg0) { diff --git a/src/menus.c b/src/menus.c index dac775f906..811161237a 100644 --- a/src/menus.c +++ b/src/menus.c @@ -179,7 +179,7 @@ s8 gCustomMenuOptionValues[CUSTOM_MENU_ROWS] = { 0 }; // Per-row number of selectable values (matches label arrays in render_custom_overlay) // tracks, stats, scaling, widescreen, mp music, mp train boat, AA, force minimap, // extra, practice mode -static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 3, 3, 2, 2, 4, 2, 3, 2, 2 }; +static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 4, 3, 3, 2, 2, 4, 2, 3, 2, 2 }; // end of new var init From b43130c1db316e4728a45e97b4fbc7ea6a63aa37 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sat, 8 Aug 2026 09:15:33 -0400 Subject: [PATCH 63/73] added old set_places code path back to fix GP positions not updating properly. fixed progress view/map lock not working in 3p. brought c-right and c-up toggle noise back in non-versus game modes updated build date --- src/code_80057C60.c | 24 +++++++++++++++++++++++- src/code_8006E9C0.c | 4 ++-- src/cpu_vehicles_camera_path.c | 22 +++++++++++++++++----- src/menu_items.c | 2 +- 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 654f7a9c8d..c578286590 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -1542,6 +1542,27 @@ void func_8005A3C0(void) { break; // 3p case 3: + // force progress view at all times (N/A in battle) + // 3p case adds the map as well + if (gTournamentForceMap == 1) { + if (gModeSelection != BATTLE) { + D_801657F0 = 1; + } + D_801657E4 = 1; + b = true; + break; + } + // force map view at all times + if (gTournamentForceMap == 2) { + if (gModeSelection != BATTLE) { + D_801657F0 = 0; + } + D_801657E4 = 0; + b = true; + break; + } + // in 3p, the map and the prog view can be both on. + else { if ((gControllerOne->buttonPressed & R_CBUTTONS) || (gControllerTwo->buttonPressed & R_CBUTTONS) || (gControllerThree->buttonPressed & R_CBUTTONS)) { if (gModeSelection != BATTLE) { @@ -1551,8 +1572,9 @@ void func_8005A3C0(void) { b = true; } break; - + } // 4p + // TODO: Clean up logic to be closer to 3P case 4: // run default settings (togglable map/prog view) when forcemap = 0 if (gTournamentForceMap == 0) { diff --git a/src/code_8006E9C0.c b/src/code_8006E9C0.c index c33c397ad9..7ad4195151 100644 --- a/src/code_8006E9C0.c +++ b/src/code_8006E9C0.c @@ -368,8 +368,8 @@ void func_8006F824(s32 arg0) { D_80165828 = D_801657F8; D_80165832[0] = D_80165800[0]; D_80165832[1] = D_80165800[1]; - if ((arg0 != 0) && (gIsGamePaused == 0)) { - // play_sound2(SOUND_ACTION_PING); + if ((arg0 != 0) && (gIsGamePaused == 0) && (gModeSelection != VERSUS)) { + play_sound2(SOUND_ACTION_PING); } } diff --git a/src/cpu_vehicles_camera_path.c b/src/cpu_vehicles_camera_path.c index 6abe997cd9..b83967c1f6 100644 --- a/src/cpu_vehicles_camera_path.c +++ b/src/cpu_vehicles_camera_path.c @@ -1756,9 +1756,17 @@ void update_player(s32 playerId) { break; } - // checks on last player to ensure all players positions have been updated - if ((gCurrentCourseId != COURSE_AWARD_CEREMONY) && (playerId == (numPlayer - 1))) { - set_places(); + if (gModeSelection == VERSUS) { + // checks on last player to ensure all players positions have been updated + if ((gCurrentCourseId != COURSE_AWARD_CEREMONY) && (playerId == (numPlayer - 1))) { + set_places(); + } + } + // runs old placement logic; runs in gp mode (new logic is broken in GP mode) + else { + if ((gCurrentCourseId != COURSE_AWARD_CEREMONY) && ((gCrossedFinishLine[playerId] == 1) || (playerId == 0))) { + set_places(); + } } } } @@ -3531,14 +3539,18 @@ void func_80019C50(s32 playerIndex) { case 0: if (D_80164608[playerIndex] == 1) { D_80164678[playerIndex] = 1; - // func_800C9060(playerIndex, SOUND_ARG_LOAD(0x19, 0x00, 0x90, 0x4F)); + if (gModeSelection != VERSUS) { + func_800C9060(playerIndex, SOUND_ARG_LOAD(0x19, 0x00, 0x90, 0x4F)); + } D_80164670[playerIndex] = D_80164678[playerIndex]; } break; case 1: if (D_80164608[playerIndex] == 1) { D_80164678[playerIndex] = 0; - // func_800C9060(playerIndex, SOUND_ARG_LOAD(0x19, 0x00, 0x90, 0x50)); + if (gModeSelection != VERSUS) { + func_800C9060(playerIndex, SOUND_ARG_LOAD(0x19, 0x00, 0x90, 0x50)); + } D_80164670[playerIndex] = D_80164678[playerIndex]; } break; diff --git a/src/menu_items.c b/src/menu_items.c index 918de0f003..dc0de39314 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -5942,7 +5942,7 @@ void render_custom_overlay(void) { print_text1_center_mode_1(x, y - 0x28, "WEATHERTON ABNEY CLIMATEE ZSERF DNTN31", 0, 0.60f, 0.60f); // version / date (smaller) - left-aligned to start under 'KART' - print_text1_left(x + 0x78, y + 0x06, "TE V2026-08-02 RELEASE 1.2b", 0, 0.65f, 0.65f); + print_text1_left(x + 0x78, y + 0x06, "TE V2026-08-08 RELEASE 1.3b", 0, 0.65f, 0.65f); // option name placeholders (second column) and values (third column) for (i = 0; i < CUSTOM_MENU_ROWS; i++) { From 4516fc8510ea7fa9f5e31d885f32f0f83ccf4b89 Mon Sep 17 00:00:00 2001 From: Jed Grabman Date: Mon, 10 Aug 2026 23:20:56 -0400 Subject: [PATCH 64/73] Fix kerning on time offsets --- src/menu_items.c | 39 +++++++++++++++++++++++++++++++++++++-- src/menu_items.h | 1 + 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/menu_items.c b/src/menu_items.c index 138a62eb63..2cdb4289a2 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -2064,6 +2064,41 @@ void text_draw(s32 column, s32 row, char* text, s32 tracking, f32 scaleX, f32 sc print_text2(column, row, text, tracking, scaleX, scaleY, 2); } +void text_draw_right(s32 column, s32 row, char* text, s32 tracking, f32 scaleX, f32 scaleY) { + s32 stringWidth; + stringWidth = get_string_width2(text, tracking, scaleX); + print_text2(column - stringWidth, row, text, tracking, scaleX, scaleY, 2); +} + +s32 get_string_width2(char* text, s32 tracking, f32 scaleX){ + s32 glyphIndex; + s32 characterWidth; + s32 stringWidth = 0; + + char* temp_string = text; + while (*temp_string != 0) { + glyphIndex = char_to_glyph_index(temp_string); + if (glyphIndex >= 0) { + if ((glyphIndex >= 0xD5) && (glyphIndex < 0xE0)) { + characterWidth = 0x20; + } else { + characterWidth = 0xC; + } + stringWidth += ((characterWidth + tracking) * scaleX); + } else if ((glyphIndex != -2) && (glyphIndex == -1)) { + stringWidth += ((tracking + 7) * scaleX); + } else { + return; + } + if (glyphIndex >= 0x30) { + temp_string += 2; + } else { + temp_string += 1; + } + } + return stringWidth; +} + void func_80093A30(s32 arg0) { func_8009E2A8(D_800F0B1C[arg0]); } @@ -8650,7 +8685,7 @@ void func_800A69C8(UNUSED MenuItem* arg0) { set_text_color(TEXT_YELLOW); finishTimeText = time_to_ascii(gFinishTime[playerId] - gWinnerTime, 3, false, true); } - print_text1_right(thing->column + 60, thing->row + 92, finishTimeText, 0, 0.7f, 0.7f); + text_draw_right(thing->column + 65, thing->row + 92, finishTimeText, 0, 0.7f, 0.7f); } } set_text_color(TEXT_BLUE); @@ -8889,7 +8924,7 @@ void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { finishTimeText = time_to_ascii(gFinishTime[playerId] - gWinnerTime, 3, false, true); } // right aligned to keep digit significance consistent - print_text1_right(temp_s0->column + 60, temp_s0->row + 90, finishTimeText, 0, 0.7f, 0.7f); + text_draw_right(temp_s0->column + 65, temp_s0->row + 90, finishTimeText, 0, 0.7f, 0.7f); } } diff --git a/src/menu_items.h b/src/menu_items.h index 4573c76d82..c818ae30c0 100644 --- a/src/menu_items.h +++ b/src/menu_items.h @@ -359,6 +359,7 @@ s32 func_80092DF8(char*); s32 func_80092E1C(char*); s32 func_80092EE4(char*); s32 get_string_width(char*); +s32 get_string_width2(char*, s32, f32); void set_text_color(s32); void func_800930E4(s32, s32, char*); void print_text0(s32, s32, char*, s32, f32, f32, s32); From 0392eec85e5ecd794e8968063af3220a8f586de0 Mon Sep 17 00:00:00 2001 From: Jed Grabman Date: Wed, 12 Aug 2026 01:55:48 -0400 Subject: [PATCH 65/73] Fix possible softlock on KTB --- src/cpu_vehicles_camera_path.c | 575 ++++++++++++++++----------------- src/cpu_vehicles_camera_path.h | 1 + 2 files changed, 288 insertions(+), 288 deletions(-) diff --git a/src/cpu_vehicles_camera_path.c b/src/cpu_vehicles_camera_path.c index b83967c1f6..c7e8f7c6eb 100644 --- a/src/cpu_vehicles_camera_path.c +++ b/src/cpu_vehicles_camera_path.c @@ -1390,24 +1390,302 @@ void update_player_timer_sound(s32 playerId, UNUSED Player* unused) { } } -void update_player(s32 playerId) { - UNUSED s32 pad[14]; +void update_cpu_player(s32 playerId, Player* player){ s16 var_a0_2; s16 newAngle; u16 pathIndex; - f32 distX; f32 minAngle; - s16 angle; s16 steeringSensitivity; - - s32 maxAngle; - Player* player; - UNUSED s32 pad3[10]; TrackPathPoint* pathPoint; f32 onePointFive = 1.5f; + + if ((gIsPlayerNewPathPoint == true) && (gCurrentCourseId != COURSE_AWARD_CEREMONY)) { + cpu_behaviour(playerId); + } + // one update it try to use an item, the other it doesn't + if ((playerId & 1) != (gIncrementUpdatePlayer & 1)) { + cpu_use_item_strategy(playerId); + } + update_player_timer_sound(playerId, player); + D_80162FD0 = 0; + switch (gModeSelection) { /* switch 1; irregular */ + case 1: /* switch 1 */ + case 2: /* switch 1 */ + case 3: /* switch 1 */ + break; + case 0: /* switch 1 */ + break; + } + D_801631E0[playerId] = false; + if ((player->effects & LOST_RACE_EFFECT) && (gCurrentCourseId != COURSE_AWARD_CEREMONY)) { + D_801631E0[playerId] = true; + } + if ((D_801646CC == 1) || (player->type & PLAYER_CINEMATIC_MODE) || + (gCurrentCourseId == COURSE_AWARD_CEREMONY)) { + if (gCurrentCourseId != COURSE_TOADS_TURNPIKE) { + gPlayerTrackPositionFactorInstruction[playerId].target = 0.0f; + } + gPlayerTrackPositionFactorInstruction[playerId].unkC = 0.0f; + } + if (gPlayerPathIndex > 0) { + gPlayerTrackPositionFactorInstruction[playerId].target = 0.0f; + gPlayerTrackPositionFactorInstruction[playerId].unkC = 0.0f; + } + gPlayerPathY[playerId] = + gTrackPaths[gPlayerPathIndex][gNearestPathPointByPlayerId[playerId]].posY + 4.3f; + if ((D_801631F8[playerId] == 1) && (D_801631E0[playerId] == false)) { + func_8002E4C4(player); + } + if (D_801631E0[playerId] == true) { + player->pos[1] = gPlayerPathY[playerId]; + } + D_801631F8[playerId] = D_801631E0[playerId]; + switch (gCurrentCourseId) { + case COURSE_YOSHI_VALLEY: + case COURSE_AWARD_CEREMONY: + gPlayerTrackPositionFactorInstruction[playerId].target = 0.0f; + break; + default: + break; + case COURSE_TOADS_TURNPIKE: + update_player_track_position_factor_from_box_trucks(playerId); + update_player_track_position_factor_from_buses(playerId); + update_player_track_position_factor_from_tanker_truck(playerId); + update_player_track_position_factor_from_cars(playerId); + break; + } + if (D_801631E0[playerId] == true) { + D_801630E8[playerId] = 0; + player->effects &= ~DRIFTING_EFFECT; + if ((playerId & 1) != (gIncrementUpdatePlayer & 1)) { + apply_cpu_turn(player, 0); + regulate_cpu_speed(playerId, gPreviousCpuTargetSpeed[playerId], player); + return; + } + if ((gPlayerCount > 0) && (gPlayerCount < 3) && (D_80163330[playerId] == 1) && + (D_8016334C[playerId] < gGPCurrentRaceRankByPlayerId[playerId])) { + gPreviousCpuTargetSpeed[playerId] = 8.333333f; + } else if (D_80162FD0 == (s16) 1U) { + gPreviousCpuTargetSpeed[playerId] = GET_COURSE_D_0D0096B8(gCCSelection); + gPlayerTrackPositionFactorInstruction[playerId].target = -0.5f; + } else if (gCurrentTrackConsecutiveCurveCountsPath[sSomeNearestPathPoint] > 0) { + gPreviousCpuTargetSpeed[playerId] = GET_COURSE_cpu_CurveTargetSpeed(gCCSelection); + } else { + gPreviousCpuTargetSpeed[playerId] = GET_COURSE_cpu_NormalTargetSpeed(gCCSelection); + } + check_ai_crossing_distance(playerId); + cpu_track_position_factor(playerId); + determine_ideal_cpu_position_offset(playerId, gCurrentNearestPathPoint); + distX = gOffsetPosition[0] - player->pos[0]; + minAngle = gOffsetPosition[2] - player->pos[2]; + if (!(player->effects & BANANA_SPINOUT_EFFECT) && !(player->effects & DRIVING_SPINOUT_EFFECT) && + !(player->effects & BANANA_NEAR_SPINOUT_EFFECT)) { + if (((distX * distX) + (minAngle * minAngle)) > 6400.0f) { + if (gPlayerPathIndex == 0) { + func_8000B140(playerId); + if (D_80162FF8[playerId] > 0) { + pathIndex = gCurrentNearestPathPoint + 5; + pathIndex %= gSelectedPathCount; + set_track_offset_position(pathIndex, D_80163090[playerId], gPlayerPathIndex); + } + } + player->rotation[1] = -get_xz_angle_between_points(player->pos, gOffsetPosition); + } else { + player->rotation[1] = + gPathExpectedRotation[gPlayerPathIndex] + [(gCurrentNearestPathPoint + 4) % gSelectedPathCount]; + } + } + apply_cpu_turn(player, 0); + regulate_cpu_speed(playerId, gPreviousCpuTargetSpeed[playerId], player); + return; + } + if ((D_801630E8[playerId] == 1) || (D_801630E8[playerId] == -1)) { + player->effects |= DRIFTING_EFFECT; + } + if (D_801630E8[playerId] != 0) { + sPlayerAngle[playerId] = -get_xz_angle_between_points(player->oldPos, player->pos); + var_a0_2 = + (gCurrentPathPointExpectedRotationPath[(sSomeNearestPathPoint + 2) % gSelectedPathCount] * + 0x168) / + 65535; + newAngle = (sPlayerAngle[playerId] * 0x168) / 65535; + if (var_a0_2 < -0xB4) { + var_a0_2 += 0x168; + } + if (var_a0_2 > 0xB4) { + var_a0_2 -= 0x168; + } + if (newAngle < -0xB4) { + newAngle += 0x168; + } + if (newAngle > 0xB4) { + newAngle -= 0x168; + } + steeringSensitivity = var_a0_2 - newAngle; + if (steeringSensitivity < -0xB4) { + steeringSensitivity += 0x168; + } + if (steeringSensitivity > 0xB4) { + steeringSensitivity -= 0x168; + } + switch (D_801630E8[playerId]) { + case -1: + if (steeringSensitivity > 5) { + D_801630E8[playerId] = 0; + player->effects &= ~DRIFTING_EFFECT; + } + break; + case 1: + if (steeringSensitivity < -5) { + D_801630E8[playerId] = 0; + player->effects &= ~DRIFTING_EFFECT; + } + break; + default: + break; + } + } + + if ((playerId & 1) != (gIncrementUpdatePlayer & 1)) { + apply_cpu_turn(player, gPreviousAngleSteering[playerId]); + regulate_cpu_speed(playerId, gPreviousCpuTargetSpeed[playerId], player); + return; + } + gIsPlayerInCurve[playerId] = are_in_curve(playerId, sSomeNearestPathPoint); + determine_ideal_cpu_position_offset(playerId, sSomeNearestPathPoint); + if (gCurrentCourseId != COURSE_AWARD_CEREMONY) { + if (gNumPathPointsTraversed[playerId] < 0xB) { + pathIndex = gCurrentNearestPathPoint; + if ((gNumPathPointsTraversed[playerId] > 0) && (gCurrentCourseId == COURSE_TOADS_TURNPIKE)) { + pathIndex += 0x14; + pathIndex %= gSelectedPathCount; + set_track_offset_position(pathIndex, 0.0f, 0); + gPlayerTrackPositionFactorInstruction[playerId].target = 0.0f; + } else { + pathIndex += 8; + pathIndex %= gSelectedPathCount; + set_track_offset_position(pathIndex, gTrackPositionFactor[playerId], gPlayerPathIndex); + gPlayerTrackPositionFactorInstruction[playerId].current = gTrackPositionFactor[playerId]; + } + } + if ((D_80162FD0 == 1) && (D_80162FF8[playerId] == 0)) { + pathIndex = gCurrentNearestPathPoint + 7; + pathIndex %= gSelectedPathCount; + set_track_offset_position(pathIndex, -0.7f, gPlayerPathIndex); + } + if (1) { } if (1) { } if (1) { } if (1) { } if (1) { } if (1) { } + if (gPlayerPathIndex == 0) { + func_8000B140(playerId); + if (D_80162FF8[playerId] > 0) { + pathIndex = gCurrentNearestPathPoint + 5; + + pathIndex %= gSelectedPathCount; + set_track_offset_position(pathIndex, D_80163090[playerId], gPlayerPathIndex); + } + } + } + if (gCurrentCourseId == COURSE_AWARD_CEREMONY) { + switch (D_80163410[playerId]) { /* switch 3; irregular */ + case 3: /* switch 3 */ + gOffsetPosition[0] = D_80163418[playerId]; + gOffsetPosition[2] = D_80163438[playerId]; + break; + case 4: /* switch 3 */ + pathPoint = &gTrackPaths[playerId][(gNearestPathPointByPlayerId[playerId] + 0xA) % + gPathCountByPathIndex[playerId]]; + gOffsetPosition[0] = pathPoint->posX; + gOffsetPosition[2] = pathPoint->posZ; + break; + } + } + gOffsetPosition[0] = (gPreviousPlayerAiOffsetX[playerId] + gOffsetPosition[0]) * 0.5f; // average + gOffsetPosition[2] = (gPreviousPlayerAiOffsetZ[playerId] + gOffsetPosition[2]) * 0.5f; // average + gPreviousPlayerAiOffsetX[playerId] = gOffsetPosition[0]; + gPreviousPlayerAiOffsetZ[playerId] = gOffsetPosition[2]; + minAngle = onePointFive * 182.0f; + maxAngle = -onePointFive * 182.0f; + + angle = -get_xz_angle_between_points(player->pos, gOffsetPosition); + angle -= (newAngle = player->rotation[1]); + if ((s16) minAngle < angle) { + angle = minAngle; + } + if (angle < (s16) maxAngle) { + angle = maxAngle; + } + steeringSensitivity = GET_COURSE_AISteeringSensitivity; + switch (gCurrentTrackSectionTypesPath[playerId]) { /* switch 4; irregular */ + case RIGHT_CURVE: /* switch 4 */ + if (gTrackPositionFactor[playerId] > (0.5f * 1.0f)) { + steeringSensitivity = 0x0014; + } + if (gTrackPositionFactor[playerId] < -0.5f) { + steeringSensitivity = 0x0035; + } + break; + case LEFT_CURVE: /* switch 4 */ + if (gTrackPositionFactor[playerId] > 0.5f) { + steeringSensitivity = 0x0035; + } + if (gTrackPositionFactor[playerId] < -0.5f) { + steeringSensitivity = 0x0014; + } + break; + } + if ((cpu_BehaviourState[playerId] == CPU_BEHAVIOUR_STATE_RUNNING) && + ((gTrackPositionFactor[playerId] > 0.9f) || (gTrackPositionFactor[playerId] < -0.9f))) { + D_801630E8[playerId] = 0; + player->effects &= ~DRIFTING_EFFECT; + } + if (player->effects & HOP_EFFECT) { + switch (D_801630E8[playerId]) { + case 1: + newAngle = 0x0035; + break; + case -1: + newAngle = -0x0035; + break; + default: + newAngle = + (gPreviousAngleSteering[playerId] + ((angle * steeringSensitivity) / minAngle)) / 2; + break; + } + } else if (player->effects & (UNKNOWN_EFFECT_0x10000000 | MIDAIR_EFFECT | BOOST_RAMP_WOOD_EFFECT)) { + newAngle = 0; + } else { + newAngle = (gPreviousAngleSteering[playerId] + ((angle * steeringSensitivity) / minAngle)) / 2; + } + apply_cpu_turn(player, newAngle); + gPreviousAngleSteering[playerId] = newAngle; + if ((gIsPlayerInCurve[playerId] == true) || (D_801630E8[playerId] == 1) || + (D_801630E8[playerId] == -1) || + (player->effects & (UNKNOWN_EFFECT_0x10000000 | MIDAIR_EFFECT | BOOST_RAMP_WOOD_EFFECT))) { + cpu_TargetSpeed[playerId] = GET_COURSE_cpu_CurveTargetSpeed(gCCSelection); + } else { + cpu_TargetSpeed[playerId] = GET_COURSE_cpu_NormalTargetSpeed(gCCSelection); + } + if ((gTrackPositionFactor[playerId] > 0.9f) || (gTrackPositionFactor[playerId] < -0.9f)) { + cpu_TargetSpeed[playerId] = GET_COURSE_cpu_OffTrackTargetSpeed(gCCSelection); + } + if (D_80162FD0 == 1) { + cpu_TargetSpeed[playerId] = GET_COURSE_D_0D0096B8(gCCSelection); + } + if ((D_801630E8[playerId] == 2) || (D_801630E8[playerId] == -2) || (D_801630E8[playerId] == 3)) { + cpu_TargetSpeed[playerId] = 3.3333333f; + } + gCurrentCpuTargetSpeed = cpu_TargetSpeed[playerId]; + player->effects &= ~CPU_FAST_EFFECT; + gPreviousCpuTargetSpeed[playerId] = gCurrentCpuTargetSpeed; + check_ai_crossing_distance(playerId); + regulate_cpu_speed(playerId, gCurrentCpuTargetSpeed, player); +} + +void update_player(s32 playerId) { + Player* player; s8 numPlayer; player = &gPlayers[playerId]; @@ -1460,286 +1738,7 @@ void update_player(s32 playerId) { update_player_path_completion(playerId, player); if (player->type & PLAYER_CPU) { - if ((gIsPlayerNewPathPoint == true) && (gCurrentCourseId != COURSE_AWARD_CEREMONY)) { - cpu_behaviour(playerId); - } - // one update it try to use an item, the other it doesn't - if ((playerId & 1) != (gIncrementUpdatePlayer & 1)) { - cpu_use_item_strategy(playerId); - } - update_player_timer_sound(playerId, player); - D_80162FD0 = 0; - switch (gModeSelection) { /* switch 1; irregular */ - case 1: /* switch 1 */ - case 2: /* switch 1 */ - case 3: /* switch 1 */ - break; - case 0: /* switch 1 */ - break; - } - D_801631E0[playerId] = false; - if ((player->effects & LOST_RACE_EFFECT) && (gCurrentCourseId != COURSE_AWARD_CEREMONY)) { - D_801631E0[playerId] = true; - } - if ((D_801646CC == 1) || (player->type & PLAYER_CINEMATIC_MODE) || - (gCurrentCourseId == COURSE_AWARD_CEREMONY)) { - if (gCurrentCourseId != COURSE_TOADS_TURNPIKE) { - gPlayerTrackPositionFactorInstruction[playerId].target = 0.0f; - } - gPlayerTrackPositionFactorInstruction[playerId].unkC = 0.0f; - } - if (gPlayerPathIndex > 0) { - gPlayerTrackPositionFactorInstruction[playerId].target = 0.0f; - gPlayerTrackPositionFactorInstruction[playerId].unkC = 0.0f; - } - gPlayerPathY[playerId] = - gTrackPaths[gPlayerPathIndex][gNearestPathPointByPlayerId[playerId]].posY + 4.3f; - if ((D_801631F8[playerId] == 1) && (D_801631E0[playerId] == false)) { - func_8002E4C4(player); - } - if (D_801631E0[playerId] == true) { - player->pos[1] = gPlayerPathY[playerId]; - } - D_801631F8[playerId] = D_801631E0[playerId]; - switch (gCurrentCourseId) { - case COURSE_YOSHI_VALLEY: - case COURSE_AWARD_CEREMONY: - gPlayerTrackPositionFactorInstruction[playerId].target = 0.0f; - break; - default: - break; - case COURSE_TOADS_TURNPIKE: - update_player_track_position_factor_from_box_trucks(playerId); - update_player_track_position_factor_from_buses(playerId); - update_player_track_position_factor_from_tanker_truck(playerId); - update_player_track_position_factor_from_cars(playerId); - break; - } - if (D_801631E0[playerId] == true) { - D_801630E8[playerId] = 0; - player->effects &= ~DRIFTING_EFFECT; - if ((playerId & 1) != (gIncrementUpdatePlayer & 1)) { - apply_cpu_turn(player, 0); - regulate_cpu_speed(playerId, gPreviousCpuTargetSpeed[playerId], player); - return; - } - if ((gPlayerCount > 0) && (gPlayerCount < 3) && (D_80163330[playerId] == 1) && - (D_8016334C[playerId] < gGPCurrentRaceRankByPlayerId[playerId])) { - gPreviousCpuTargetSpeed[playerId] = 8.333333f; - } else if (D_80162FD0 == (s16) 1U) { - gPreviousCpuTargetSpeed[playerId] = GET_COURSE_D_0D0096B8(gCCSelection); - gPlayerTrackPositionFactorInstruction[playerId].target = -0.5f; - } else if (gCurrentTrackConsecutiveCurveCountsPath[sSomeNearestPathPoint] > 0) { - gPreviousCpuTargetSpeed[playerId] = GET_COURSE_cpu_CurveTargetSpeed(gCCSelection); - } else { - gPreviousCpuTargetSpeed[playerId] = GET_COURSE_cpu_NormalTargetSpeed(gCCSelection); - } - check_ai_crossing_distance(playerId); - cpu_track_position_factor(playerId); - determine_ideal_cpu_position_offset(playerId, gCurrentNearestPathPoint); - distX = gOffsetPosition[0] - player->pos[0]; - minAngle = gOffsetPosition[2] - player->pos[2]; - if (!(player->effects & BANANA_SPINOUT_EFFECT) && !(player->effects & DRIVING_SPINOUT_EFFECT) && - !(player->effects & BANANA_NEAR_SPINOUT_EFFECT)) { - if (((distX * distX) + (minAngle * minAngle)) > 6400.0f) { - if (gPlayerPathIndex == 0) { - func_8000B140(playerId); - if (D_80162FF8[playerId] > 0) { - pathIndex = gCurrentNearestPathPoint + 5; - pathIndex %= gSelectedPathCount; - set_track_offset_position(pathIndex, D_80163090[playerId], gPlayerPathIndex); - } - } - player->rotation[1] = -get_xz_angle_between_points(player->pos, gOffsetPosition); - } else { - player->rotation[1] = - gPathExpectedRotation[gPlayerPathIndex] - [(gCurrentNearestPathPoint + 4) % gSelectedPathCount]; - } - } - apply_cpu_turn(player, 0); - regulate_cpu_speed(playerId, gPreviousCpuTargetSpeed[playerId], player); - return; - } - if ((D_801630E8[playerId] == 1) || (D_801630E8[playerId] == -1)) { - player->effects |= DRIFTING_EFFECT; - } - if (D_801630E8[playerId] != 0) { - sPlayerAngle[playerId] = -get_xz_angle_between_points(player->oldPos, player->pos); - var_a0_2 = - (gCurrentPathPointExpectedRotationPath[(sSomeNearestPathPoint + 2) % gSelectedPathCount] * - 0x168) / - 65535; - newAngle = (sPlayerAngle[playerId] * 0x168) / 65535; - if (var_a0_2 < -0xB4) { - var_a0_2 += 0x168; - } - if (var_a0_2 > 0xB4) { - var_a0_2 -= 0x168; - } - if (newAngle < -0xB4) { - newAngle += 0x168; - } - if (newAngle > 0xB4) { - newAngle -= 0x168; - } - steeringSensitivity = var_a0_2 - newAngle; - if (steeringSensitivity < -0xB4) { - steeringSensitivity += 0x168; - } - if (steeringSensitivity > 0xB4) { - steeringSensitivity -= 0x168; - } - switch (D_801630E8[playerId]) { - case -1: - if (steeringSensitivity > 5) { - D_801630E8[playerId] = 0; - player->effects &= ~DRIFTING_EFFECT; - } - break; - case 1: - if (steeringSensitivity < -5) { - D_801630E8[playerId] = 0; - player->effects &= ~DRIFTING_EFFECT; - } - break; - default: - break; - } - } - - if ((playerId & 1) != (gIncrementUpdatePlayer & 1)) { - apply_cpu_turn(player, gPreviousAngleSteering[playerId]); - regulate_cpu_speed(playerId, gPreviousCpuTargetSpeed[playerId], player); - return; - } - gIsPlayerInCurve[playerId] = are_in_curve(playerId, sSomeNearestPathPoint); - determine_ideal_cpu_position_offset(playerId, sSomeNearestPathPoint); - if (gCurrentCourseId != COURSE_AWARD_CEREMONY) { - if (gNumPathPointsTraversed[playerId] < 0xB) { - pathIndex = gCurrentNearestPathPoint; - if ((gNumPathPointsTraversed[playerId] > 0) && (gCurrentCourseId == COURSE_TOADS_TURNPIKE)) { - pathIndex += 0x14; - pathIndex %= gSelectedPathCount; - set_track_offset_position(pathIndex, 0.0f, 0); - gPlayerTrackPositionFactorInstruction[playerId].target = 0.0f; - } else { - pathIndex += 8; - pathIndex %= gSelectedPathCount; - set_track_offset_position(pathIndex, gTrackPositionFactor[playerId], gPlayerPathIndex); - gPlayerTrackPositionFactorInstruction[playerId].current = gTrackPositionFactor[playerId]; - } - } - if ((D_80162FD0 == 1) && (D_80162FF8[playerId] == 0)) { - pathIndex = gCurrentNearestPathPoint + 7; - pathIndex %= gSelectedPathCount; - set_track_offset_position(pathIndex, -0.7f, gPlayerPathIndex); - } - if (1) { } if (1) { } if (1) { } if (1) { } if (1) { } if (1) { } - if (gPlayerPathIndex == 0) { - func_8000B140(playerId); - if (D_80162FF8[playerId] > 0) { - pathIndex = gCurrentNearestPathPoint + 5; - - pathIndex %= gSelectedPathCount; - set_track_offset_position(pathIndex, D_80163090[playerId], gPlayerPathIndex); - } - } - } - if (gCurrentCourseId == COURSE_AWARD_CEREMONY) { - switch (D_80163410[playerId]) { /* switch 3; irregular */ - case 3: /* switch 3 */ - gOffsetPosition[0] = D_80163418[playerId]; - gOffsetPosition[2] = D_80163438[playerId]; - break; - case 4: /* switch 3 */ - pathPoint = &gTrackPaths[playerId][(gNearestPathPointByPlayerId[playerId] + 0xA) % - gPathCountByPathIndex[playerId]]; - gOffsetPosition[0] = pathPoint->posX; - gOffsetPosition[2] = pathPoint->posZ; - break; - } - } - gOffsetPosition[0] = (gPreviousPlayerAiOffsetX[playerId] + gOffsetPosition[0]) * 0.5f; // average - gOffsetPosition[2] = (gPreviousPlayerAiOffsetZ[playerId] + gOffsetPosition[2]) * 0.5f; // average - gPreviousPlayerAiOffsetX[playerId] = gOffsetPosition[0]; - gPreviousPlayerAiOffsetZ[playerId] = gOffsetPosition[2]; - minAngle = onePointFive * 182.0f; - maxAngle = -onePointFive * 182.0f; - - angle = -get_xz_angle_between_points(player->pos, gOffsetPosition); - angle -= (newAngle = player->rotation[1]); - if ((s16) minAngle < angle) { - angle = minAngle; - } - if (angle < (s16) maxAngle) { - angle = maxAngle; - } - steeringSensitivity = GET_COURSE_AISteeringSensitivity; - switch (gCurrentTrackSectionTypesPath[playerId]) { /* switch 4; irregular */ - case RIGHT_CURVE: /* switch 4 */ - if (gTrackPositionFactor[playerId] > (0.5f * 1.0f)) { - steeringSensitivity = 0x0014; - } - if (gTrackPositionFactor[playerId] < -0.5f) { - steeringSensitivity = 0x0035; - } - break; - case LEFT_CURVE: /* switch 4 */ - if (gTrackPositionFactor[playerId] > 0.5f) { - steeringSensitivity = 0x0035; - } - if (gTrackPositionFactor[playerId] < -0.5f) { - steeringSensitivity = 0x0014; - } - break; - } - if ((cpu_BehaviourState[playerId] == CPU_BEHAVIOUR_STATE_RUNNING) && - ((gTrackPositionFactor[playerId] > 0.9f) || (gTrackPositionFactor[playerId] < -0.9f))) { - D_801630E8[playerId] = 0; - player->effects &= ~DRIFTING_EFFECT; - } - if (player->effects & HOP_EFFECT) { - switch (D_801630E8[playerId]) { - case 1: - newAngle = 0x0035; - break; - case -1: - newAngle = -0x0035; - break; - default: - newAngle = - (gPreviousAngleSteering[playerId] + ((angle * steeringSensitivity) / minAngle)) / 2; - break; - } - } else if (player->effects & (UNKNOWN_EFFECT_0x10000000 | MIDAIR_EFFECT | BOOST_RAMP_WOOD_EFFECT)) { - newAngle = 0; - } else { - newAngle = (gPreviousAngleSteering[playerId] + ((angle * steeringSensitivity) / minAngle)) / 2; - } - apply_cpu_turn(player, newAngle); - gPreviousAngleSteering[playerId] = newAngle; - if ((gIsPlayerInCurve[playerId] == true) || (D_801630E8[playerId] == 1) || - (D_801630E8[playerId] == -1) || - (player->effects & (UNKNOWN_EFFECT_0x10000000 | MIDAIR_EFFECT | BOOST_RAMP_WOOD_EFFECT))) { - cpu_TargetSpeed[playerId] = GET_COURSE_cpu_CurveTargetSpeed(gCCSelection); - } else { - cpu_TargetSpeed[playerId] = GET_COURSE_cpu_NormalTargetSpeed(gCCSelection); - } - if ((gTrackPositionFactor[playerId] > 0.9f) || (gTrackPositionFactor[playerId] < -0.9f)) { - cpu_TargetSpeed[playerId] = GET_COURSE_cpu_OffTrackTargetSpeed(gCCSelection); - } - if (D_80162FD0 == 1) { - cpu_TargetSpeed[playerId] = GET_COURSE_D_0D0096B8(gCCSelection); - } - if ((D_801630E8[playerId] == 2) || (D_801630E8[playerId] == -2) || (D_801630E8[playerId] == 3)) { - cpu_TargetSpeed[playerId] = 3.3333333f; - } - gCurrentCpuTargetSpeed = cpu_TargetSpeed[playerId]; - player->effects &= ~CPU_FAST_EFFECT; - gPreviousCpuTargetSpeed[playerId] = gCurrentCpuTargetSpeed; - check_ai_crossing_distance(playerId); - regulate_cpu_speed(playerId, gCurrentCpuTargetSpeed, player); + update_cpu_player(playerId, player); } } diff --git a/src/cpu_vehicles_camera_path.h b/src/cpu_vehicles_camera_path.h index 7b6fba533b..a5f6d4dcd9 100644 --- a/src/cpu_vehicles_camera_path.h +++ b/src/cpu_vehicles_camera_path.h @@ -121,6 +121,7 @@ void update_vehicles(void); void play_cpu_sound_effect(s32, Player*); void update_player_timer_sound(s32, Player*); void update_player(s32); +void update_cpu_player(s32, Player*); void func_8000B140(s32); s32 are_in_curve(s32, u16); From 984dd4d76caf943e5f53d1ab28c88c5818d1a2f5 Mon Sep 17 00:00:00 2001 From: Jed Grabman Date: Wed, 12 Aug 2026 02:38:29 -0400 Subject: [PATCH 66/73] Shrink text to prevent times overlapping --- src/menu_items.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/menu_items.c b/src/menu_items.c index 2cdb4289a2..e50f135542 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -8924,7 +8924,7 @@ void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { finishTimeText = time_to_ascii(gFinishTime[playerId] - gWinnerTime, 3, false, true); } // right aligned to keep digit significance consistent - text_draw_right(temp_s0->column + 65, temp_s0->row + 90, finishTimeText, 0, 0.7f, 0.7f); + text_draw_right(temp_s0->column + 65, temp_s0->row + 90, finishTimeText, 0, 0.6f, 0.6f); } } From 7a6ad78d98a49a253d729cac292a64b0cc16cb00 Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sun, 16 Aug 2026 15:27:13 -0400 Subject: [PATCH 67/73] -removed kaillera mmf track order option -updated vs mode ranking menu to match OG TE rom -updated track/course progression code path -removed unused code and some older AI comments -practice bots can pick up items, but still cannot use them -annotated various functions -cleaned up code all around -updated build date and version to 1.4b --- src/code_80057C60.c | 1 + src/cpu_vehicles_camera_path.c | 4 +- src/menu_items.c | 229 +++------------------------------ src/menus.c | 2 +- src/player_controller.c | 1 + src/racing/race_logic.c | 68 ++++++++-- src/spawn_players.c | 4 +- 7 files changed, 89 insertions(+), 220 deletions(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index b3a4b64b44..09ef069f2d 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -2759,6 +2759,7 @@ void func_8005D0FC(s32 playerId) { } } +// rank scroll? void func_8005D18C(void) { if ((gModeSelection == GRAND_PRIX) && (gPlayerCountSelection1 == TIME_TRIALS)) { D_801657D8 = 1; diff --git a/src/cpu_vehicles_camera_path.c b/src/cpu_vehicles_camera_path.c index 4425aaaf5d..f0a32e2f3f 100644 --- a/src/cpu_vehicles_camera_path.c +++ b/src/cpu_vehicles_camera_path.c @@ -3577,10 +3577,11 @@ void func_80019D2C(Camera* camera, Player* player, s32 arg2) { } } +// camera stuff for drivers points gp mode void func_80019DE4(void) { D_801646CC = 1; } - +// camera init for vs winner void func_80019DF4(void) { s32 i; s32 playerId = gGPCurrentRacePlayerIdByRank[0]; @@ -3593,6 +3594,7 @@ void func_80019DF4(void) { D_801646CC = 2; } +// time trials camera stuff void func_80019E58(void) { D_80164680[0] = 1; func_80019890(0, 0); diff --git a/src/menu_items.c b/src/menu_items.c index d5eb78ad70..4771aeca7a 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -460,7 +460,7 @@ static s32 getRandomTrackOrderIndex(COURSES courseId) { return -1; } -static COURSES getRandomNextCourseId(void) { +COURSES getRandomNextCourseId(void) { s32 currentIndex; if (!sRandomTrackOrderInitialized || (sRandomTrackOrderMode != gTournamentCourseMode)) { @@ -1613,6 +1613,7 @@ void func_80092290(s32 arg0, s32* arg1, s32* arg2) { } } +// display time void func_80092500(void) { switch (gModeSelection) { @@ -1625,6 +1626,7 @@ void func_80092500(void) { } } +// display loss in GP mode void func_80092564(void) { add_menu_item(MENU_ITEM_TYPE_0AC, 0, 0, MENU_ITEM_PRIORITY_0); func_8005D18C(); @@ -1642,7 +1644,7 @@ void func_800925CC(void) { } } -// 4p and 3p vs menu? +// 4p and 3p vs menu void func_80092604(void) { add_menu_item(MENU_ITEM_TYPE_0B0, 0, 0, MENU_ITEM_PRIORITY_0); } @@ -4795,7 +4797,7 @@ void func_8009CE1C(void) { } } -// fade out transition for versus menu +// fade out transition for menu void func_8009CE64(s32 arg0) { s32 thing; s32 var_a1; @@ -4831,16 +4833,11 @@ void func_8009CE64(s32 arg0) { var_a1 = 0; temp_v0 = find_menu_items(0x000000B0); if (temp_v0 != NULL) { + // EVENT HANDLER FOR VS MENU switch (temp_v0->state) { /* switch 8; irregular */ case 10: /* switch 8 */ - if (gModeSelection == VERSUS) { - // custom function: go to next track - gotoNextTrack(); - } - else { - // retry (vs mode) - func_802903B0(); - } + // go to next track in selection (VS mode) + gotoNextTrack(); break; case 11: /* switch 8 */ // course change (vs mode) @@ -4852,8 +4849,8 @@ void func_8009CE64(s32 arg0) { break; default: /* switch 8 */ case 13: /* switch 8 */ - // quit (vs mode) - func_80290338(); + // retry (vs mode) + func_802903B0(); break; } } else { @@ -5960,7 +5957,7 @@ void render_custom_overlay(void) { }; /* per-option label arrays */ - static const char* tracks_labels[] = {"VA", "kaillera", "kaillera mmf", "random"}; + static const char* tracks_labels[] = {"VA", "kaillera", "random"}; static const char* stats_labels[] = {"all yoshi", "default", "all wario"}; static const char* scaling_labels[] = {"default", "30fps", "60fps"}; static const char* widescreen_labels[] = {"default", "enabled"}; @@ -5977,7 +5974,7 @@ void render_custom_overlay(void) { print_text1_center_mode_1(x, y - 0x28, "WEATHERTON ABNEY CLIMATEE ZSERF DNTN31", 0, 0.60f, 0.60f); // version / date (smaller) - left-aligned to start under 'KART' - print_text1_left(x + 0x78, y + 0x06, "TE V2026-08-08 RELEASE 1.3b", 0, 0.65f, 0.65f); + print_text1_left(x + 0x78, y + 0x06, "TE V2026-08-16 RELEASE 1.4b", 0, 0.65f, 0.65f); // option name placeholders (second column) and values (third column) for (i = 0; i < CUSTOM_MENU_ROWS; i++) { @@ -6089,131 +6086,8 @@ void render_custom_overlay(void) { } } - -s16 getNextCourseId(void) { - switch (gTournamentCourseMode) { - // va track order - case 0: - switch(gCurrentCourseId) { - case COURSE_LUIGI_RACEWAY: - return COURSE_MOO_MOO_FARM; - case COURSE_MOO_MOO_FARM: - return COURSE_KOOPA_BEACH; - case COURSE_KOOPA_BEACH: - return COURSE_KALAMARI_DESERT; - case COURSE_KALAMARI_DESERT: - return COURSE_DK_JUNGLE; - case COURSE_DK_JUNGLE: - return COURSE_YOSHI_VALLEY; - case COURSE_YOSHI_VALLEY: - return COURSE_BANSHEE_BOARDWALK; - case COURSE_BANSHEE_BOARDWALK: - return COURSE_RAINBOW_ROAD; - case COURSE_RAINBOW_ROAD: - return COURSE_WARIO_STADIUM; - case COURSE_WARIO_STADIUM: - return COURSE_SHERBET_LAND; - case COURSE_SHERBET_LAND: - return COURSE_ROYAL_RACEWAY; - case COURSE_ROYAL_RACEWAY: - return COURSE_BOWSER_CASTLE; - case COURSE_BOWSER_CASTLE: - return COURSE_TOADS_TURNPIKE; - case COURSE_TOADS_TURNPIKE: - return COURSE_FRAPPE_SNOWLAND; - case COURSE_FRAPPE_SNOWLAND: - return COURSE_CHOCO_MOUNTAIN; - case COURSE_CHOCO_MOUNTAIN: - return COURSE_MARIO_RACEWAY; - case COURSE_MARIO_RACEWAY: - return COURSE_LUIGI_RACEWAY; - default: - break; - } - // kaillera track order - case 1: - switch(gCurrentCourseId) { - case COURSE_LUIGI_RACEWAY: - return COURSE_MOO_MOO_FARM; - case COURSE_MOO_MOO_FARM: - return COURSE_KOOPA_BEACH; - case COURSE_KOOPA_BEACH: - return COURSE_KALAMARI_DESERT; - case COURSE_KALAMARI_DESERT: - return COURSE_TOADS_TURNPIKE; - case COURSE_TOADS_TURNPIKE: - return COURSE_FRAPPE_SNOWLAND; - case COURSE_FRAPPE_SNOWLAND: - return COURSE_CHOCO_MOUNTAIN; - case COURSE_CHOCO_MOUNTAIN: - return COURSE_MARIO_RACEWAY; - case COURSE_MARIO_RACEWAY: - return COURSE_WARIO_STADIUM; - case COURSE_WARIO_STADIUM: - return COURSE_SHERBET_LAND; - case COURSE_SHERBET_LAND: - return COURSE_ROYAL_RACEWAY; - case COURSE_ROYAL_RACEWAY: - return COURSE_BOWSER_CASTLE; - case COURSE_BOWSER_CASTLE: - return COURSE_DK_JUNGLE; - case COURSE_DK_JUNGLE: - return COURSE_YOSHI_VALLEY; - case COURSE_YOSHI_VALLEY: - return COURSE_BANSHEE_BOARDWALK; - case COURSE_BANSHEE_BOARDWALK: - return COURSE_RAINBOW_ROAD; - case COURSE_RAINBOW_ROAD: - return COURSE_LUIGI_RACEWAY; - default: - break; - } - // kaillera mmf track order - case 2: - switch(gCurrentCourseId) { - case COURSE_LUIGI_RACEWAY: - return COURSE_MOO_MOO_FARM; - case COURSE_MOO_MOO_FARM: - return COURSE_KOOPA_BEACH; - case COURSE_KOOPA_BEACH: - return COURSE_KALAMARI_DESERT; - case COURSE_KALAMARI_DESERT: - return COURSE_TOADS_TURNPIKE; - case COURSE_TOADS_TURNPIKE: - return COURSE_FRAPPE_SNOWLAND; - case COURSE_FRAPPE_SNOWLAND: - return COURSE_CHOCO_MOUNTAIN; - case COURSE_CHOCO_MOUNTAIN: - return COURSE_MARIO_RACEWAY; - case COURSE_MARIO_RACEWAY: - return COURSE_WARIO_STADIUM; - case COURSE_WARIO_STADIUM: - return COURSE_SHERBET_LAND; - case COURSE_SHERBET_LAND: - return COURSE_ROYAL_RACEWAY; - case COURSE_ROYAL_RACEWAY: - return COURSE_BOWSER_CASTLE; - case COURSE_BOWSER_CASTLE: - return COURSE_DK_JUNGLE; - case COURSE_DK_JUNGLE: - return COURSE_YOSHI_VALLEY; - case COURSE_YOSHI_VALLEY: - return COURSE_BANSHEE_BOARDWALK; - case COURSE_BANSHEE_BOARDWALK: - return COURSE_MOO_MOO_FARM; - default: - break; - } - // randomized track order - case 3: - return getRandomNextCourseId(); - default: - break; - } - -} - // Get the course abbreviation string for the next course +// used for printing on the vs points screen char* getNextCourseAbbrString(void) { switch (gTournamentCourseMode) { // va track order @@ -6292,43 +6166,8 @@ char* getNextCourseAbbrString(void) { default: break; } - // kaillera mmf track order + // random track order case 2: - switch(gCurrentCourseId) { - case COURSE_LUIGI_RACEWAY: - return "MMF"; - case COURSE_MOO_MOO_FARM: - return "KTB"; - case COURSE_KOOPA_BEACH: - return "KD"; - case COURSE_KALAMARI_DESERT: - return "TT"; - case COURSE_TOADS_TURNPIKE: - return "FS"; - case COURSE_FRAPPE_SNOWLAND: - return "CM"; - case COURSE_CHOCO_MOUNTAIN: - return "MR"; - case COURSE_MARIO_RACEWAY: - return "WS"; - case COURSE_WARIO_STADIUM: - return "SL"; - case COURSE_SHERBET_LAND: - return "RRy"; - case COURSE_ROYAL_RACEWAY: - return "BC"; - case COURSE_BOWSER_CASTLE: - return "DKJP"; - case COURSE_DK_JUNGLE: - return "YV"; - case COURSE_YOSHI_VALLEY: - return "BB"; - case COURSE_BANSHEE_BOARDWALK: - return "MMF"; - default: - break; - } - case 3: return getCourseAbbrFromId(getRandomNextCourseId()); default: break; @@ -7184,13 +7023,7 @@ void func_800A1500(MenuItem* arg0) { break; } } -/*Renders a course selection menu item by determining the course ID -from the cup/course order based on the item's type, displaying -the course image and name bar, and optionally drawing a flashing -selection highlight with a checkmark icon (from D_02004A0C) if the - course has been completed (as indicated by func_800B639C returning - a non-negative value). Note: the ^ 0 XOR on arg0->row is a deliberate - no-op used to force a specific register allocation in the compiled output.*/ + void func_800A15EC(MenuItem* arg0) { s16 courseId = gCupCourseOrder[(arg0->type - 0x7C) / 4][(arg0->type - 0x7C) % 4]; gDisplayListHead = @@ -7207,14 +7040,7 @@ void func_800A15EC(MenuItem* arg0) { func_8009C204(gDisplayListHead, segmented_to_virtual_dupe(&D_02004A0C), arg0->column + 0x20, arg0->row, 2); } } -/*This function renders a menu item by interpolating between -two consecutive colors from a color table (D_800E74D0) based on param1 -as a blend factor (0-256) and param2 as the base color index, -setting the result as the display list's primitive color, -and then drawing a menu texture at the item's column and row position. -The color interpolation cycles through three colors using modular - arithmetic, creating a smooth color transition effect for the menu - element.*/ + void func_800A1780(MenuItem* arg0) { RGBA16* temp_a1; RGBA16* temp_v1; @@ -8590,15 +8416,6 @@ void func_800A6034(MenuItem* arg0) { } } -/*Renders a pause menu overlay by drawing a darkened background box -and displaying pause button text entries, with behavior depending on -the menu's state: when in state 0, it fades in using param1 as an -opacity factor and draws text in yellow, otherwise it draws at -full opacity with a rainbow text effect and a selection cursor -(func_800A66A8) positioned based on the current state. -Additionally, if param2 is positive, it draws horizontal -screen-wipe bars from the top and bottom edges of the - screen, used for a transition or iris effect.*/ void func_800A6154(MenuItem* arg0) { UNUSED s32 stackPadding0; UNUSED s32 stackPadding1; @@ -8687,7 +8504,7 @@ void func_800A638C(MenuItem* arg0) { if (arg0->state >= 10) { for (var_s1 = 0; var_s1 < 4; var_s1++) { - /* For 3P/4P Versus, change the first option to "CONTINUE TO " */ + // For 3P/4P Versus, change the first option to "CONTINUE TO " text_rainbow_effect(arg0->state - 0xA, var_s1, TEXT_GREEN); if ((var_s1 == 0) && (gModeSelection == VERSUS) && ((gPlayerCount == 3) || (gPlayerCount == 4))) { continueText = "CONTINUE TO "; @@ -8695,6 +8512,10 @@ void func_800A638C(MenuItem* arg0) { xOffset = (get_string_width(continueText) * 0.8f) + 1.0f; print_text_mode_1((s32) (0x00000069 + xOffset), 0xAE + (0xF * var_s1) + 10, getNextCourseAbbrString(), 0, 0.8f, 0.8f); + // For 3P/4P Versus, change the last option to "RETRY" + } else if ((var_s1 == 3) && (gModeSelection == VERSUS) && ((gPlayerCount == 3) || (gPlayerCount == 4))) { + print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1) + 10, gTextPauseButton[1], 0, 0.8f, + 0.8f); } else { print_text_mode_1(0x00000069, 0xAE + (0xF * var_s1) + 10, gTextPauseButton[var_s1 + 1], 0, 0.8f, 0.8f); @@ -8704,14 +8525,6 @@ void func_800A638C(MenuItem* arg0) { } } - /*This function animates and renders a 3D menu item with a spinning/tumbling effect - by applying cumulative rotations around all three axes - (with rotation speeds derived from arg0->paramf and arg0->subState) - and a scaling factor, while gradually decaying paramf toward a minimum of 1.5. - It constructs a composite transformation matrix (scale → Y rotation → Z rotation → X rotation - → translation to the item's grid position), pushes it to the display list, - and draws the display list D_0D003090 with cloud-surface blending and modulated - intensity-alpha combine mode.*/ void func_800A66A8(MenuItem* arg0, Unk_D_800E70A0* arg1) { Mtx* mtx; f32 tmp; diff --git a/src/menus.c b/src/menus.c index 811161237a..dac775f906 100644 --- a/src/menus.c +++ b/src/menus.c @@ -179,7 +179,7 @@ s8 gCustomMenuOptionValues[CUSTOM_MENU_ROWS] = { 0 }; // Per-row number of selectable values (matches label arrays in render_custom_overlay) // tracks, stats, scaling, widescreen, mp music, mp train boat, AA, force minimap, // extra, practice mode -static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 4, 3, 3, 2, 2, 4, 2, 3, 2, 2 }; +static const s8 gCustomMenuValueCounts[CUSTOM_MENU_ROWS] = { 3, 3, 3, 2, 2, 4, 2, 3, 2, 2 }; // end of new var init diff --git a/src/player_controller.c b/src/player_controller.c index 4c7d02aa66..a3cca9144a 100644 --- a/src/player_controller.c +++ b/src/player_controller.c @@ -1103,6 +1103,7 @@ void func_8002A5F4(Vec3f arg0, f32 arg1, Vec3f arg2, f32 arg3, f32 arg4) { } } +// set start boost function void func_8002A704(Player* player, s8 playerIndex) { player->effects |= MUSHROOM_EFFECT; player->triggers &= ~START_BOOST_TRIGGER; diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index a7ef790b21..a1e2eee019 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -37,6 +37,7 @@ extern u16 D_802BA048; extern s32 D_8018D2AC; extern s32 D_802B91E0; extern s16 getNextCourseId(void); +extern COURSES getRandomNextCourseId(void); u16 D_802BA030; u16 D_802BA032; @@ -70,10 +71,7 @@ void func_8028DF38(void) { controllers++; } } -/*This function increments a tracked statistic for the winning player - by updating a specific global array based on the current player count. - Additionally, it calls a helper function using the winner's index, - updates a state variable, and initializes the demo timer.*/ + void func_8028E028(void) { switch (gPlayerCountSelection1) { @@ -150,16 +148,22 @@ void func_8028E298(void) { update_player_rankings(); } +// check if race is finished and moves next course select pointer in cup +// does not actually advance to next track when "CONTINUE TO..." is pressed void func_8028E3A0(void) { + // if race is cleared if (D_80150120) { - + // if race cleared and last course was finished if (gCourseIndexInCup == COURSE_FOUR) { gGotoMode = ENDING; + // if not in the last course of the cup } else { + // cup number D_800DC544++; gCourseIndexInCup++; gGotoMode = RACING; } + // if race is not cleared } else { D_800DC544++; gCourseIndexInCup++; @@ -167,6 +171,7 @@ void func_8028E3A0(void) { } } +// zoom animation for vs finish void func_8028E438(void) { struct UnkStruct_800DC5EC* temp_v0 = &D_8015F480[gPlayerWinningIndex]; s32 phi_v1_4; @@ -242,11 +247,14 @@ void func_8028E438(void) { } } +// function for zoom animation finish +// I dont think this is ever called in VS mode void func_8028E678(void) { s32 phi_a0_10 = 0; D_800DC5B0 = 1; + // camera zoom flag switch (D_8015F894) { case 0: // Unused switch? @@ -1200,12 +1208,56 @@ void func_802903B0(void) { // proceed to next track in selection (vs mode only) void gotoNextTrack(void) { - s16 nextCourse; + s8 prevCupSelection; + + // Kaillera track order + if (gTournamentCourseMode == 1) { + + if (!(gCourseIndexInCup == COURSE_FOUR)) { + gCourseIndexInCup++; + } else { + gCourseIndexInCup = 0; + gCupSelection++; // Move to next cup + if (gCupSelection > 3) { + gCupSelection = 0; + } + } + gCurrentCourseId = gCupCourseOrder[gCupSelection][gCourseIndexInCup]; + } + // VA track order + else if (gTournamentCourseMode == 0) { + if (!(gCourseIndexInCup == COURSE_FOUR)) { + gCourseIndexInCup++; + } else { + gCourseIndexInCup = 0; + prevCupSelection = gCupSelection; + + // mushroom -> special + if (prevCupSelection == 0) { + gCupSelection = SPECIAL_CUP; + } + // special -> star + else if (prevCupSelection == 3) { + gCupSelection = STAR_CUP; + } + // star -> flower + else if (prevCupSelection == 2) { + gCupSelection = FLOWER_CUP; + } + // to mushroom cup default + else { + gCupSelection = MUSHROOM_CUP; + } + } + gCurrentCourseId = gCupCourseOrder[gCupSelection][gCourseIndexInCup]; + } + // random track order + else if (gTournamentCourseMode == 2) { + gCurrentCourseId = getRandomNextCourseId(); + } gIsInQuitToMenuTransition = 1; gQuitToMenuTransitionCounter = 5; - nextCourse = getNextCourseId(); - gCurrentCourseId = nextCourse; gGotoMode = RACING; } diff --git a/src/spawn_players.c b/src/spawn_players.c index 58a1597299..b97e6fd42b 100644 --- a/src/spawn_players.c +++ b/src/spawn_players.c @@ -89,8 +89,8 @@ void spawn_player(Player* player, s8 playerIndex, f32 startingRow, f32 startingC && (playerType & PLAYER_HUMAN) && !(playerType & PLAYER_INVISIBLE_OR_BOMB) && !(getLiveControllerBits() & (1 << playerIndex))) { - playerType = (playerType & ~PLAYER_HUMAN | PLAYER_CPU); - gPracticeCPU[playerIndex] = true; + playerType |= PLAYER_CPU; + gPracticeCPU[playerIndex] = true; } } From af260935da6299100fd7d01f37bcc4488c69ac9e Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sun, 16 Aug 2026 17:42:09 -0400 Subject: [PATCH 68/73] added some comments and fixed player audio with green shells --- src/audio/external.c | 1 + src/effects.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/audio/external.c b/src/audio/external.c index 98f8a953e7..7eb8b2fe4c 100644 --- a/src/audio/external.c +++ b/src/audio/external.c @@ -2931,6 +2931,7 @@ void func_800C9060(u8 playerId, u32 soundBits) { } } +// plays character voice void func_800C90F4(u8 playerId, u32 soundBits) { if (D_800EA108 == 0) { switch (D_800EA0EC[playerId]) { diff --git a/src/effects.c b/src/effects.c index 9ef102c10d..bec3546c00 100644 --- a/src/effects.c +++ b/src/effects.c @@ -196,6 +196,7 @@ void clean_effect(Player* player, s8 playerIndex) { player->effects = (s32) (player->effects & ~AB_SPIN_EFFECT); } +// rollover/green shell tumbles void func_8008C528(Player* player, s8 playerIndex) { UNUSED s32 sp24; s32 temp_v1; @@ -217,7 +218,7 @@ void func_8008C528(Player* player, s8 playerIndex) { player->unk_042 = 0; if (((player->type & PLAYER_HUMAN) == PLAYER_HUMAN) && ((player->type & PLAYER_INVISIBLE_OR_BOMB) != PLAYER_INVISIBLE_OR_BOMB)) { - func_800C90F4(playerIndex, (temp_v1 * 0x10) + 0x29008005); + func_800C90F4(playerIndex, (player->characterId * 0x10) + 0x29008005); func_800C9060(playerIndex, SOUND_ACTION_EXPLOSION); } else { play_cpu_sound_effect(playerIndex, player); From 2f5f9d72c45f9ba569cb8cc298d36225512512f7 Mon Sep 17 00:00:00 2001 From: "Luke D." <102872635+LukeDischiave@users.noreply.github.com> Date: Sun, 16 Aug 2026 19:09:28 -0400 Subject: [PATCH 69/73] Update README.md --- README.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d8908bec4e..3a3d813923 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,60 @@ -# Mario Kart 64 +# Refactor of Mario Kart 64 Multiplayer ROM Hack (Tournament Edition) +Refactor of Mario Kart 64 ROM hack with configuration menu + +## Features +### TITLE MENU Options +- Game Pacing: Default/original (15-30fps)* / 30fps** / 60fps +- Widescreen: 4:3*(default) / 16:9** +- MP Music: Disabled*(Default) / Enabled** +- VS Detail: Original*(Default) / Enabled** / Both + - Multiplayer DKJP Boat: Enabled* / Disabled** + - Multiplayer KD Train: Original* / Full** +- Practice mode: Disabled*(Default) / Enabled** +- Extra mode: Disabled*(Default) / Enabled** +- Force Minimap: Disabled*(Default) / prog view**, map +- Anti-aliasing: Disabled*(Default) / Enabled** + +### FEATURES +- Tie-logic: Based off the in-game timer instead of player port +- Lightning: Single white flash so easier on the eyes +- VS timer: Players' finish timers are displayed on the points screen +- Sounds: No c-up or c-right sounds during the race +- Slow pause: players must hold pause for roughly .5 sec to mitigate accidental pauses + +### CHARACTER SELECT Options +- Character Stats: Original / All Yoshi / All Wario + +### VS MAP SELECT Screen +- Track Selection: VA*(Original) / Kaillera**(in-order) / Random + +### VS MATCH RANKING Screen +- Include total score by player as 3/2/1 (3P) or 3/2/1/0 (4P) +- Include ability to adjust VS scores if all players hold L + R bumpers and use C-UP and C-DOWN to adjust scores + +## TODO + +### TITLE MENU Options + +### GAME SELECT Menu Options +- Course Z Scaler: Original / Minimum / Maximum +- Randomizer +- Engine (150cc): 150cc / 200cc +- Engine (Extra): 100cc / 150cc / 200cc +- Practice mode bots + +### VS MAP SELECT Screen +- VS Track Order: All Cups (Random Order) +- VS Bomb Karts: Enabled / Disabled +- VS CPUs: None / 1 / 2 / 3 / 4 / 5 / 6 / 7 + +### VS MATCH RANKING Screen + + +### CREDITS +- Megamech and the mk64 decomp team +Please credit Climatee, Zserf, and dntn31 if you decided to fork this specific repo + +## Building (Windows) This decompilation of Mario Kart 64 pursues historical and educational elements within the game found via taking it apart and putting it back together. Inspiration to do so not only emanates from the game's hardware and technology but also its immensely positive effects on the cultures and families of nearly every nationality. This repository does not contain assets. Compiling requires asset extraction from a prior copy of the game. From 474d0fd0fcc4c12c63580638942b35645a95747a Mon Sep 17 00:00:00 2001 From: "Luke D." <102872635+LukeDischiave@users.noreply.github.com> Date: Sun, 16 Aug 2026 19:11:00 -0400 Subject: [PATCH 70/73] Update README.md --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3a3d813923..a3896fe202 100644 --- a/README.md +++ b/README.md @@ -38,20 +38,17 @@ Refactor of Mario Kart 64 ROM hack with configuration menu ### GAME SELECT Menu Options - Course Z Scaler: Original / Minimum / Maximum - Randomizer -- Engine (150cc): 150cc / 200cc -- Engine (Extra): 100cc / 150cc / 200cc -- Practice mode bots +- 200cc +- Improved practice mode bots ### VS MAP SELECT Screen -- VS Track Order: All Cups (Random Order) -- VS Bomb Karts: Enabled / Disabled -- VS CPUs: None / 1 / 2 / 3 / 4 / 5 / 6 / 7 + ### VS MATCH RANKING Screen ### CREDITS -- Megamech and the mk64 decomp team +Megamech and the mk64 decomp team Please credit Climatee, Zserf, and dntn31 if you decided to fork this specific repo ## Building (Windows) From ad19723dd66ca80ef01008efdd0caa2abb0438c1 Mon Sep 17 00:00:00 2001 From: "Luke D." <102872635+LukeDischiave@users.noreply.github.com> Date: Sun, 16 Aug 2026 19:11:23 -0400 Subject: [PATCH 71/73] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a3896fe202..438e876c0a 100644 --- a/README.md +++ b/README.md @@ -48,8 +48,8 @@ Refactor of Mario Kart 64 ROM hack with configuration menu ### CREDITS -Megamech and the mk64 decomp team -Please credit Climatee, Zserf, and dntn31 if you decided to fork this specific repo +- Megamech and the mk64 decomp team +- Please credit Climatee, Zserf, and dntn31 if you decided to fork this specific repo ## Building (Windows) This decompilation of Mario Kart 64 pursues historical and educational elements within the game found via taking it apart and putting it back together. Inspiration to do so not only emanates from the game's hardware and technology but also its immensely positive effects on the cultures and families of nearly every nationality. From dbf6c1356cbb33c7e497a066adc6746ea7e78059 Mon Sep 17 00:00:00 2001 From: "Luke D." <102872635+LukeDischiave@users.noreply.github.com> Date: Mon, 17 Aug 2026 07:29:59 -0400 Subject: [PATCH 72/73] Update README.md --- README.md | 61 +++++++++++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 438e876c0a..b108e041c3 100644 --- a/README.md +++ b/README.md @@ -3,52 +3,47 @@ Refactor of Mario Kart 64 ROM hack with configuration menu ## Features ### TITLE MENU Options -- Game Pacing: Default/original (15-30fps)* / 30fps** / 60fps -- Widescreen: 4:3*(default) / 16:9** -- MP Music: Disabled*(Default) / Enabled** -- VS Detail: Original*(Default) / Enabled** / Both - - Multiplayer DKJP Boat: Enabled* / Disabled** - - Multiplayer KD Train: Original* / Full** -- Practice mode: Disabled*(Default) / Enabled** -- Extra mode: Disabled*(Default) / Enabled** -- Force Minimap: Disabled*(Default) / prog view**, map -- Anti-aliasing: Disabled*(Default) / Enabled** - -### FEATURES -- Tie-logic: Based off the in-game timer instead of player port -- Lightning: Single white flash so easier on the eyes -- VS timer: Players' finish timers are displayed on the points screen -- Sounds: No c-up or c-right sounds during the race +- Widescreen: 4:3(default) / 16:9 +- Game Pacing: Default/original (15-30fps) / 30fps (emulator) / 60fps +- MP Music: (Default) / Enabled +- VS Detail: Original / High + - Multiplayer DKJP Boat: Enabled / Disabled + - Multiplayer KD Train: Original / Full +- Track Selection: Original / Kaillera / Random +- Practice mode: Default / Enabled +- Extra mode: Disabled(Default) / Enabled +- Force Minimap: Default / Prog view / Map +- Anti-aliasing: Default / Disabled + +### NON-MENU FEATURES +- Tie-logic: Same-frame finishes now determined by in-game timer instead of player port +- Lightning: Now a single white flash instead of many alterating blue and white flashes +- VS timer: Players' finish time are displayed on the VS points screen +- Sounds: No c-up or c-right sounds during VS races - Slow pause: players must hold pause for roughly .5 sec to mitigate accidental pauses -### CHARACTER SELECT Options -- Character Stats: Original / All Yoshi / All Wario - -### VS MAP SELECT Screen -- Track Selection: VA*(Original) / Kaillera**(in-order) / Random ### VS MATCH RANKING Screen -- Include total score by player as 3/2/1 (3P) or 3/2/1/0 (4P) +- Include total score by player as 2/1/0 (3P) or 3/2/1/0 (4P) - Include ability to adjust VS scores if all players hold L + R bumpers and use C-UP and C-DOWN to adjust scores ## TODO - ### TITLE MENU Options - -### GAME SELECT Menu Options +- 200cc - Course Z Scaler: Original / Minimum / Maximum - Randomizer -- 200cc -- Improved practice mode bots - -### VS MAP SELECT Screen - - -### VS MATCH RANKING Screen +- Improve practice mode bots +## NON-MENU Stuff +- Patch shortcuts +- Update microcode + optimize code so that 4p runs at 30fps on console + fix jumbotron +- internal rollback netcode for future online play +- storing item stats for each VS race, export data somehow +- DKR-inspired timer for 3p/4p vs mode +- Amped Up-style practice bots ### CREDITS -- Megamech and the mk64 decomp team +- Megamech + the mk64 decomp team, and abitalive - Please credit Climatee, Zserf, and dntn31 if you decided to fork this specific repo ## Building (Windows) From 0276fcf2abd984429becf869417059af0e77839d Mon Sep 17 00:00:00 2001 From: LukeDischiave Date: Sat, 22 Aug 2026 11:22:05 -0400 Subject: [PATCH 73/73] implemented podium finish for 3p/4p vs mode and added various comments --- src/code_80057C60.c | 3 +- src/ending/code_80281780.c | 9 +++- src/ending/podium_ceremony_actors.c | 7 +-- src/main.c | 2 +- src/menu_items.c | 68 ++++++++++++++++------------ src/menu_items.h | 1 + src/player_controller.c | 2 + src/racing/race_logic.c | 70 +++++++++++++++++++++++++++-- src/racing/skybox_and_splitscreen.c | 1 + src/render_player.c | 6 +-- src/save.c | 2 +- src/spawn_players.c | 3 ++ src/update_objects.c | 4 +- 13 files changed, 134 insertions(+), 44 deletions(-) diff --git a/src/code_80057C60.c b/src/code_80057C60.c index 09ef069f2d..ecbe1e052c 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -1195,6 +1195,7 @@ void render_hud_4p_multi(void) { } } +// stores player params somewhere void func_80059820(s32 playerId) { hud_player* temp_v0; @@ -1411,7 +1412,7 @@ void func_80059D00(void) { func_800744CC(); } } - +// various init for items in podium finish? void func_8005A070(void) { func_8008C1D8(&D_80165678); gMatrixHudCount = 0; diff --git a/src/ending/code_80281780.c b/src/ending/code_80281780.c index 0f303fa474..10d380822d 100644 --- a/src/ending/code_80281780.c +++ b/src/ending/code_80281780.c @@ -68,11 +68,18 @@ void func_802818BC(void) { s32 sp1C; s32 temp_v0_2; - if (gPlayerCount != TWO_PLAYERS_SELECTED) { + if (gPlayerCount == ONE_PLAYERS_SELECTED) { + // always follows P1 (default behavior) D_802874D8.unk1D = func_80281880(0); D_802874D8.unk1E = gCharacterSelections[0]; return; } + else if (gPlayerCount != TWO_PLAYERS_SELECTED) { + // changed to always follow the winning player + D_802874D8.unk1D = func_80281880(gPlayerWinningIndex); + D_802874D8.unk1E = gCharacterSelections[gPlayerWinningIndex]; + return; + } // weird pattern but if it matches it matches temp_v0 = sp1C = func_80281880(0); temp_v0_2 = func_80281880(1); diff --git a/src/ending/podium_ceremony_actors.c b/src/ending/podium_ceremony_actors.c index 0667cf1e5b..25e2df4e8e 100644 --- a/src/ending/podium_ceremony_actors.c +++ b/src/ending/podium_ceremony_actors.c @@ -449,17 +449,18 @@ void podium_ceremony_loop(void) { gMatrixObjectCount = 0; D_802874FC = 0; update_camera_podium_ceremony(); - func_80028F70(); - func_80022744(); + func_80028F70(); // something graphical + func_80022744(); // also something graphical? func_80059AC8(); func_80059AC8(); func_8005A070(); + // if kart is not moving? if (D_802874D8.unk1C != 0) { func_8001C14C(); update_vehicles(); } render_podium_ceremony(); - func_80281540(); + func_80281540(); // does literally nothing #if DVDL display_dvdl(); #endif diff --git a/src/main.c b/src/main.c index a7254ce591..7cbaf127de 100644 --- a/src/main.c +++ b/src/main.c @@ -115,7 +115,7 @@ f32 D_80150118; u16 wasSoftReset; u16 D_8015011E; - +// race cleared s32 D_80150120; s32 gGotoMode; UNUSED s32 D_80150128; diff --git a/src/menu_items.c b/src/menu_items.c index 4771aeca7a..42579c3b50 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -55,6 +55,7 @@ void* gSomeDLBuffer; * has scored */ s8 gGPPointsByCharacterId[8]; +s8 gVSPoints[8] = {0}; s8 gCharacterIdByGPOverallRank[8]; s8 D_8018D9D8; s8 D_8018D9D9; @@ -6124,7 +6125,7 @@ char* getNextCourseAbbrString(void) { case COURSE_CHOCO_MOUNTAIN: return "MR"; case COURSE_MARIO_RACEWAY: - return "LR"; + return "AWARDS"; default: break; } @@ -6162,7 +6163,7 @@ char* getNextCourseAbbrString(void) { case COURSE_BANSHEE_BOARDWALK: return "RRd"; case COURSE_RAINBOW_ROAD: - return "LR"; + return "AWARDS"; default: break; } @@ -7567,13 +7568,7 @@ void func_800A32B4(s32 arg0, s32 arg1, s32 characterId, s32 rank) { print_text_mode_1(arg0 + 0x62, arg1, "\"", 0, 0.7f, 0.7f); func_800939C8(arg0 + 0x6A, arg1, sp3C, 0, 0.7f, 0.7f); } -/*Renders the Grand Prix "Driver's Points" scoreboard UI for a MenuItem, -displaying the current round number, each player's rank and character -with animated text colors (cycling for human players, static for CPU), -the cup name, and the CC/engine class selection, with support for -both mid-race rankings (states 1-8) and final overall rankings - (state 9+), including a staggered reveal animation controlled by - param1.*/ +/*Renders the Grand Prix "Driver's Points" scoreboard UI*/ void func_800A34A8(MenuItem* arg0) { s8 sp80[8]; UNUSED s32 stackPadding0; @@ -8634,8 +8629,7 @@ void func_800A69C8(UNUSED MenuItem* arg0) { /*Iterates over all players and, based on the current mode selection, calls either func_800A6E94 (for Versus mode) or func_800A6D94 (for Battle mode) with a fixed parameter of 3 (3 PLAYER VERSUS), the current player - index, and a mode-specific global value (nmi_gVersusResults3P or gNmiUnknown5). - The MenuItem parameter is unused.*/ + index, and a mode-specific global value (nmi_gVersusResults3P or gNmiUnknown5)..*/ void func_800A6BEC(UNUSED MenuItem* arg0) { s32 var_s0; @@ -8800,9 +8794,18 @@ void func_800A6E94(s32 playerCount, s32 playerId, u8* placeAry) { seconds = tally[i * 3 + 1]; thirds = tally[i * 3 + 2]; - // custom point calculation; wraps around to 0 after hitting 48 - points = (u8)((( (firsts * 3) + (seconds * 2) + (thirds * 1) + tally_overrides[i] ) % 49 + 49) % 49); + // custom point calculation; wraps around to 0 after hitting 48 for 4p + // wraps around to 0 after hitting 32 for 3p + if (gPlayerCountSelection1 == 4) { + points = (u8)((( (firsts * 3) + (seconds * 2) + (thirds * 1) + tally_overrides[i] ) % 49 + 49) % 49); + } + if (gPlayerCountSelection1 == 3) { + points = (u8)((( (firsts * 2) + (seconds * 1) + (thirds * 0) + tally_overrides[i] ) % 33 + 33) % 33); + } + // copy points into global array sorted by playerId + gVSPoints[i] = (s8)points; + // convert to ascii char convert_number_to_ascii(points, pointsBuf); @@ -8910,10 +8913,13 @@ void func_800A72FC(MenuItem* arg0) { s32 cupNameLength = (((f32) get_string_width(gCupNames[gCupSelection]) * 1) + 10) / 2; s32 ccNameLength = (((f32) get_string_width(D_800E76CC[gCCSelection]) * 1) + 10) / 2; - set_text_color(TEXT_YELLOW); - print_text1_center_mode_1(arg0->column - ccNameLength, arg0->row, gCupNames[gCupSelection], 0, 1, 1); - set_text_color(TEXT_YELLOW); - print_text1_center_mode_1(arg0->column + cupNameLength, arg0->row, D_800E76DC[gCCSelection], 0, 1, 1); + // don't render the text for CUP + CC on congratulations screen + if (gPlayerCount < 3) { + set_text_color(TEXT_YELLOW); + print_text1_center_mode_1(arg0->column - ccNameLength, arg0->row, gCupNames[gCupSelection], 0, 1, 1); + set_text_color(TEXT_YELLOW); + print_text1_center_mode_1(arg0->column + cupNameLength, arg0->row, D_800E76DC[gCCSelection], 0, 1, 1); + } } void func_800A7448(MenuItem* arg0) { @@ -8921,16 +8927,19 @@ void func_800A7448(MenuItem* arg0) { s32 sp40; s32 sp3C; s32 thing = D_802874D8.unk1D; - if (thing >= 3) { - set_text_color(TEXT_YELLOW); - print_text1_center_mode_1(arg0->column, arg0->row, D_800E7A98, 0, 0.75f, 0.75f); - } else { - sp40 = (s32) (((f32) (get_string_width(D_800E7A88[0]) + 5) * 0.75f) / 2); - sp3C = (s32) (((f32) (get_string_width(D_800E7A88[thing + 1]) + 5) * 0.75f) / 2); - set_text_color(TEXT_YELLOW); - print_text1_center_mode_1(arg0->column - sp3C, arg0->row, D_800E7A88[0], 0, 0.75f, 0.75f); - set_text_color(TEXT_YELLOW); - print_text1_center_mode_1(arg0->column + sp40, arg0->row, D_800E7A88[thing + 1], 0, 0.75f, 0.75f); + // don't render the text for "you have been awarded the bronze/silver/gold cup" + if (gPlayerCount < 3) { + if (thing >= 3) { + set_text_color(TEXT_YELLOW); + print_text1_center_mode_1(arg0->column, arg0->row, D_800E7A98, 0, 0.75f, 0.75f); + } else { + sp40 = (s32) (((f32) (get_string_width(D_800E7A88[0]) + 5) * 0.75f) / 2); + sp3C = (s32) (((f32) (get_string_width(D_800E7A88[thing + 1]) + 5) * 0.75f) / 2); + set_text_color(TEXT_YELLOW); + print_text1_center_mode_1(arg0->column - sp3C, arg0->row, D_800E7A88[0], 0, 0.75f, 0.75f); + set_text_color(TEXT_YELLOW); + print_text1_center_mode_1(arg0->column + sp40, arg0->row, D_800E7A88[thing + 1], 0, 0.75f, 0.75f); + } } } @@ -11272,7 +11281,7 @@ void func_800AC324(MenuItem* arg0) { break; } } - +// handles game points for GP mode? void func_800AC458(MenuItem* arg0) { s32 var_a1; s32 var_t1; @@ -11370,7 +11379,10 @@ void func_800AC458(MenuItem* arg0) { if (arg0->param1 <= 0) { arg0->state = 0x0000000A; arg0->param1 = 0; + + // IF LAST COURSE IN CUP if (gCourseIndexInCup == 3) { + // go thru all 8 players? for (var_a1 = 0; var_a1 < 8; var_a1++) { if (gGetPlayerByCharacterId[gCharacterIdByGPOverallRank[var_a1]] < gPlayerCount) { func_800B536C(var_a1); diff --git a/src/menu_items.h b/src/menu_items.h index c818ae30c0..795b784d51 100644 --- a/src/menu_items.h +++ b/src/menu_items.h @@ -862,5 +862,6 @@ extern s8 gTournamentShellLimit; // unused extern s8 gTournamentForceMap; extern s8 gTournamentExtraMode; extern s8 gPracticeMode; +extern s8 gVSPoints[8]; #endif diff --git a/src/player_controller.c b/src/player_controller.c index a3cca9144a..ef41108bfd 100644 --- a/src/player_controller.c +++ b/src/player_controller.c @@ -616,6 +616,7 @@ void func_80028D3C(Player* player, Camera* camera, s8 playerId, s8 screenId) { } } +// moves the kart void func_80028E70(Player* player, Camera* camera, s8 playerId, s8 screenId) { if ((player->type & PLAYER_EXISTS) == PLAYER_EXISTS) { switch (gGamestate) { @@ -4880,6 +4881,7 @@ void func_80038BE4(Player* player, s16 arg1) { player->unk_08C = (player->currentSpeed * player->currentSpeed) / 25.0f; } +// run karts in podium finish? void func_80038C6C(Player* player, UNUSED Camera* camera, s8 screenId, s8 playerId) { Vec3f sp114 = { 0.0, 0.0, 1.0 }; Vec3f sp108 = { 0.0, 0.0, 0.0 }; diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index a1e2eee019..684be8e0d0 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -12,6 +12,7 @@ #include "main.h" #include "code_800029B0.h" #include "code_80057C60.h" +#include "code_80281780.h" #include "update_objects.h" #include "menu_items.h" #include "cpu_vehicles_camera_path.h" @@ -28,6 +29,10 @@ #pragma intrinsic(sqrtf) +extern s8 gVSPoints[8]; +extern s8 gCharacterSelections[8]; +extern s8 gCharacterIdByGPOverallRank[8]; + extern s16 gPlayerBalloonCount[]; extern s16 D_8016348C; @@ -750,6 +755,7 @@ void func_8028F4E8(void) { } } +// function to set the Vp scale void func_8028F588(void) { s16 screenWidth; @@ -996,7 +1002,7 @@ void end_demo_update(void) { gMenuSelection = LOGO_INTRO_MENU; } } - +// controls races void func_8028FCBC(void) { Player* ply = &gPlayers[0]; s32 i; @@ -1206,9 +1212,47 @@ void func_802903B0(void) { gGotoMode = RACING; } +// builds vs standings for ALL 8 players :) +// if a player gets 0 points, an empty slot should never be ranked above +// resolves ties based off of port priority (no other way) +void build_vs_standings() { + s32 i,j; + u8 order[8]; + u8 key; + u8 defaultCharacterIds[] = { 1, 2, 3, 4, 5, 6, 7, 0 }; + + + for (i=0; i<8; i++) { + // default characters are mario for non-players + gCharacterIdByGPOverallRank[i] = 0; + } + + for (i=0; i < gPlayerCount; i++) { + order[i] = i; + } + + + // insertion sort + for (i=1; i<8; i++) { + key = order[i]; + j = i -1; + while (j>=0 && gVSPoints[order[j]] < gVSPoints[key]) { + order[j+1] = order[j]; + j--; + } + order[j+1] = key; + } + + for (i=0; i 3) { gCupSelection = 0; } + + } + if (gCurrentCourseId == COURSE_RAINBOW_ROAD) { + // this spot in memory needs to be populated or else the ceremony wont run + // bcopy(&defaultCharacterIds, &gCharacterIdByGPOverallRank, 8); + build_vs_standings(); + gGamestateNext = ENDING; + return; + } + else { + gCurrentCourseId = gCupCourseOrder[gCupSelection][gCourseIndexInCup]; } - gCurrentCourseId = gCupCourseOrder[gCupSelection][gCourseIndexInCup]; } // VA track order else if (gTournamentCourseMode == 0) { @@ -1249,13 +1303,21 @@ void gotoNextTrack(void) { gCupSelection = MUSHROOM_CUP; } } - gCurrentCourseId = gCupCourseOrder[gCupSelection][gCourseIndexInCup]; + if (gCurrentCourseId == COURSE_MARIO_RACEWAY) { + // this spot in memory needs to be populated or else the ceremony wont run + // bcopy(&defaultCharacterIds, &gCharacterIdByGPOverallRank, 8); + build_vs_standings(); + gGamestateNext = ENDING; + return; + } + else { + gCurrentCourseId = gCupCourseOrder[gCupSelection][gCourseIndexInCup]; + } } // random track order else if (gTournamentCourseMode == 2) { gCurrentCourseId = getRandomNextCourseId(); } - gIsInQuitToMenuTransition = 1; gQuitToMenuTransitionCounter = 5; gGotoMode = RACING; diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index 4a81dec7a0..1eb9e84763 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -1392,6 +1392,7 @@ void render_player_four_3p_4p_screen(void) { D_8015F788 += 1; } +// init some data void func_802A74BC(void) { struct UnkStruct_800DC5EC* wrapper = &D_8015F480[0]; Player* player = &gPlayers[0]; diff --git a/src/render_player.c b/src/render_player.c index b3af9c91d8..21f051e226 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -876,8 +876,8 @@ void move_u16_towards(u16* startingValue, s16 targetValue, f32 somePercent) { } void func_80022744(void) { - func_8006E058(); - func_8002276C(); + func_8006E058(); // something to do with kart effect + func_8002276C(); // something to do with vtx } void func_8002276C(void) { @@ -940,7 +940,7 @@ void func_8002276C(void) { } break; case SCREEN_MODE_3P_4P_SPLITSCREEN: - if ((VERSUS == gModeSelection) || (BATTLE == gModeSelection)) { + if ((gModeSelection == VERSUS) || (gModeSelection == BATTLE)) { func_80022A98(gPlayerOne, 0); func_80022A98(gPlayerTwo, 1); func_80022A98(gPlayerThree, 2); diff --git a/src/save.c b/src/save.c index 12d4631f78..c01fe09358 100644 --- a/src/save.c +++ b/src/save.c @@ -347,7 +347,7 @@ s32 func_800B5218(void) { return 0; } } - +// save cup points void func_800B536C(s32 arg0) { u8* points; u8 tmp; diff --git a/src/spawn_players.c b/src/spawn_players.c index b97e6fd42b..949600e9c9 100644 --- a/src/spawn_players.c +++ b/src/spawn_players.c @@ -383,6 +383,7 @@ void spawn_player(Player* player, s8 playerIndex, f32 startingRow, f32 startingC void func_80039AE4(void) { switch (gActiveScreenMode) { case SCREEN_MODE_1P: + case SCREEN_MODE_3P_4P_SPLITSCREEN: if (gGamestate == ENDING) { D_80165578 = 0x898; D_8016557A = 0; @@ -833,12 +834,14 @@ void spawn_players_4p_battle(f32* arg0, f32* arg1, f32 arg2) { } void func_8003BE30(void) { + //spawn character spawning at the highest point earner spawn_player(gPlayerOne, 0, -2770.774f, -345.187f, -34.6f, 0.0f, gCharacterIdByGPOverallRank[0], PLAYER_EXISTS | PLAYER_CPU | PLAYER_START_SEQUENCE); spawn_player(gPlayerTwo, 1, -3691.506f, -6.822f, -6.95f, 36400.0f, gCharacterIdByGPOverallRank[1], PLAYER_EXISTS | PLAYER_CPU | PLAYER_START_SEQUENCE); spawn_player(gPlayerThree, 2, -3475.028f, -998.485f, -8.059f, 45500.0f, gCharacterIdByGPOverallRank[2], PLAYER_EXISTS | PLAYER_CPU | PLAYER_START_SEQUENCE); + // this spawns players at the start of the race based off of pole position if (D_802874D8.unk1D >= 3) { spawn_player(gPlayerFour, 3, -3025.772f, 110.039f, -23.224f, 28210.0f, D_802874D8.unk1E, PLAYER_EXISTS | PLAYER_CPU | PLAYER_START_SEQUENCE); diff --git a/src/update_objects.c b/src/update_objects.c index c142fd6cab..b0f028a272 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -7925,7 +7925,7 @@ void func_80086528(s32 objectIndex, s32 arg1) { break; } } - +// spawning/moving objects? void func_80086604(void) { s32 objectIndex; s32 var_s1; @@ -8080,7 +8080,7 @@ void func_80086C6C(s32 objectIndex) { } func_800773D8(sp24, (s32) D_801658F4); } - +// spawning golden cup? void func_80086D80(void) { s32 temp_s2; s32 var_s0;