Documentation prs combined (#694)

* WIP: Document checkpoint-related function

* Document several checkpoint-related functions

* Fix misnamed argument

* Change "inactive" flag to "alternate"

* Add another function

* Add missing comment

* Fix score locally

* Document ramp switch functions

* Add comments for named wave functions

* Document and rename two-player adventure functions and globals

* Fix score locally

* Document obj_loop_char_select

* Fix return type

* Fix build errors

* Convert enum to macros

* Try bringing back enum

* Move enum back into menu header

* Fix score locally

* Slightly improve progress messages in score display (#687)

* Slightly improve progress messages in score display

* Add specific counts of undocumented functions

* Roll back redundant calculations

* More concise Trophy Race descriptions

* Fix score locally

* chore: update score

---------

Co-authored-by: Jordan Longstaff <jrdnlngstff@gmail.com>
Co-authored-by: Jordan Longstaff <JordanLongstaff@users.noreply.github.com>
Co-authored-by: Dominik Peters <dominik.peters@committance.com>
This commit is contained in:
Dominik Peters
2025-07-24 01:10:29 +02:00
committed by GitHub
co-authored by Jordan Longstaff Jordan Longstaff Dominik Peters
parent 3534199c4c
commit ab1a65087e
23 changed files with 659 additions and 552 deletions
+45 -39
View File
@@ -5,41 +5,44 @@ This repo contains a work-in-progress decompilation of Diddy Kong Racing for the
All versions are supported, and the US 1.0 version (SHA1 = 0cb115d8716dbbc2922fda38e533b9fe63bb9670) of the game is the default if not specified.
<!-- README_SCORE_SUMMARY_BEGIN -->
As of July 20, 2025, this is our current score:
As of July 23, 2025, this is our current score:
&emsp;&emsp;&emsp;&emsp;Decomp progress: 96.77%
&emsp;&emsp;&emsp;&emsp;Documentation progress: 63.57%
&emsp;&emsp;&emsp;&emsp;Documentation progress: 65.10%
<!-- README_SCORE_SUMMARY_END -->
---
## Dependencies
* `gcc`, Version 8.0 or higher
* `make`, Version 4.2 or higher
* `python3`
* `libpcre2-dev` and `libpcre2-8-0` (Not technically required, but will speedup extracting/building some assets.)
* `gcc-mips-linux-gnu` is optionally used if compiling NON_MATCHING with COMPILER=gcc
- `gcc`, Version 8.0 or higher
- `make`, Version 4.2 or higher
- `python3`
- `libpcre2-dev` and `libpcre2-8-0` (Not technically required, but will speedup extracting/building some assets.)
- `gcc-mips-linux-gnu` is optionally used if compiling NON_MATCHING with COMPILER=gcc
`sudo apt install build-essential pkg-config git python3 python3-pip binutils-mips-linux-gnu python3-venv libpcre2-dev libpcre2-8-0`
## Setup / Building
1. Install the dependencies
2. Place the ROM file within the `baseroms` directory.
**a.** The name of the ROM file does not matter. It will be detected automatically from an sha1 checksum.
**a.** The name of the ROM file does not matter. It will be detected automatically from an sha1 checksum.
3. Grab tools: `git submodule update --init --recursive`
4. Run `make setup` to install the IDO compiler, python venv, and packages required.
5. Run `make extract` to run splat to extract all required files from the baserom.
6. Run `make` in the main directory.
**a.** Use the `-jN` argument to use `N` number of threads to speed up building. For example, if you have a system with 4 cores / 4 threads, you should do `make -j4`.
**a.** Use the `-jN` argument to use `N` number of threads to speed up building. For example, if you have a system with 4 cores / 4 threads, you should do `make -j4`.
### Building on macOS
1. Use homebrew to install dependencies: `brew install make`
2. Place the ROM file within the `baseroms` directory. See [Setup](#setup--building) above for more info.
3. Run `gmake` from the main directory. Note that macOS built-in `make` will not work since it does not meet the version requirements.
### Building other versions
To build other versions of the ROM, just specifcy the region and version in the make command. All examples are below:
Baserom|REGION|VERSION|Command
---|--|---|-
@@ -50,9 +53,10 @@ US 1.1 | US | v80 | `make REGION=us VERSION=v80`
PAL 1.1 | PAL | v80 | `make REGION=pal VERSION=v80`
## Modding
If you are modifying the code in the repo, then you should add `NON_MATCHING=1` to the make command.
Example: `make NON_MATCHING=1 -j4`
Example: `make NON_MATCHING=1 -j4`
The `NON_MATCHING` define will include the functions that don't exactly match one-to-one, but should be no different functionality-wise. If you do notice any bugs that occur in a `NON_MATCHING` build that are not in the vanilla game, then please file an issue describing the bug. It would be helpful if you can track down which function is causing the bug, but that is not required.
## Style Guide
@@ -95,18 +99,20 @@ Example: `./rename.sh D_A4001000 SP_IMEM`
Prints out the current completion percentage of the decomp. You do need to have an `OK` build for this to work properly.
The scoring is split into 2 sections:
The scoring is split into 2 sections:
1. Assembly to C Decompilation (Adventure One)
2. Cleanup and Documentation (Adventure Two)
Show scores for Adventure One & Adventure Two: `./score.sh`
Show score for Adventure One only: `./score.sh -a 1`
Show score for Adventure Two only: `./score.sh -a 2`
Show top 10 files remaining: `./score.sh -t 10`
Show top 10 files remaining: `./score.sh -t 10`
To make progress in Adventure 2, a function must be properly named (must not start with `func_`) and also include a doxygen comment above it.
For example:
```c
/**
* Returns 1 if Drumstick is available to use, or 0 if not.
@@ -117,32 +123,32 @@ s32 is_drumstick_unlocked(void) {
```
<!-- README_SCORE_BEGIN -->
As of July 20, 2025, this is our current score:
As of July 23, 2025, this is our current score:
```
=============================================================================
ADVENTURE ONE (ASM -> C Decompilation)
------------------- 96.77% Complete (97.77% NON_MATCHING) -------------------
# Decompiled functions: 1941
# GLOBAL_ASM remaining: 11
# NON_MATCHING functions: 5
# NON_EQUIVALENT WIP functions: 6
-------------------------------- Game Status --------------------------------
Balloons: 46/47, Keys: 4/4, Trophies: 4/5
T.T. Amulets: 4/4, Wizpig Amulets: 4/4
-----------------------------------------------------------------------------
We are collecting silver coins in Star City. (7/8 silver coins)
=============================================================================
ADVENTURE TWO (Cleanup & Documentation)
------------------------------ 63.57% Complete ------------------------------
# Documented functions: 1241
# Undocumented remaining: 411
# Functions named `func_*`: 250
# Functions without comments: 411
-------------------------------- Game Status --------------------------------
Balloons: 30/47, Keys: 3/4, Trophies: 2/5
T.T. Amulets: 3/4, Wizpig Amulets: 3/4
-----------------------------------------------------------------------------
We are participating in the Sherbet Island Trophy Race. (Round Four, Lap 3/3)
=============================================================================
===============================================================
ADVENTURE ONE (ASM -> C Decompilation)
------------ 96.77% Complete (97.77% NON_MATCHING) ------------
# Decompiled functions: 1941
# GLOBAL_ASM remaining: 11
# NON_MATCHING functions: 5
# NON_EQUIVALENT WIP functions: 6
------------------------- Game Status -------------------------
Balloons: 46/47, Keys: 4/4, Trophies: 4/5
T.T. Amulets: 4/4, Wizpig Amulets: 4/4
---------------------------------------------------------------
We are collecting silver coins in Star City. (7/8 silver coins)
===============================================================
ADVENTURE TWO (Cleanup & Documentation)
----------------------- 65.10% Complete -----------------------
# Documented functions: 1262
# Undocumented remaining: 390
# Functions named `func_*`: 238
# Functions without comments: 390
------------------------- Game Status -------------------------
Balloons: 30/47, Keys: 3/4, Trophies: 3/5
T.T. Amulets: 3/4, Wizpig Amulets: 3/4
---------------------------------------------------------------
We are racing Taj in the Plane Challenge. (Lap 3/3)
===============================================================
```
<!-- README_SCORE_END -->
+3 -3
View File
@@ -131,7 +131,7 @@ typedef struct LevelObjectEntry_Dino_Whale {
typedef struct LevelObjectEntry_Checkpoint {
/* 0x00 */ LevelObjectEntryCommon common;
/* 0x08 */ u8 scale;
/* 0x09 */ u8 unk9;
/* 0x09 */ u8 index;
/* 0x0A */ u8 angleY; Hint((Angle, DivideBy:64))
/* 0x0B */ s8 unkB;
/* 0x0C */ s8 unkC;
@@ -145,10 +145,10 @@ typedef struct LevelObjectEntry_Checkpoint {
/* 0x14 */ s8 unk14;
/* 0x15 */ s8 unk15;
/* 0x16 */ s8 unk16;
/* 0x17 */ u8 unk17;
/* 0x17 */ u8 isAltCheckpoint;
/* 0x18 */ s8 unk18;
/* 0x19 */ u8 unk19;
/* 0x1A */ s8 unk1A;
/* 0x1A */ s8 vehicleType;
/* 0x1B */ u8 unk1B;
} LevelObjectEntry_Checkpoint;
+4 -4
View File
@@ -1238,7 +1238,7 @@ typedef struct Object_Racer {
/* 0x18C */ s16 unk18C;
/* 0x18E */ s16 shieldTimer;
/* 0x190 */ s16 courseCheckpoint;
/* 0x192 */ s8 checkpoint;
/* 0x192 */ s8 nextCheckpoint;
/* 0x193 */ s8 lap;
/* 0x194 */ s8 countLap;
/* 0x195 */ s8 magnetLevel3;
@@ -1266,7 +1266,7 @@ typedef struct Object_Racer {
/* 0x1C2 */ s16 unk1C2;
/* 0x1C4 */ s16 unk1C4;
/* 0x1C6 */ s16 unk1C6;
/* 0x1C8 */ u8 unk1C8;
/* 0x1C8 */ u8 isOnAlternateRoute;
/* 0x1C9 */ u8 unk1C9;
/* 0x1CA */ s8 unk1CA;
/* 0x1CB */ s8 unk1CB;
@@ -1488,9 +1488,9 @@ typedef struct Object_AnimatedObject {
/* 0x20 */ u32 soundMask;
/* 0x24 */ s16 currentSound;
/* 0x26 */ s16 unk26;
/* 0x28 */ s16 unk28;
/* 0x28 */ s16 actorIndex;
/* 0x2A */ s16 startDelay;
/* 0x2C */ u8 unk2C;
/* 0x2C */ u8 loopType;
/* 0x2D */ u8 unk2D;
/* 0x2E */ u8 unk2E;
/* 0x2F */ s8 unk2F;
+1 -1
View File
@@ -638,7 +638,7 @@ void viewport_main(Gfx **dlist, Mtx **mats) {
originalCameraID = gActiveCameraID;
savedCameraID = gActiveCameraID;
if (func_8000E184() && gViewportLayout == VIEWPORT_LAYOUT_1_PLAYER) {
if (is_player_two_in_control() && gViewportLayout == VIEWPORT_LAYOUT_1_PLAYER) {
gActiveCameraID = 1;
savedCameraID = 0;
}
+5 -5
View File
@@ -305,7 +305,7 @@ s32 D_80127180;
Settings *gHudSettings;
u8 gHudSilverCoinRace;
u8 gAdventurePlayerFinish;
u8 D_8012718A;
u8 gAdvRaceStartedByP2;
u8 gMinimapOpacityTarget;
s32 gStopwatchErrorX;
s32 gStopwatchErrorY;
@@ -430,7 +430,7 @@ void hud_init_element(void) {
gAdventurePlayerFinish = FALSE;
D_80126D4C = -100;
D_80126D50 = rand_range(120, 360);
D_8012718A = func_8000E158();
gAdvRaceStartedByP2 = is_race_started_by_player_two();
gStopwatchErrorX = 55;
gStopwatchErrorY = 179;
if (osTvType == OS_TV_TYPE_PAL) {
@@ -680,7 +680,7 @@ void hud_render_player(Gfx **dList, Mtx **mtx, Vertex **vertexList, Object *obj,
Object_Racer *racer;
gHudCurrentViewport = get_current_viewport();
if (D_8012718A) {
if (gAdvRaceStartedByP2) {
obj = get_racer_object_by_port(1 - gHudCurrentViewport);
}
gHudLevelHeader = level_header();
@@ -708,7 +708,7 @@ void hud_render_player(Gfx **dList, Mtx **mtx, Vertex **vertexList, Object *obj,
}
if (gShowHUD == FALSE) {
racer = obj->racer;
if (D_8012718A) {
if (gAdvRaceStartedByP2) {
gHudController = 1 - racer->playerIndex;
} else {
gHudController = racer->playerIndex;
@@ -2604,7 +2604,7 @@ void hud_race_finish_multiplayer(Object_Racer *racer, s32 updateRate) {
raceType = level_type();
if (is_in_two_player_adventure() && is_postrace_viewport_active() && gAdventurePlayerFinish == FALSE) {
if (func_8000E184()) {
if (is_player_two_in_control()) {
gCurrentHud->entry[HUD_CHALLENGE_FINISH_POS_1].pos.y -= 108.0f;
gCurrentHud->entry[HUD_CHALLENGE_FINISH_POS_2].pos.y -= 108.0f;
gCurrentHud->entry[HUD_RACE_TIME_NUMBER].pos.y -= 108.0f;
+11 -9
View File
@@ -6788,7 +6788,7 @@ void menu_character_select_init(void) {
gCurrCharacterSelectData = (CharacterSelectData(*)[10]) & gCharacterSelectBytesDefault;
}
for (i = 0; i < ARRAY_COUNT(gCharselectStatus); i++) {
gCharselectStatus[i] = 0;
gCharselectStatus[i] = CHARSELECT_STATUS_UNCONFIRMED;
}
gNumberOfReadyPlayers = 0;
gMenuDelay = 0;
@@ -6936,9 +6936,9 @@ void charselect_pick(void) {
} else {
// Character Deselected
for (i = 0; i < ARRAY_COUNT(gActivePlayersArray); i++) {
if (gActivePlayersArray[i] && gCharselectStatus[i] != 0) {
if (gActivePlayersArray[i] && gCharselectStatus[i] != CHARSELECT_STATUS_UNCONFIRMED) {
if (gMenuButtons[i] & B_BUTTON) {
gCharselectStatus[i] = 0;
gCharselectStatus[i] = CHARSELECT_STATUS_UNCONFIRMED;
gNumberOfReadyPlayers--;
if (gMenuSoundMasks[i] != 0) {
sndp_stop(gMenuSoundMasks[i]);
@@ -6965,9 +6965,9 @@ void charselect_input(s8 *activePlayers) {
for (i = 0; i < MAXCONTROLLERS; i++) {
if (activePlayers[i] != 0) {
if (gCharselectStatus[i] != 0) {
if (gCharselectStatus[i] != CHARSELECT_STATUS_UNCONFIRMED) {
if (gMenuButtons[i] & B_BUTTON) {
gCharselectStatus[i] = 0;
gCharselectStatus[i] = CHARSELECT_STATUS_UNCONFIRMED;
gNumberOfReadyPlayers -= 1;
if (gMenuSoundMasks[i] != 0) {
sndp_stop(gMenuSoundMasks[i]);
@@ -7002,7 +7002,7 @@ void charselect_input(s8 *activePlayers) {
transition_begin(&sMenuTransitionFadeIn);
}
} else if (gMenuButtons[i] & (A_BUTTON | START_BUTTON)) {
gCharselectStatus[i] = 1;
gCharselectStatus[i] = CHARSELECT_STATUS_CONFIRMED;
gNumberOfReadyPlayers++;
if (gMenuSoundMasks[i] != 0) {
sndp_stop(gMenuSoundMasks[i]);
@@ -7096,8 +7096,10 @@ s32 menu_character_select_loop(s32 updateRate) {
menu_input();
for (i = 0; i < ARRAY_COUNT(gCharselectStatus); i++) {
if (gCharselectStatus[i] == 1) {
gCharselectStatus[i] = 2;
// Automatically advance all "confirmed" character selections to "ready".
// This prevents particle effects from spawning repeatedly on selection.
if (gCharselectStatus[i] == CHARSELECT_STATUS_CONFIRMED) {
gCharselectStatus[i] = CHARSELECT_STATUS_READY;
}
}
gIgnorePlayerInputTime = 0;
@@ -8119,7 +8121,7 @@ s32 menu_file_select_loop(s32 updateRate) {
}
gIsInTwoPlayerAdventure = (gNumberOfActivePlayers == 2);
if (gIsInTwoPlayerAdventure) {
fontUseFont();
reset_lead_player_index();
}
gNumberOfActivePlayers = 1;
D_800E0FAC = TRUE;
+6
View File
@@ -182,6 +182,12 @@ enum TrackMenuTypes {
TRACKMENU_TYPE_LOAD_LEVEL
};
enum CharacterSelectStatus {
CHARSELECT_STATUS_UNCONFIRMED,
CHARSELECT_STATUS_CONFIRMED,
CHARSELECT_STATUS_READY,
};
#define CHEAT(index) 1 << index
typedef enum Cheats {
+61 -47
View File
@@ -64,13 +64,13 @@ Triangle D_800DC9D0[8] = {
{ { { 0, 2, 5, 4 } }, { { { 1, 0 } } }, { { { 0, 4 } } }, { { { 0, 0 } } } },
};
u8 D_800DCA50[8] = { 2, 5, 6, 3, 10, 8, 7, 9 };
u8 D_800DCA58[9] = { 2, 5, 6, 3, 10, 8, 7, 9, 11 };
u8 D_800DCA64[9] = { 2, 5, 6, 3, 10, 8, 7, 9, 12 };
u8 D_800DCA70[10] = { 2, 5, 6, 3, 10, 8, 7, 9, 11, 12 };
u8 D_800DCA7C[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
u8 gCharacterSelectMainActorIDs[8] = { 2, 5, 6, 3, 10, 8, 7, 9 };
u8 gCharacterSelectMainActorIDsPlusDrumstick[9] = { 2, 5, 6, 3, 10, 8, 7, 9, 11 };
u8 gCharacterSelectMainActorIDsPlusTT[9] = { 2, 5, 6, 3, 10, 8, 7, 9, 12 };
u8 gCharacterSelectAllActorIDs[10] = { 2, 5, 6, 3, 10, 8, 7, 9, 11, 12 };
u8 gSignHoldingFrames[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
u8 D_800DCA88[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
u8 gSignHoldingIndices[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
s8 D_800DCA94[8] = { 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00 };
@@ -2027,21 +2027,25 @@ void obj_loop_snowball(Object *obj, s32 updateRate) {
UNUSED void obj_init_char_select(UNUSED s32 arg0, UNUSED s32 arg1) {
}
/**
* Character select loop behaviour.
* Animates characters dancing, chooses which player sign they're holding up etc.
*/
void obj_loop_char_select(Object *charSelectObj, s32 updateRate) {
s32 i2;
s32 i;
f32 temp_f0;
f32 animFrame;
ObjectModel *objMdl;
Object_AnimatedObject *charSelect;
s32 charCount;
s32 var_s0;
s32 playerIndex;
s8 *status = NULL;
ModelInstance *modInst;
u8 sp50[4];
u8 sp4F;
u8 *var_a2;
u8 playerSelectIndices[4];
u8 numCursors;
u8 *actorIDs;
var_s0 = 0;
playerIndex = 0;
func_8001F460(charSelectObj, updateRate, NULL);
charSelect = charSelectObj->animatedObject;
charSelectObj->particleEmittersEnabled = OBJ_EMIT_NONE;
@@ -2051,45 +2055,46 @@ void obj_loop_char_select(Object *charSelectObj, s32 updateRate) {
objMdl = modInst->objModel;
if (is_drumstick_unlocked()) {
if (is_tt_unlocked()) {
var_a2 = D_800DCA70;
actorIDs = gCharacterSelectAllActorIDs;
charCount = 10;
} else {
var_a2 = D_800DCA58;
actorIDs = gCharacterSelectMainActorIDsPlusDrumstick;
charCount = 9;
}
} else if (is_tt_unlocked()) {
var_a2 = D_800DCA64;
actorIDs = gCharacterSelectMainActorIDsPlusTT;
charCount = 9;
} else {
var_a2 = D_800DCA50;
actorIDs = gCharacterSelectMainActorIDs;
charCount = 8;
}
for (i = 0; i < charCount && !var_s0; i++) {
if (charSelect->unk28 == var_a2[i]) {
var_s0 = 1;
for (i = 0; i < charCount && !playerIndex; i++) {
if (charSelect->actorIndex == actorIDs[i]) {
playerIndex = 1;
}
}
i--;
if (var_s0) {
if (playerIndex) {
charSelectObj->animationID = 1;
for (var_s0 = 0, sp4F = 0; var_s0 < MAXCONTROLLERS; var_s0++) {
if (get_player_character(var_s0) == i) {
sp50[sp4F++] = var_s0;
for (playerIndex = 0, numCursors = 0; playerIndex < MAXCONTROLLERS; playerIndex++) {
if (get_player_character(playerIndex) == i) {
playerSelectIndices[numCursors++] = playerIndex;
}
}
D_800DCA7C[i] += updateRate;
if (D_800DCA7C[i] >= 16) {
D_800DCA7C[i] &= 0xF;
D_800DCA88[i]++;
gSignHoldingFrames[i] += updateRate;
if (gSignHoldingFrames[i] >= 16) {
gSignHoldingFrames[i] &= 0xF;
gSignHoldingIndices[i]++;
}
if (D_800DCA88[i] >= sp4F) {
D_800DCA88[i] = 0;
if (gSignHoldingIndices[i] >= numCursors) {
gSignHoldingIndices[i] = 0;
}
if (sp4F > 0) {
if (numCursors > 0) {
status = charselect_status();
for (i2 = 0; i2 < sp4F; i2++) {
if (status[sp50[i2]] == 1) {
for (i2 = 0; i2 < numCursors; i2++) {
if (status[playerSelectIndices[i2]] == CHARSELECT_STATUS_CONFIRMED) {
// Emit particle effects for every player confirming their selection of this character.
charSelectObj->particleEmittersEnabled = OBJ_EMIT_1;
obj_spawn_particle(charSelectObj, LOGIC_30FPS);
}
@@ -2099,7 +2104,7 @@ void obj_loop_char_select(Object *charSelectObj, s32 updateRate) {
// Unneccessary check for textureIndex to be greater than or equal to zero since it's a u8 and
// can't be less.
if (objMdl->batches[i2].textureIndex >= 0 && objMdl->batches[i2].textureIndex < 4) {
objMdl->batches[i2].textureIndex = sp50[D_800DCA88[i]];
objMdl->batches[i2].textureIndex = playerSelectIndices[gSignHoldingIndices[i]];
}
}
charSelectObj->animationID = 0;
@@ -2108,15 +2113,15 @@ void obj_loop_char_select(Object *charSelectObj, s32 updateRate) {
if (charSelectObj->animationID >= 0) {
if ((charSelectObj->animationID < objMdl->numberOfAnimations)) {
i = (objMdl->animations[charSelectObj->animationID].animLength - 1) << 4;
if (charSelect->unk2C == 1) {
temp_f0 = music_animation_fraction();
if (temp_f0 > 0.5) {
temp_f0 -= 0.5;
temp_f0 *= 2.0;
charSelectObj->animFrame = i - (temp_f0 * i);
if (charSelect->loopType == 1) {
animFrame = music_animation_fraction();
if (animFrame > 0.5) {
animFrame -= 0.5;
animFrame *= 2.0;
charSelectObj->animFrame = i - (animFrame * i);
} else {
temp_f0 *= 2;
charSelectObj->animFrame = temp_f0 * i;
animFrame *= 2;
charSelectObj->animFrame = animFrame * i;
}
}
}
@@ -4045,7 +4050,7 @@ void obj_loop_bridge_whaleramp(Object *obj, s32 updateRate) {
}
break;
default:
if (func_8001E2EC(entry->unkA) != 0) {
if (is_bridge_raised(entry->unkA) != 0) {
obj->properties.bridgeWhaleRamp.unk0 = (entry->unkD * 2);
}
if (obj->properties.bridgeWhaleRamp.unk0 > 0) {
@@ -4061,6 +4066,10 @@ void obj_loop_bridge_whaleramp(Object *obj, s32 updateRate) {
obj->interactObj->flags &= ~INTERACT_FLAGS_PUSHING;
}
/**
* Ramp switch init function.
* Sets interaction attributes.
*/
void obj_init_rampswitch(Object *obj, LevelObjectEntry_RampSwitch *entry) {
obj->interactObj->flags = INTERACT_FLAGS_TANGIBLE;
obj->interactObj->unk11 = 0;
@@ -4069,9 +4078,14 @@ void obj_init_rampswitch(Object *obj, LevelObjectEntry_RampSwitch *entry) {
obj->properties.rampSwitch.unk0 = entry->unk8;
}
/**
* Ramp switch loop function.
* When a player goes through this object, the switch will raise the drawbridge.
* The distance is set to 255 so that it doesn't interact with the player again.
*/
void obj_loop_rampswitch(Object *obj, UNUSED s32 updateRate) {
if (obj->interactObj->distance < 45) {
func_8001E344(obj->properties.rampSwitch.unk0);
start_bridge_timer(obj->properties.rampSwitch.unk0);
}
obj->interactObj->distance = 255;
}
@@ -4875,8 +4889,8 @@ void weapon_projectile(Object *obj, s32 updateRate) {
if (weapon->weaponID == WEAPON_ROCKET_HOMING) {
numCheckpoints = get_checkpoint_count();
if (numCheckpoints > 0) {
if (func_800185E4(weapon->checkpoint, obj, posX, posY, posZ, &weapon->checkpointDist, (u8 *) &surface) ==
FALSE) {
if (checkpoint_is_passed(weapon->checkpoint, obj, posX, posY, posZ, &weapon->checkpointDist,
(u8 *) &surface) == FALSE) {
weapon->checkpoint++;
if (weapon->checkpoint >= numCheckpoints) {
weapon->checkpoint = 0;
@@ -5026,8 +5040,8 @@ void homing_rocket_prevent_overshoot(Object *obj, s32 updateRate, Object_Weapon
}
dist = sqrtf(dist + distY);
if (dist > 300.0f && rocket->checkpoint != -1 && rocket->hitObj == NULL) {
sp58 = func_8001955C(obj, rocket->checkpoint, racer->unk1C8, rocket->unk14, rocket->unk16,
rocket->checkpointDist, &diffX, &diffY, &diffZ);
sp58 = homing_rocket_get_next_direction(obj, rocket->checkpoint, racer->isOnAlternateRoute, rocket->unk14,
rocket->unk16, rocket->checkpointDist, &diffX, &diffY, &diffZ);
sineY = arctan2_f(diffY, 500.0f) & 0xFFFF;
shift = 3;
} else {
+283 -226
View File
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -240,9 +240,9 @@ typedef struct CheckpointNode {
/* 0x18 */ f32 z;
/* 0x1C */ f32 scale;
/* 0x20 */ f32 distance;
/* 0x24 */ f32 unk24; // Appears to be exactly the same as distance?
/* 0x24 */ f32 altDistance; // Appears to be exactly the same as distance?
/* 0x28 */ Object *obj;
/* 0x2C */ s16 unk2C;
/* 0x2C */ s16 checkpointID;
/* 0x2E */ s8 unk2E[4];
/* 0x32 */ s8 unk32[4];
/* 0x36 */ s8 unk36[4]; // Appear to be flags of some sort?
@@ -304,10 +304,10 @@ s32 get_contpak_error(void);
void instShowBearBar(void);
s8 func_8000E138(void);
s8 racetype_demo(void);
s8 func_8000E158(void);
s8 func_8000E184(void);
void func_8000E194(void);
void fontUseFont(void);
s8 is_race_started_by_player_two(void);
s8 is_player_two_in_control(void);
void toggle_lead_player_index(void);
void reset_lead_player_index(void);
s8 find_non_car_racers(void);
s8 check_if_silver_coin_race(void);
void despawn_player_racer(Object *obj, s32 vehicleID);
@@ -350,7 +350,7 @@ s32 timetrial_staff_unbeaten(void);
SIDeviceStatus timetrial_save_player_ghost(s32 controllerIndex);
u8 has_ghost_to_save(void);
void set_ghost_none(void);
f32 func_8001B834(Object_Racer *racer1, Object_Racer *racer2);
f32 racer_calc_distance_to_opponent(Object_Racer *racer1, Object_Racer *racer2);
CheckpointNode *get_checkpoint_node(s32 checkpointID);
CheckpointNode *find_next_checkpoint_node(s32 splinePos, s32 arg1);
s32 get_checkpoint_count(void);
@@ -368,8 +368,8 @@ void set_world_shading(f32 ambient, f32 diffuse, s16 angleX, s16 angleY, s16 ang
void set_shading_properties(ShadeProperties *arg0, f32 ambient, f32 diffuse, s16 angleX, s16 angleY, s16 angleZ);
void obj_shade_fancy(ObjectModel *model, Object *object, s32 arg2, f32 intensity);
s32 *get_misc_asset(s32 index);
s32 func_8001E2EC(s32 arg0);
void func_8001E344(s32 arg0);
s32 is_bridge_raised(s32 arg0);
void start_bridge_timer(s32 arg0);
void obj_bridge_pos(s32 timing, f32 *x, f32 *y, f32 *z);
s16 cutscene_id(void);
void cutscene_id_set(s32 cutsceneID);
@@ -411,7 +411,7 @@ void racerfx_free(void);
void func_80016BC4(Object *obj);
s32 ainode_register(Object *obj);
void obj_taj_create_balloon(s32 blockID, f32 x, f32 y, f32 z);
Object *func_8001B7A8(Object_Racer *racer, s32 position, f32 *distance);
Object *racer_find_nearest_opponent_relative(Object_Racer *racer, s32 position, f32 *distance);
s32 obj_init_collision(Object *obj, ObjectCollision *colData);
void func_8000E4E8(s32 index);
void objFreeAssets(Object *obj, s32 count, s32 objType);
@@ -437,7 +437,7 @@ void obj_init_animobject(Object *, Object *);
Object *obj_butterfly_node(f32 x, f32 y, f32 z, f32 maxDistCheck, s32 dontCheckYAxis);
void func_8002125C(Object *obj, LevelObjectEntry_Animation *entry, Object_AnimatedObject *animObj, UNUSED s32 index);
void func_80021104(Object *obj, Object_AnimatedObject *animObj, LevelObjectEntry_Animation *entry);
s32 func_8001955C(Object *obj, s32 checkpoint, u8 arg2, s32 arg3, s32 arg4, f32 checkpointDist, f32 *outX, f32 *outY,
s32 homing_rocket_get_next_direction(Object *obj, s32 checkpoint, u8 arg2, s32 arg3, s32 arg4, f32 checkpointDist, f32 *outX, f32 *outY,
f32 *outZ);
void func_80016500(Object *obj, Object_Racer *racer);
void track_spawn_objects(s32, s32);
@@ -487,7 +487,7 @@ Object *spawn_object(LevelObjectEntryCommon *entry, s32);
s32 func_8001F460(Object *, s32, Object *);
void func_8000B750(Object *racerObj, s32 racerIndex, s32 vehicleIDPrev, s32 boostType, s32 arg4);
void func_80018CE0(Object *racerObj, f32 xPos, f32 yPos, f32 zPos, s32 updateRate);
s32 func_800185E4(s32 checkpointIndex, Object *obj, f32 objX, f32 objY, f32 objZ, f32 *arg5, u8 *arg6);
s32 checkpoint_is_passed(s32 checkpointIndex, Object *obj, f32 objX, f32 objY, f32 objZ, f32 *arg5, u8 *arg6);
void obj_tex_animate(Object *, s32);
Object *find_furthest_telepoint(f32 x, f32 z);
void model_init_collision(ObjectModel *);
@@ -495,7 +495,7 @@ void set_temp_model_transforms(Object *);
void obj_destroy(Object *, s32);
void func_800135B8(Object *);
void track_setup_racers(Vehicle, u32, s32);
void func_80017E98(void);
void checkpoint_update_all(void);
void spectate_update(void);
void func_8001E93C(void);
void func_80019808(s32 updateRate);
+65 -58
View File
@@ -292,12 +292,12 @@ void func_80042D20(Object *obj, Object_Racer *racer, s32 updateRate) {
sp94 = 0.0f;
sp90 = 0.0f;
sp5C = NULL;
obj = func_8001B7A8(racer, 1, &sp94);
obj = racer_find_nearest_opponent_relative(racer, 1, &sp94);
if (obj != NULL) {
sp5C = obj->racer;
}
sp58 = NULL;
obj = func_8001B7A8(racer, -1, &sp90);
obj = racer_find_nearest_opponent_relative(racer, -1, &sp90);
if (obj != NULL) {
sp58 = obj->racer;
}
@@ -1400,7 +1400,7 @@ void func_80045C48(Object *obj, Object_Racer *racer, s32 updateRate) {
return;
}
s0 = racer->checkpoint - 2;
s0 = racer->nextCheckpoint - 2;
magnitude = 1.0 - racer->checkpoint_distance;
if (magnitude < 0.0) {
magnitude = 0.0f;
@@ -1416,7 +1416,7 @@ void func_80045C48(Object *obj, Object_Racer *racer, s32 updateRate) {
}
for (i = 0; i < 4; i++) {
checkpoint = find_next_checkpoint_node(s0, racer->unk1C8);
checkpoint = find_next_checkpoint_node(s0, racer->isOnAlternateRoute);
splineX[i] = checkpoint->x;
splineY[i] = checkpoint->y;
splineZ[i] = checkpoint->z;
@@ -1473,7 +1473,7 @@ void func_80045C48(Object *obj, Object_Racer *racer, s32 updateRate) {
spC4 = TRUE;
}
s0 = racer->checkpoint - 2;
s0 = racer->nextCheckpoint - 2;
magnitude = 1.0 - racer->checkpoint_distance;
if (magnitude < 0.0) {
magnitude = 0.0;
@@ -1493,7 +1493,7 @@ void func_80045C48(Object *obj, Object_Racer *racer, s32 updateRate) {
s0 -= v0;
}
for (i = 0; i < 4; i++) {
checkpoint = find_next_checkpoint_node(s0, racer->unk1C8);
checkpoint = find_next_checkpoint_node(s0, racer->isOnAlternateRoute);
splineX[i] = checkpoint->x + checkpoint->scale * checkpoint->rotationZFrac * racer->unk1BA;
splineY[i] = checkpoint->y + checkpoint->scale * racer->unk1BC;
splineZ[i] = checkpoint->z + checkpoint->scale * -checkpoint->rotationXFrac * racer->unk1BA;
@@ -4040,7 +4040,8 @@ void obj_init_racer(Object *obj, LevelObjectEntry_Racer *racer) {
// Decide which player ID to assign to this object. Human players get a value from 0-3.
// Computer players will be -1.
if (player >= PLAYER_ONE && player <= PLAYER_FOUR) {
if (func_8000E158()) {
if (is_race_started_by_player_two()) {
//!@bug player ID could be negative if there are more than two players
player = 1 - player;
}
tempRacer->playerIndex = player;
@@ -4297,7 +4298,7 @@ void update_player_racer(Object *obj, s32 updateRate) {
tempVar = tempRacer->playerIndex;
if (tempRacer->playerIndex != PLAYER_COMPUTER) {
if (tempRacer->exitObj == 0) {
if (func_8000E158()) {
if (is_race_started_by_player_two()) {
tempVar = 1 - tempVar;
}
// Cap the joystick tilt and write the button inputs to the current buffer.
@@ -4468,27 +4469,27 @@ void update_player_racer(Object *obj, s32 updateRate) {
racer_sound_update(obj, gCurrentButtonsPressed, gCurrentRacerInput, updateRate);
}
lastCheckpointDist = tempRacer->checkpoint_distance;
tempVar = func_800185E4(tempRacer->checkpoint, obj, xTemp, yTemp, zTemp, &tempRacer->checkpoint_distance,
&tempRacer->unk1C8);
tempVar = checkpoint_is_passed(tempRacer->nextCheckpoint, obj, xTemp, yTemp, zTemp,
&tempRacer->checkpoint_distance, &tempRacer->isOnAlternateRoute);
if (tempVar == -100) {
func_8005C270(tempRacer);
racer_update_progress(tempRacer);
}
checkpointNode = find_next_checkpoint_node(tempRacer->checkpoint, tempRacer->unk1C8);
checkpointNode = find_next_checkpoint_node(tempRacer->nextCheckpoint, tempRacer->isOnAlternateRoute);
if (tempRacer->playerIndex == PLAYER_COMPUTER && checkpointNode->unk36[tempRacer->unk1CA] == 5 &&
tempRacer->waterTimer) {
tempRacer->unk1C8 = 1;
tempRacer->isOnAlternateRoute = TRUE;
}
if (checkpointNode->unk36[tempRacer->unk1CA] == 6) {
tempRacer->lap = header->laps + 1;
}
if (tempVar == 0) {
if (tempRacer->playerIndex == PLAYER_COMPUTER && checkpointNode->unk36[tempRacer->unk1CA] == 2) {
tempRacer->unk1C8 = 1;
tempRacer->isOnAlternateRoute = TRUE;
}
checkpointCount = get_checkpoint_count();
tempRacer->checkpoint++;
if (tempRacer->checkpoint >= checkpointCount) {
tempRacer->checkpoint = 0;
tempRacer->nextCheckpoint++;
if (tempRacer->nextCheckpoint >= checkpointCount) {
tempRacer->nextCheckpoint = 0;
if (tempRacer->courseCheckpoint > 0) {
if (tempRacer->lap < 120) {
tempRacer->lap++;
@@ -4502,7 +4503,8 @@ void update_player_racer(Object *obj, s32 updateRate) {
}
if (is_taj_challenge()) {
if (gCurrentPlayerIndex != PLAYER_COMPUTER) {
checkpointNode = find_next_checkpoint_node(tempRacer->checkpoint, tempRacer->unk1C8);
checkpointNode =
find_next_checkpoint_node(tempRacer->nextCheckpoint, tempRacer->isOnAlternateRoute);
if (!tempRacer->challengeMarker) {
newObject.x = 0;
newObject.y = 0;
@@ -5602,13 +5604,13 @@ void handle_racer_head_turning(Object *obj, Object_Racer *racer, UNUSED s32 upda
foundObj = turn_head_towards_object(obj, racer, tempObj, 400.0f * 400.0f);
}
if (foundObj == FALSE) {
tempObj = func_8001B7A8(racer, 1, &distance);
tempObj = racer_find_nearest_opponent_relative(racer, 1, &distance);
if (tempObj && !gRaceStartTimer) {
foundObj = turn_head_towards_object(obj, racer, tempObj, 400.0f * 400.0f);
}
}
if (foundObj == FALSE) {
tempObj = func_8001B7A8(racer, -1, &distance);
tempObj = racer_find_nearest_opponent_relative(racer, -1, &distance);
if (tempObj && !gRaceStartTimer) {
foundObj = turn_head_towards_object(obj, racer, tempObj, 30000.0f);
}
@@ -7191,7 +7193,7 @@ void handle_racer_items(Object *obj, Object_Racer *racer, UNUSED s32 updateRate)
weapon = spawnedObj->weapon;
weapon->owner = obj;
weapon->target = intendedTarget;
weapon->checkpoint = racer->checkpoint;
weapon->checkpoint = racer->nextCheckpoint;
weapon->forwardVel = (racer->velocity - velocity);
weapon->weaponID = weaponID;
switch (weapon->weaponID) {
@@ -7282,7 +7284,7 @@ Object *func_8005698C(Object *racerObj, Object_Racer *racer, f32 *outDistance) {
isChallengeRace = raceType & RACETYPE_CHALLENGE;
if (racer->playerIndex == PLAYER_COMPUTER && !isChallengeRace) {
curDistance = 0.0f;
curRacerObj = func_8001B7A8(racer, 1, &curDistance);
curRacerObj = racer_find_nearest_opponent_relative(racer, 1, &curDistance);
*outDistance = curDistance;
return curRacerObj;
}
@@ -8108,13 +8110,13 @@ void set_position_goal_from_path(UNUSED Object *obj, Object_Racer *racer, f32 *x
if (magnitude < 0.0f) {
magnitude = 0.0f;
}
if (racer->checkpoint) {} // Fakematch
splinePos = racer->checkpoint - 2;
if (racer->nextCheckpoint) {} // Fakematch
splinePos = racer->nextCheckpoint - 2;
if (splinePos < 0) {
splinePos += splineEnd;
}
for (i = 0; i < 5; i++) {
checkpoint = find_next_checkpoint_node(splinePos, racer->unk1C8);
checkpoint = find_next_checkpoint_node(splinePos, racer->isOnAlternateRoute);
splineX[i] = checkpoint->x;
splineY[i] = checkpoint->y;
splineZ[i] = checkpoint->z;
@@ -8163,16 +8165,16 @@ void func_80059208(Object *obj, Object_Racer *racer, s32 updateRate) {
if (temp_v0 == 0) {
return;
}
if ((level_id() == 0) && (racer->checkpoint >= temp_v0)) {
if ((level_id() == 0) && (racer->nextCheckpoint >= temp_v0)) {
racer->lap = 0;
racer->checkpoint = 0;
racer->nextCheckpoint = 0;
racer->courseCheckpoint = 0;
}
splinePos = 1.0 - racer->checkpoint_distance;
if (splinePos < -0.2) {
racer->checkpoint--;
if (racer->checkpoint < 0) {
racer->checkpoint += temp_v0;
racer->nextCheckpoint--;
if (racer->nextCheckpoint < 0) {
racer->nextCheckpoint += temp_v0;
if (racer->lap > 0) {
racer->lap--;
}
@@ -8180,18 +8182,18 @@ void func_80059208(Object *obj, Object_Racer *racer, s32 updateRate) {
if (racer->courseCheckpoint > -0x7D00) {
racer->courseCheckpoint--;
}
if (racer->unk1C8) {
temp_v0_4 = get_checkpoint_node(racer->checkpoint);
if (racer->isOnAlternateRoute) {
temp_v0_4 = get_checkpoint_node(racer->nextCheckpoint);
if (temp_v0_4->altRouteID == -1) {
racer->unk1C8 = 0;
racer->isOnAlternateRoute = FALSE;
}
angle = racer->checkpoint - 1;
angle = racer->nextCheckpoint - 1;
if (angle < 0) {
angle += temp_v0;
}
temp_v0_4 = get_checkpoint_node(angle);
if (temp_v0_4->altRouteID == -1) {
racer->unk1C8 = 0;
racer->isOnAlternateRoute = FALSE;
}
}
return;
@@ -8199,21 +8201,21 @@ void func_80059208(Object *obj, Object_Racer *racer, s32 updateRate) {
if (splinePos < 0.0f) {
splinePos = 0.0f;
}
temp_v0_4 = find_next_checkpoint_node(racer->checkpoint, racer->unk1C8);
temp_v0_4 = find_next_checkpoint_node(racer->nextCheckpoint, racer->isOnAlternateRoute);
scale = temp_v0_4->scale;
counter = racer->checkpoint - 1;
counter = racer->nextCheckpoint - 1;
if (counter < 0) {
counter = temp_v0 - 1;
}
temp_v0_4 = get_checkpoint_node(counter);
distance = temp_v0_4->scale;
divisor = ((scale - temp_v0_4->scale) * splinePos) + distance;
counter = racer->checkpoint - 2;
counter = racer->nextCheckpoint - 2;
if (counter < 0) {
counter += temp_v0;
}
for (i = 0; (i < 5) ^ 0; i++) {
temp_v0_4 = find_next_checkpoint_node(counter, racer->unk1C8);
temp_v0_4 = find_next_checkpoint_node(counter, racer->isOnAlternateRoute);
posX[i] = temp_v0_4->x + ((temp_v0_4->scale * temp_v0_4->rotationZFrac) * racer->unk1BA);
posY[i] = temp_v0_4->y + (temp_v0_4->scale * racer->unk1BC);
posZ[i] = temp_v0_4->z + ((temp_v0_4->scale * (-temp_v0_4->rotationXFrac)) * racer->unk1BA);
@@ -8830,16 +8832,17 @@ void update_AI_racer(Object *obj, Object_Racer *racer, s32 updateRate, f32 updat
racer_sound_update(obj, gCurrentButtonsPressed, gCurrentRacerInput, updateRate);
}
lastCheckpointDist = racer->checkpoint_distance;
countOfObjects = racer->checkpoint;
var_t2 = func_800185E4(racer->checkpoint, obj, xPos, yPos, zPos, &racer->checkpoint_distance, &racer->unk1C8);
countOfObjects = racer->nextCheckpoint;
var_t2 = checkpoint_is_passed(racer->nextCheckpoint, obj, xPos, yPos, zPos, &racer->checkpoint_distance,
&racer->isOnAlternateRoute);
if (var_t2 == -100) {
func_8005C270(racer);
racer_update_progress(racer);
}
checkpoint = find_next_checkpoint_node(racer->checkpoint, racer->unk1C8);
checkpoint = find_next_checkpoint_node(racer->nextCheckpoint, racer->isOnAlternateRoute);
if (checkpoint->unk36[racer->unk1CA] == 5) {
racer->unk201 = 30;
if (racer->waterTimer) {
racer->unk1C8 = 1;
racer->isOnAlternateRoute = TRUE;
}
}
if (checkpoint->unk36[racer->unk1CA] == 6) {
@@ -8852,12 +8855,12 @@ void update_AI_racer(Object *obj, Object_Racer *racer, s32 updateRate, f32 updat
}
if (var_t2 == 0) {
if (checkpoint->unk36[racer->unk1CA] == 2) {
racer->unk1C8 = 1;
racer->isOnAlternateRoute = TRUE;
}
temp_v0_10 = get_checkpoint_count();
racer->checkpoint++;
if (racer->checkpoint >= temp_v0_10) {
racer->checkpoint = 0;
racer->nextCheckpoint++;
if (racer->nextCheckpoint >= temp_v0_10) {
racer->nextCheckpoint = 0;
if (racer->courseCheckpoint > 0) {
if (racer->lap < 120) {
racer->lap++;
@@ -9056,7 +9059,7 @@ void func_8005B818(Object *obj, Object_Racer *racer, s32 updateRate, f32 updateR
racer->velocity += ((-var_f12 - racer->velocity) * 0.25);
}
checkpointIdx = racer->checkpoint - 2;
checkpointIdx = racer->nextCheckpoint - 2;
if (checkpointIdx < 0) {
checkpointIdx += checkpointCount;
}
@@ -9066,7 +9069,7 @@ void func_8005B818(Object *obj, Object_Racer *racer, s32 updateRate, f32 updateR
}
for (i = 0; i < 5; i++) {
checkpoint = find_next_checkpoint_node(checkpointIdx, racer->unk1C8);
checkpoint = find_next_checkpoint_node(checkpointIdx, racer->isOnAlternateRoute);
checkpointX[i] = checkpoint->x;
checkpointY[i] = checkpoint->y;
checkpointZ[i] = checkpoint->z;
@@ -9129,9 +9132,9 @@ void func_8005B818(Object *obj, Object_Racer *racer, s32 updateRate, f32 updateR
}
racer->checkpoint_distance = (1.0 - checkpointDistance);
if (checkpointSplineIdx != 0) {
racer->checkpoint++;
if (racer->checkpoint >= checkpointCount) {
racer->checkpoint = 0;
racer->nextCheckpoint++;
if (racer->nextCheckpoint >= checkpointCount) {
racer->nextCheckpoint = 0;
if (racer->courseCheckpoint > 0) {
if (racer->lap < 120) {
racer->lap++;
@@ -9250,12 +9253,16 @@ void drm_vehicle_traction(void) {
}
#endif
void func_8005C270(Object_Racer *racer) {
s32 temp = get_checkpoint_count();
/**
* Updates the racer's progress in the race when they cross a checkpoint. The racer
* completes a lap when the last checkpoint, the starting line, is reached.
*/
void racer_update_progress(Object_Racer *racer) {
s32 count = get_checkpoint_count();
racer->checkpoint--;
if (racer->checkpoint < 0) {
racer->checkpoint += temp;
racer->nextCheckpoint--;
if (racer->nextCheckpoint < 0) {
racer->nextCheckpoint += count;
if (racer->lap > 0) {
racer->lap--;
}
+1 -1
View File
@@ -177,7 +177,7 @@ void drm_checksum_balloon(void);
void drm_vehicle_traction(void);
s32 turn_head_towards_object(Object *obj, Object_Racer *racer, Object *targetObj, f32 distance);
void onscreen_ai_racer_physics(Object *obj, Object_Racer *racer, s32 arg2);
void func_8005C270(Object_Racer *racer);
void racer_update_progress(Object_Racer *racer);
f32 handle_racer_top_speed(Object *obj, Object_Racer *racer);
void play_random_character_voice(Object *obj, s32 soundID, s32 range, s32 flags);
void apply_vehicle_rotation_offset(Object_Racer *obj, s32 max, s16 yRotation, s16 xRotation, s16 zRotation);
+1 -1
View File
@@ -69,7 +69,7 @@ u32 D_801241F4;
* Returns the player ID of the controller. Flips them around in 2 player adventure if the players have been swapped.
*/
u8 input_get_id(s32 controllerIndex) {
if ((controllerIndex == 0 || controllerIndex == 1) && func_8000E158()) {
if ((controllerIndex == 0 || controllerIndex == 1) && is_race_started_by_player_two()) {
controllerIndex = 1 - controllerIndex;
}
return input_player_id(controllerIndex);
+1 -1
View File
@@ -1546,7 +1546,7 @@ void swap_lead_player(void) {
u8 *second_racer_data;
input_swap_id();
func_8000E194();
toggle_lead_player_index();
first_racer_data = (u8 *) (gSettingsPtr->racers);
second_racer_data = (u8 *) (gSettingsPtr->racers + 1);
+1 -1
View File
@@ -359,7 +359,7 @@ void render_scene(Gfx **dList, Mtx **mtx, Vertex **vtx, Triangle **tris, s32 upd
for (j = gSceneCurrentPlayerID = 0; j < numViewports; gSceneCurrentPlayerID++, j = gSceneCurrentPlayerID) {
if (gCurrentLevelHeader2 && !gCurrentLevelHeader2 && !gCurrentLevelHeader2) {} // Fakematch
if (j == 0) {
if (func_8000E184() && numViewports == 1) {
if (is_player_two_in_control() && numViewports == 1) {
gSceneCurrentPlayerID = PLAYER_TWO;
}
}
+1 -1
View File
@@ -117,7 +117,7 @@ void update_bluey(s32 updateRate, f32 updateRateF, Object *obj, Object_Racer *ra
racer->velocity = -sqrtf((diffX * diffX) + (diffZ * diffZ));
}
sp3C = FALSE;
if ((find_next_checkpoint_node(racer->checkpoint, racer->unk1C8))->unk36[racer->unk1CA] == 1) {
if ((find_next_checkpoint_node(racer->nextCheckpoint, racer->isOnAlternateRoute))->unk36[racer->unk1CA] == 1) {
sp3C = TRUE;
}
if (obj->animationID != ANIM_BLUEY_DAMAGE) {
+1 -1
View File
@@ -131,7 +131,7 @@ void update_wizpig(s32 updateRate, f32 updateRateF, Object *obj, Object_Racer *r
}
}
nextCheckpoint = FALSE;
if (find_next_checkpoint_node(racer->checkpoint, racer->unk1C8)->unk36[racer->unk1CA] == 1) {
if (find_next_checkpoint_node(racer->nextCheckpoint, racer->isOnAlternateRoute)->unk36[racer->unk1CA] == 1) {
nextCheckpoint = TRUE;
}
racer->x_rotation_offset = -obj->trans.rotation.x_rotation;
+22 -7
View File
@@ -749,6 +749,9 @@ void func_800B97A8(s32 blockID, s32 arg1) {
}
}
/**
* Updates the animations and UV mapping of the waves.
*/
void waves_update(s32 updateRate) {
s32 i;
s32 j;
@@ -954,6 +957,9 @@ void wave_load_material(TextureHeader *tex, s32 rtile) {
}
}
/**
* Renders waves in the current viewport.
*/
void waves_render(Gfx **dList, Mtx **mtx, s32 viewportID) {
s32 sp11C;
Vertex *vtx;
@@ -2365,6 +2371,9 @@ f32 waves_get_y(s32 blockID, s32 arg1, s32 arg2) {
return y;
}
/**
* Removes a wave generator object from the list.
*/
void wavegen_destroy(Object *obj) {
s32 i;
s32 k;
@@ -2407,26 +2416,32 @@ void wavegen_destroy(Object *obj) {
gWaveGenCount--;
}
/**
* Adds a wave generator point.
*/
void wavegen_add(Object *obj) {
LevelObjectEntry_WaveGenerator *temp_v0;
LevelObjectEntry_WaveGenerator *waveGen;
s32 flags;
temp_v0 = &obj->level_entry->waveGenerator;
waveGen = &obj->level_entry->waveGenerator;
flags = 0;
if (temp_v0->unk10 != 0) {
if (waveGen->unk10 != 0) {
flags = 1;
}
if (temp_v0->unk11 != 0) {
if (waveGen->unk11 != 0) {
flags |= 2;
}
wavegen_register(obj, obj->trans.x_position, obj->trans.z_position, (f32) temp_v0->waveSize, temp_v0->unk9 << 8,
(f32) temp_v0->unk8 / 16.0, (f32) temp_v0->unkE, (f32) temp_v0->unkC / 16.0, flags);
wavegen_register(obj, obj->trans.x_position, obj->trans.z_position, (f32) waveGen->waveSize, waveGen->unk9 << 8,
(f32) waveGen->unk8 / 16.0, (f32) waveGen->unkE, (f32) waveGen->unkC / 16.0, flags);
}
const char D_800E9228[] = "\nError :: more than eight swells overlap on column %d.";
const char gWavesOverlapErrorMsg[] = "\nError :: more than eight swells overlap on column %d.";
/**
* Registers a new wave generator point with the given properties.
*/
WaveGen *wavegen_register(Object *obj, f32 xPos, f32 zPos, f32 waveSize, s32 arg4, f32 arg5, f32 arg6, f32 arg7,
s32 flags) {
f32 stepSize;
+26 -26
View File
@@ -196,10 +196,10 @@ get_contpak_error = 0x8000E0B0;
instShowBearBar = 0x8000E128;
func_8000E138 = 0x8000E138;
racetype_demo = 0x8000E148;
func_8000E158 = 0x8000E158;
func_8000E184 = 0x8000E184;
func_8000E194 = 0x8000E194;
fontUseFont = 0x8000E1B8;
is_race_started_by_player_two = 0x8000E158;
is_player_two_in_control = 0x8000E184;
toggle_lead_player_index = 0x8000E194;
reset_lead_player_index = 0x8000E1B8;
find_non_car_racers = 0x8000E1CC;
check_if_silver_coin_race = 0x8000E1DC;
despawn_player_racer = 0x8000E1EC;
@@ -285,11 +285,11 @@ func_800179D0 = 0x800179D0;
func_80017A18 = 0x80017A18;
set_taj_challenge_type = 0x80017E74;
get_taj_challenge_type = 0x80017E88;
func_80017E98 = 0x80017E98;
func_800185E4 = 0x800185E4;
checkpoint_update_all = 0x80017E98;
checkpoint_is_passed = 0x800185E4;
find_taj_object = 0x80018C6C;
func_80018CE0 = 0x80018CE0;
func_8001955C = 0x8001955C;
homing_rocket_get_next_direction = 0x8001955C;
race_check_finish = 0x80019808;
set_course_finish_flags = 0x8001A7D8;
race_finish_adventure = 0x8001A8D4;
@@ -309,9 +309,9 @@ timetrial_init_player_ghost = 0x8001B668;
timetrial_save_player_ghost = 0x8001B738;
has_ghost_to_save = 0x8001B780;
set_ghost_none = 0x8001B790;
func_8001B7A8 = 0x8001B7A8;
func_8001B834 = 0x8001B834;
func_8001B954 = 0x8001B954;
racer_find_nearest_opponent_relative = 0x8001B7A8;
racer_calc_distance_to_opponent = 0x8001B834;
race_calc_distance_to_start_line = 0x8001B954;
get_checkpoint_node = 0x8001BA00;
find_next_checkpoint_node = 0x8001BA1C;
get_checkpoint_count = 0x8001BA64;
@@ -346,8 +346,8 @@ calc_dynamic_lighting_for_object_1 = 0x8001D80C;
calc_env_mapping_for_object = 0x8001DD54;
set_racer_position_and_angle = 0x8001E13C;
get_misc_asset = 0x8001E29C;
func_8001E2EC = 0x8001E2EC;
func_8001E344 = 0x8001E344;
is_bridge_raised = 0x8001E2EC;
start_bridge_timer = 0x8001E344;
obj_bridge_pos = 0x8001E36C;
cutscene_id = 0x8001E440;
cutscene_id_set = 0x8001E450;
@@ -752,7 +752,7 @@ racer_enter_door = 0x8005A450;
update_AI_racer = 0x8005A71C;
func_8005B818 = 0x8005B844;
drm_vehicle_traction = 0x8005C288;
func_8005C270 = 0x8005C29C;
racer_update_progress = 0x8005C29C;
//vehicle_tricky.c .text
@@ -2217,10 +2217,10 @@ gTimeTrialCharacter = 0x800DE0BC;
gHasGhostToSave = 0x800DE0C0;
gTimeTrialStaffGhost = 0x800DE0C4;
gBeatStaffGhost = 0x800DE0C8;
D_800DC73C = 0x800DE0CC;
D_800DC740 = 0x800DE0D0;
gLeadPlayerIndex = 0x800DE0CC;
gTwoActivePlayersInAdventure = 0x800DE0D0;
gSwapLeadPlayer = 0x800DE0D4;
D_800DC748 = 0x800DE0D8;
gIsP2LeadPlayer = 0x800DE0D8;
gBoostVerts = 0x800DE0DC;
gBoostTris = 0x800DE0E4;
gShieldEffectObject = 0x800DE0EC;
@@ -2267,12 +2267,12 @@ gCharacterFlagVertices = 0x800DE320;
D_800DC9A8 = 0x800DE348;
D_800DC9CC = 0x800DE36C;
D_800DC9D0 = 0x800DE370;
D_800DCA50 = 0x800DE3F0;
D_800DCA58 = 0x800DE3F8;
D_800DCA64 = 0x800DE404;
D_800DCA70 = 0x800DE410;
D_800DCA7C = 0x800DE41C;
D_800DCA88 = 0x800DE428;
gCharacterSelectMainActorIDs = 0x800DE3F0;
gCharacterSelectMainActorIDsPlusDrumstick = 0x800DE3F8;
gCharacterSelectMainActorIDsPlusTT = 0x800DE404;
gCharacterSelectAllActorIDs = 0x800DE410;
gSignHoldingFrames = 0x800DE41C;
gSignHoldingIndices = 0x800DE428;
D_800DCA94 = 0x800DE434;
D_800DCA9C = 0x800DE43C;
D_800DCAA8 = 0x800DE448;
@@ -3624,7 +3624,7 @@ gNumFinishedRacers = 0x8011C830;
gFirstTimeFinish = 0x8011C834;
D_8011ADC5 = 0x8011C835;
gBalloonCutsceneTimer = 0x8011C838;
D_8011ADCC = 0x8011C83C;
gDrawbridgeTimers = 0x8011C83C;
gObjectOffsetY = 0x8011C840;
D_8011ADD4 = 0x8011C844;
gOverrideDoors = 0x8011C845;
@@ -3667,8 +3667,8 @@ gObjectMapIndex = 0x8011C930;
gParticlePtrList = 0x8011C934;
gFreeListCount = 0x8011C938;
gTrackCheckpoints = 0x8011C93C;
gNumberOfCheckpoints = 0x8011C940;
D_8011AED4 = 0x8011C944;
gNumberOfMainCheckpoints = 0x8011C940;
gNumberOfTotalCheckpoints = 0x8011C944;
gTajChallengeType = 0x8011C948;
gCameraObjList = 0x8011C94C;
gCameraObjCount = 0x8011C950;
@@ -4419,7 +4419,7 @@ D_80127180 = 0x80128C30;
gHudSettings = 0x80128C34;
gHudSilverCoinRace = 0x80128C38;
gAdventurePlayerFinish = 0x80128C39;
D_8012718A = 0x80128C3A;
gAdvRaceStartedByP2 = 0x80128C3A;
gMinimapOpacityTarget = 0x80128C3B;
gStopwatchErrorX = 0x80128C3C;
gStopwatchErrorY = 0x80128C40;
+27 -27
View File
@@ -196,10 +196,10 @@ get_contpak_error = 0x8000E0B0;
instShowBearBar = 0x8000E128;
func_8000E138 = 0x8000E138;
racetype_demo = 0x8000E148;
func_8000E158 = 0x8000E158;
func_8000E184 = 0x8000E184;
func_8000E194 = 0x8000E194;
fontUseFont = 0x8000E1B8;
is_race_started_by_player_two = 0x8000E158;
is_player_two_in_control = 0x8000E184;
toggle_lead_player_index = 0x8000E194;
reset_lead_player_index = 0x8000E1B8;
find_non_car_racers = 0x8000E1CC;
check_if_silver_coin_race = 0x8000E1DC;
despawn_player_racer = 0x8000E1EC;
@@ -285,11 +285,11 @@ func_800179D0 = 0x800179D0;
func_80017A18 = 0x80017A18;
set_taj_challenge_type = 0x80017E74;
get_taj_challenge_type = 0x80017E88;
func_80017E98 = 0x80017E98;
func_800185E4 = 0x800185E4;
checkpoint_update_all = 0x80017E98;
checkpoint_is_passed = 0x800185E4;
find_taj_object = 0x80018C6C;
func_80018CE0 = 0x80018CE0;
func_8001955C = 0x8001955C;
homing_rocket_get_next_direction = 0x8001955C;
race_check_finish = 0x80019808;
set_course_finish_flags = 0x8001A7D8;
race_finish_adventure = 0x8001A8D4;
@@ -309,9 +309,9 @@ timetrial_init_player_ghost = 0x8001B668;
timetrial_save_player_ghost = 0x8001B738;
has_ghost_to_save = 0x8001B780;
set_ghost_none = 0x8001B790;
func_8001B7A8 = 0x8001B7A8;
func_8001B834 = 0x8001B834;
func_8001B954 = 0x8001B954;
racer_find_nearest_opponent_relative = 0x8001B7A8;
racer_calc_distance_to_opponent = 0x8001B834;
race_calc_distance_to_start_line = 0x8001B954;
get_checkpoint_node = 0x8001BA00;
find_next_checkpoint_node = 0x8001BA1C;
get_checkpoint_count = 0x8001BA64;
@@ -346,8 +346,8 @@ calc_dynamic_lighting_for_object_1 = 0x8001D80C;
calc_env_mapping_for_object = 0x8001DD54;
set_racer_position_and_angle = 0x8001E13C;
get_misc_asset = 0x8001E29C;
func_8001E2EC = 0x8001E2EC;
func_8001E344 = 0x8001E344;
is_bridge_raised = 0x8001E2EC;
start_bridge_timer = 0x8001E344;
obj_bridge_pos = 0x8001E36C;
cutscene_id = 0x8001E440;
cutscene_id_set = 0x8001E450;
@@ -752,7 +752,7 @@ racer_enter_door = 0x8005A424;
update_AI_racer = 0x8005A6F0;
func_8005B818 = 0x8005B818;
drm_vehicle_traction = 0x8005C25C;
func_8005C270 = 0x8005C270;
racer_update_progress = 0x8005C270;
//vehicle_tricky.c .text
racer_special_init = 0x8005C2F0;
@@ -2117,10 +2117,10 @@ gTimeTrialCharacter = 0x800DC7BC;
gHasGhostToSave = 0x800DC7C0;
gTimeTrialStaffGhost = 0x800DC7C4;
gBeatStaffGhost = 0x800DC7C8;
D_800DC73C = 0x800DC7CC;
D_800DC740 = 0x800DC7D0;
gLeadPlayerIndex = 0x800DC7CC;
gTwoActivePlayersInAdventure = 0x800DC7D0;
gSwapLeadPlayer = 0x800DC7D4;
D_800DC748 = 0x800DC7D8;
gIsP2LeadPlayer = 0x800DC7D8;
gBoostVerts = 0x800DC7DC;
gBoostTris = 0x800DC7E4;
gShieldEffectObject = 0x800DC7EC;
@@ -2161,12 +2161,12 @@ gCharacterFlagVertices = 0x800DCA10;
D_800DC9A8 = 0x800DCA38;
D_800DC9CC = 0x800DCA5C;
D_800DC9D0 = 0x800DCA60;
D_800DCA50 = 0x800DCAE0;
D_800DCA58 = 0x800DCAE8;
D_800DCA64 = 0x800DCAF4;
D_800DCA70 = 0x800DCB00;
D_800DCA7C = 0x800DCB0C;
D_800DCA88 = 0x800DCB18;
gCharacterSelectMainActorIDs = 0x800DCAE0;
gCharacterSelectMainActorIDsPlusDrumstick = 0x800DCAE8;
gCharacterSelectMainActorIDsPlusTT = 0x800DCAF4;
gCharacterSelectAllActorIDs = 0x800DCB00;
gSignHoldingFrames = 0x800DCB0C;
gSignHoldingIndices = 0x800DCB18;
D_800DCA94 = 0x800DCB24;
D_800DCA9C = 0x800DCB2C;
D_800DCAA8 = 0x800DCB38;
@@ -3217,7 +3217,7 @@ D_800E8EA0 = 0x800E8F30; // type:asciz force_not_migration:true defined:true
D_800E9160 = 0x800E91F0;
D_800E91AC = 0x800E923C;
D_800E91E4 = 0x800E9274;
D_800E9228 = 0x800E92B8;
gWavesOverlapErrorMsg = 0x800E92B8;
D_800E9260 = 0x800E92F0;
D_800E92A0 = 0x800E9330;
D_800E92A4 = 0x800E9334;
@@ -3362,7 +3362,7 @@ gNumFinishedRacers = 0x8011AE50;
gFirstTimeFinish = 0x8011AE54;
D_8011ADC5 = 0x8011AE55;
gBalloonCutsceneTimer = 0x8011AE58;
D_8011ADCC = 0x8011AE5C;
gDrawbridgeTimers = 0x8011AE5C;
gObjectOffsetY = 0x8011AE60;
D_8011ADD4 = 0x8011AE64;
gOverrideDoors = 0x8011AE65;
@@ -3405,8 +3405,8 @@ gObjectMapIndex = 0x8011AF50;
gParticlePtrList = 0x8011AF54;
gFreeListCount = 0x8011AF58;
gTrackCheckpoints = 0x8011AF5C;
gNumberOfCheckpoints = 0x8011AF60;
D_8011AED4 = 0x8011AF64;
gNumberOfMainCheckpoints = 0x8011AF60;
gNumberOfTotalCheckpoints = 0x8011AF64;
gTajChallengeType = 0x8011AF68;
gCameraObjList = 0x8011AF6C;
gCameraObjCount = 0x8011AF70;
@@ -4108,7 +4108,7 @@ D_80127180 = 0x80127210;
gHudSettings = 0x80127214;
gHudSilverCoinRace = 0x80127218;
gAdventurePlayerFinish = 0x80127219;
D_8012718A = 0x8012721A;
gAdvRaceStartedByP2 = 0x8012721A;
gMinimapOpacityTarget = 0x8012721B;
gStopwatchErrorX = 0x8012721C;
gStopwatchErrorY = 0x80127220;

Some files were not shown because too many files have changed in this diff Show More