mk64/src/code_800029B0.c

388 lines
12 KiB
C

#include <ultra64.h>
#include <macros.h>
#include "code_800029B0.h"
#include "types.h"
#include "memory.h"
#include "variables.h"
#include "waypoints.h"
#include "actors.h"
#include "actor_types.h"
#include "math_util.h"
#include "audio/external.h"
#include <defines.h>
#include "collision.h"
#include "memory.h"
#include "code_80091750.h"
#include "skybox_and_splitscreen.h"
#include "code_8006E9C0.h"
#include "spawn_players.h"
#include "staff_ghosts.h"
#include "render_courses.h"
#include "main.h"
#include "courses/all_course_data.h"
#include "courses/all_course_packed.h"
#include "menus.h"
#include "data/other_textures.h"
extern s32 D_802BA038;
extern s16 D_802BA048;
s16 gCurrentCourseId = 0;
s16 gCurrentlyLoadedCourseId = 0xFF;
u16 D_800DC5A8 = 0;
s32 D_800DC5AC = 0;
u16 D_800DC5B0 = 1;
u16 D_800DC5B4 = 0;
u16 D_800DC5B8 = 0;
u16 D_800DC5BC = 0;
u16 gIsInQuitToMenuTransition = 0;
u16 gQuitToMenuTransitionCounter = 0;
u16 D_800DC5C8 = 0;
UNUSED u16 D_800DC5CC = 0;
s32 D_800DC5D0 = 0;
s32 D_800DC5D4 = 0;
s32 D_800DC5D8 = 0;
s32 D_800DC5DC = 64;
s32 D_800DC5E0 = 32;
// This is tracking which credit "state" we're in, decides which credits are shown (and probably other stuff)
u16 D_800DC5E4 = 0;
// TODO: gPlayerWinningIndex (D_800DC5E8) accessed as word, D_800DC5EB as u8
s32 gPlayerWinningIndex = 0;
struct UnkStruct_800DC5EC D_8015F480[4];
struct UnkStruct_800DC5EC *D_800DC5EC = &D_8015F480[0];
struct UnkStruct_800DC5EC *D_800DC5F0 = &D_8015F480[1];
struct UnkStruct_800DC5EC *D_800DC5F4 = &D_8015F480[2];
struct UnkStruct_800DC5EC *D_800DC5F8 = &D_8015F480[3];
u16 gIsGamePaused = 0; // 1 if the game is paused and 0 if the game is not paused
u8 *pAppNmiBuffer = (u8 *) &osAppNmiBuffer;
s32 gIsMirrorMode = 0;
f32 vtxStretchY = 1.0f;
Lights1 D_800DC610[] = {
gdSPDefLights1(175, 175, 175, 255, 255, 255, 0, 0, 120),
gdSPDefLights1(115, 115, 115, 255, 255, 255, 0, 0, 120),
};
static s32 pad_800029B0 = 0x80000000;
s16 gCreditsCourseId = COURSE_LUIGI_RACEWAY;
s16 gPlaceItemBoxes = 1;
// Technically a pointer to an array, but declaring it so creates regalloc issues.
mk64_surface_map_ram *gSurfaceMap;
u16 *D_8015F584;
u16 D_8015F588; // Number of entries in gSurfaceMap
u16 D_8015F58A;
u32 D_8015F58C;
Vec3f D_8015F590;
s32 D_8015F59C;
s32 D_8015F5A0;
s32 D_8015F5A4;
s32 code_800029B0_bss_pad[48];
Vtx *vtxBuffer[32];
s16 D_8015F6E8;
s16 D_8015F6EA;
s16 D_8015F6EC; // s16 or u16?
s16 D_8015F6EE;
s16 D_8015F6F0;
s16 D_8015F6F2;
s16 D_8015F6F4;
s16 D_8015F6F6;
u16 D_8015F6F8;
s16 D_8015F6FA;
s16 D_8015F6FC;
/**
* Incremented by one every time the player spawns a new shell actor.
* A cleaning routine runs once twenty-one shells have spawned.
*/
u16 gNumSpawnedShells;
u16 D_8015F700;
u16 D_8015F702;
f32 D_8015F704;
Vec3f D_8015F708;
UNUSED u32 D_8015F718[3]; // Likely held ptrs to segmented data.
size_t gFreeMemorySize;
uintptr_t gNextFreeMemoryAddress;
uintptr_t gHeapEndPtr;
u32 D_8015F730;
uintptr_t gFreeMemoryResetAnchor;
Vec3f D_8015F738;
Vec3f D_8015F748;
Vec3f D_8015F758;
Vec3f D_8015F768;
Vec3f D_8015F778;
f32 gCourseDirection; // Extra mode, flips vertices.
s32 D_8015F788;
s32 D_8015F790[64]; // Unknown data, potentially not used.
u16 D_8015F890;
u16 D_8015F892;
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 *gNmiUnknown4;
u8 *gNmiUnknown5;
u8 *gNmiUnknown6;
Vec3f D_8015F8D0;
s32 D_8015F8DC;
s32 D_8015F8E0;
f32 D_8015F8E4;
f32 D_8015F8E8;
s16 gPlayerPositionLUT[8]; // Player index at each position
u16 gNumPermanentActors;
s32 code_800029B0_bss_pad2[44];
struct Actor gActorList[ACTOR_LIST_SIZE];
// @warning todo: Is this apart of the actor array?
UNUSED u8 D_80162578[sizeof(struct Actor)];
s16 gDebugPathCount;
s16 sIsController1Unplugged;
s32 D_801625EC;
s32 D_801625F0;
s32 D_801625F4;
s32 D_801625F8;
f32 D_801625FC;
void func_800029B0(void) {
switch(D_800DC5A8) {
case 0:
func_800C8F44(127);
break;
case 1:
func_800C8F44(75);
break;
case 2:
func_800C8F44(0);
break;
}
}
void setup_race(void) {
struct Controller *controller;
int i;
gPlayerCountSelection1 = gPlayerCount;
if (gGamestate != RACING) {
gIsMirrorMode = 0;
}
if (gIsMirrorMode) {
gCourseDirection = -1.0f;
} else {
gCourseDirection = 1.0f;
}
if (gModeSelection == GRAND_PRIX) {
gCurrentCourseId = gCupCourseOrder[gCupSelection][gCupCourseSelection];
}
gActiveScreenMode = gScreenModeSelection;
if (gCurrentCourseId != gCurrentlyLoadedCourseId) {
D_80150120 = 0;
gCurrentlyLoadedCourseId = gCurrentCourseId;
gNextFreeMemoryAddress = gFreeMemoryResetAnchor;
load_course(gCurrentCourseId);
func_80295D88();
D_8015F730 = gNextFreeMemoryAddress;
} else {
gNextFreeMemoryAddress = D_8015F730;
}
func_802969F8();
func_80005310();
func_8003D080();
init_object_list();
D_800DC510 = 0;
gNumSpawnedShells = 0;
D_800DC5B8 = 0;
D_80152308 = 0;
D_802BA038 = -1;
D_802BA048 = 0;
func_802A74BC();
func_802A4D18();
func_80091FA4();
func_8029E158();
if (gModeSelection != BATTLE) {
D_8015F8D0[1] = (f32) (D_80164490->posY - 15);;
D_8015F8D0[2] = D_80164490->posZ;
if (gCurrentCourseId == COURSE_TOADS_TURNPIKE) {
D_8015F8D0[0] = (gIsMirrorMode != 0) ?
D_80164490->posX + 138.0f :
D_80164490->posX - 138.0f;
} else if (gCurrentCourseId == COURSE_WARIO_STADIUM) {
D_8015F8D0[0] = (gIsMirrorMode != 0) ?
D_80164490->posX + 12.0f :
D_80164490->posX - 12.0f;
} else {
D_8015F8D0[0] = D_80164490->posX;
}
}
if (!gDemoMode) {
func_800CA008(gPlayerCountSelection1 - 1, gCurrentCourseId + 4);
func_800CB2C4();
}
controller = gControllerOne;
for (i = 0; i < 7; i++, controller++){
controller->rawStickX = 0;
controller->rawStickY = 0;
controller->buttonPressed = 0;
controller->buttonDepressed = 0;
controller->button = 0;
}
}
void func_80002DAC(void) {
switch (gCurrentCourseId) {
case COURSE_MARIO_RACEWAY:
vec3f_set(D_8015F748, -223.0f, 94.0f, -155.0f);
func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B);
break;
case COURSE_ROYAL_RACEWAY:
vec3f_set(D_8015F748, 177.0f, 87.0f, -393.0f);
func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B);
break;
case COURSE_LUIGI_RACEWAY:
vec3f_set(D_8015F748, 85.0f, 21.0f, -219.0f);
func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B);
break;
case COURSE_WARIO_STADIUM:
vec3f_set(D_8015F748, 298.0f, 202.0f, -850.0f);
func_800C9D80(D_8015F748, D_802B91C8, 0x5103700B);
vec3f_set(D_8015F758, -1600.0f, 202.0f, -2430.0f);
func_800C9D80(D_8015F758, D_802B91C8, 0x5103700B);
vec3f_set(D_8015F768, -2708.0f, 202.0f, 1762.0f);
func_800C9D80(D_8015F768, D_802B91C8, 0x5103700B);
vec3f_set(D_8015F778, -775.0f, 202.0f, 1930.0f);
func_800C9D80(D_8015F778, D_802B91C8, 0x5103700B);
break;
case COURSE_KOOPA_BEACH:
vec3f_set(D_8015F738, 153.0f, 0.0f, 2319.0f);
func_800C9D80(D_8015F738, D_802B91C8, 0x51028001);
break;
case COURSE_DK_JUNGLE:
vec3f_set(D_8015F738, -790.0f, -255.0f, -447.0f);
func_800C9D80(D_8015F738, D_802B91C8, 0x51028001);
break;
default:
break;
}
}
/**
* The nmi buffer allows developers to save 64 bytes of data through a soft reset.
*/
void clear_nmi_buffer(void) {
s32 i;
for (i = 0; i < 16; i++) {
osAppNmiBuffer[i] = 0;
}
}
void func_80003040(void) {
Vec3f position;
Vec3f velocity = {0, 0, 0};
Vec3s rotation = {0, 0, 0};
D_800DC5BC = 0;
D_800DC5C8 = 0;
gNumActors = 0;
gIsMirrorMode = 0;
gCourseDirection = 1.0f;
gPlayerCountSelection1 = 1;
set_segment_base_addr(0x3, (void *) (gNextFreeMemoryAddress + 0xFFFF7000));
destroy_all_actors();
switch (gCurrentCourseId) {
case COURSE_MARIO_RACEWAY:
dma_textures(gTextureTrees1, 0x35B, 0x800);
spawn_foliage(d_course_mario_raceway_tree_spawns);
break;
case COURSE_BOWSER_CASTLE:
// d_course_bowsers_castle_packed_dl_1350
find_vtx_and_set_colours(0x07001350, 0x32, 0, 0, 0);
break;
case COURSE_BANSHEE_BOARDWALK:
// d_course_banshee_boardwalk_packed_dl_878
find_vtx_and_set_colours(0x07000878, -0x80, 0, 0, 0);
break;
case COURSE_YOSHI_VALLEY:
vec3f_set(position, -2300.0f, 0.0f, 634.0f);
position[0] *= gCourseDirection;
addActorToEmptySlot(position, rotation, velocity, ACTOR_YOSHI_VALLEY_EGG);
break;
case COURSE_MOO_MOO_FARM:
dma_textures(gTextureTrees4Left, 0x3E8, 0x800);
dma_textures(gTextureTrees4Right, 0x3E8, 0x800);
dma_textures(gTextureCow01Left, 0x400, 0x800);
dma_textures(gTextureCow01Right, 0x400, 0x800);
dma_textures(gTextureCow02Left, 0x400, 0x800);
dma_textures(gTextureCow02Right, 0x400, 0x800);
dma_textures(gTextureCow03Left, 0x400, 0x800);
dma_textures(gTextureCow03Right, 0x400, 0x800);
dma_textures(gTextureCow04Left, 0x400, 0x800);
dma_textures(gTextureCow04Right, 0x400, 0x800);
dma_textures(gTextureCow05Left, 0x400, 0x800);
dma_textures(gTextureCow05Right, 0x400, 0x800);
spawn_foliage(d_course_moo_moo_farm_tree_spawn);
break;
case COURSE_SHERBET_LAND:
// d_course_sherbet_land_packed_dl_1EB8
find_vtx_and_set_colours(0x07001EB8, -0x4C, 0xFF, 0xFF, 0xFF);
// d_course_sherbet_land_packed_dl_2308
find_vtx_and_set_colours(0x07002308, -0x6A, 0xFF, 0xFF, 0xFF);
break;
case COURSE_RAINBOW_ROAD:
// d_course_rainbow_road_packed_dl_2068
find_vtx_and_set_colours(0x07002068, -0x6A, 0xFF, 0xFF, 0xFF);
// d_course_rainbow_road_packed_dl_1E18
find_vtx_and_set_colours(0x07001E18, -0x6A, 0xFF, 0xFF, 0xFF);
// d_course_rainbow_road_packed_dl_1318
find_vtx_and_set_colours(0x07001318, -1, 0xFF, 0xFF, 0);
break;
case COURSE_WARIO_STADIUM:
vec3f_set(position, -131.0f, 83.0f, 286.0f);
addActorToEmptySlot(position, rotation, velocity, ACTOR_WARIO_STADIUM_SIGN);
vec3f_set(position, -2353.0f, 72.0f, -1608.0f);
addActorToEmptySlot(position, rotation, velocity, ACTOR_WARIO_STADIUM_SIGN);
vec3f_set(position, -2622.0f, 79.0f, 739.0f);
addActorToEmptySlot(position, rotation, velocity, ACTOR_WARIO_STADIUM_SIGN);
// d_course_wario_stadium_packed_dl_C50
find_vtx_and_set_colours(0x07000C50, 0x64, 0xFF, 0xFF, 0xFF);
// d_course_wario_stadium_packed_dl_BD8
find_vtx_and_set_colours(0x07000BD8, 0x64, 0xFF, 0xFF, 0xFF);
// d_course_wario_stadium_packed_dl_B60
find_vtx_and_set_colours(0x07000B60, 0x64, 0xFF, 0xFF, 0xFF);
// d_course_wario_stadium_packed_dl_AE8
find_vtx_and_set_colours(0x07000AE8, 0x64, 0xFF, 0xFF, 0xFF);
// d_course_wario_stadium_packed_dl_CC8
find_vtx_and_set_colours(0x07000CC8, 0x64, 0xFF, 0xFF, 0xFF);
// d_course_wario_stadium_packed_dl_D50
find_vtx_and_set_colours(0x07000D50, 0x64, 0xFF, 0xFF, 0xFF);
// d_course_wario_stadium_packed_dl_DD0
find_vtx_and_set_colours(0x07000DD0, 0x64, 0xFF, 0xFF, 0xFF);
// d_course_wario_stadium_packed_dl_E48
find_vtx_and_set_colours(0x07000E48, 0x64, 0xFF, 0xFF, 0xFF);
break;
case COURSE_DK_JUNGLE:
// d_course_dks_jungle_parkway_packed_dl_3FA8
find_vtx_and_set_colours(0x07003FA8, 0x78, 0xFF, 0xFF, 0xFF);
break;
default:
break;
}
gNumPermanentActors = gNumActors;
}