diff --git a/.gitignore b/.gitignore index 0057cda895..be1d212415 100644 --- a/.gitignore +++ b/.gitignore @@ -105,3 +105,6 @@ mingw64/ # torch torch.hash.yml + +# makefile +Makefile diff --git a/Makefile b/Makefile index e4d98c41a6..4dd1321466 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ $(eval $(call validate-option,COMPILER,ido gcc)) DEBUG ?= 0 # Avoid undefined behavior. Enables shiftability when making changes -AVOID_UB ?= 0 +AVOID_UB ?= 1 # Compile with GCC GCC ?= 0 @@ -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) @@ -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)) @@ -789,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/README.md b/README.md index d8908bec4e..b108e041c3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,52 @@ -# 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 +- 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 + + +### VS MATCH RANKING Screen +- 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 +- 200cc +- Course Z Scaler: Original / Minimum / Maximum +- Randomizer +- 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 + the mk64 decomp team, and abitalive +- 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. 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 */ 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/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/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/include/defines.h b/include/defines.h index acc0f1dbfa..5467517e3e 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 @@ -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/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/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/audio/external.c b/src/audio/external.c index 41835ae6d1..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]) { @@ -3249,6 +3250,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/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/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 9d6619977e..ecbe1e052c 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -36,10 +36,14 @@ #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)) +bool gFinished[8]; +f32 gFinishTime[8]; +f32 gWinnerTime; s32 D_80165590; s32 D_80165594; s32 D_80165598; @@ -149,17 +153,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; @@ -1191,6 +1195,7 @@ void render_hud_4p_multi(void) { } } +// stores player params somewhere void func_80059820(s32 playerId) { hud_player* temp_v0; @@ -1407,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; @@ -1494,6 +1499,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) { @@ -1515,6 +1521,7 @@ void func_8005A3C0(void) { b = true; } break; + // 2p case 2: if (gModeSelection != BATTLE) { if (gControllerOne->buttonPressed & R_CBUTTONS) { @@ -1535,28 +1542,76 @@ void func_8005A3C0(void) { } } break; + // 3p case 3: - if ((gControllerOne->buttonPressed & R_CBUTTONS) || (gControllerTwo->buttonPressed & R_CBUTTONS) || - (gControllerThree->buttonPressed & R_CBUTTONS)) { + // 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 = (D_801657F0 + 1) & 1; + D_801657F0 = 1; } - D_801657E4 = (D_801657E4 + 1) & 1; + D_801657E4 = 1; b = true; + break; } - break; - 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; + // force map view at all times + if (gTournamentForceMap == 2) { if (gModeSelection != BATTLE) { - D_801657F0 = (D_801657F0 + 1) & 1; + 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) { + D_801657F0 = (D_801657F0 + 1) & 1; + } + D_801657E4 = (D_801657E4 + 1) & 1; + 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) { + 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; + } + 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) { func_8006F824(1); @@ -2705,6 +2760,7 @@ void func_8005D0FC(s32 playerId) { } } +// rank scroll? void func_8005D18C(void) { if ((gModeSelection == GRAND_PRIX) && (gPlayerCountSelection1 == TIME_TRIALS)) { D_801657D8 = 1; @@ -2746,26 +2802,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); @@ -2781,11 +2837,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) { @@ -2822,7 +2878,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; @@ -2861,7 +2917,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); } @@ -2934,7 +2990,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); } @@ -2958,7 +3014,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); } @@ -2986,7 +3042,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; @@ -2995,7 +3051,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; @@ -3009,14 +3065,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); } @@ -3027,14 +3083,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); } @@ -3045,14 +3101,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); } @@ -3063,14 +3119,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); @@ -3083,14 +3139,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); } @@ -3105,7 +3161,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); } @@ -3115,7 +3171,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); } @@ -3159,12 +3215,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); } } @@ -3200,7 +3256,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); } @@ -3222,7 +3278,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); } @@ -3249,7 +3305,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; @@ -3257,7 +3313,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; @@ -3270,13 +3326,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); } @@ -3286,13 +3342,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); } @@ -3302,13 +3358,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); } @@ -3318,13 +3374,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); } @@ -3335,13 +3391,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); } @@ -3353,13 +3409,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); } @@ -3394,7 +3450,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); } @@ -3416,7 +3472,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); } @@ -3442,14 +3498,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; @@ -3461,12 +3517,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); } @@ -3475,12 +3531,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); } @@ -3489,12 +3545,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); } @@ -3503,12 +3559,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); } @@ -3518,12 +3574,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); } @@ -3534,12 +3590,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); } @@ -3573,13 +3629,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; @@ -3633,7 +3689,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 { @@ -3679,7 +3735,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); @@ -3688,7 +3744,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); @@ -3700,7 +3756,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); @@ -3717,7 +3773,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; @@ -3727,7 +3783,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); @@ -3824,7 +3880,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); @@ -3865,7 +3921,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); @@ -3873,7 +3929,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); @@ -3929,7 +3985,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) { @@ -3945,7 +4001,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) { @@ -3990,7 +4046,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; @@ -4012,7 +4068,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) { @@ -5062,7 +5118,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; @@ -5115,7 +5171,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; @@ -5143,12 +5199,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); @@ -5159,7 +5215,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); @@ -5289,12 +5345,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); @@ -5303,12 +5359,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); @@ -5408,12 +5464,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); @@ -5478,7 +5534,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; @@ -5494,12 +5550,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); @@ -5524,12 +5580,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); @@ -5578,12 +5634,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); @@ -5649,7 +5705,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 @@ -5854,7 +5910,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, }; @@ -6058,18 +6114,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); } } @@ -6591,10 +6647,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: @@ -6603,10 +6659,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: @@ -6673,7 +6729,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); @@ -6807,7 +6863,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 95e9e1fdba..49adf9feb8 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); @@ -116,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); @@ -192,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); @@ -205,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); @@ -220,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); @@ -256,6 +257,9 @@ void func_8006E940(Player*, s8, s8); void func_80075CA8(void); void func_80085214(); +extern bool gFinished[]; +extern f32 gFinishTime[]; +extern f32 gWinnerTime; extern s16 D_800E4730[]; extern u8** D_800E4770[]; extern u8** D_800E47A0[]; @@ -606,27 +610,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 03073c1e3a..7ad4195151 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 @@ -368,7 +368,7 @@ 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)) { + 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 26fa50d4ae..f0a32e2f3f 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]; @@ -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; + 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 + 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) { @@ -992,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; @@ -1018,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) { @@ -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 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)); } void update_player_path_completion(s32 playerId, Player* player) { @@ -1220,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; @@ -1269,6 +1262,13 @@ 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] = 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) { // clang-format off @@ -1276,12 +1276,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); } } } @@ -1393,25 +1393,304 @@ 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]; if ((s32) GET_COURSE_AIMaximumSeparation >= 0) { D_80163100[playerId] += 1; @@ -1460,290 +1739,35 @@ 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))) { - set_places(); - } + 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; - } - } + update_cpu_player(playerId, player); + } + } - 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); + 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; + } + + 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(); } } } @@ -2088,6 +2112,10 @@ 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; + gWinnerTime = 1000000.0f; if (gModeSelection == GRAND_PRIX) { if (1) {}; if (1) {}; // Maybe some debug code? @@ -2099,7 +2127,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; @@ -2186,7 +2214,7 @@ void init_players(void) { } gIsInExtra = false; - if (gCCSelection == CC_EXTRA) { + if (gCCSelection == CC_EXTRA || gTournamentExtraMode == 1) { gIsInExtra = true; } @@ -3508,19 +3536,24 @@ 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)); + 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; @@ -3544,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]; @@ -3560,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); @@ -3615,6 +3650,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); diff --git a/src/cpu_vehicles_camera_path.h b/src/cpu_vehicles_camera_path.h index ae46283e80..a5f6d4dcd9 100644 --- a/src/cpu_vehicles_camera_path.h +++ b/src/cpu_vehicles_camera_path.h @@ -115,12 +115,13 @@ 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*); 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); @@ -323,7 +324,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 +384,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/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/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; 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/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 33b31f625c..bec3546c00 100644 --- a/src/effects.c +++ b/src/effects.c @@ -19,7 +19,9 @@ #include "menu_items.h" #include -s32 D_8018D900[8]; +#define PLAYER_STATS_CHARACTER_ID(player) ((gTournamentCharacterStats == 0) ? YOSHI : (gTournamentCharacterStats == 2) ? WARIO : (player)->characterId) + +s32 D_8018D900[8]; s16 D_8018D920[8]; s32 gPlayerStarEffectStartTime[8]; s32 gPlayerBooEffectStartTime[8]; @@ -152,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); @@ -194,17 +196,20 @@ 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; + 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[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; @@ -213,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); @@ -257,7 +262,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)) { @@ -293,7 +298,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; @@ -347,7 +352,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 { @@ -357,7 +362,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); } @@ -372,7 +377,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; @@ -384,13 +389,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; @@ -411,7 +416,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; @@ -435,16 +440,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; @@ -455,7 +460,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; @@ -476,7 +481,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; @@ -500,12 +505,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; } @@ -563,9 +568,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 +616,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 +627,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 +670,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 +822,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 +912,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 +924,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 +1012,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 +1121,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 +1225,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 +1579,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 +2092,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/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/ending/camera_junk.c b/src/ending/camera_junk.c index 5f360ea41b..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,7 +39,13 @@ void init_camera_podium_ceremony(void) { cameras[0].up[1] = 1.0f; cameras[0].up[2] = 0.0f; gCameraZoom[0] = 40.0f; - 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/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 044cc235f0..7cbaf127de 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 @@ -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]; @@ -111,7 +115,7 @@ f32 D_80150118; u16 wasSoftReset; u16 D_8015011E; - +// race cleared s32 D_80150120; s32 gGotoMode; UNUSED s32 D_80150128; @@ -162,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; @@ -236,6 +240,8 @@ void thread1_idle(void* arg) { osStartThread(&gVideoThread); osSetThreadPri(NULL, 0); + // uncomment for lagfix (in osViData.c) + // osViModeNtscLan1.comRegs.vSync = 3341; // Halt while (true) { ; @@ -465,7 +471,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) { @@ -474,6 +486,7 @@ void display_and_vsync(void) { if (++sRenderingFramebuffer == 3) { sRenderingFramebuffer = 0; } + gGlobalTimer++; } @@ -594,7 +607,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++) { @@ -653,11 +673,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) { @@ -698,11 +729,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++) { @@ -750,11 +792,37 @@ void race_logic_loop(void) { case COURSE_MOO_MOO_FARM: case COURSE_SKYSCRAPER: case COURSE_DK_JUNGLE: + // 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 @@ -762,14 +830,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; - 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; - 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) { @@ -1179,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 6d7ac7aac2..dbe8b6339e 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]; // 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 @@ -198,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 edf8e9ad26..42579c3b50 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; @@ -52,6 +55,7 @@ void* gSomeDLBuffer; * has scored */ s8 gGPPointsByCharacterId[8]; +s8 gVSPoints[8] = {0}; s8 gCharacterIdByGPOverallRank[8]; s8 D_8018D9D8; s8 D_8018D9D9; @@ -67,9 +71,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]; @@ -126,6 +130,7 @@ Unk_D_800E70A0 D_800E7108[][4] = { }, }; +// not character potraits Unk_D_800E70A0 D_800E7148[] = { { 0x17, 0x3b, 0x00, 0x00 }, { 0x5d, 0x3b, 0x00, 0x00 }, @@ -199,22 +204,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; used for cursor Unk_D_800E70A0 D_800E7360[] = { - { 0x61, 0xa7, 0x00, 0x00 }, - { 0x61, 0xb6, 0x00, 0x00 }, - { 0x61, 0xc5, 0x00, 0x00 }, - { 0x61, 0xd4, 0x00, 0x00 }, + { 0x61, 0xb1, 0x00, 0x00 }, + { 0x61, 0xc0, 0x00, 0x00 }, + { 0x61, 0xcf, 0x00, 0x00 }, + { 0x61, 0xde, 0x00, 0x00 }, }; Unk_D_800E70A0 D_800E7380[] = { @@ -278,7 +285,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 }, @@ -355,6 +362,121 @@ s8 gCupSelectionByCourseId[] = { #include "assets/course_metadata/gCupSelectionByCourseId.inc.c" }; +s8 gTournamentCourseMode = 0; +s8 gTournamentCharacterStats = 0; +s8 gTournamentScaling = 0; +s8 gTournamentWidescreen = 0; +s8 gTournamentMusic = 0; +s8 gTournamentTrainBoat = 0; +s8 gTournamentAA = 0; +s8 gTournamentForceMap = 0; +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; +} + +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", @@ -713,19 +835,24 @@ 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 +// 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 }; 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 + { 0xff, 0xff, 0xff, 0xff }, // white + { 0x00, 0x00, 0x50, 0xff }, // dark blue + { 0xff, 0xff, 0xff, 0xff }, // white }; RGBA16 D_800E7AE8[] = { @@ -833,12 +960,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, @@ -884,7 +1011,7 @@ MenuTexture* D_800E81E4[] = { }; MenuTexture* D_800E822C[] = { - D_02004534, + seg2_textureFontComma, D_0200455C, }; @@ -896,7 +1023,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 @@ -1073,6 +1200,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; @@ -1246,7 +1388,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++) { @@ -1342,7 +1484,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++) { @@ -1472,6 +1614,7 @@ void func_80092290(s32 arg0, s32* arg1, s32* arg2) { } } +// display time void func_80092500(void) { switch (gModeSelection) { @@ -1484,6 +1627,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(); @@ -1501,6 +1645,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); } @@ -2040,6 +2185,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]); } @@ -2152,7 +2332,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++) { @@ -2297,6 +2477,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: @@ -2375,11 +2556,12 @@ void setup_menus(void) { add_menu_item(MENU_ITEM_TYPE_0D9, 0, 0, MENU_ITEM_PRIORITY_A); break; case START_MENU: + // 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); } @@ -2477,7 +2659,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 @@ -2538,8 +2720,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); } @@ -3225,12 +3408,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) { @@ -4253,7 +4436,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); @@ -4530,9 +4713,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); @@ -4550,7 +4733,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: @@ -4559,7 +4742,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]; @@ -4589,24 +4772,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) { @@ -4615,6 +4798,7 @@ void func_8009CE1C(void) { } } +// fade out transition for menu void func_8009CE64(s32 arg0) { s32 thing; s32 var_a1; @@ -4643,26 +4827,31 @@ 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); if (temp_v0 != NULL) { + // EVENT HANDLER FOR VS MENU switch (temp_v0->state) { /* switch 8; irregular */ case 10: /* switch 8 */ - func_802903B0(); + // go to next track in selection (VS mode) + gotoNextTrack(); 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 */ - func_80290338(); + // retry (vs mode) + func_802903B0(); break; } } else { @@ -4708,7 +4897,7 @@ void func_8009CE64(s32 arg0) { var_a1 = 1; break; default: - D_8018E7AC[arg0] = 5; + gTransitionType[arg0] = 5; break; } if (var_a1 != 0) { @@ -4747,14 +4936,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 */ @@ -4970,7 +5159,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; } @@ -4985,8 +5174,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); } } @@ -5040,12 +5229,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; } @@ -5059,11 +5248,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; } @@ -5073,8 +5262,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; } @@ -5096,7 +5285,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; } @@ -5107,11 +5296,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; } @@ -5129,11 +5318,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; } @@ -5154,14 +5343,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; } } @@ -5172,25 +5361,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++) { @@ -5200,11 +5389,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; } @@ -5252,7 +5441,7 @@ void func_8009E2A8(s32 arg0) { break; } } - +// lightning flash renderer void func_8009E2F0(s32 arg0) { UNUSED s32 stackPadding0; UNUSED s32 stackPadding1; @@ -5432,9 +5621,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; @@ -5740,6 +5929,255 @@ 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; + int idx; + s32 rowY; + s32 valIdx; + char nameBuf[32]; + char valBuf[4]; + MenuItem cursorItem; + Unk_D_800E70A0 sp84; + + + /* 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 boat", + "AA", + "force minimap", + "extra", + "practice mode" + /* keep last empty if CUSTOM_MENU_ROWS > 12 */ + }; + + /* per-option label arrays */ + 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"}; + 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* 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); + + // title (centered) + 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-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++) { + /* standard row stride (single-line names) - reduced spacing */ + 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 - 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 - 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 - 0x40, rowY, (char*)customModifierNames[i], 0, 0.6f, 0.6f); + } + + /* third column: current value for this row */ + switch (i) { + case 0: + /* 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; + 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: + /* 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; + 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) */ + 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 + 0x50, rowY, (char*)scaling_labels[idx], 0, 0.6f, 0.6f); + gTournamentScaling = idx; + break; + case 3: + /* 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 + 0x50, rowY, (char*)widescreen_labels[idx], 0, 0.6f, 0.6f); + gTournamentWidescreen = idx; + break; + case 4: + /* 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 + 0x50, rowY, (char*)mpMusic_labels[idx], 0, 0.6f, 0.6f); + gTournamentMusic = idx; + break; + case 5: + /* mp train boat: labels (default, both, train, boat) */ + idx = gCustomMenuOptionValues[i]; + 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 */ + idx = gCustomMenuOptionValues[i]; + 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: + /* force minimap: labels (default, progress view, map) */ + idx = gCustomMenuOptionValues[i]; + if (idx < 0) idx = 0; + 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: + /* 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 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; + } + } +} + +// 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 + 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 "AWARDS"; + 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 "AWARDS"; + default: + break; + } + // random track order + case 2: + return getCourseAbbrFromId(getRandomNextCourseId()); + default: + break; + } + + return ""; + +} + void render_menus(MenuItem* arg0) { s32 var_a1; s32 var_v1; @@ -5807,6 +6245,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) { @@ -6156,6 +6600,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; @@ -7011,7 +7456,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: @@ -7044,6 +7497,7 @@ void func_800A2D1C(MenuItem* arg0) { } } +// 1/2p gp results screen? void func_800A2EB8(MenuItem* arg0) { s8 sp70[8]; UNUSED s32 stackPadding0; @@ -7089,6 +7543,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; @@ -7113,7 +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*/ void func_800A34A8(MenuItem* arg0) { s8 sp80[8]; UNUSED s32 stackPadding0; @@ -7990,23 +8445,29 @@ void func_800A6154(MenuItem* arg0) { } } +// 4p/3p vs results screen menu draw void func_800A638C(MenuItem* arg0) { UNUSED s32 temp_a0; s32 var_a1; UNUSED s32 var_s0; s32 var_s1; UNUSED s8** var_s2; + 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); - 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: var_a1 = 0x000000FF; @@ -8019,7 +8480,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); @@ -8033,10 +8496,25 @@ 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); - 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 "; + 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) + 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); + } } func_800A66A8(arg0, &D_800E7360[arg0->state - 10]); } @@ -8085,30 +8563,38 @@ 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; - s32 var_s0; + s32 playerId; char sp74[5]; s32 var_v1; char* temp_s3; u8* var_s4; + char* finishTimeText; - 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 = &nmi_gVersusResults2P[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]; @@ -8118,21 +8604,39 @@ 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 + 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 + if (gFinished[playerId]){ + // 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); + } + text_draw_right(thing->column + 65, 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, "ー", 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, + 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)..*/ void func_800A6BEC(UNUSED MenuItem* arg0) { s32 var_s0; 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); @@ -8141,13 +8645,19 @@ 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 (nmi_gVersusResults4P or gNmiUnknown6). The MenuItem parameter + is unused.*/ void func_800A6CC0(UNUSED MenuItem* arg0) { s32 var_s0; 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); @@ -8181,43 +8691,182 @@ void func_800A6D94(s32 arg0, s32 arg1, u8* arg2) { 0.75f); } -// The s/n/r/ー are not ASCII characters, they're EUC-JP characters -void func_800A6E94(s32 arg0, s32 arg1, u8* arg2) { +/*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 playerCount, s32 playerId, u8* placeAry) { UNUSED s32 stackPadding0; u8* temp_v0; Unk_D_800E70A0* temp_s0; char sp40[3]; s32 rank; + char* finishTimeText; + + // 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]; + + // tally override initially zero + static s32 tally_overrides[4] = {0, 0, 0, 0}; + // Everything about this variable is bizarre - s32 sp38 = -1; + s32 rankIdx = -1; + + // flag that checks if manual point override is active + s32 isComboActive = 0; - temp_s0 = &D_800E7300[((arg0 - 2) * 4) + arg1]; - rank = gGPCurrentRaceRankByPlayerId[arg1]; - if (rank == ++sp38) { + // base x and y position for drawing scores + // x-coord increment will be different for 3p and 4p vs + base_xPos_4p = 26; + base_xPos_3p = 52; + Y_pos = 27; + // i: player index + i = 0; + + // change tally var based off of player count + // 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) + 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; 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); + + // 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 * 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] == ' ') ? -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]; + 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); - convert_number_to_ascii(temp_v0[0], sp40); - text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x5A, sp40, 0, 0.8f, 0.8f); - if (rank == ++sp38) { + 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 + 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 + 0x69, "2 n ー", 0, 0.8f, 0.8f); - convert_number_to_ascii(temp_v0[1], sp40); - text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x69, sp40, 0, 0.8f, 0.8f); - if (++sp38 == rank) { + 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 + 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 + 0x78, "3 r ー", 0, 0.8f, 0.8f); - convert_number_to_ascii(temp_v0[2], sp40); - text_draw(temp_s0->column + 0x2D, temp_s0->row + 0x78, sp40, 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 + 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); + } + // right aligned to keep digit significance consistent + text_draw_right(temp_s0->column + 65, temp_s0->row + 90, finishTimeText, 0, 0.6f, 0.6f); + } } void func_800A70E8(MenuItem* arg0) { @@ -8264,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) { @@ -8275,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); + } } } @@ -8344,8 +8999,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; } @@ -10626,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; @@ -10724,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); @@ -10848,6 +11506,7 @@ void func_800ACA14(MenuItem* arg0) { } } +// renders VS/battle end-of-race rankings menu void func_800ACC50(MenuItem* arg0) { s32 i; @@ -10903,6 +11562,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/menu_items.h b/src/menu_items.h index 7ed1964bc9..795b784d51 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, @@ -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); @@ -455,9 +456,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 +677,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 +722,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[]; @@ -850,4 +851,17 @@ extern f32 D_8018EDA4; extern f32 D_8018EDA8; extern f32 D_8018EDAC; +extern s8 gTournamentCourseMode; +extern s8 gTournamentCharacterStats; +extern s8 gTournamentScaling; +extern s8 gTournamentWidescreen; +extern s8 gTournamentMusic; +extern s8 gTournamentTrainBoat; +extern s8 gTournamentAA; +extern s8 gTournamentShellLimit; // unused +extern s8 gTournamentForceMap; +extern s8 gTournamentExtraMode; +extern s8 gPracticeMode; +extern s8 gVSPoints[8]; + #endif diff --git a/src/menus.c b/src/menus.c index 5223158f56..dac775f906 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 @@ -143,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 }, @@ -164,8 +166,78 @@ 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 }; + +// 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 }; + +// 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 ((physicalBits & (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 ((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; + + // 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 @@ -227,6 +299,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: @@ -1022,7 +1097,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; @@ -1036,6 +1111,51 @@ void splash_menu_act(struct Controller* controller, u16 controllerIdx) { 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) { + 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_SELECT); + } + // go backwards one if press left dpad and not at first index + else if (btnAndStick & L_JPAD && (gCustomMenuOptionValues[gCustomMenuSelection] != 0) ) { + 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_SELECT); + } + // go to end if press left dpad at first index + else if (btnAndStick & L_JPAD && (gCustomMenuOptionValues[gCustomMenuSelection] == 0) ) { + 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_SELECT); + } switch (gDebugMenuSelection) { case DEBUG_MENU_DISABLED: { isDebug = false; @@ -1249,7 +1369,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; @@ -1487,14 +1607,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; } @@ -1533,7 +1654,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); @@ -1557,6 +1678,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; @@ -1642,7 +1764,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); } @@ -1777,6 +1900,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); @@ -1996,7 +2120,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/menus.h b/src/menus.h index 8b16558a65..f08d29f556 100644 --- a/src/menus.h +++ b/src/menus.h @@ -262,7 +262,16 @@ extern s8 gControllerPakScrollDirection; extern const s8 gPlayerModeSelection[]; extern const s32 gGameModePlayerSelection[][3]; extern const s16 gCupCourseOrder[NUM_CUPS][NUM_COURSES_PER_CUP]; - // end of menus.c variables +// start of custom menu var +#define CUSTOM_MENU_ROWS 10 +#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 */ 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]; 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; diff --git a/src/player_controller.c b/src/player_controller.c index 23f1e6feff..ef41108bfd 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 : (gTournamentCharacterStats == 2) ? WARIO : (player)->characterId) extern s32 D_8018D168; @@ -588,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) { @@ -613,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) { @@ -1100,6 +1104,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; @@ -1136,7 +1141,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) { @@ -1181,9 +1186,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 +1242,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 { @@ -1375,7 +1380,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); @@ -1396,7 +1401,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); @@ -1417,7 +1422,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); @@ -1567,7 +1572,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 { @@ -1578,7 +1583,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])); @@ -1729,7 +1734,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) { @@ -1958,10 +1963,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); @@ -2013,7 +2018,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); } @@ -2109,7 +2114,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); } @@ -2382,12 +2387,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 +2668,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 +2746,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 +2856,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 +2875,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 +2937,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 +2971,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 +3010,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 +3072,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 +3268,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 : (gTournamentCharacterStats == 2) ? WARIO : 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 +3566,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 +3601,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 : (gTournamentCharacterStats == 2) ? WARIO : 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 +3678,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 : (gTournamentCharacterStats == 2) ? WARIO : 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 +3730,41 @@ void player_decelerate(Player* player, f32 speedReduction) { } void player_accelerate_global(Player* player, s32 playerIndex) { + s32 statsCharacterId; + + statsCharacterId = (gTournamentCharacterStats == 0) ? YOSHI : (gTournamentCharacterStats == 2) ? WARIO : 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) { @@ -3778,7 +3792,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)) { @@ -3835,7 +3849,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)) { @@ -3883,7 +3897,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; @@ -3918,10 +3932,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 +3951,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 +3961,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)); @@ -3977,96 +3991,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) { @@ -4092,10 +4106,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 +4118,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)) { @@ -4134,7 +4148,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) { @@ -4143,7 +4157,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)))); @@ -4220,7 +4234,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; @@ -4248,7 +4262,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); } } } @@ -4263,7 +4277,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)) { @@ -4867,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 }; @@ -4997,12 +5012,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/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/profiler.c b/src/profiler.c index eca4e9a718..1d16bd6c7e 100644 --- a/src/profiler.c +++ b/src/profiler.c @@ -224,8 +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(); -} +} \ No newline at end of file diff --git a/src/racing/actors.c b/src/racing/actors.c index 42b3bd0576..7f03fabf6a 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,21 +167,44 @@ 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 != 1) { + if ((s32) gNumSpawnedShells >= 0x15) { + cleanup_red_and_green_shells((struct ShellActor*) actor); + } + break; + } + // custom shell limit of 30 + else { + if ((s32) gNumSpawnedShells >= 0x1F) { + 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 != 1) { + if ((s32) gNumSpawnedShells >= 0x15) { + cleanup_red_and_green_shells((struct ShellActor*) actor); + } + break; + } + // custom shell limit of 30 + else { + if ((s32) gNumSpawnedShells >= 0x1F) { + cleanup_red_and_green_shells((struct ShellActor*) actor); + } + break; } - 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; @@ -499,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++; @@ -641,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; @@ -650,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++; } @@ -1186,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/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 */ 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/racing/race_logic.c b/src/racing/race_logic.c index 43c7048d32..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" @@ -24,9 +25,14 @@ #include "math.h" #include "menus.h" #include "seq_ids.h" +#include "spawn_players.h" #pragma intrinsic(sqrtf) +extern s8 gVSPoints[8]; +extern s8 gCharacterSelections[8]; +extern s8 gCharacterIdByGPOverallRank[8]; + extern s16 gPlayerBalloonCount[]; extern s16 D_8016348C; @@ -35,6 +41,8 @@ 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; @@ -47,6 +55,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; @@ -81,7 +91,7 @@ void func_8028E028(void) { break; } func_800CA118((u8) gPlayerWinningIndex); - D_800DC510 = 5; + gRaceState = 5; gDemoTimer = 10; } @@ -143,17 +153,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++; @@ -161,6 +176,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; @@ -210,6 +226,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; @@ -225,7 +243,7 @@ void func_8028E438(void) { func_80019DF4(); } else { func_80092564(); - D_800DC510 = 7; + gRaceState = 7; } } break; @@ -234,11 +252,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? @@ -290,7 +311,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; @@ -324,7 +346,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; @@ -348,6 +371,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(); @@ -399,7 +424,7 @@ void func_8028E678(void) { case 4: gIsInQuitToMenuTransition = 1; gQuitToMenuTransitionCounter = 5; - D_800DC510 = 7; + gRaceState = 7; func_8028E3A0(); break; } @@ -407,7 +432,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; @@ -416,12 +441,18 @@ 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) { - 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) { @@ -497,8 +528,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++) { @@ -522,38 +553,47 @@ f32 func_8028EE8C(s32 arg0) { return gCourseTimer - ((COURSE_TIMER_ITER_f * temp_f14) / (temp_f14 + temp_f16)); } -void func_8028EEF0(s32 i) { +// set finish state +void add_cinematic_mode(s32 i) { gPlayers[i].type |= PLAYER_CINEMATIC_MODE; } void func_8028EF28(void) { s16 currentPosition; - s32 i; + 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]; - if ((gPlayers[i].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; } - if (gLapCountByPlayerId[i] < gPlayers[i].lapCount) { - gPlayers[i].lapCount--; - } else if (gLapCountByPlayerId[i] > gPlayers[i].lapCount) { - gPlayers[i].lapCount++; + // handles increasing and decreasing lap count + // two diff var for tracking lap counts + if (gLapCountByPlayerId[playerId] < player->lapCount) { + player->lapCount--; + } else if (gLapCountByPlayerId[playerId] > player->lapCount) { + player->lapCount++; - if ((gPlayers[i].type & PLAYER_HUMAN) != 0) { - if (gPlayers[i].lapCount == 3) { - func_8028EEF0(i); + // 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); - currentPosition = gPlayers[i].currentRank; - gPlayers[i].type |= PLAYER_CPU; + currentPosition = player->currentRank; // store rank as currentPosition + player->type |= PLAYER_CPU; // cpu take over finishing player if (currentPosition < 4) { D_80150120 = 1; } - func_800CA118((u8) i); + // ? + func_800CA118((u8) playerId); if ((D_802BA032 & PLAYER_EXISTS) == 0) { D_802BA032 |= PLAYER_EXISTS; } @@ -561,8 +601,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 (gRaceState <= 4){ + // 4 means somebody has finished the race (or something similar) + // 5 means 2nd to last has finished, concluding the race + gRaceState = 4; + } } if (gModeSelection == TIME_TRIALS) { func_80005AE8(player); @@ -570,71 +617,80 @@ void func_8028EF28(void) { if (gModeSelection == VERSUS) { gDemoTimer = 180; - if (currentPosition == 0) { - gPlayerWinningIndex = i; + if (currentPosition == 0) { // winning player + gPlayerWinningIndex = playerId; } switch (gPlayerCountSelection1) { case 2: - if (currentPosition == 0) { - *(gNmiUnknown1 + i) += 1; - } - if (*(gNmiUnknown1 + i) > 99) { - *(gNmiUnknown1 + i) = 99; + // 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 + *(nmi_gVersusResults2P + playerId) += 1; // add tally + if (*(nmi_gVersusResults2P + playerId) > 99) { + *(nmi_gVersusResults2P + playerId) = 99; + } + 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 + func_800CA118((u8) playerIdLast); // call animation sequence, pass in losing player idx as parameter? } - D_800DC510 = 5; - i = gPlayerPositionLUT[1]; - gPlayers[i].triggers |= SPINOUT_TRIGGER; - gPlayers[i].type |= PLAYER_CPU; - func_800CA118((u8) i); break; case 3: - if (currentPosition < 3) { - *(gNmiUnknown2 + i * 3 + currentPosition) += 1; - } - if (*(gNmiUnknown2 + i * 3 + currentPosition) > 99) { - *(gNmiUnknown2 + i * 3 + currentPosition) = 99; - } - if (currentPosition == 1) { - D_800DC510 = 5; - i = gPlayerPositionLUT[2]; - *(gNmiUnknown2 + i * 3 + 2) += 1; - if (*(gNmiUnknown2 + i * 3 + 2) > 99) { - *(gNmiUnknown2 + i * 3 + 2) = 99; + if (currentPosition < 2) { + *(nmi_gVersusResults3P + playerId * 3 + currentPosition) += 1; + + 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) { + gRaceState = 5; // triggers results screen + + playerIdLast = gPlayerPositionLUT[2]; + // update 3rd place (last) tally here because they may not cross finish line + *(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 + func_800CA118((u8) playerIdLast); // call animation sequence, pass in losing player idx as parameter? } - gPlayers[i].triggers |= SPINOUT_TRIGGER; - gPlayers[i].type |= PLAYER_CPU; - func_800CA118((u8) i); } break; case 4: + // 4th place gets no tally if (currentPosition < 3) { - *(gNmiUnknown3 + i * 3 + currentPosition) += 1; - } - if (*(gNmiUnknown3 + i * 3 + currentPosition) > 99) { - *(gNmiUnknown3 + i * 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; - i = gPlayerPositionLUT[3]; - gPlayers[i].triggers |= SPINOUT_TRIGGER; - gPlayers[i].type |= PLAYER_CPU; - func_800CA118((u8) i); + 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 + 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); } @@ -656,8 +712,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; @@ -668,7 +723,7 @@ void update_race_position_data(void) { void func_8028F474(void) { s32 i; - switch (D_800DC510) { + switch (gRaceState) { case 3: case 4: case 5: @@ -691,7 +746,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; @@ -700,6 +755,7 @@ void func_8028F4E8(void) { } } +// function to set the Vp scale void func_8028F588(void) { s16 screenWidth; @@ -795,6 +851,7 @@ void func_8028F914(void) { void func_8028F970(void) { s32 i; + static u16 sPauseHoldCounter[4]; if (D_8015F890) { return; @@ -825,25 +882,65 @@ void func_8028F970(void) { func_800029B0(); } } - 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); + + // 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] >= 15)) { + 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)) { + ++sPauseHoldCounter[i]; + } + // reset pause counter if player i is not holding down start + if (!(controller->button & START_BUTTON)) { + sPauseHoldCounter[i] = 0; } } @@ -874,7 +971,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; @@ -905,7 +1002,7 @@ void end_demo_update(void) { gMenuSelection = LOGO_INTRO_MENU; } } - +// controls races void func_8028FCBC(void) { Player* ply = &gPlayers[0]; s32 i; @@ -914,7 +1011,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) { @@ -926,7 +1023,7 @@ void func_8028FCBC(void) { } } func_80002DAC(); - D_800DC510 = 1; + gRaceState = 1; D_80150118 = 3.0f; creditsRenderMode = 0; D_802BA032 = 0; @@ -959,7 +1056,7 @@ void func_8028FCBC(void) { func_802A7728(); } } - D_800DC510 = 2; + gRaceState = 2; D_800DC5B0 = 0; D_800DC5B8 = 1; func_80078F64(); @@ -1010,7 +1107,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: @@ -1026,7 +1123,7 @@ void func_8028FCBC(void) { func_8028E298(); gDemoTimer = 600; - D_800DC510 = 5; + gRaceState = 5; } break; } @@ -1040,9 +1137,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; } @@ -1057,7 +1154,7 @@ void func_8028FCBC(void) { func_8028E678(); } else if (gScreenModeSelection == SCREEN_MODE_1P) { func_80092564(); - D_800DC510 = 7; + gRaceState = 7; } else { func_8028E438(); } @@ -1108,13 +1205,125 @@ void func_80290388(void) { gQuitToMenuTransitionCounter = 5; gGotoMode = COURSE_SELECT_MENU_FROM_QUIT; } - +// retry function void func_802903B0(void) { gIsInQuitToMenuTransition = 1; gQuitToMenuTransitionCounter = 5; 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]; + } + } + // 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; + } + } + 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; +} + +// 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; @@ -1125,10 +1334,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); diff --git a/src/racing/race_logic.h b/src/racing/race_logic.h index 3ab60a14ec..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); @@ -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); diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index 78f95fe7ce..1eb9e84763 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -583,18 +583,38 @@ 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; + // 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; } } @@ -1372,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_objects.c b/src/render_objects.c index 21ac663f18..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; @@ -2847,7 +2888,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]; } @@ -4793,6 +4834,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); 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); diff --git a/src/render_player.c b/src/render_player.c index ca979a9775..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); @@ -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/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 95605c73e7..949600e9c9 100644 --- a/src/spawn_players.c +++ b/src/spawn_players.c @@ -72,45 +72,59 @@ 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) { f32 ret; s8 idx; - + 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 |= PLAYER_CPU; + gPracticeCPU[playerIndex] = true; + } + } + 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 : (gTournamentCharacterStats == 2) ? WARIO : 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; @@ -355,7 +369,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); @@ -369,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; @@ -819,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/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[]; 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;