summaryrefslogtreecommitdiff
path: root/src/spawn_players.c
diff options
context:
space:
mode:
authorMegaMech <MegaMech@users.noreply.github.com>2025-12-07 13:14:45 -0700
committerGitHub <noreply@github.com>2025-12-07 13:14:45 -0700
commit65853330926fa5c77ad75effab8c479ba1d96952 (patch)
treeb2bd8f865401a8d7c4ce9f78b94f34bfb778dbaf /src/spawn_players.c
parent02ad54ca72f5baf4614cb9b7c30f8dd780764d90 (diff)
Camera Refactor --> Adds Track Tour Camera (#568)
* Impl SpawnParams * Added json submodule * Update json * Update * Works * Remove comment * Works refactor * Snowman and thwomp working * Impl hot air balloon * More progress * All OObjects are done * cleanup * Refactor 2Dpath to normal path * Update nlohmann json & fix compile * Rest of actors * MORE CHANGES * Finish actors * Done PR, some fix to collision viewer * Impl falling rocks * Add const * wip editor refactor * Property work * continue * Overridable editor properties * Actor saving/loading works now * Fix light alignment * Clarification * Impl penguin * params impl signs * properties impl falling rock * More property impls * impl air balloon * Add spawnParams to OObject Translate * Snowman translate better * impl hedgehog properly * properties impl trophy * thwomp progress * Finish impl properties * Fix compile * Fix cursor collisions * Move registered actors * Rename pathPoint XYZ to xyz * Fix editor pause bug * Clean up * Review comments * Remove SpawnParams struct from actor classes * Rename * Player Label First Iteration * Work now * Working 3d text * Fix boo bug * Finish AText actor * Fix spawnparams compile * Register AText * Finish Text Actor * Fix thwomp interpolation * Fix compile * Fix crab and hedgehog * Fix loading flagpole * Fix Hot Air Balloon * Turn zbuffer on for AText * Update * Camera Refactor * Camera Refactor Complete * Place Lookbehind behind a CVar * Make Tour CVar * Fix Tour Camera Billboarding * micro optimization * Impl tour cam in imgui editor and add to scenefile * As per review * Revert cleanWorld change as per review * Cleanup SceneManager * Func rename * Proper enabling of freecam and wip zoom fix * Couple fix * Fix credits * Fix podium ceremony * Stop music on reset & label new play sequence func * Rename func_800C8EF8 to play_sequence2 * Rename func_800CA414 to play_sequences * Fix compile * Label play_sequences * Clean up * Verify lakitu access * Renames * Fix tour enable logic * Add Audio * tour camera impl ending transition * As per review * Fix linux compile, probably * Update TourCamera.cpp * Update TourCamera.cpp * Update TrackProperties.cpp * Update TrackProperties.cpp * Update Game.cpp * Update SceneManager.cpp * Update camera.c * Update render_objects.h * Update render_objects.h * Update code_80057C60.h * fixing compile * addition --------- Co-authored-by: MegaMech <7255464+MegaMech@users.noreply.github.com>
Diffstat (limited to 'src/spawn_players.c')
-rw-r--r--src/spawn_players.c280
1 files changed, 144 insertions, 136 deletions
diff --git a/src/spawn_players.c b/src/spawn_players.c
index 464049043..cf85a2fd2 100644
--- a/src/spawn_players.c
+++ b/src/spawn_players.c
@@ -868,16 +868,25 @@ void func_8003BE30(void) {
}
void func_8003C0F0(void) {
+ if (gModeSelection == BATTLE) {
+ func_8000EEDC();
+ } else if (!IsPodiumCeremony()) {
+ init_course_path_point();
+ }
+
+ // The tour delays player spawning until the end of the tour
+ if ((CM_IsTourEnabled() == false) || (gIsEditorPaused == true)) {
+ spawn_and_set_player_spawns();
+ }
+}
+
+void spawn_and_set_player_spawns(void) {
s16 sp5E;
s16 sp5C;
s16 sp5A = 0;
s32 temp;
- UNUSED s32 pad[4];
- if (gModeSelection == BATTLE) {
- func_8000EEDC();
- } else if (!IsPodiumCeremony()) {
- init_course_path_point();
+ if ((!IsPodiumCeremony()) && (gModeSelection != BATTLE)) {
sp5E = (f32) gTrackPaths[0][0].x;
sp5C = (f32) gTrackPaths[0][0].z;
sp5A = (f32) gTrackPaths[0][0].y;
@@ -1172,174 +1181,173 @@ void func_8003CD98(Player* player, Camera* camera, s8 playerId, s8 screenId) {
}
}
-void func_8003D080(void) {
+void spawn_players_and_cameras(void) {
UNUSED s32 pad;
Player* player = &gPlayers[0];
+ Camera* camera;
+ // Load textures for balloons and kart shadows
func_8005D290();
+ // Spawn players
if (gGamestate == ENDING) {
func_8003CD78();
} else {
func_8003C0F0();
}
- if (!gDemoMode) {
- switch (gActiveScreenMode) {
- case SCREEN_MODE_1P:
- switch (gModeSelection) {
- case GRAND_PRIX:
- if (IsToadsTurnpike()) {
- camera_init(0.0f, player->pos[1], D_80165230[7], player->rotation[1], 8, 0);
- } else {
- camera_init((D_80165210[7] + D_80165210[6]) / 2, player->pos[1], D_80165230[7],
- player->rotation[1], 8, 0);
- }
- break;
+ u32 mode; // set camera mode
+ switch (gModeSelection) {
+ case GRAND_PRIX:
+ if (gActiveScreenMode == SCREEN_MODE_1P) {
+ mode = 8;
+ } else {
+ mode = 1;
+ }
+ break;
+ case TIME_TRIALS:
+ mode = 1;
+ break;
+ case BATTLE:
+ mode = 9;
+ break;
+ default:
+ mode = 1;
+ break;
+ }
- case TIME_TRIALS:
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 0);
- break;
+ if (gDemoMode) {
+ mode = 3;
+ }
- default:
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 10, 0);
- break;
- }
- break;
+ for (size_t i = 0; i < 4; i++) {
+ D_80164A08[i] = 0;
+ D_80164498[i] = 0;
+ }
- case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL:
- case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL:
- switch (gModeSelection) {
- case GRAND_PRIX:
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 0);
- player++;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 1);
- break;
+ if (gActiveScreenMode == SCREEN_MODE_1P) {
+ spawn_single_player_camera(mode);
+ } else {
+ spawn_multiplayer_cameras(mode);
+ }
- case BATTLE:
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 9, 0);
- player++;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 9, 1);
- break;
+ // Add freecam, tourcam, and lookbehind cameras
+ Vec3f spawn = {player->pos[0], player->pos[1], player->pos[2]};
- default:
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 0);
- player++;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 1);
- break;
- }
- break;
- case SCREEN_MODE_3P_4P_SPLITSCREEN:
- if (gModeSelection == BATTLE) {
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 9, 0);
- player++;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 9, 1);
- player++;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 9, 2);
- if (gPlayerCountSelection1 == 4) {
- player++;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 9, 3);
- }
- } else {
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 0);
- player++;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 1);
- player++;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 2);
- if (gPlayerCountSelection1 == 4) {
- player++;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 3);
- }
- }
- break;
+ camera = CM_AddFreeCamera(spawn, player->rotation[1], 1);
+ D_8015F480[PLAYER_ONE].freeCamera = camera;
+
+ if (CVarGetInteger("gFreecam", false) == true) {
+ CM_SetFreeCamera(true);
+ D_8015F480[PLAYER_ONE].camera = camera;
+ }
+
+ if ((CM_IsTourEnabled() == true) && (gModeSelection == GRAND_PRIX) && (gIsEditorPaused == false)) {
+ camera = CM_AddTourCamera(spawn, player->rotation[1], 1);
+ if (NULL != camera) {
+ CM_AttachCamera(camera, PLAYER_ONE);
+ D_8015F480[PLAYER_ONE].camera = camera;
+ D_8015F480[PLAYER_ONE].pendingCamera = NULL;
+ CM_CameraSetActive(0, false);
+ CM_ActivateTourCamera(camera);
}
- } else {
- switch (gActiveScreenMode) {
- case SCREEN_MODE_1P:
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 3, 0);
- break;
+ }
+}
- case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL:
- case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL:
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 3, 0);
- player++;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 3, 1);
- break;
+void spawn_single_player_camera(u32 mode) {
+ Vec3f spawn = {gPlayerOne->pos[0], gPlayerOne->pos[1], gPlayerOne->pos[2]};
+
+ // Technically there should be a default case of mode 10 here. Except it never gets used.
+ if (gModeSelection == GRAND_PRIX && !gDemoMode) {
+ if (IsToadsTurnpike()) {
+ spawn[0] = 0.0f;
+ spawn[2] = D_80165230[7];
+ } else {
+ spawn[0] = (D_80165210[7] + D_80165210[6]) / 2;
+ spawn[2] = D_80165230[7];
- case SCREEN_MODE_3P_4P_SPLITSCREEN:
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 3, 0);
- player++;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 3, 1);
- player++;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 3, 2);
- player++;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 3, 3);
- break;
}
}
- // Init freecam
- freecam_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 4);
+ Camera* camera = CM_AddCamera(spawn, gPlayerOne->rotation[1], mode);
+ if (camera) {
+ CM_AttachCamera(camera, PLAYER_ONE);
+ D_8015F480[PLAYER_ONE].camera = camera;
+ D_8015F480[PLAYER_ONE].raceCamera = camera;
+ }
- switch (gActiveScreenMode) {
+ camera = CM_AddLookBehindCamera(spawn, gPlayerOne->rotation[1], mode);
+ if (camera) {
+ CM_AttachCamera(camera, PLAYER_ONE);
+ D_8015F480[PLAYER_ONE].lookBehindCamera = camera;
+ }
+}
+
+void spawn_multiplayer_cameras(u32 mode) {
+ Camera* camera;
+ for (size_t i = 0; i < gPlayerCountSelection1; i++) {
+ Vec3f spawn = {gPlayers[i].pos[0], gPlayers[i].pos[1], gPlayers[i].pos[2]};
+ camera = CM_AddCamera(spawn, gPlayers[i].rotation[1], mode);
+ if (camera) {
+ CM_AttachCamera(camera, i);
+ D_8015F480[i].camera = camera;
+ D_8015F480[i].raceCamera = camera;
+ }
+
+ }
+
+ for (size_t i = 0; i < gPlayerCountSelection1; i++) {
+ Vec3f spawn = {gPlayers[i].pos[0], gPlayers[i].pos[1], gPlayers[i].pos[2]};
+ camera = CM_AddLookBehindCamera(spawn, gPlayers[i].rotation[1], mode);
+ if (camera) {
+ CM_AttachCamera(camera, i);
+ D_8015F480[i].lookBehindCamera = camera;
+ }
+ }
+
+}
+
+/**
+ * Loads 8 players per screen in 1p/2p mode
+ * Loads 4 players per screen in 3p/4p mode
+ */
+void load_kart_textures(void) {
+ size_t screens = 0;
+ switch(gActiveScreenMode) {
case SCREEN_MODE_1P:
- func_8003CD98(gPlayerOne, camera1, 0, 0); // sic
- func_8003CD98(gPlayerTwo, camera1, 1, 0);
- func_8003CD98(gPlayerThree, camera1, 2, 0);
- func_8003CD98(gPlayerFour, camera1, 3, 0);
- func_8003CD98(gPlayerFive, camera1, 4, 0);
- func_8003CD98(gPlayerSix, camera1, 5, 0);
- func_8003CD98(gPlayerSeven, camera1, 6, 0);
- func_8003CD98(gPlayerEight, camera1, 7, 0);
+ screens = 1;
break;
-
case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL:
case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL:
- func_8003CD98(gPlayerOne, camera1, 0, 0);
- func_8003CD98(gPlayerTwo, camera1, 1, 0);
- func_8003CD98(gPlayerThree, camera1, 2, 0);
- func_8003CD98(gPlayerFour, camera1, 3, 0);
- func_8003CD98(gPlayerFive, camera1, 4, 0);
- func_8003CD98(gPlayerSix, camera1, 5, 0);
- func_8003CD98(gPlayerSeven, camera1, 6, 0);
- func_8003CD98(gPlayerEight, camera1, 7, 0);
- func_8003CD98(gPlayerOne, camera2, 0, 1);
- func_8003CD98(gPlayerTwo, camera2, 1, 1);
- func_8003CD98(gPlayerThree, camera2, 2, 1);
- func_8003CD98(gPlayerFour, camera2, 3, 1);
- func_8003CD98(gPlayerFive, camera2, 4, 1);
- func_8003CD98(gPlayerSix, camera2, 5, 1);
- func_8003CD98(gPlayerSeven, camera2, 6, 1);
- func_8003CD98(gPlayerEight, camera2, 7, 1);
+ screens = 2;
break;
-
case SCREEN_MODE_3P_4P_SPLITSCREEN:
- func_8003CD98(gPlayerOne, camera1, 0, 0);
- func_8003CD98(gPlayerTwo, camera1, 1, 0);
- func_8003CD98(gPlayerThree, camera1, 2, 0);
- func_8003CD98(gPlayerFour, camera1, 3, 0);
- func_8003CD98(gPlayerOne, camera2, 0, 1);
- func_8003CD98(gPlayerTwo, camera2, 1, 1);
- func_8003CD98(gPlayerThree, camera2, 2, 1);
- func_8003CD98(gPlayerFour, camera2, 3, 1);
- func_8003CD98(gPlayerOne, camera3, 0, 2);
- func_8003CD98(gPlayerTwo, camera3, 1, 2);
- func_8003CD98(gPlayerThree, camera3, 2, 2);
- func_8003CD98(gPlayerFour, camera3, 3, 2);
- func_8003CD98(gPlayerOne, camera4, 0, 3);
- func_8003CD98(gPlayerTwo, camera4, 1, 3);
- func_8003CD98(gPlayerThree, camera4, 2, 3);
- func_8003CD98(gPlayerFour, camera4, 3, 3);
+ screens = 4;
break;
}
+
+ static const size_t playerCounts[4] = { 8, 8, 4, 4 };
+ for (size_t i = 0; i < screens; i++) {
+ for (size_t ply = 0; ply < playerCounts[i]; ply++) {
+ func_8003CD98(&gPlayers[ply], D_8015F480[i].camera, ply, i);
+ }
+ }
}
void func_8003DB5C(void) {
Player* player = gPlayerOne;
+ Camera* camera;
s32 playerId;
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 3, 0);
- camera_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 3, 1);
+ Vec3f spawn = {player->pos[0], player->pos[1], player->pos[2]};
+ camera = CM_AddCamera(spawn, player->rotation[1], 3);
+ if (camera) {
+ CM_AttachCamera(camera, PLAYER_ONE);
+ }
+ camera = CM_AddCamera(spawn, player->rotation[1], 3);
+ if (camera) {
+ CM_AttachCamera(camera, PLAYER_ONE);
+ }
for (playerId = 0; playerId < NUM_PLAYERS; playerId++, player++) {
load_kart_palette(player, playerId, 1, 0);