diff options
| author | MegaMech <MegaMech@users.noreply.github.com> | 2025-12-07 13:14:45 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-12-07 13:14:45 -0700 |
| commit | 65853330926fa5c77ad75effab8c479ba1d96952 (patch) | |
| tree | b2bd8f865401a8d7c4ce9f78b94f34bfb778dbaf /src/spawn_players.c | |
| parent | 02ad54ca72f5baf4614cb9b7c30f8dd780764d90 (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.c | 280 |
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); |
