diff --git a/include/level_object_entries.h b/include/level_object_entries.h index 0d344e87..7fc76133 100644 --- a/include/level_object_entries.h +++ b/include/level_object_entries.h @@ -41,11 +41,37 @@ typedef struct LevelObjectEntry_Smoke { typedef struct LevelObjectEntry_Exit { /* 0x00 */ LevelObjectEntryCommon common; - /* 0x08 */ u8 pad8[8]; + /* 0x08 */ u8 destinationMapId; + /* 0x09 */ u8 pad9; + + // Defines the location in overworld the player will spawn at. + // Only used if the exit goes to overworld. + // 0: Future Fun Land exit (also game start spawn) + // 2: Dino Domain exit + // 3: Snowflake Mountain exit + // 4: Sherbet Island exit + // 6: Dragon Forest exit + // 7: Wizpig head exit + /* 0x0A */ s8 overworldSpawnIndex; + + /* 0x0B */ u8 padB[5]; /* 0x10 */ u8 unk10; /* 0x11 */ u8 unk11; - /* 0x12 */ u8 pad12[6]; - /* 0x18 */ s8 unk18; + /* 0x12 */ u8 pad12[5]; + + // Defines the location in a hub world the player will spawn at when exiting `destinationMapId`. + // Only used if the exit goes to a race. + // 0: Hub exit door + // 1-4: One of the 4 race doors + // 5: Boss door + // 6: Minigame door + // 7: Wizpig head + /* 0x17 */ u8 returnSpawnIndex; + + // -1: Doesn't warp to a boss race + // 0: Warps to a boss 1 race + // 1: Warps to a boss 2 race + /* 0x18 */ s8 bossFlag; } LevelObjectEntry_Exit; typedef struct LevelObjectEntry_Audio { diff --git a/include/structs.h b/include/structs.h index 43c1fd3c..7fe980e6 100644 --- a/include/structs.h +++ b/include/structs.h @@ -162,43 +162,84 @@ typedef struct Settings4C { /* Size: 0x118 bytes */ typedef struct Settings { + // Balloon indices: + // 0 = Total balloons + // 1 = Dino Domain balloons + // 2 = Sherbet Island balloons + // 3 = Snowflake Mountain balloons + // 4 = Dragon Forest balloons + // 5 = Future Fun Land balloons /* 0x0000 */ s16 *balloonsPtr; + + // Course flag bits: + // 0x1 = Map has been visited. + // 0x2 = Map has been completed. + // 0x4 = Map's silver coin challenge has been completed. + // 0x00000000-0xFFFF0000 = Used as bit fields for hub worlds to indicate whether or not a door can open when the player gets near it. /* 0x0004 */ s32 *courseFlagsPtr; + + // Key bits: + // 0x02 = Dino Domain key + // 0x04 = Sherbet Island key + // 0x08 = Snowflake Mountain key + // 0x10 = Dragon Forest key /* 0x0008 */ u16 keys; + /* 0x000A */ u16 unkA; + + // Boss bits: + // 0x001 = Wizpig 1 + // 0x002 = Tricky 1 + // 0x004 = Bubbler 1 + // 0x008 = Bluey 1 + // 0x010 = Smokey 1 + // 0x020 = Wizpig 2 + // 0x080 = Tricky 2 + // 0x100 = Bubbler 2 + // 0x200 = Bluey 2 + // 0x400 = Smokey 2 /* 0x000C */ u16 bosses; + + // Trophy bits: + // Bit field 0b00-0b11 = Empty, 3rd, 2nd, and 1st place trophies. + // `trophies` consists of 5 of these bit fields, from LSB to MSB, Dino, Sherbet, Snowflake, Dragon, and FFL. /* 0x000E */ u16 trophies; + + // Cutscene flags: + // 0x1 = Lighthouse rocket cutscene + // 0x2 = T.T. help prompt + // 0x4 = Adventure 2 flag? + // 0x8 = Dino domain boss cutscene + // 0x10 = Sherbet island boss cutscene + // 0x20 = Snowflake mountain boss cutscene + // 0x40 = Dragon forest boss cutscene + // 0x80 = Future Fun Land boss cutscene + // 0x100 = Dino domain boss cutscene 2 + // 0x200 = Shertbet island boss cutscene 2 + // 0x400 = Snowflake mountain boss cutscene 2 + // 0x800 = Dragon forest boss cutscene 2 + // 0x2000 = Wizpig face cutscene + // 0x4000 = Dino domain key cutscene + // 0x8000 = Sherbet Island key cutscene + // 0x10000 = Snowflake mountain key cutscene + // 0x20000 = Dragon forest key cutscene /* 0x0010 */ u32 cutsceneFlags; - /* Cutscene flags: - * 0x1 = Lighthouse rocket cutscene - * 0x2 = T.T. help prompt - * 0x4 = Adventure 2 flag? - * 0x8 = Dino domain boss cutscene - * 0x10 = Sherbet island boss cutscene - * 0x20 = Snowflake mountain boss cutscene - * 0x40 = Dragon forest boss cutscene - * 0x80 = Future Fun Land boss cutscene - * 0x100 = Dino domain boss cutscene 2 - * 0x200 = Shertbet island boss cutscene 2 - * 0x400 = Snowflake mountain boss cutscene 2 - * 0x800 = Dragon forest boss cutscene 2 - * 0x2000 = Wizpig face cutscene - * 0x4000 = Dino domain key cutscene - * 0x8000 = Sherbet Island key cutscene - * 0x10000 = Snowflake mountain key cutscene - * 0x20000 = Dragon forest key cutscene - */ + + // Taj flags: + // 0x1 = Car challenge unlocked + // 0x2 = Hover challenge unlocked + // 0x4 = Plane challenge unlocked + // 0x8 = Car challenge completed + // 0x10 = Hover challenge completed + // 0x20 = Plane challenge completed /* 0x0014 */ u16 tajFlags; - /* Taj flags: - * 0x1 = Car challenge unlocked - * 0x2 = Hover challenge unlocked - * 0x4 = Plane challenge unlocked - * 0x8 = Car challenge completed - * 0x10 = Hover challenge completed - * 0x20 = Plane challenge completed - */ + + // Not a bitfield, just a counter from 0-4. /* 0x0016 */ u8 ttAmulet; + + // Not a bitfield, just a counter from 0-4. /* 0x0017 */ u8 wizpigAmulet; + /* 0x0018 */ u16 *flapInitialsPtr[3]; /* 0x0024 */ u16 *flapTimesPtr[3]; /* 0x0030 */ u16 *courseInitialsPtr[3]; @@ -966,8 +1007,8 @@ typedef struct Object_Racer { /* 0x18C */ s16 unk18C; /* 0x18E */ s16 shieldTimer; /* 0x190 */ s16 unk190; - /* 0x192 */ s8 unk192; - /* 0x193 */ s8 lapCount; + /* 0x192 */ s8 checkpoint; + /* 0x193 */ s8 lap; /* 0x194 */ s8 unk194; /* 0x195 */ s8 unk195; /* 0x196 */ s16 unk196; @@ -1111,7 +1152,7 @@ typedef struct Object_Door { /* 0x11 */ u8 unk11; /* 0x12 */ u8 unk12; /* 0x13 */ u8 unk13; - /* 0x14 */ u8 unk14; + /* 0x14 */ s8 unk14; } Object_Door; typedef struct Object_Trigger { diff --git a/src/game_ui.c b/src/game_ui.c index 882cf639..9a910681 100644 --- a/src/game_ui.c +++ b/src/game_ui.c @@ -864,7 +864,7 @@ void render_racer_bananas(Object_64 *obj, s32 updateRate) { s16 temp_v1; s32 temp_lo; u8 var_v1; - if(obj->racer.playerIndex == PLAYER_COMPUTER || ((gHUDNumPlayers < 1 || D_800E2794[gHUDNumPlayers][obj->racer.playerIndex] == 2 || D_80126D60->race_type == 0x41 || D_80126D60->race_type == 0x40) && obj->racer.raceFinished == FALSE) && (gHUDNumPlayers < 1 || (obj->racer.lapCount < 1) || obj->racer.lap_times[obj->racer.lapCount] >= 180 || D_80126D60->race_type & 0x40)) { + if(obj->racer.playerIndex == PLAYER_COMPUTER || ((gHUDNumPlayers < 1 || D_800E2794[gHUDNumPlayers][obj->racer.playerIndex] == 2 || D_80126D60->race_type == 0x41 || D_80126D60->race_type == 0x40) && obj->racer.raceFinished == FALSE) && (gHUDNumPlayers < 1 || (obj->racer.lap < 1) || obj->racer.lap_times[obj->racer.lap] >= 180 || D_80126D60->race_type & 0x40)) { func_800AA600(&gHUDCurrDisplayList, (Matrix *) &gHUDCurrMatrix, (TriangleList *) &gHUDCurrTriList, (unk80126CDC *) &D_80126CDC->unk240); bananas = obj->racer.bananas; var_v1 = D_80126CDC->unkF8; @@ -942,7 +942,7 @@ void func_800A45F0(Object_Racer* racer) { D_80126CD5 = FALSE; } for (i = 0; i < 10; i++) { - if (i >= racer->lapCount) { + if (i >= racer->lap) { D_800E2834 = 0x80808080; } D_80126CD5 = TRUE; @@ -1038,7 +1038,7 @@ GLOBAL_ASM("asm/non_matchings/game_ui/func_800A4C44.s") * In multiplayer, shows a cut down display, if the display setting is set to show laps. */ void render_lap_count(Object_64 *obj, s32 updateRate) { - if (obj->racer.raceFinished == FALSE && (gHUDNumPlayers <= 0 || obj->racer.lapCount <= 0 || obj->racer.lap_times[obj->racer.lapCount] >= 180) + if (obj->racer.raceFinished == FALSE && (gHUDNumPlayers <= 0 || obj->racer.lap <= 0 || obj->racer.lap_times[obj->racer.lap] >= 180) && (gHUDNumPlayers <= 0 || D_800E2794[gHUDNumPlayers][obj->racer.playerIndex] == 3)) { if (D_80126D60->laps == (0, obj->racer.unk194 + 1) && gHUDNumPlayers < 2) { D_80126CDC->unk21A += updateRate; @@ -1066,8 +1066,8 @@ void render_lap_count(Object_64 *obj, s32 updateRate) { func_8007BF1C(TRUE); } if (is_game_paused() == FALSE) { - if (obj->racer.lap_times[obj->racer.lapCount] < 30 && D_80126CDC->unk3DA == 0 && obj->racer.raceFinished == FALSE) { - if ((obj->racer.lapCount == 1) && D_80126D60->laps >= 3) { + if (obj->racer.lap_times[obj->racer.lap] < 30 && D_80126CDC->unk3DA == 0 && obj->racer.raceFinished == FALSE) { + if ((obj->racer.lap == 1) && D_80126D60->laps >= 3) { D_80126CDC->unk3DA = 2; D_80126CDC->unk3DB = 1; D_80126CDC->unk3DD = 0; @@ -1099,7 +1099,7 @@ void render_lap_count(Object_64 *obj, s32 updateRate) { } break; } - } else if (D_80126D60->laps == (0, obj->racer.lapCount + 1) && obj->racer.lapCount != 0) { + } else if (D_80126D60->laps == (0, obj->racer.lap + 1) && obj->racer.lap != 0) { D_80126CDC->unk3DA = 3; D_80126CDC->unk3DB = -1; D_80126CDC->unk3DD = 0; @@ -1146,7 +1146,7 @@ void render_lap_count(Object_64 *obj, s32 updateRate) { } else { D_80126CDC->unk3EC = D_80126CDC->unk3FC; } - if (obj->racer.lap_times[obj->racer.lapCount] >= 60) { + if (obj->racer.lap_times[obj->racer.lap] >= 60) { D_80126CDC->unk3DB = -1; play_sound_global(SOUND_WHOOSH1, NULL); } @@ -1179,7 +1179,7 @@ void render_lap_count(Object_64 *obj, s32 updateRate) { } else { D_80126CDC->unk3AC = D_80126CDC->unk3BC; } - if (obj->racer.lap_times[obj->racer.lapCount] >= 0x3C) { + if (obj->racer.lap_times[obj->racer.lap] >= 0x3C) { D_80126CDC->unk3DB = 1; play_sound_global(SOUND_WHOOSH1, NULL); } @@ -1435,11 +1435,11 @@ void render_race_time(Object_64* obj, s32 updateRate) { s32 countingDown; s32 timerHideCounter; - if (!(gHUDNumPlayers && D_800E2794[gHUDNumPlayers][obj->racer.playerIndex] != 1) || (gHUDNumPlayers > 0 && obj->racer.lapCount > 0 && obj->racer.lap_times[obj->racer.lapCount] < 180)) { + if (!(gHUDNumPlayers && D_800E2794[gHUDNumPlayers][obj->racer.playerIndex] != 1) || (gHUDNumPlayers > 0 && obj->racer.lap > 0 && obj->racer.lap_times[obj->racer.lap] < 180)) { if (obj->racer.raceFinished == FALSE) { timerHideCounter = D_80126CDC->unk15A + 127; - if (obj->racer.lapCount > 0 && obj->racer.lap_times[obj->racer.lapCount] < 180 && obj->racer.lapCount < D_80126D60->laps) { - stopwatchTimer = obj->racer.lap_times[obj->racer.lapCount - 1]; + if (obj->racer.lap > 0 && obj->racer.lap_times[obj->racer.lap] < 180 && obj->racer.lap < D_80126D60->laps) { + stopwatchTimer = obj->racer.lap_times[obj->racer.lap - 1]; countingDown = TRUE; if (timerHideCounter == 0) { timerHideCounter = 180; diff --git a/src/game_ui.h b/src/game_ui.h index ebff0e51..79543118 100644 --- a/src/game_ui.h +++ b/src/game_ui.h @@ -216,12 +216,6 @@ typedef struct unk80126CDC { s8 unk704[0x1C]; } unk80126CDC; -typedef struct { - u8 unk0[0x4B]; - s8 numLaps; - s8 unk4C; -} unk80126D60; - typedef struct unk800E1E64 { s32 unk0; s32 unk4; diff --git a/src/object_functions.c b/src/object_functions.c index 01c15f53..554a00dd 100644 --- a/src/object_functions.c +++ b/src/object_functions.c @@ -1467,7 +1467,7 @@ void obj_init_exit(Object *obj, LevelObjectEntry_Exit *entry) { obj64->unk8 = sine_s(obj->segment.trans.y_rotation); obj64->unkC = -((obj64->unk0 * obj->segment.trans.x_position) + (obj64->unk8 * obj->segment.trans.z_position)); obj64->unk10 = entry->unk10; - obj64->unk14 = entry->unk18; + obj64->unk14 = entry->bossFlag; obj->unk4C->unk14 = 2; obj->unk4C->unk11 = 0; obj->unk4C->unk10 = entry->unk10; diff --git a/src/objects.c b/src/objects.c index f1d53c48..b21f2cc2 100644 --- a/src/objects.c +++ b/src/objects.c @@ -1901,8 +1901,8 @@ void func_800228EC(s32 arg0) { D_8011AEF7 = 3; object_64 = &get_racer_object(0)->unk64->racer; object_64->unk190 = 0; - object_64->unk192 = 0; - object_64->lapCount = 0; + object_64->checkpoint = 0; + object_64->lap = 0; object_64->unk1BA = 0; func_80017E74(arg0); func_8006F388(10); diff --git a/src/racer.c b/src/racer.c index fc0e2514..f61e4630 100644 --- a/src/racer.c +++ b/src/racer.c @@ -360,7 +360,7 @@ void func_80045128(struct TempStruct2 *header) { for (i = 0; i < 4; i++) { obj = (Object_Racer *) header->unk0[i]->unk64; - D_8011D588[i] = obj->lapCount; + D_8011D588[i] = obj->lap; if (obj->unk1CF != 0) { D_8011D588[i] |= 0x40; } @@ -1455,31 +1455,31 @@ void update_player_racer(Object* obj, s32 updateRate) { func_800050D0(obj, gCurrentButtonsPressed, gCurrentRacerInput, updateRate); } lastCheckpointDist = tempRacer->checkpoint_distance; - tempVar = func_800185E4(tempRacer->unk192, obj, xTemp, yTemp, zTemp, &tempRacer->checkpoint_distance, &tempRacer->unk1C8); + tempVar = func_800185E4(tempRacer->checkpoint, obj, xTemp, yTemp, zTemp, &tempRacer->checkpoint_distance, &tempRacer->unk1C8); if (tempVar == -100) { func_8005C270(tempRacer); } - temp_v0_16 = func_8001BA1C(tempRacer->unk192, tempRacer->unk1C8); + temp_v0_16 = func_8001BA1C(tempRacer->checkpoint, tempRacer->unk1C8); if (tempRacer->playerIndex == PLAYER_COMPUTER && temp_v0_16->unk36[tempRacer->unk1CA] == 5 && tempRacer->unk1E5) { tempRacer->unk1C8 = 1; } if (temp_v0_16->unk36[tempRacer->unk1CA] == 6) { - tempRacer->lapCount = header->laps + 1; + tempRacer->lap = header->laps + 1; } if (tempVar == 0) { if (tempRacer->playerIndex == PLAYER_COMPUTER && temp_v0_16->unk36[tempRacer->unk1CA] == 2) { tempRacer->unk1C8 = 1; } temp_v0_17 = func_8001BA64(); - tempRacer->unk192++; - if (tempRacer->unk192 >= temp_v0_17) { - tempRacer->unk192 = 0; + tempRacer->checkpoint++; + if (tempRacer->checkpoint >= temp_v0_17) { + tempRacer->checkpoint = 0; if (tempRacer->unk190 > 0) { - if (tempRacer->lapCount < 120) { - tempRacer->lapCount++; + if (tempRacer->lap < 120) { + tempRacer->lap++; } } - if (tempRacer->playerIndex != PLAYER_COMPUTER && tempRacer->lapCount + 1 == header->laps + if (tempRacer->playerIndex != PLAYER_COMPUTER && tempRacer->lap + 1 == header->laps && !D_8011D580 && get_current_level_race_type() == RACETYPE_DEFAULT) { func_800014BC(1.12f); D_8011D580 = 1; @@ -1487,7 +1487,7 @@ void update_player_racer(Object* obj, s32 updateRate) { } if (func_8002341C()) { if (gCurrentPlayerIndex != PLAYER_COMPUTER) { - temp_v0_16 = func_8001BA1C(tempRacer->unk192, tempRacer->unk1C8); + temp_v0_16 = func_8001BA1C(tempRacer->checkpoint, tempRacer->unk1C8); if (!tempRacer->unk15C) { newObject.x = 0; newObject.y = 0; @@ -1648,8 +1648,8 @@ void update_player_racer(Object* obj, s32 updateRate) { } else { tempRacer->unk212 = 0; } - if (tempRacer->unk194 < tempRacer->lapCount) { - tempRacer->unk194 = tempRacer->lapCount; + if (tempRacer->unk194 < tempRacer->lap) { + tempRacer->unk194 = tempRacer->lap; } } } @@ -3423,8 +3423,8 @@ void func_80059080(UNUSED Object *obj, Object_Racer *racer, f32 *xVel, f32 *yVel if (magnitude < 0.0f) { magnitude = 0.0f; } - if (racer->unk192) {} - splinePos = racer->unk192 - 2; + if (racer->checkpoint) {} + splinePos = racer->checkpoint - 2; if (splinePos < 0) { splinePos += splineEnd; } @@ -3798,12 +3798,12 @@ void func_8005A6F0(Object *obj, Object_Racer *racer, s32 updateRate, f32 updateR func_800050D0(obj, gCurrentButtonsPressed, gCurrentRacerInput, updateRate); } sp80 = racer->checkpoint_distance; - countOfObjects = racer->unk192; - var_t2 = func_800185E4(racer->unk192, obj, xPos, yPos, zPos, &racer->checkpoint_distance, &racer->unk1C8); + countOfObjects = racer->checkpoint; + var_t2 = func_800185E4(racer->checkpoint, obj, xPos, yPos, zPos, &racer->checkpoint_distance, &racer->unk1C8); if (var_t2 == -100) { func_8005C270(racer); } - temp_v0_9 = func_8001BA1C(racer->unk192, racer->unk1C8); + temp_v0_9 = func_8001BA1C(racer->checkpoint, racer->unk1C8); if (temp_v0_9->unk36[racer->unk1CA] == 5) { racer->unk201 = 30; if (racer->unk1E5 != 0) { @@ -3811,7 +3811,7 @@ void func_8005A6F0(Object *obj, Object_Racer *racer, s32 updateRate, f32 updateR } } if (temp_v0_9->unk36[racer->unk1CA] == 6) { - racer->lapCount = levelHeader->laps + 1; + racer->lap = levelHeader->laps + 1; } if (temp_v0_9->unk36[racer->unk1CA] == 4) { if (racer->velocity < -4.0) { @@ -3823,12 +3823,12 @@ void func_8005A6F0(Object *obj, Object_Racer *racer, s32 updateRate, f32 updateR racer->unk1C8 = 1; } temp_v0_10 = func_8001BA64(); - racer->unk192++; - if (racer->unk192 >= temp_v0_10) { - racer->unk192 = 0; + racer->checkpoint++; + if (racer->checkpoint >= temp_v0_10) { + racer->checkpoint = 0; if (racer->unk190 > 0) { - if (racer->lapCount < 120) { - racer->lapCount++; + if (racer->lap < 120) { + racer->lap++; } } } @@ -4020,7 +4020,7 @@ void func_8005B818(Object *obj, Object_Racer *racer, s32 updateRate, f32 updateR racer->velocity += ((-var_f12 - racer->velocity) * 0.25); } var_a3 = &spD8; - var_a0 = racer->unk192 - 2; + var_a0 = racer->checkpoint - 2; var_t1 = &spB8; if (var_a0 < 0) { var_a0 += sp11C; @@ -4089,13 +4089,13 @@ void func_8005B818(Object *obj, Object_Racer *racer, s32 updateRate, f32 updateR } racer->checkpoint_distance = (1 - var_f22); if (var_s2 != 0) { - racer->unk192 += 1; - if (racer->unk192 >= sp11C) { - racer->unk192 = 0; + racer->checkpoint += 1; + if (racer->checkpoint >= sp11C) { + racer->checkpoint = 0; if (racer->unk190 > 0) { - temp_v0_3 = racer->lapCount; + temp_v0_3 = racer->lap; if (temp_v0_3 < 0x78) { - racer->lapCount = temp_v0_3 + 1; + racer->lap = temp_v0_3 + 1; } } } @@ -4183,11 +4183,11 @@ void antipiracy_modify_surface_traction_table(void) { void func_8005C270(Object_Racer *racer) { s32 temp = func_8001BA64(); - racer->unk192--; - if (racer->unk192 < 0) { - racer->unk192 += temp; - if (racer->lapCount > 0) { - racer->lapCount--; + racer->checkpoint--; + if (racer->checkpoint < 0) { + racer->checkpoint += temp; + if (racer->lap > 0) { + racer->lap--; } }