From 548ccf0063f6c4d6608cf87f46a347c71079c0bd Mon Sep 17 00:00:00 2001 From: MegaMech Date: Tue, 24 Feb 2026 14:51:25 -0700 Subject: [PATCH] Impl Sky and SkyActors (#630) * Create Cloud.cpp * Create Cloud.h * Fix the cloud * Cleanup * More cleanup * Update Track.h * Refactor SkyboxCloud position calculations * Update SkyboxStar.cpp * Update SkyboxStar.cpp * Refactor SkyboxStar.cpp by removing redundant code * Update SkyboxCloud.cpp * Refactor SkyboxSnow.cpp by reordering includes * Update SkyboxCloud.h * Refactor SkyboxStar.h for improved formatting * Impl skyboxcloud * Update comment * update comment * Work now * Fully impl Sky * Fix define * Fix args --- CMakeLists.txt | 6 + include/actor_types.h | 4 +- include/defines.h | 9 - include/objects.h | 2 +- src/code_800029B0.c | 2 +- src/code_800029B0.h | 8 +- src/code_80057C60.c | 54 ++-- src/code_80057C60.h | 2 +- src/code_8006E9C0.c | 27 +- src/code_8006E9C0.h | 4 +- src/code_80086E70.c | 5 - src/code_80086E70.h | 1 - src/ending/code_80280000.c | 20 +- src/ending/code_80281780.c | 2 +- src/ending/code_80281C40.c | 6 +- src/engine/AllTracks.h | 1 + src/engine/TrackBrowser.h | 17 ++ src/engine/World.cpp | 2 + src/engine/World.h | 3 +- src/engine/objects/Boos.cpp | 1 + src/engine/registry/RegisterTracks.cpp | 9 + src/engine/sky/Sky.cpp | 350 +++++++++++++++++++++++++ src/engine/sky/Sky.h | 43 +++ src/engine/sky/SkyActor.h | 45 ++++ src/engine/sky/SkyCloud.cpp | 112 ++++++++ src/engine/sky/SkyCloud.h | 35 +++ src/engine/sky/SkySnow.cpp | 183 +++++++++++++ src/engine/sky/SkySnow.h | 49 ++++ src/engine/sky/SkyStar.cpp | 165 ++++++++++++ src/engine/sky/SkyStar.h | 48 ++++ src/engine/tracks/BansheeBoardwalk.h | 1 - src/engine/tracks/BowsersCastle.h | 1 - src/engine/tracks/DKJungle.h | 1 - src/engine/tracks/FrappeSnowland.cpp | 21 +- src/engine/tracks/FrappeSnowland.h | 2 - src/engine/tracks/PodiumCeremony.cpp | 1 + src/engine/tracks/PodiumCeremony.h | 3 - src/engine/tracks/RainbowRoad.cpp | 9 +- src/engine/tracks/RainbowRoad.h | 2 - src/engine/tracks/Skyscraper.h | 1 - src/engine/tracks/ToadsTurnpike.cpp | 9 +- src/engine/tracks/ToadsTurnpike.h | 2 - src/engine/tracks/Track.cpp | 22 +- src/engine/tracks/Track.h | 12 +- src/engine/tracks/WarioStadium.cpp | 9 +- src/engine/tracks/WarioStadium.h | 2 - src/main.c | 51 ++-- src/port/Game.cpp | 23 +- src/port/Game.h | 4 +- src/port/ui/ContentBrowser.cpp | 5 + src/port/ui/PortMenu.cpp | 8 + src/racing/actors.c | 1 - src/racing/race_logic.c | 8 +- src/racing/skybox_and_splitscreen.c | 308 ++++++---------------- src/racing/skybox_and_splitscreen.h | 25 +- src/render_objects.c | 127 ++------- src/render_objects.h | 17 +- src/update_objects.c | 232 +--------------- src/update_objects.h | 9 +- 59 files changed, 1346 insertions(+), 785 deletions(-) create mode 100644 src/engine/sky/Sky.cpp create mode 100644 src/engine/sky/Sky.h create mode 100644 src/engine/sky/SkyActor.h create mode 100644 src/engine/sky/SkyCloud.cpp create mode 100644 src/engine/sky/SkyCloud.h create mode 100644 src/engine/sky/SkySnow.cpp create mode 100644 src/engine/sky/SkySnow.h create mode 100644 src/engine/sky/SkyStar.cpp create mode 100644 src/engine/sky/SkyStar.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c4870b59b..277d34612 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -224,7 +224,9 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/src/debug ${CMAKE_CURRENT_SOURCE_DIR}/src/engine ${CMAKE_CURRENT_SOURCE_DIR}/src/engine/tracks + ${CMAKE_CURRENT_SOURCE_DIR}/src/engine/actors ${CMAKE_CURRENT_SOURCE_DIR}/src/engine/objects + ${CMAKE_CURRENT_SOURCE_DIR}/src/engine/sky ${CMAKE_CURRENT_SOURCE_DIR}/src/engine/particles ${CMAKE_CURRENT_SOURCE_DIR}/src/enhancements ${CMAKE_CURRENT_SOURCE_DIR}/src/enhancements/freecam @@ -272,8 +274,12 @@ file(GLOB_RECURSE ALL_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/engine/*.h" "src/engine/tracks/*.c" "src/engine/tracks/*.h" + "src/engine/actors/*.cpp" + "src/engine/actors/*.h" "src/engine/objects/*.cpp" "src/engine/objects/*.h" + "src/engine/sky/*.cpp" + "src/engine/sky/*.h" "src/engine/particles/*.cpp" "src/engine/particles/*.h" "src/enhancements/*.c" diff --git a/include/actor_types.h b/include/actor_types.h index 2e4c47087..947c78288 100644 --- a/include/actor_types.h +++ b/include/actor_types.h @@ -83,10 +83,8 @@ enum ActorType { ACTOR_CAR, ACTOR_KIWANO_FRUIT }; -size_t CM_GetActorSize(void); -#define ACTOR_LIST_SIZE CM_GetActorSize() -struct Actor* CM_GetActor(size_t); +#define ACTOR_LIST_SIZE CM_GetActorSize() #define GET_ACTOR(index) CM_GetActor(index) // Actor flags diff --git a/include/defines.h b/include/defines.h index 0d823a4b5..942271c11 100644 --- a/include/defines.h +++ b/include/defines.h @@ -124,15 +124,6 @@ #define FOUR_PLAYERS_SELECTED 4 #define SELECTED_PLAYER_DEFINES_TOTAL 5 -// Camera index into cameras array -enum CameraId { - CAMERA_ONE = 0, - CAMERA_TWO, - CAMERA_THREE, - CAMERA_FOUR, - CAMERA_FREECAM -}; - enum PlayerId { PLAYER_NONE = -1, PLAYER_ONE = 0, diff --git a/include/objects.h b/include/objects.h index 2862b7587..d6535dd06 100644 --- a/include/objects.h +++ b/include/objects.h @@ -421,7 +421,7 @@ extern s32 gNextFreeLeafParticle; // See `func_800704A0` and `func_800703E0` for star initialization typedef struct { // rotY and posY seem relative to the camera. - // See `func_800788F8` to see how rotY is used to decide whether and where to display clouds/stars + // See `func_800788F8` (SkyCloud Tick2 now) to see how rotY is used to decide whether and where to display clouds/stars // See `func_80078A44` and `func_800789AC` to see how stars and clouds (respectively) are looped over /* 0x00 */ u16 rotY; /* 0x02 */ u16 posY; diff --git a/src/code_800029B0.c b/src/code_800029B0.c index a2402080f..42f9c279a 100644 --- a/src/code_800029B0.c +++ b/src/code_800029B0.c @@ -37,7 +37,7 @@ uintptr_t gCurrentlyLoadedTrackAddr = NULL; u16 D_800DC5A8 = 0; s32 D_800DC5AC = 0; u16 D_800DC5B0 = 1; -u16 D_800DC5B4 = 0; +bool bDrawSkybox = false; u16 D_800DC5B8 = 0; bool bFog = false; u16 gIsInQuitToMenuTransition = 0; diff --git a/src/code_800029B0.h b/src/code_800029B0.h index 1809fe665..4ea0028da 100644 --- a/src/code_800029B0.h +++ b/src/code_800029B0.h @@ -5,7 +5,11 @@ #include #include #include "camera.h" -#include "engine/CoreMath.h" + +/** + * To include in C++, you must include libultraship.h + * and place this file in extern "C" + */ typedef struct { /* 0x00 */ struct Controller* controllers; // gControllers ptr 800F6910 @@ -45,7 +49,7 @@ extern uintptr_t gCurrentlyLoadedTrackAddr; extern u16 D_800DC5A8; extern s32 D_800DC5AC; extern u16 D_800DC5B0; -extern u16 D_800DC5B4; +extern bool bDrawSkybox; extern u16 D_800DC5B8; extern bool bFog; extern u16 gIsInQuitToMenuTransition; diff --git a/src/code_80057C60.c b/src/code_80057C60.c index b7aaa3342..948285d77 100644 --- a/src/code_80057C60.c +++ b/src/code_80057C60.c @@ -412,31 +412,31 @@ void func_80057C60(void) { void func_80057CE4(void) { switch (D_8018D21C) { case 0: - func_802A3730(gScreenOneCtx); + race_set_viewport(gScreenOneCtx); break; case 1: - func_802A3730(gScreenOneCtx); + race_set_viewport(gScreenOneCtx); break; case 2: - func_802A3730(gScreenTwoCtx); + race_set_viewport(gScreenTwoCtx); break; case 3: - func_802A3730(gScreenOneCtx); + race_set_viewport(gScreenOneCtx); break; case 4: - func_802A3730(gScreenTwoCtx); + race_set_viewport(gScreenTwoCtx); break; case 8: - func_802A3730(gScreenOneCtx); + race_set_viewport(gScreenOneCtx); break; case 9: - func_802A3730(gScreenTwoCtx); + race_set_viewport(gScreenTwoCtx); break; case 10: - func_802A3730(gScreenThreeCtx); + race_set_viewport(gScreenThreeCtx); break; case 11: - func_802A3730(gScreenFourCtx); + race_set_viewport(gScreenFourCtx); break; } } @@ -458,7 +458,7 @@ void func_80057DD0(void) { } } -void func_80057FC4(u32 arg0) { +void func_80057FC4(ScreenContext* ctx, u32 arg0) { UNUSED Gfx* temp_v1; if ((gHUDDisable != 0)) { @@ -473,19 +473,27 @@ void func_80057FC4(u32 arg0) { switch (arg0) { case 0: - func_80051EBC(); + func_80051EBC(ctx); break; case 1: - func_80051EF8(); + func_80051EF8(ctx); break; case 2: - func_80051F9C(); + func_80051F9C(ctx); break; case 3: - func_80052044(); + func_80052044(ctx); break; case 4: - func_80052080(); + func_80052080(ctx); + break; + case 8: + case 9: + case 10: + case 11: + if (CVarGetInteger("gMultiplayerNoFeatureCuts", 0) == true) { + func_80052080(ctx); + } break; } } @@ -1113,16 +1121,16 @@ void func_80059D00(void) { if (!gDemoMode) { // func_8007AA44(0); } - func_80078C70(0); + func_80078C70(); if (playerHUD[PLAYER_ONE].raceCompleteBool == 0) { func_8005C360((gPlayerOne->speed / 18.0f) * 216.0f); } func_8005D0FC(PLAYER_ONE); } else { func_80059820(PLAYER_ONE); - func_80078C70(1); + func_80078C70(); func_80059820(PLAYER_TWO); - func_80078C70(2); + //func_80078C70(); } break; case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: @@ -1133,14 +1141,14 @@ void func_80059D00(void) { if (!gDemoMode) { // func_8007AA44(0); } - func_80078C70(1); + func_80078C70(); func_8005D1F4(0); func_80059820(PLAYER_TWO); func_8005D0FC(PLAYER_TWO); if (!gDemoMode) { // func_8007AA44(1); } - func_80078C70(2); + //func_80078C70(); func_8005D1F4(1); break; case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: @@ -1151,14 +1159,13 @@ void func_80059D00(void) { if (!gDemoMode) { // func_8007AA44(0); } - func_80078C70(3); + func_80078C70(); func_8005D1F4(0); func_80059820(PLAYER_TWO); func_8005D0FC(PLAYER_TWO); if (!gDemoMode) { // func_8007AA44(1); } - func_80078C70(4); func_8005D1F4(1); break; case SCREEN_MODE_3P_4P_SPLITSCREEN: @@ -1171,6 +1178,7 @@ void func_80059D00(void) { if (!gDemoMode) { // func_8007AA44(0); } + func_80078C70(); func_8005D1F4(0); func_80059820(PLAYER_TWO); func_8005D0FC(PLAYER_TWO); @@ -1217,7 +1225,7 @@ void func_8005A070(void) { CM_TickParticles(); } else if (gGamestate == CREDITS_SEQUENCE) { func_80059820(PLAYER_ONE); - func_80078C70(0); + func_80078C70(); CM_TickObjects(); CM_TickParticles(); } else { // normal gameplay diff --git a/src/code_80057C60.h b/src/code_80057C60.h index fdb650040..3ff6e6681 100644 --- a/src/code_80057C60.h +++ b/src/code_80057C60.h @@ -36,7 +36,7 @@ void func_8005C674(s8, s16*, s16*, s16*); void func_80057C60(void); void func_80057CE4(void); void func_80057DD0(void); -void func_80057FC4(u32); +void func_80057FC4(ScreenContext* screen, u32); void render_object(ScreenContext* screen); void render_player_snow_effect(Camera* camera); diff --git a/src/code_8006E9C0.c b/src/code_8006E9C0.c index fa6a96322..1ffadf8b1 100644 --- a/src/code_8006E9C0.c +++ b/src/code_8006E9C0.c @@ -31,6 +31,7 @@ #include "port/Engine.h" #include "engine/editor/Editor.h" #include "engine/tracks/Track.h" +#include "engine/sky/Sky.h" void init_hud(void) { @@ -613,11 +614,11 @@ void init_stars(StarData* starList) { D_8018D230 = 1; } -void func_8007055C(void) { +void func_8007055C(ScreenContext* screen) { s32 var_s0; s32 var_s4; - CM_InitClouds(); + InitSkyActors(screen); func_8008C23C(); } @@ -656,8 +657,8 @@ void init_hud_one_player(void) { find_unused_obj_index(&gItemWindowObjectByPlayerId[0]); find_unused_obj_index(&gItemWindowObjectByPlayerId[1]); init_object_list_index(); - func_8007055C(); - func_8007055C(); + func_8007055C(gScreenOneCtx); + func_8007055C(gScreenTwoCtx); init_course_object(); playerHUD[PLAYER_ONE].speedometerX = 0x0156; playerHUD[PLAYER_ONE].speedometerY = 0x0106; @@ -734,8 +735,8 @@ void init_hud_two_player_vertical(void) { find_unused_obj_index(&gItemWindowObjectByPlayerId[1]); init_object_list_index(); - func_8007055C(); - func_8007055C(); + func_8007055C(gScreenOneCtx); + func_8007055C(gScreenTwoCtx); init_course_object(); playerHUD[PLAYER_ONE].itemBoxX = -0x52; @@ -799,8 +800,8 @@ void init_hud_two_player_horizontal() { find_unused_obj_index(&gItemWindowObjectByPlayerId[1]); init_object_list_index(); - func_8007055C(); - func_8007055C(); + func_8007055C(gScreenOneCtx); + func_8007055C(gScreenTwoCtx); init_course_object(); playerHUD[PLAYER_ONE].itemBoxY = 0x22; @@ -872,6 +873,16 @@ void init_hud_three_four_player(void) { find_unused_obj_index(&gItemWindowObjectByPlayerId[3]); init_object_list_index(); + + if (CVarGetInteger("gMultiplayerNoFeatureCuts", false) == true) { + func_8007055C(gScreenOneCtx); + func_8007055C(gScreenTwoCtx); + func_8007055C(gScreenThreeCtx); + if (gPlayerCountSelection1 == 4) { + func_8007055C(gScreenFourCtx); + } + } + init_course_object(); playerHUD[PLAYER_ONE].itemBoxX = -0x36; diff --git a/src/code_8006E9C0.h b/src/code_8006E9C0.h index e41f7da1e..6859f71ac 100644 --- a/src/code_8006E9C0.h +++ b/src/code_8006E9C0.h @@ -23,7 +23,7 @@ void init_cloud_object(s32, s32, CloudData*); void init_clouds(CloudData*); void init_star_object(s32, s32, StarData*); void init_stars(StarData*); -void func_8007055C(void); +void func_8007055C(ScreenContext* screen); void func_80070714(void); void init_course_object(void); void init_hud_one_player(void); @@ -31,6 +31,8 @@ void init_hud_two_player_vertical(void); void init_hud_three_four_player(void); void init_hud_two_player_horizontal(void); +extern Vtx cloudvtx[4][4]; +extern Vtx cloudvtx2[3][4]; extern s16 D_800E5520[]; extern u8* gCourseOutlineTextures[0x14]; // 800e54d0 diff --git a/src/code_80086E70.c b/src/code_80086E70.c index 4c94b3fcf..00c3fcffd 100644 --- a/src/code_80086E70.c +++ b/src/code_80086E70.c @@ -1946,11 +1946,6 @@ void func_8008BF64(s32 objectIndex) { D_80183E80[2] = object->direction_angle[2]; } -void func_8008BFC0(s32 objectIndex) { - gObjectList[objectIndex].unk_09C = gObjectList[objectIndex].pos[0]; - gObjectList[objectIndex].unk_09E = gObjectList[objectIndex].pos[1]; -} - void func_8008BFFC(s32 objectIndex) { Object* object; diff --git a/src/code_80086E70.h b/src/code_80086E70.h index f921405a2..3348d6e16 100644 --- a/src/code_80086E70.h +++ b/src/code_80086E70.h @@ -159,7 +159,6 @@ void object_origin_pos_randomize_around_xz(s32, s16, s16, u16, u16); void object_origin_pos_randomize_around_xyz(s32, s16, s16, s16, u16, u16, u16); void object_origin_pos_around_player_one(s32, s16, u16); void func_8008BEA4(s32, u16, u16); -void func_8008BFC0(s32); void object_calculate_new_pos_offset(s32); void func_8008BF64(s32); void func_8008BFFC(s32); diff --git a/src/ending/code_80280000.c b/src/ending/code_80280000.c index 134083225..13f8cdb1b 100644 --- a/src/ending/code_80280000.c +++ b/src/ending/code_80280000.c @@ -52,9 +52,13 @@ void func_80280038(Camera* camera) { gMatrixEffectCount = 0; gMatrixHudCount = 0; init_rdp(); - func_802A53A4(); + race_begin_viewport(gScreenOneCtx, 0); + if ((CVarGetInteger("gDrawSky", true) == true)) { + CM_RaceDrawSky(gScreenOneCtx, 0); + func_80093A30(0); // Fill box for thunderbolt? + } init_rdp(); - func_80057FC4(0); + func_80057FC4(gScreenOneCtx, 0); gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); guPerspective(camera->perspectiveMatrix , &perspNorm, camera->fieldOfView, gScreenAspect, CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); @@ -140,16 +144,24 @@ void load_credits(void) { if (!camera) { CM_ThrowRuntimeError("[code_80280000] [load_credits] NULL camera while attempting to create camera for player one"); } - CM_AttachCamera(camera, PLAYER_ONE); gScreenOneCtx->camera = camera; + + // init_hud_one_player uses a second camera for whatever reason... + Camera* camera2 = CM_AddCamera(spawn, 0, 0); + if (!camera2) { + CM_ThrowRuntimeError("[code_80280000] [load_credits] NULL camera while attempting to create camera for player two"); + } + CM_AttachCamera(camera2, PLAYER_TWO); + gScreenTwoCtx->camera = camera2; + camera->renderMode = RENDER_FULL_SCENE; camera->unk_B4 = 60.0f; camera->fieldOfView = 60.0f; gCurrentCourseId = gCreditsCourseId; TrackBrowser_SetTrackByIdx(gCreditsCourseId); - D_800DC5B4 = 1; + bDrawSkybox = true; func_802A4D18(); set_screen(); gScreenOneCtx->screenWidth = SCREEN_WIDTH; diff --git a/src/ending/code_80281780.c b/src/ending/code_80281780.c index 3876fbc79..37de7df73 100644 --- a/src/ending/code_80281780.c +++ b/src/ending/code_80281780.c @@ -99,7 +99,7 @@ void setup_podium_ceremony(void) { gCurrentCourseId = TRACK_ROYAL_RACEWAY; SelectPodiumCeremony(); - D_800DC5B4 = (u16) 1; + bDrawSkybox = true; set_mirror_mode(0); gGotoMenu = 0xFFFF; D_80287554 = 0; diff --git a/src/ending/code_80281C40.c b/src/ending/code_80281C40.c index d22ac69e5..d265f8824 100644 --- a/src/ending/code_80281C40.c +++ b/src/ending/code_80281C40.c @@ -61,7 +61,11 @@ void func_80281D00(void) { Mat4 matrix; UNUSED s32 pad2[3]; - func_802A53A4(); + race_begin_viewport(gScreenOneCtx, 0); + if ((CVarGetInteger("gDrawSky", true) == true)) { + CM_RaceDrawSky(gScreenOneCtx, 0); + func_80093A30(0); // Fill box for thunderbolt? + } init_rdp(); if (gGotoMenu != 0xFFFF) { clear_framebuffer(0); diff --git a/src/engine/AllTracks.h b/src/engine/AllTracks.h index d8b55d1f8..fb5827e1e 100644 --- a/src/engine/AllTracks.h +++ b/src/engine/AllTracks.h @@ -21,5 +21,6 @@ #include "engine/tracks/DoubleDeck.h" #include "engine/tracks/DKJungle.h" #include "engine/tracks/BigDonut.h" +#include "engine/tracks/PodiumCeremony.h" #include "engine/tracks/TestTrack.h" diff --git a/src/engine/TrackBrowser.h b/src/engine/TrackBrowser.h index 4bcccf16f..89dec2f00 100644 --- a/src/engine/TrackBrowser.h +++ b/src/engine/TrackBrowser.h @@ -21,6 +21,9 @@ public: TrackBrowser(const Registry& registry) { mTracks = registry.GetAllInfo(); + + RemovePodiumCeremony(); + std::sort(mTracks.begin(), mTracks.end(), [](const TrackInfo* a, const TrackInfo* b) { return a->Id < b->Id; }); @@ -32,6 +35,9 @@ public: void Refresh(const Registry& registry) { mTracks.clear(); mTracks = registry.GetAllInfo(); + + RemovePodiumCeremony(); + std::sort(mTracks.begin(), mTracks.end(), [](const TrackInfo* a, const TrackInfo* b) { return a->Id < b->Id; }); @@ -42,6 +48,17 @@ public: mTrackIndex = 0; } + // Podium is not a valid user selectable option in the menus, remove it. + void RemovePodiumCeremony() { + mTracks.erase( + std::remove_if(mTracks.begin(), mTracks.end(), + [](const TrackInfo* track) { + return track && track->ResourceName == "mk:podium_ceremony"; + }), + mTracks.end() + ); + } + void SetTrack(std::string name) { if (gTrackRegistry.Find(name)) { gTrackRegistry.Invoke(name); diff --git a/src/engine/World.cpp b/src/engine/World.cpp index bc6cbfc1b..d1619ae18 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -6,6 +6,7 @@ #include #include "objects/Object.h" #include "port/Game.h" +#include "engine/sky/Sky.h" extern "C" { #include "objects.h" @@ -270,4 +271,5 @@ void World::CleanWorld(void) { Objects.clear(); Emitters.clear(); Lakitus.clear(); + Sky::Instance->GetSkyActors().clear(); } diff --git a/src/engine/World.h b/src/engine/World.h index db782eccf..96b620bb6 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -16,6 +16,7 @@ #include "Actor.h" #include "StaticMeshActor.h" #include "particles/ParticleEmitter.h" +#include "engine/sky/SkyCloud.h" #include "editor/Editor.h" #include "editor/GameObject.h" @@ -119,7 +120,7 @@ public: std::vector> StaticMeshActors; std::vector> Actors; - std::vector> Objects; + std::deque> Objects; std::vector> Emitters; std::unordered_map Lakitus; diff --git a/src/engine/objects/Boos.cpp b/src/engine/objects/Boos.cpp index 20b16355e..f05d62be1 100644 --- a/src/engine/objects/Boos.cpp +++ b/src/engine/objects/Boos.cpp @@ -20,6 +20,7 @@ extern "C" { #include "menus.h" #include "race_logic.h" #include "external.h" +#include "some_data.h" } size_t OBoos::_count = 0; diff --git a/src/engine/registry/RegisterTracks.cpp b/src/engine/registry/RegisterTracks.cpp index 47a6a6ff2..a347e907f 100644 --- a/src/engine/registry/RegisterTracks.cpp +++ b/src/engine/registry/RegisterTracks.cpp @@ -213,6 +213,15 @@ void RegisterTracks(Registry& r) { r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique()); }); + info = { + .ResourceName = "mk:podium_ceremony", + .Name = "podium ceremony", + .DebugName = "podium", + .Length = "1025m", + }; + + r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique()); }); + info = { .ResourceName = "hm:test_track", .Name = "test track", diff --git a/src/engine/sky/Sky.cpp b/src/engine/sky/Sky.cpp new file mode 100644 index 000000000..a7b1f0676 --- /dev/null +++ b/src/engine/sky/Sky.cpp @@ -0,0 +1,350 @@ +#include "Sky.h" + +#include +#include +#include "port/Engine.h" +#include "port/Game.h" + +#include "engine/CoreMath.h" +#include "engine/tracks/Track.h" + +#include "engine/sky/SkyCloud.h" +#include "engine/sky/SkySnow.h" +#include "engine/sky/SkyStar.h" + +extern "C" { +#include "macros.h" +#include "mk64.h" +#include "math_util.h" +#include "skybox_and_splitscreen.h" +#include "menus.h" +} + +Vtx Sky::mSkyboxScreenOne[8] = { // D_802B8890 + { { { SCREEN_WIDTH, SCREEN_HEIGHT, -1 }, 0, { 0, 0 }, { 0xC8, 0xC8, 0xFF, 0xFF } } }, + { { { SCREEN_WIDTH, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, + { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, + { { { 0, SCREEN_HEIGHT, -1 }, 0, { 0, 0 }, { 0xC8, 0xC8, 0xFF, 0xFF } } }, + { { { SCREEN_WIDTH, 120, -1 }, 0, { 0, 0 }, { 0x00, 0xDC, 0x00, 0xFF } } }, + { { { SCREEN_WIDTH, 0, -1 }, 0, { 0, 0 }, { 0x78, 0xFF, 0x78, 0xFF } } }, + { { { 0, 0, -1 }, 0, { 0, 0 }, { 0x78, 0xFF, 0x78, 0xFF } } }, + { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x00, 0xDC, 0x00, 0xFF } } }, +}; + +Vtx Sky::mSkyboxScreenTwo[8] = { // D_802B8910 + { { { SCREEN_WIDTH, SCREEN_HEIGHT, -1 }, 0, { 0, 0 }, { 0xC8, 0xC8, 0xFF, 0xFF } } }, + { { { SCREEN_WIDTH, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, + { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, + { { { 0, SCREEN_HEIGHT, -1 }, 0, { 0, 0 }, { 0xC8, 0xC8, 0xFF, 0xFF } } }, + { { { SCREEN_WIDTH, 120, -1 }, 0, { 0, 0 }, { 0x00, 0xDC, 0x00, 0xFF } } }, + { { { SCREEN_WIDTH, 0, -1 }, 0, { 0, 0 }, { 0x78, 0xFF, 0x78, 0xFF } } }, + { { { 0, 0, -1 }, 0, { 0, 0 }, { 0x78, 0xFF, 0x78, 0xFF } } }, + { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x00, 0xDC, 0x00, 0xFF } } }, +}; + +Vtx Sky::mSkyboxScreenThree[8] = { // D_802B8990 + { { { SCREEN_WIDTH, SCREEN_HEIGHT, -1 }, 0, { 0, 0 }, { 0xC8, 0xC8, 0xFF, 0xFF } } }, + { { { SCREEN_WIDTH, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, + { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, + { { { 0, SCREEN_HEIGHT, -1 }, 0, { 0, 0 }, { 0xC8, 0xC8, 0xFF, 0xFF } } }, + { { { SCREEN_WIDTH, 120, -1 }, 0, { 0, 0 }, { 0x00, 0xDC, 0x00, 0xFF } } }, + { { { SCREEN_WIDTH, 0, -1 }, 0, { 0, 0 }, { 0x78, 0xFF, 0x78, 0xFF } } }, + { { { 0, 0, -1 }, 0, { 0, 0 }, { 0x78, 0xFF, 0x78, 0xFF } } }, + { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x00, 0xDC, 0x00, 0xFF } } }, +}; + +Vtx Sky::mSkyboxScreenFour[8] = { // D_802B8A10 + { { { SCREEN_WIDTH, SCREEN_HEIGHT, -1 }, 0, { 0, 0 }, { 0xC8, 0xC8, 0xFF, 0xFF } } }, + { { { SCREEN_WIDTH, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, + { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x1E, 0x1E, 0xFF, 0xFF } } }, + { { { 0, SCREEN_HEIGHT, -1 }, 0, { 0, 0 }, { 0xC8, 0xC8, 0xFF, 0xFF } } }, + { { { SCREEN_WIDTH, 120, -1 }, 0, { 0, 0 }, { 0x00, 0xDC, 0x00, 0xFF } } }, + { { { SCREEN_WIDTH, 0, -1 }, 0, { 0, 0 }, { 0x78, 0xFF, 0x78, 0xFF } } }, + { { { 0, 0, -1 }, 0, { 0, 0 }, { 0x78, 0xFF, 0x78, 0xFF } } }, + { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x00, 0xDC, 0x00, 0xFF } } }, +}; + +Sky* Sky::Instance; + +Sky::Sky() { + Instance = this; + guMtxIdent(&mSkyboxMatrix); +} + +Sky* Sky::GetSky() { + return Instance; +} + +std::vector>& Sky::GetSkyActors() { + return mSkyActors; +} + +void Sky::SetColours(Vtx* skybox) { // func_802A450C(Vtx* skybox) + s32 i; + + if (bFog) { + + if (gFogColour.r < 0) { + gFogColour.r = 0; + } + + if (gFogColour.g < 0) { + gFogColour.g = 0; + } + + if (gFogColour.b < 0) { + gFogColour.b = 0; + } + + if (gFogColour.r > 255) { + gFogColour.r = 255; + } + + if (gFogColour.g > 255) { + gFogColour.g = 255; + } + + if (gFogColour.b > 255) { + gFogColour.b = 255; + } + + for (i = 0; i < 8; i++) { + skybox[i].v.cn[0] = (s16) gFogColour.r; + skybox[i].v.cn[1] = (s16) gFogColour.g; + skybox[i].v.cn[2] = (s16) gFogColour.b; + } + return; + } + + SkyboxColours* prop = (SkyboxColours*) &CM_GetProps()->Skybox; + + skybox[0].v.cn[0] = prop->TopRight.r; + skybox[0].v.cn[1] = prop->TopRight.g; + skybox[0].v.cn[2] = prop->TopRight.b; + + skybox[1].v.cn[0] = prop->BottomRight.r; + skybox[1].v.cn[1] = prop->BottomRight.g; + skybox[1].v.cn[2] = prop->BottomRight.b; + + skybox[2].v.cn[0] = prop->BottomLeft.r; + skybox[2].v.cn[1] = prop->BottomLeft.g; + skybox[2].v.cn[2] = prop->BottomLeft.b; + + skybox[3].v.cn[0] = prop->TopLeft.r; + skybox[3].v.cn[1] = prop->TopLeft.g; + skybox[3].v.cn[2] = prop->TopLeft.b; + + // Floor + skybox[4].v.cn[0] = prop->FloorTopRight.r; + skybox[4].v.cn[1] = prop->FloorTopRight.g; + skybox[4].v.cn[2] = prop->FloorTopRight.b; + + skybox[5].v.cn[0] = prop->FloorBottomRight.r; + skybox[5].v.cn[1] = prop->FloorBottomRight.g; + skybox[5].v.cn[2] = prop->FloorBottomRight.b; + + skybox[6].v.cn[0] = prop->FloorBottomLeft.r; + skybox[6].v.cn[1] = prop->FloorBottomLeft.g; + skybox[6].v.cn[2] = prop->FloorBottomLeft.b; + + skybox[7].v.cn[0] = prop->FloorTopLeft.r; + skybox[7].v.cn[1] = prop->FloorTopLeft.g; + skybox[7].v.cn[2] = prop->FloorTopLeft.b; +} + +void Sky::Draw(ScreenContext* screen) { // func_802A4A0C(Vtx* vtx, ScreenContext* screen) + Camera* camera = screen->camera; + s16 temp_t5; + f32 temp_f0; + UNUSED s32 pad[2]; + UNUSED u16 pad2; + u16 sp128; + Mat4 matrix1 = { 0 }; + Mat4 matrix2 = { 0 }; + Mat4 matrix3 = { 0 }; + Vec3f sp5C; + f32 sp58; + + Vtx* vtx; + switch(screen - gScreenContexts) { + case 0: + vtx = mSkyboxScreenOne; + break; + case 1: + vtx = mSkyboxScreenTwo; + break; + case 2: + vtx = mSkyboxScreenThree; + break; + case 3: + vtx = mSkyboxScreenFour; + break; + } + + this->SetColours(vtx); //func_802A450C(vtx); + // Widescreen skybox + // Note that this is the correct fit for each screen due to how the viewport works + vtx[0].v.ob[0] = OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH); + vtx[1].v.ob[0] = OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH); + vtx[2].v.ob[0] = OTRGetRectDimensionFromLeftEdge(0); + vtx[3].v.ob[0] = OTRGetRectDimensionFromLeftEdge(0); + + vtx[4].v.ob[0] = OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH); + vtx[5].v.ob[0] = OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH); + vtx[6].v.ob[0] = OTRGetRectDimensionFromLeftEdge(0); + vtx[7].v.ob[0] = OTRGetRectDimensionFromLeftEdge(0); + + sp5C[0] = 0.0f; + sp5C[1] = 0.0f; + sp5C[2] = 30000.0f; + func_802B5564(matrix1, &sp128, camera->unk_B4, gScreenAspect, CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, + 1.0f); + func_802B5794(matrix2, camera->pos, camera->lookAt); + mtxf_multiplication(matrix3, matrix1, matrix2); + + sp58 = ((matrix3[0][3] * sp5C[0]) + (matrix3[1][3] * sp5C[1]) + (matrix3[2][3] * sp5C[2])) + matrix3[3][3]; + + mtxf_translate_vec3f_mat4(sp5C, matrix3); + + temp_f0 = (1.0 / sp58); + + sp5C[0] *= temp_f0; + sp5C[1] *= temp_f0; + + sp5C[0] *= 160.0f; + sp5C[1] *= 120.0f; + + temp_t5 = 120 - (s32) sp5C[1]; + screen->cameraHeight = temp_t5; + vtx[1].v.ob[1] = temp_t5; + vtx[2].v.ob[1] = temp_t5; + vtx[4].v.ob[1] = temp_t5; + vtx[7].v.ob[1] = temp_t5; + + init_rdp(); + gDPSetRenderMode(gDisplayListHead++, G_RM_OPA_SURF, G_RM_OPA_SURF2); + gSPClearGeometryMode(gDisplayListHead++, G_ZBUFFER | G_LIGHTING); + guOrtho(&gGfxPool->mtxScreen, 0.0f, SCREEN_WIDTH, 0.0f, SCREEN_HEIGHT, 0.0f, 5.0f, 1.0f); + gSPPerspNormalize(gDisplayListHead++, 0xFFFF); + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxScreen), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + gSPMatrix(gDisplayListHead++, (uintptr_t)&mSkyboxMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPVertex(gDisplayListHead++, (uintptr_t)&vtx[0], 4, 0); + gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0); + if (IsRainbowRoad()) { + gSPVertex(gDisplayListHead++, (uintptr_t)&vtx[4], 4, 0); + gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0); + } +} + +void Sky::DrawFloor(ScreenContext* screen) { // func_802A487C + init_rdp(); + + Vtx* vtx; + switch(screen - gScreenContexts) { + case 0: + vtx = mSkyboxScreenOne; + break; + case 1: + vtx = mSkyboxScreenTwo; + break; + case 2: + vtx = mSkyboxScreenThree; + break; + case 3: + vtx = mSkyboxScreenFour; + break; + } + + // Only draw black + if (IsRainbowRoad()) { + return; + } + + gDPSetRenderMode(gDisplayListHead++, G_RM_OPA_SURF, G_RM_OPA_SURF2); + gSPClearGeometryMode(gDisplayListHead++, G_ZBUFFER | G_LIGHTING); + guOrtho(&gGfxPool->mtxScreen, 0.0f, SCREEN_WIDTH, 0.0f, SCREEN_HEIGHT, 0.0f, 5.0f, 1.0f); + gSPPerspNormalize(gDisplayListHead++, 0xFFFF); + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxScreen), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + gSPMatrix(gDisplayListHead++, (uintptr_t)&mSkyboxMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPVertex(gDisplayListHead++, (uintptr_t)&vtx[4], 4, 0); + gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0); +} + +void Sky::InitActors(ScreenContext* screen) { + size_t iterations = 0; + size_t numSnow = 0; + Track* track = GetWorld()->GetTrack(); + + if (!track) { + printf("[Sky] No track ptr found, skipping sky actors\n"); + return; + } + + CloudData* cloud = &track->Props.Clouds[0]; + + // Handle spawning snow + if (track->mCloudType == Track::CloudType::SNOW) { + if (gPlayerCount == 1) { + numSnow = 50; + } else { + numSnow = 25; + } + + for (size_t i = 0; i < numSnow; i++) { + mSkyActors.emplace_back(std::make_unique(screen)); + iterations += 1; + } + D_8018D230 = 0; + } + + // Handle spawning the other cloud types + if (nullptr != cloud) { + while ((cloud->rotY != 0xFFFF) && (iterations < 50)) { + switch(track->mCloudType) { + case Track::CloudType::NONE: + case Track::CloudType::SNOW: + break; + case Track::CloudType::CLOUDS: { + mSkyActors.emplace_back(std::make_unique(screen, cloud->subType, cloud->posY, cloud->rotY, cloud->scalePercent)); + D_8018D230 = 0; + break; + } + case Track::CloudType::STARS: { + mSkyActors.emplace_back(std::make_unique(screen, cloud->subType, cloud->posY, cloud->rotY, cloud->scalePercent)); + D_8018D230 = 1; + break; + } + } + + cloud++; + iterations += 1; + } + } + + D_8018D1F8 += iterations; + D_8018D1F0 = iterations; +} + +EXTERN_C void InitSkyActors(ScreenContext* screen) { + Sky::Instance->InitActors(screen); +} + +EXTERN_C void DrawSkyActors(ScreenContext* screen, s32 arg0) { + if (CVarGetInteger("gDrawSkyActors", true) == false) { + return; + } + + for (auto& cloud : Sky::Instance->GetSkyActors()) { + if (cloud->mScreen == screen) { + cloud->Draw(screen, arg0); + } + } +} + +EXTERN_C void TickSkyActors() { + for (auto& cloud : Sky::Instance->GetSkyActors()) { + cloud->Tick(); + } +} diff --git a/src/engine/sky/Sky.h b/src/engine/sky/Sky.h new file mode 100644 index 000000000..12c94f5a0 --- /dev/null +++ b/src/engine/sky/Sky.h @@ -0,0 +1,43 @@ +#ifndef SKY_H +#define SKY_H + +#ifdef __cplusplus + +#include +#include + +#include "SkyActor.h" + +#include "defines.h" + +EXTERN_C_START +#include "code_800029B0.h" +EXTERN_C_END + +class Sky { +public: + static Sky* Instance; + Sky(); + virtual void Draw(ScreenContext* screen); + virtual void DrawFloor(ScreenContext* screen); + Sky* GetSky(); + void SetColours(Vtx* skybox); + void InitActors(ScreenContext* screen); + std::vector>& GetSkyActors(); +private: + Mtx mSkyboxMatrix; + static Vtx mSkyboxScreenOne[8]; + static Vtx mSkyboxScreenTwo[8]; + static Vtx mSkyboxScreenThree[8]; + static Vtx mSkyboxScreenFour[8]; + + std::vector> mSkyActors; +}; +#endif // __cplusplus + +/** C Compatible functions **/ +EXTERN_C void InitSkyActors(ScreenContext* screen); +EXTERN_C void TickSkyActors(); +EXTERN_C void DrawSkyActors(ScreenContext* screen, s32 arg0); + +#endif // SKY_H diff --git a/src/engine/sky/SkyActor.h b/src/engine/sky/SkyActor.h new file mode 100644 index 000000000..6e95d4e84 --- /dev/null +++ b/src/engine/sky/SkyActor.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include "engine/SpawnParams.h" +#include "engine/CoreMath.h" + +extern "C" { +#include "common_structs.h" +#include "code_800029B0.h" +} + +/** + * SkyActor base class + * + * + */ +class SkyActor { +public: + SkyActor(ScreenContext* screen) { + mScreen = screen; + }; + SkyActor(ScreenContext* screen, u16 cloudVariant, u16 posY, u16 rotY, u16 scalePercent) {}; + + virtual void Draw(ScreenContext* ctx, s32 arg0) {}; + virtual void Tick() {}; + ScreenContext* mScreen; +protected: + f32 mScale; + u16 mCloudVariant; + u8* mTexture; + s32 mTextureWidth; + s32 mTextureHeight; + bool mVisible; + Vtx* mVtx; + int32_t mX; + int32_t mY; + int32_t mRotY; + int32_t mOldX; + int32_t mOldY; + + s16 mUnk208; + s16 mUnk210; + f32 mUnk1E8; + s16 mUnk218; +}; diff --git a/src/engine/sky/SkyCloud.cpp b/src/engine/sky/SkyCloud.cpp new file mode 100644 index 000000000..2cad8b7c6 --- /dev/null +++ b/src/engine/sky/SkyCloud.cpp @@ -0,0 +1,112 @@ +#include +#include +#include "SkyCloud.h" +#include +#include "engine/tracks/Track.h" +#include "engine/World.h" + +#include "port/Engine.h" +#include "port/Game.h" +#include "port/interpolation/FrameInterpolation.h" + +extern "C" { +#include "update_objects.h" +#include "code_80057C60.h" +#include "code_8006E9C0.h" +#include "assets/models/common_data.h" +#include "math_util_2.h" +#include "render_objects.h" +} + +size_t SkyCloud::_count = 0; + +SkyCloud::SkyCloud(ScreenContext* screen, u16 cloudVariant, u16 posY, u16 rotY, u16 scalePercent) : SkyActor(screen) { + _idx = _count; + mScreen = screen; + mCloudVariant = cloudVariant; + mY = posY; + mRotY = rotY; + mScale = (f32) scalePercent / 100.0; + + if (GameEngine_ResourceGetTexTypeByName((const char*)CM_GetProps()->CloudTexture) != 1) { + mTexture = ((u8*) LOAD_ASSET_RAW(CM_GetProps()->CloudTexture)) + (cloudVariant * 1024); + mTextureWidth = 64; + mTextureHeight = 32; + mVtx = (Vtx*)D_0D005FB0; + } else { + mTexture = CM_GetProps()->CloudTexture; + if (strcmp((const char*)CM_GetProps()->CloudTexture, gTextureExhaust0) == 0 || + strcmp((const char*)CM_GetProps()->CloudTexture, gTextureExhaust1) == 0 || + strcmp((const char*)CM_GetProps()->CloudTexture, gTextureExhaust2) == 0) { + mTextureWidth = 64; + mTextureHeight = 32; + mVtx = cloudvtx2[cloudVariant]; + } else { + mTextureWidth = 64; + mTextureHeight = 32; + mVtx = cloudvtx2[cloudVariant]; + } + } + + _count += 1; +} + +void SkyCloud::Tick() { // func_800788F8 + s16 cameraRot; + + s16 mUnk200 = mScreen->camera->fieldOfView + 40.0f; + mUnk208 = ((mUnk200 / 2) * 0xB6) + 0x71C; + mUnk210 = (-(mUnk200 / 2) * 0xB6) - 0x71C; + mUnk1E8 = 1.7578125 / mUnk200; + mUnk218 = SCREEN_WIDTH / 2; + + // Adjustable culling factor + const float cullingFactor = OTRGetAspectRatio(); + + // Calculate the cloud's rotation relative to the camera + cameraRot = (u16)mScreen->camera->rot[1] + (u16)mRotY; + // Adjust bounds based on the culling factor + s16 adjustedLowerBound = (s16) (mUnk210 * cullingFactor); + s16 adjustedUpperBound = (s16) (mUnk208 * cullingFactor); + + // Check if the object is within the adjusted bounds + if ((cameraRot >= adjustedLowerBound) && (adjustedUpperBound >= cameraRot)) { + // Calculate and update the object's X position + // 160 (SCREEN_WIDTH / 2) + (D_8018D1E8 * cameraRot); + // Grab center of screen, scale by fov factor, offset based on camera rotation + mX = mUnk218 + (mUnk1E8 * cameraRot); + + // Mark the object as visible + mVisible = true; + } else { + // If outside the bounds, mark the object as not visible + mVisible = false; + } +} + +void SkyCloud::Draw(ScreenContext* screen, s32 arg0) { // render_clouds + // Object* object = &gObjectList[_objectIndex]; + s32 posY = arg0 - mY; + func_8004B6C4(255, 255, 255); + // Skip drawing the object this frame if it warped to the other side of the screen + if ((fabs(mX - mOldX) > SCREEN_WIDTH / 2) || (fabs(posY - mOldY) > SCREEN_HEIGHT / 2)) { + mOldX = mX; + mOldY = posY; + return; + } + if (mVisible) { + FrameInterpolation_RecordOpenChild("render_clouds", TAG_CLOUDS((_idx << 4) | (mScreen - gScreenOneCtx))); + + if (D_8018D228 != mCloudVariant) { + D_8018D228 = mCloudVariant; + func_80044DA0(mTexture, mTextureWidth, mTextureHeight); + } + func_80042330_unchanged(mX, posY, 0, mScale); + gSPVertex(gDisplayListHead++, (uintptr_t)mVtx, 4, 0); + gSPDisplayList(gDisplayListHead++, (Gfx*)common_rectangle_display); + + FrameInterpolation_RecordCloseChild(); + } + mOldX = mX; + mOldY = posY; +} diff --git a/src/engine/sky/SkyCloud.h b/src/engine/sky/SkyCloud.h new file mode 100644 index 000000000..366298d39 --- /dev/null +++ b/src/engine/sky/SkyCloud.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include "engine/SpawnParams.h" +#include "engine/CoreMath.h" +#include "engine/sky/SkyActor.h" + +extern "C" { +#include "common_structs.h" +#include "code_800029B0.h" +} + +/** + * Skybox clouds + * + * @cloudVariant The cloud texture to use + */ +class SkyCloud : public SkyActor { +public: + SkyCloud(ScreenContext* screen, u16 cloudVariant, u16 posY, u16 rotY, u16 scalePercent); + + ~SkyCloud() { + _count--; + } + + static size_t GetCount() { + return _count; + } + + virtual void Draw(ScreenContext* ctx, s32 arg0) override; + virtual void Tick() override; +private: + static size_t _count; + size_t _idx; +}; diff --git a/src/engine/sky/SkySnow.cpp b/src/engine/sky/SkySnow.cpp new file mode 100644 index 000000000..c9e556fba --- /dev/null +++ b/src/engine/sky/SkySnow.cpp @@ -0,0 +1,183 @@ +#include +#include +#include "SkySnow.h" +#include +#include "engine/tracks/Track.h" +#include "engine/World.h" + +#include "port/Engine.h" +#include "port/Game.h" +#include "port/interpolation/FrameInterpolation.h" + +extern "C" { +#include "update_objects.h" +#include "code_80057C60.h" +#include "code_8006E9C0.h" +#include "assets/models/common_data.h" +#include "assets/textures/common_data.h" +#include "math_util_2.h" +#include "render_objects.h" +#include "math_util.h" +} + +size_t SkySnow::_count = 0; + +SkySnow::SkySnow(ScreenContext* screen) : SkyActor(screen) { + _idx = _count; + + mState = 0; + mState2 = 0; + + _count += 1; +} + +void SkySnow::Tick() { + + s16 mUnk200 = mScreen->camera->fieldOfView + 40.0f; + mUnk208 = ((mUnk200 / 2) * 0xB6) + 0x71C; + mUnk210 = (-(mUnk200 / 2) * 0xB6) - 0x71C; + mUnk1E8 = 1.7578125 / mUnk200; + mUnk218 = SCREEN_WIDTH / 2; + + if (D_8016559C == 0) { + D_8018D17C += 1; + if (D_8018D17C >= D_8018D1F0) { + D_8018D17C = 0; + } + if (mState == 0) { + //init_object(_objectIndex, 1); + mState = 1; + } + } + + switch (mState) { + case 1: + SkySnow::func_80077E20(); + break; + case 2: + SkySnow::func_80077F64(mScreen->camera); + if (mState2 == 0) { // unk_0AE + mState2 += 1; + //object_next_state(_objectIndex); + } + break; + case 0: + break; + case 3: + //func_80072428(_objectIndex); + mState = 0; + //mStatus = 0; + mVisible = false; + mState2 = 0; + break; + } +} + +void SkySnow::Draw(ScreenContext* screen, s32 arg0) { // render_clouds + s32 posY = arg0 - mY; + func_8004B6C4(255, 255, 255); + // Skip drawing the object this frame if it warped to the other side of the screen + if ((fabs(mX - mOldX) > SCREEN_WIDTH / 2) || (fabs(posY - mOldY) > SCREEN_HEIGHT / 2)) { + mOldX = mX; + mOldY = posY; + return; + } + + if (mVisible) { + FrameInterpolation_RecordOpenChild("render_snow", TAG_CLOUDS((_idx << 4) | (screen - gScreenOneCtx))); + + if (D_8018D228 != mCloudVariant) { + D_8018D228 = mCloudVariant; + func_80044DA0((u8*)mTexture, mTextureWidth, mTextureHeight); + } + func_80042330_unchanged(mX, posY, 0, mScale); + gSPVertex(gDisplayListHead++, (uintptr_t)mVtx, 4, 0); + gSPDisplayList(gDisplayListHead++, (Gfx*)common_rectangle_display); + + FrameInterpolation_RecordCloseChild(); + } + mOldX = mX; + mOldY = posY; +} + +void SkySnow::func_80077E20() { + u8* tex = (u8*) LOAD_ASSET(D_0D0293D8); + Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_rectangle); + + mTexture = tex; + //! @bug frappe snowland There's something up with the handling of common_vtx_rectangle and the loading of 0x10 + //! right here + // root function: func_80078C70 + mVtx = vtx; + mTextureWidth = 16; + mTextureHeight = 16; + mScale = 0.15f; + mVisible = true; + + mState2 = 1; // UNK_0AE func_80086EF0 + mState += 1; + //object_next_state(objectIndex); +} + +void SkySnow::func_80077F64(Camera* camera) { + + f64 rand; + + switch (mState2) { /* irregular */ + case 1: { + mDirectionAngle[1] = (camera->rot[1] + random_int(0x4000U)) - 0x2000; + //object_origin_pos_randomize_around_y(objectIndex, 0x00B4, 0x0014U); + s16 offset_y = random_int(20) - (20 / 2); + mOrigin.y = 180 + offset_y; +// gObjectList[objectIndex].origin_pos[1] = y + offset_y; + + rand = random_int(0x0064U); + mVelocity.y = (f32) (-0.75 - (f64) (f32) (rand * 0.01)); + // gObjectList[objectIndex].velocity[1] = (f32) (-0.75 - (f64) (f32) (rand * 0.01)); + mOffset.x = 0.0f; + mOffset.y = 0.0f; + //gObjectList[objectIndex].offset[0] = 0.0f; + //gObjectList[objectIndex].offset[1] = 0.0f; + //func_80086FD4(objectIndex); + mState2 += 1; + break; + } + case 2: { + //func_80077EB8(objectIndex, gObjectList[objectIndex].direction_angle[1], camera); + s16 temp_v0 = camera->rot[1] - mDirectionAngle[1]; + if ((temp_v0 >= mUnk210) || (mUnk208 >= temp_v0)) { + mOffset.x = mUnk218 + (mUnk1E8 * (f32) temp_v0); + mVisible = true; + //set_object_flag(objectIndex, 0x00000010); + } else { + mVisible = false; + } + //clear_object_flag(objectIndex, 0x00000010); + + +// object_add_velocity_offset_y(objectIndex); + + mOffset.y += mVelocity.y; + + //object_calculate_new_pos_offset(objectIndex); + + mX = mOrigin.x + mOffset.x; + mY = mOrigin.y + mOffset.y; + //mZ = mOrigin.z + mOffset.z; + + //func_8008BFC0(objectIndex); + if (mY <= 0.0f) { + //func_80086FD4(objectIndex); + mState2 += 1; + break; + } + break; + } + case 0: + break; + case 3: + //func_80086F60(objectIndex); + mState2 = 0; + break; + } +} \ No newline at end of file diff --git a/src/engine/sky/SkySnow.h b/src/engine/sky/SkySnow.h new file mode 100644 index 000000000..1d9dcccc1 --- /dev/null +++ b/src/engine/sky/SkySnow.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include "SkyCloud.h" +#include "engine/registry/RegisterContent.h" +#include "engine/World.h" +#include "engine/SpawnParams.h" +#include "engine/CoreMath.h" + +#include "engine/objects/Object.h" + +extern "C" { +#include "common_structs.h" +} + +/** + * Skybox Stars + * + * Inherits from SkyCloud so that stars/clouds can be stored in the same list + * and called the same way. + * + * @cloudVariant unused for stars + */ +class SkySnow : public SkyActor { +public: + SkySnow(ScreenContext* screen); + + ~SkySnow() { + _count--; + } + + static size_t GetCount() { + return _count; + } + + virtual void Draw(ScreenContext* ctx, s32 arg0) override; + virtual void Tick() override; + void func_80077E20(); + void func_80077F64(Camera* camera); +private: + static size_t _count; + size_t _idx; + s32 mState; + s32 mState2; + FVector mOffset; + FVector mOrigin; + FVector mVelocity; + Vec3su mDirectionAngle; +}; diff --git a/src/engine/sky/SkyStar.cpp b/src/engine/sky/SkyStar.cpp new file mode 100644 index 000000000..7f696d7bb --- /dev/null +++ b/src/engine/sky/SkyStar.cpp @@ -0,0 +1,165 @@ +#include +#include +#include "SkyStar.h" +#include +#include "engine/tracks/Track.h" +#include "engine/World.h" + +#include "port/Engine.h" +#include "port/Game.h" +#include "port/interpolation/FrameInterpolation.h" + +extern "C" { +#include "update_objects.h" +#include "code_80057C60.h" +#include "code_8006E9C0.h" +#include "assets/models/common_data.h" +#include "assets/textures/common_data.h" +#include "math_util_2.h" +#include "render_objects.h" +} + +size_t SkyStar::_count = 0; + +SkyStar::SkyStar(ScreenContext* screen, u16 cloudVariant, u16 posY, u16 rotY, u16 scalePercent) : SkyActor(screen) { + _idx = _count; + + // ItemWindowObjects* temp_v0; + //find_unused_obj_index(&_objectIndex); + //init_object(_objectIndex, 1); +// temp_v0 = (ItemWindowObjects*) &gObjectList[_objectIndex]; + mCloudVariant = cloudVariant; +// temp_v0->unk_0D5 = cloudVariant; + // temp_v0->currentItem = ITEM_BANANA; + // temp_v0->direction_angle[1] = rotY; + mY = posY; +// temp_v0->unk_09E = posY; + mScale = (f32) scalePercent / 100.0; +// temp_v0->sizeScaling = (f32) scalePercent / 100.0; + mTexture = (u8*)D_0D0293D8; +// temp_v0->activeTexture = (u8*)D_0D0293D8; + //func_80073404(_objectIndex, 0x10U, 0x10U, (Vtx*)common_vtx_rectangle); + mVtx = (Vtx*)common_vtx_rectangle; + mTextureWidth = 16; + mTextureHeight = 16; + mRotY = rotY; + + mPrimAlpha = 0; + mUnk_0CF = 0; + mUnk_0AC = 0; + mUnk_0D0 = 0; + + + _count += 1; +} + +void SkyStar::Tick() { + s16 cameraRot; + + s16 mUnk200 = mScreen->camera->fieldOfView + 40.0f; + mUnk208 = ((mUnk200 / 2) * 0xB6) + 0x71C; + mUnk210 = (-(mUnk200 / 2) * 0xB6) - 0x71C; + mUnk1E8 = 1.7578125 / mUnk200; + mUnk218 = SCREEN_WIDTH / 2; + + // Adjustable culling factor + const float cullingFactor = OTRGetAspectRatio(); + + // Calculate the cloud's rotation relative to the camera + cameraRot = (u16)mScreen->camera->rot[1] + (u16)mRotY; + // Adjust bounds based on the culling factor + s16 adjustedLowerBound = (s16) (mUnk210 * cullingFactor); + s16 adjustedUpperBound = (s16) (mUnk208 * cullingFactor); + + // Check if the object is within the adjusted bounds + if ((cameraRot >= adjustedLowerBound) && (adjustedUpperBound >= cameraRot)) { + // Calculate and update the object's position + // 160 (SCREEN_WIDTH / 2) + (mUnk1E8 * cameraRot); + // Grab center of screen, scale by fov factor, offset based on camera rotation + mX = mUnk218 + (mUnk1E8 * cameraRot); + + mVisible = true; + } else { + mVisible = false; + } + + // Vary the star based on star index + switch (_idx % 5U) { + case 0: + star_func_80073B78(1, 0x00000028, 0x000000B4, 0x000000FF, 0, -1); + break; + case 1: + star_func_80073B78(1, 0x00000080, 0x000000FF, 0x000000FF, 0, -1); + break; + case 2: + star_func_80073B78(1, 0x00000050, 0x000000C8, 0x000000FF, 0, -1); + break; + case 3: + star_func_80073B78(1, 0, 0x0000009B, 0x000000FF, 0, -1); + break; + case 4: + star_func_80073B78(1, 0x0000005A, 0x00000080, 0x000000FF, 0, -1); + break; + } +} + +void SkyStar::Draw(ScreenContext* screen, s32 arg0) { // render_stars + s32 posY = arg0 - mY; + func_8004B414(255, 255, 255, 255); + if (mVisible) { + FrameInterpolation_RecordOpenChild("render_stars", TAG_CLOUDS((_idx << 4) | (screen - gScreenOneCtx))); + + func_80044DA0((u8*)mTexture, mTextureWidth, mTextureHeight); + + func_8004B138(0xFF, 0xFF, 0xFF, mPrimAlpha); + func_80042330_unchanged(mX, posY, 0, mScale); + gSPVertex(gDisplayListHead++, (uintptr_t)mVtx, 4, 0); + gSPDisplayList(gDisplayListHead++, (Gfx*)common_rectangle_display); + FrameInterpolation_RecordCloseChild(); + } +} + +bool SkyStar::star_func_80073B78(s32 arg0, s32 arg3, s32 arg4, s32 arg5, s32 arg6, s32 arg7) { + s32 phi_t0; + + phi_t0 = false; + if (mUnk_0CF == 0) { // s8 + mUnk_0AC = arg6; // s16 + if (arg0 != 0) { + mPrimAlpha = arg3; + } + mUnk_0D0 = arg7; // s8 + //func_80073800(objectIndex, 1); + mUnk_0CF = 1; + } else { + mUnk_0AC--; + if (mUnk_0AC < 0) { + mUnk_0AC = arg6; + if (mUnk_0CF == 1) { + mPrimAlpha += arg5; + if (mPrimAlpha >= arg4) { + mPrimAlpha = arg4; + mUnk_0CF++; + } + } else { + mPrimAlpha -= arg5; + if (arg3 >= mPrimAlpha) { + mPrimAlpha = arg3; + if (mUnk_0D0 > 0) { + mUnk_0D0--; + } + if (mUnk_0D0 == 0) { + //func_80073800(objectIndex, 0); + mUnk_0CF = 0; + //func_8007381C(objectIndex); // does nothing? += unk_0DC + phi_t0 = true; + } else { + mUnk_0CF = 1; + } + } + } + } + } + + return phi_t0; +} \ No newline at end of file diff --git a/src/engine/sky/SkyStar.h b/src/engine/sky/SkyStar.h new file mode 100644 index 000000000..c12d2be5e --- /dev/null +++ b/src/engine/sky/SkyStar.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include "SkyCloud.h" +#include "engine/registry/RegisterContent.h" +#include "engine/World.h" +#include "engine/SpawnParams.h" +#include "engine/CoreMath.h" + +#include "engine/sky/SkyActor.h" +#include "engine/objects/Object.h" + +extern "C" { +#include "common_structs.h" +} + +/** + * Skybox Stars + * + * Inherits from SkyCloud so that stars/clouds can be stored in the same list + * and called the same way. + * + * @cloudVariant unused for stars + */ +class SkyStar : public SkyActor { +public: + SkyStar(ScreenContext* screen, u16 cloudVariant, u16 posY, u16 rotY, u16 scalePercent); + + virtual ~SkyStar() { + _count--; + } + + static size_t GetCount() { + return _count; + } + + virtual void Draw(ScreenContext* ctx, s32 arg0) override; + virtual void Tick() override; + bool star_func_80073B78(s32 arg0, s32 arg3, s32 arg4, s32 arg5, s32 arg6, s32 arg7); +private: + static size_t _count; + size_t _idx; + + s16 mPrimAlpha; + s8 mUnk_0CF; + s16 mUnk_0AC; + s8 mUnk_0D0; +}; diff --git a/src/engine/tracks/BansheeBoardwalk.h b/src/engine/tracks/BansheeBoardwalk.h index 90de15c3d..3c113c5a5 100644 --- a/src/engine/tracks/BansheeBoardwalk.h +++ b/src/engine/tracks/BansheeBoardwalk.h @@ -25,7 +25,6 @@ public: // course_texture* textures, const char* displaylists, size_t dlSize); virtual void Load() override; virtual void BeginPlay() override; - //virtual void InitClouds() override; virtual void InitTrackObjects() override; virtual void TickTrackObjects() override; virtual void DrawTrackObjects(s32 cameraId) override; diff --git a/src/engine/tracks/BowsersCastle.h b/src/engine/tracks/BowsersCastle.h index f12ed3b39..53e26e928 100644 --- a/src/engine/tracks/BowsersCastle.h +++ b/src/engine/tracks/BowsersCastle.h @@ -26,7 +26,6 @@ public: virtual void Load() override; void SpawnStockThwomp(); virtual void BeginPlay() override; - //virtual void InitClouds() override; virtual void InitTrackObjects() override; virtual void TickTrackObjects() override; virtual void DrawTrackObjects(s32 cameraId) override; diff --git a/src/engine/tracks/DKJungle.h b/src/engine/tracks/DKJungle.h index da7fb92fd..6454fb559 100644 --- a/src/engine/tracks/DKJungle.h +++ b/src/engine/tracks/DKJungle.h @@ -26,7 +26,6 @@ public: virtual void Load() override; virtual f32 GetWaterLevel(FVector pos, Collision* collision) override; virtual void BeginPlay() override; - //virtual void InitClouds() override; virtual void InitTrackObjects() override; virtual void TickTrackObjects() override; virtual void DrawTrackObjects(s32 cameraId) override; diff --git a/src/engine/tracks/FrappeSnowland.cpp b/src/engine/tracks/FrappeSnowland.cpp index 338a2be2a..e74b02f93 100644 --- a/src/engine/tracks/FrappeSnowland.cpp +++ b/src/engine/tracks/FrappeSnowland.cpp @@ -100,6 +100,7 @@ FrappeSnowland::FrappeSnowland() { Props.Clouds = NULL; // not used for frappe Props.CloudList = NULL; + mCloudType = CloudType::SNOW; Props.Skybox.TopRight = {28, 11, 90}; Props.Skybox.BottomRight = {0, 99, 164}; @@ -165,26 +166,6 @@ void FrappeSnowland::BeginPlay() { } } -void FrappeSnowland::InitClouds() { - s32 var_s0; - s32 var_s4; - if (gPlayerCount == 1) { - var_s4 = 0x32; - } else { - var_s4 = 0x19; - } - for (var_s0 = 0; var_s0 < var_s4; var_s0++) { - find_unused_obj_index(&D_8018CC80[D_8018D1F8 + var_s0]); - } - D_8018D1F8 += var_s0; - D_8018D1F0 = var_s0; - D_8018D230 = 0; // This must be turned off or mayhem ensues -} - -void FrappeSnowland::TickClouds(s32 sp1C, Camera* camera) { - func_80078170(sp1C, camera); -} - void FrappeSnowland::InitTrackObjects() { size_t objectId; size_t i; diff --git a/src/engine/tracks/FrappeSnowland.h b/src/engine/tracks/FrappeSnowland.h index 523093924..e14ffcd7e 100644 --- a/src/engine/tracks/FrappeSnowland.h +++ b/src/engine/tracks/FrappeSnowland.h @@ -22,8 +22,6 @@ public: virtual void Load() override; virtual void BeginPlay() override; - virtual void InitClouds() override; - virtual void TickClouds(s32 sp1C, Camera* camera) override; virtual void InitTrackObjects() override; virtual void TickTrackObjects() override; virtual void Draw(ScreenContext*) override; diff --git a/src/engine/tracks/PodiumCeremony.cpp b/src/engine/tracks/PodiumCeremony.cpp index a24e260ba..134166eb5 100644 --- a/src/engine/tracks/PodiumCeremony.cpp +++ b/src/engine/tracks/PodiumCeremony.cpp @@ -52,6 +52,7 @@ PodiumCeremony::PodiumCeremony() { Props.Minimap.FinishlineX = 0; Props.Minimap.FinishlineY = 0; + ResourceName = "mk:podium_ceremony"; Props.SetText(Props.Name, "royal raceway", sizeof(Props.Name)); Props.SetText(Props.DebugName, "p circuit", sizeof(Props.DebugName)); Props.SetText(Props.TrackLength, "1025m", sizeof(Props.TrackLength)); diff --git a/src/engine/tracks/PodiumCeremony.h b/src/engine/tracks/PodiumCeremony.h index 336b73330..72f8a51b3 100644 --- a/src/engine/tracks/PodiumCeremony.h +++ b/src/engine/tracks/PodiumCeremony.h @@ -24,11 +24,8 @@ public: // Constructor explicit PodiumCeremony(); -// virtual void Load(const char* courseVtx, -// course_texture* textures, const char* displaylists, size_t dlSize); virtual void Load() override; virtual void BeginPlay() override; - //virtual void InitClouds() override; virtual void InitTrackObjects() override; virtual void SomeSounds() override; virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; diff --git a/src/engine/tracks/RainbowRoad.cpp b/src/engine/tracks/RainbowRoad.cpp index 8666ae74e..20e7e9a56 100644 --- a/src/engine/tracks/RainbowRoad.cpp +++ b/src/engine/tracks/RainbowRoad.cpp @@ -94,6 +94,7 @@ RainbowRoad::RainbowRoad() { Props.Clouds = gToadsTurnpikeRainbowRoadStars; Props.CloudList = gToadsTurnpikeRainbowRoadStars; + mCloudType = CloudType::STARS; Props.Skybox.TopRight = {0, 0, 0}; Props.Skybox.BottomRight = {0, 0, 0}; @@ -150,14 +151,6 @@ void RainbowRoad::BeginPlay() { } } -void RainbowRoad::InitClouds() { - init_stars(this->Props.Clouds); -} - -void RainbowRoad::TickClouds(s32 sp1C, Camera* camera) { - update_stars(sp1C, camera, this->Props.CloudList); -} - void RainbowRoad::InitTrackObjects() { if (gGamestate != CREDITS_SEQUENCE) { size_t i; diff --git a/src/engine/tracks/RainbowRoad.h b/src/engine/tracks/RainbowRoad.h index 47094594a..64fcb1a39 100644 --- a/src/engine/tracks/RainbowRoad.h +++ b/src/engine/tracks/RainbowRoad.h @@ -25,8 +25,6 @@ public: // course_texture* textures, const char* displaylists, size_t dlSize); virtual void Load() override; virtual void BeginPlay() override; - virtual void InitClouds() override; - virtual void TickClouds(s32, Camera*) override; virtual void InitTrackObjects() override; virtual void TickTrackObjects() override; virtual void DrawTrackObjects(s32 cameraId) override; diff --git a/src/engine/tracks/Skyscraper.h b/src/engine/tracks/Skyscraper.h index 526ab902f..370fe8d18 100644 --- a/src/engine/tracks/Skyscraper.h +++ b/src/engine/tracks/Skyscraper.h @@ -25,7 +25,6 @@ public: // course_texture* textures, const char* displaylists, size_t dlSize); virtual void Load() override; virtual void BeginPlay() override; - //virtual void InitClouds() override; virtual void InitTrackObjects() override; virtual void SomeSounds() override; virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; diff --git a/src/engine/tracks/ToadsTurnpike.cpp b/src/engine/tracks/ToadsTurnpike.cpp index f735ba4c3..f929a56e1 100644 --- a/src/engine/tracks/ToadsTurnpike.cpp +++ b/src/engine/tracks/ToadsTurnpike.cpp @@ -102,6 +102,7 @@ ToadsTurnpike::ToadsTurnpike() { Props.Clouds = gToadsTurnpikeRainbowRoadStars; Props.CloudList = gToadsTurnpikeRainbowRoadStars; + mCloudType = CloudType::STARS; FVector finish; finish.x = -38.0f * xOrientation; @@ -199,14 +200,6 @@ void ToadsTurnpike::BeginPlay() { } } -void ToadsTurnpike::InitClouds() { - init_stars(this->Props.Clouds); -} - -void ToadsTurnpike::TickClouds(s32 sp1C, Camera* camera) { - update_stars(sp1C, camera, this->Props.CloudList); -} - void ToadsTurnpike::SomeSounds() {} void ToadsTurnpike::WhatDoesThisDo(Player* player, int8_t playerId) { diff --git a/src/engine/tracks/ToadsTurnpike.h b/src/engine/tracks/ToadsTurnpike.h index 75e1c8fbb..dc69eaa15 100644 --- a/src/engine/tracks/ToadsTurnpike.h +++ b/src/engine/tracks/ToadsTurnpike.h @@ -25,8 +25,6 @@ public: // course_texture* textures, const char* displaylists, size_t dlSize); virtual void Load() override; virtual void BeginPlay() override; - virtual void InitClouds() override; - virtual void TickClouds(s32, Camera*) override; virtual void SomeSounds() override; virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; virtual void WhatDoesThisDoAI(Player* player, int8_t playerId) override; diff --git a/src/engine/tracks/Track.cpp b/src/engine/tracks/Track.cpp index bd629bdce..617539217 100644 --- a/src/engine/tracks/Track.cpp +++ b/src/engine/tracks/Track.cpp @@ -31,6 +31,7 @@ extern "C" { #include "math_util.h" #include "code_80005FD0.h" extern StaffGhost* d_mario_raceway_staff_ghost; +extern s8 gPlayerCount; } void ResizeMinimap(MinimapProps* minimap) { @@ -406,6 +407,7 @@ Track::Track() { Props.Clouds = NULL; Props.CloudList = NULL; + mCloudType = CloudType::CLOUDS; Props.Sequence = MusicSeq::MUSIC_SEQ_UNKNOWN; bFog = false; @@ -465,26 +467,6 @@ void Track::SpawnActors() { } } -void Track::InitClouds() { - if (this->Props.Clouds) { - init_clouds(this->Props.Clouds); - } -} - -void Track::TickClouds(s32 arg0, Camera* camera) { - s32 cloudIndex; - s32 objectIndex; - CloudData* cloud; - - if (this->Props.CloudList) { - for (cloudIndex = 0; cloudIndex < D_8018D1F0; cloudIndex++) { - cloud = &this->Props.CloudList[cloudIndex]; - objectIndex = D_8018CC80[arg0 + cloudIndex]; - func_800788F8(objectIndex, cloud->rotY, camera); - } - } -} - // Adjusts player speed on steep hills void Track::SomeCollisionThing(Player* player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7) { diff --git a/src/engine/tracks/Track.h b/src/engine/tracks/Track.h index 3bea88ed0..8dfd1750e 100644 --- a/src/engine/tracks/Track.h +++ b/src/engine/tracks/Track.h @@ -307,13 +307,21 @@ typedef struct Properties { class World; // <-- Forward declare -class Track { +class Track { public: + enum class CloudType { + NONE, + CLOUDS, + SNOW, + STARS + }; // Required to save scenefile data std::shared_ptr Archive; std::string ResourceName; + Properties Props; + enum CloudType mCloudType; // This allows multiple water levels in a map. // Ex. DK Jungle where there's a waterfall and you can drive above and below it. @@ -343,8 +351,6 @@ public: */ virtual void BeginPlay(); void SpawnActors(); - virtual void InitClouds(); - virtual void TickClouds(s32, Camera*); virtual void SomeCollisionThing(Player *player, Vec3f arg1, Vec3f arg2, Vec3f arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7); virtual void InitTrackObjects(); virtual void TickTrackObjects(); diff --git a/src/engine/tracks/WarioStadium.cpp b/src/engine/tracks/WarioStadium.cpp index 1fc47c8fb..f5f940d7f 100644 --- a/src/engine/tracks/WarioStadium.cpp +++ b/src/engine/tracks/WarioStadium.cpp @@ -97,6 +97,7 @@ WarioStadium::WarioStadium() { Props.Clouds = gWarioStadiumStars; Props.CloudList = gWarioStadiumStars; + mCloudType = CloudType::STARS; FVector finish; finish.x = (gIsMirrorMode != 0) ? 13 + 12.0f : 13 - 12.0f; @@ -168,14 +169,6 @@ void WarioStadium::BeginPlay() { } } -void WarioStadium::InitClouds() { - init_stars(this->Props.Clouds); -} - -void WarioStadium::TickClouds(s32 sp1C, Camera* camera) { - update_stars(sp1C, camera, this->Props.CloudList); -} - void WarioStadium::InitTrackObjects() { } diff --git a/src/engine/tracks/WarioStadium.h b/src/engine/tracks/WarioStadium.h index 71d1d5be8..b6b6bee80 100644 --- a/src/engine/tracks/WarioStadium.h +++ b/src/engine/tracks/WarioStadium.h @@ -27,8 +27,6 @@ class WarioStadium : public Track { // course_texture* textures, const char* displaylists, size_t dlSize); virtual void Load() override; virtual void BeginPlay() override; - virtual void InitClouds() override; - virtual void TickClouds(s32, Camera*) override; virtual void InitTrackObjects() override; virtual void SomeSounds() override; virtual void WhatDoesThisDo(Player* player, int8_t playerId) override; diff --git a/src/main.c b/src/main.c index 2fe0b453d..b682244e3 100644 --- a/src/main.c +++ b/src/main.c @@ -740,50 +740,49 @@ void race_logic_loop(void) { switch (gActiveScreenMode) { case SCREEN_MODE_1P: - render_screens(RENDER_SCREEN_MODE_1P_PLAYER_ONE, 0, 0); + render_screens(gScreenOneCtx, RENDER_SCREEN_MODE_1P_PLAYER_ONE, 0, 0); break; case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: if (gPlayerWinningIndex == 0) { // In VS Mode the winning player's viewport takes over the whole screen. // Rendering the winning player last places their screen above the other screens - render_screens(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO, 1, 1); - render_screens(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE, 0, 0); + render_screens(gScreenTwoCtx, RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO, 4, 1); + render_screens(gScreenOneCtx, RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE, 3, 0); } else { - render_screens(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE, 0, 0); - render_screens(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO, 1, 1); + render_screens(gScreenOneCtx, RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE, 3, 0); + render_screens(gScreenTwoCtx, RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO, 4, 1); } break; case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: if (gPlayerWinningIndex == 0) { - render_screens(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO, 1, 1); - render_screens(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE, 0, 0); + render_screens(gScreenTwoCtx, RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO, 2, 1); + render_screens(gScreenOneCtx, RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE, 1, 0); } else { - render_screens(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE, 0, 0); - render_screens(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO, 1, 1); + render_screens(gScreenOneCtx, RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE, 1, 0); + render_screens(gScreenTwoCtx, RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO, 2, 1); } break; case SCREEN_MODE_3P_4P_SPLITSCREEN: if (gPlayerWinningIndex == 0) { - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 1, 1); - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 2, 2); - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 3, 3); - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 0, 0); + render_screens(gScreenTwoCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 9, 1); + render_screens(gScreenThreeCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 10, 2); + render_screens(gScreenFourCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 11, 3); + render_screens(gScreenOneCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 8, 0); } else if (gPlayerWinningIndex == 1) { - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 0, 0); - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 2, 2); - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 3, 3); - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 1, 1); + render_screens(gScreenOneCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 8, 0); + render_screens(gScreenThreeCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 10, 2); + render_screens(gScreenFourCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 11, 3); + render_screens(gScreenTwoCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 9, 1); } else if (gPlayerWinningIndex == 2) { - - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 0, 0); - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 1, 1); - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 3, 3); - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 2, 2); + render_screens(gScreenOneCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 8, 0); + render_screens(gScreenTwoCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 9, 1); + render_screens(gScreenFourCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 11, 3); + render_screens(gScreenThreeCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 10, 2); } else { - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 0, 0); - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 1, 1); - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 2, 2); - render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 3, 3); + render_screens(gScreenOneCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 8, 0); + render_screens(gScreenTwoCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 9, 1); + render_screens(gScreenThreeCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 10, 2); + render_screens(gScreenFourCtx, RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 11, 3); } break; } diff --git a/src/port/Game.cpp b/src/port/Game.cpp index ce22999d1..9a492f6b3 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -32,6 +32,7 @@ #include "engine/TrackBrowser.h" #include "engine/RandomItemTable.h" +#include "engine/sky/Sky.h" #ifdef _WIN32 #include @@ -47,6 +48,7 @@ extern "C" { #include "spawn_players.h" #include "src/enhancements/collision_viewer.h" #include "code_800029B0.h" +#include "code_80057C60.h" // #include "engine/wasm.h" } @@ -81,6 +83,7 @@ Registry gItemRegistry; DataRegistry gItemTableRegistry; std::unique_ptr gTrackBrowser; +std::unique_ptr gSky; World* GetWorld() { return World::Instance; @@ -91,6 +94,8 @@ void CustomEngineInit() { // This also turns off freecam gEditor.Disable(); + + gSky = std::make_unique(); RegisterTracks(gTrackRegistry); gTrackBrowser = std::make_unique(gTrackRegistry); TrackBrowser::Instance->FindCustomTracks(); @@ -361,6 +366,7 @@ void CM_DrawStaticMeshActors() { void CM_BeginPlay() { static bool tour = false; auto track = GetWorld()->GetTrack(); + GetWorld()->Actors.clear(); if (nullptr == track) { return; @@ -554,15 +560,14 @@ void CM_DrawParticles(s32 cameraId) { } } -void CM_InitClouds() { - if (GetWorld()->GetTrack()) { - GetWorld()->GetTrack()->InitClouds(); - } -} - -void CM_TickClouds(s32 arg0, Camera* camera) { - if (GetWorld()->GetTrack()) { - GetWorld()->GetTrack()->TickClouds(arg0, camera); +void CM_RaceDrawSky(ScreenContext* screen, s32 someId) { + // if (bDrawSkybox) { + if (CVarGetInteger("gDrawSky", true) == true) { + Sky::Instance->Draw(screen); + if (gGamestate != CREDITS_SEQUENCE) { + func_80057FC4(screen, someId); // DrawSkyActors + } + Sky::Instance->DrawFloor(screen); } } diff --git a/src/port/Game.h b/src/port/Game.h index fdd11c7a6..f649389af 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -72,8 +72,6 @@ void CM_ActivateSecondLapLakitu(s32 playerId); void CM_ActivateFinalLapLakitu(s32 playerId); void CM_ActivateReverseLakitu(s32 playerId); -void CM_InitClouds(); - void CM_DrawActors(Camera* camera); void CM_DrawStaticMeshActors(); @@ -102,7 +100,7 @@ void Editor_CleanWorld(); void CM_TickParticles(void); void CM_DrawParticles(s32 cameraId); -void CM_TickClouds(s32 arg0, Camera* camera); +void CM_RaceDrawSky(ScreenContext* screen, s32 someId); void CM_Waypoints(Player* player, int8_t playerId); diff --git a/src/port/ui/ContentBrowser.cpp b/src/port/ui/ContentBrowser.cpp index a5ef9baa3..1065007b6 100644 --- a/src/port/ui/ContentBrowser.cpp +++ b/src/port/ui/ContentBrowser.cpp @@ -94,6 +94,11 @@ namespace TrackEditor { for (const TrackInfo* info : gTrackRegistry.GetAllInfo()) { if (!info) { continue; } + // Skip this invalid option + if (info->ResourceName == "mk:podium_ceremony") { + continue; + } + if (!search.empty() && ToLower(info->Name).find(search) == std::string::npos) { continue; diff --git a/src/port/ui/PortMenu.cpp b/src/port/ui/PortMenu.cpp index 9eb273f5e..09a115e32 100644 --- a/src/port/ui/PortMenu.cpp +++ b/src/port/ui/PortMenu.cpp @@ -565,6 +565,14 @@ void PortMenu::AddSceneVisibility() { WidgetPath path = { "Developer", "Scene Visibility", SECTION_COLUMN_1 }; AddSidebarEntry("Developer", "Scene Visibility", 1); + AddWidget(path, "Draw Sky", WIDGET_CVAR_CHECKBOX) + .CVar("gDrawSky") + .Options(UIWidgets::CheckboxOptions().DefaultValue(true)); + + AddWidget(path, "Draw Sky Actors", WIDGET_CVAR_CHECKBOX) + .CVar("gDrawSkyActors") + .Options(UIWidgets::CheckboxOptions().DefaultValue(true)); + AddWidget(path, "Draw Track Geometry", WIDGET_CVAR_CHECKBOX) .CVar("gDrawTrackGeometry") .Options(UIWidgets::CheckboxOptions().DefaultValue(true)); diff --git a/src/racing/actors.c b/src/racing/actors.c index b407bc123..8e79331b5 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -1173,7 +1173,6 @@ void destroy_all_actors(void) { void init_actors_and_load_textures(void) { init_red_shell_texture(); destroy_all_actors(); - CM_CleanWorld(); gNumPermanentActors = 0; CM_BeginPlay(); diff --git a/src/racing/race_logic.c b/src/racing/race_logic.c index 4ea13aa35..ff95ecc88 100644 --- a/src/racing/race_logic.c +++ b/src/racing/race_logic.c @@ -414,7 +414,7 @@ void func_8028EC38(s32 arg0) { gRaceState = RACE_UNK; func_800CA330(25); func_800CA388(25); - D_800DC5B4 = 1; + bDrawSkybox = true; D_800DC5B0 = 1; D_800DC5B8 = 0; D_802BA038 = 5; @@ -642,7 +642,7 @@ void func_8028F4E8(void) { func_800CA388(0x19); gGotoMode = START_MENU_FROM_QUIT; gRaceState = RACE_UNK; - D_800DC5B4 = 1; + bDrawSkybox = true; D_800DC5B0 = 1; D_800DC5B8 = 0; D_802BA038 = 5; @@ -836,7 +836,7 @@ void func_8028FBD4(void) { gRaceState = RACE_UNK; func_800CA330(25); func_800CA388(25); - D_800DC5B4 = 1; + bDrawSkybox = true; D_800DC5B0 = 1; D_800DC5B8 = 0; D_802BA038 = 5; @@ -893,7 +893,7 @@ void func_8028FCBC(void) { gCourseTimer = 0.0f; gVBlankTimer = 0.0f; D_800DC5B0 = 1; - D_800DC5B4 = 1; + bDrawSkybox = true; D_802BA034 = 0.008f; D_8015F894 = 0; if (gScreenModeSelection != SCREEN_MODE_1P) { diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index aa3a46bf8..fba19a45b 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -75,7 +75,7 @@ Vtx D_802B8A10[] = { { { { 0, 120, -1 }, 0, { 0, 0 }, { 0x00, 0xDC, 0x00, 0xFF } } }, }; -void func_802A3730(ScreenContext* arg0) { +void race_set_viewport(ScreenContext* arg0) { s32 ulx; s32 uly; s32 lrx; @@ -209,7 +209,7 @@ void init_z_buffer(void) { gDPSetFillColor(gDisplayListHead++, 0xFFFCFFFC); gDPPipeSync(gDisplayListHead++); gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - gDPFillRectangle(gDisplayListHead++, 0, 0, 319, 239); + gDPFillRectangle(gDisplayListHead++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1); gDPPipeSync(gDisplayListHead++); gDPSetColorImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, VIRTUAL_TO_PHYSICAL(gPhysicalFramebuffers[sRenderingFramebuffer])); @@ -424,8 +424,8 @@ void func_802A487C(Vtx* arg0) { } } -void func_802A4A0C(Vtx* vtx, ScreenContext* arg1) { - Camera* camera = arg1->camera; +void func_802A4A0C(Vtx* vtx, ScreenContext* screen) { + Camera* camera = screen->camera; s16 temp_t5; f32 temp_f0; UNUSED s32 pad[2]; @@ -439,6 +439,7 @@ void func_802A4A0C(Vtx* vtx, ScreenContext* arg1) { func_802A450C(vtx); // Widescreen skybox + // Note that this is the correct fit for each screen due to how the viewport works vtx[0].v.ob[0] = OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH); vtx[1].v.ob[0] = OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH); vtx[2].v.ob[0] = OTRGetRectDimensionFromLeftEdge(0); @@ -470,7 +471,7 @@ void func_802A4A0C(Vtx* vtx, ScreenContext* arg1) { sp5C[1] *= 120.0f; temp_t5 = 120 - (s32) sp5C[1]; - arg1->cameraHeight = temp_t5; + screen->cameraHeight = temp_t5; vtx[1].v.ob[1] = temp_t5; vtx[2].v.ob[1] = temp_t5; vtx[4].v.ob[1] = temp_t5; @@ -540,259 +541,122 @@ void func_802A4EF4(void) { } } -void func_802A5004(void) { - +/** + * Refactored function, a little wonky due to preserving + * the original logic. + * + * The swapping of logic may be a required for proper draw order. + * Or, perhaps they slapped functions in differing orders for each screen on a wim. + */ +void race_begin_viewport(ScreenContext* screen, s32 mode) { init_rdp(); - func_802A3730(gScreenTwoCtx); - gSPClearGeometryMode(gDisplayListHead++, G_CLEAR_ALL_MODES); - - gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); - - func_802A39E0(gScreenTwoCtx); - if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8910, gScreenTwoCtx); - func_80057FC4(2); - func_802A487C((Vtx*) D_802B8910); - func_80093A30(2); + // -------------------------------------------------- + // Depth clear BEFORE viewport (horizontal + 3P/4P) + // -------------------------------------------------- + switch(gActiveScreenMode) { + case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: + case SCREEN_MODE_3P_4P_SPLITSCREEN: + func_802A39E0(screen); // Clear z-buffer only for this screen + break; } -} -void func_802A50EC(void) { - - init_rdp(); - func_802A3730(gScreenOneCtx); + race_set_viewport(screen); // differ on p3 gSPClearGeometryMode(gDisplayListHead++, G_CLEAR_ALL_MODES); gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); - func_802A39E0(gScreenOneCtx); - if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8890, gScreenOneCtx); - func_80057FC4(1); - func_802A487C((Vtx*) D_802B8890); - func_80093A30(1); + switch(gActiveScreenMode) { + case SCREEN_MODE_1P: + init_z_buffer(); // Clear the whole z-buffer + select_framebuffer(); + break; + case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: + func_802A39E0(screen); // Clear z-buffer only for this screen + break; } } -void func_802A51D4(void) { - - init_rdp(); - func_802A39E0(gScreenOneCtx); - func_802A3730(gScreenOneCtx); - - gSPClearGeometryMode(gDisplayListHead++, G_CLEAR_ALL_MODES); - gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); - - if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8890, gScreenOneCtx); - func_80057FC4(3); - func_802A487C((Vtx*) D_802B8890); - func_80093A30(3); - } -} - -void func_802A52BC(void) { - - init_rdp(); - func_802A39E0(gScreenTwoCtx); - func_802A3730(gScreenTwoCtx); - - gSPClearGeometryMode(gDisplayListHead++, G_CLEAR_ALL_MODES); - gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); - - if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8910, gScreenTwoCtx); - func_80057FC4(4); - func_802A487C((Vtx*) D_802B8910); - func_80093A30(4); - } -} - -void func_802A53A4(void) { - init_rdp(); - func_802A3730(gScreenOneCtx); - - gSPClearGeometryMode(gDisplayListHead++, G_CLEAR_ALL_MODES); - gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); - - init_z_buffer(); - select_framebuffer(); - if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8890, gScreenOneCtx); - if (gGamestate != CREDITS_SEQUENCE) { - func_80057FC4(0); - } - func_802A487C((Vtx*) D_802B8890); - func_80093A30(0); - } -} - -void func_802A54A8(void) { - - init_rdp(); - func_802A39E0(gScreenOneCtx); - func_802A3730(gScreenOneCtx); - - gSPClearGeometryMode(gDisplayListHead++, G_CLEAR_ALL_MODES); - gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); - - if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8890, gScreenOneCtx); - func_80057FC4(8); - func_802A487C((Vtx*) D_802B8890); - func_80093A30(8); - } -} - -void func_802A5590(void) { - - init_rdp(); - func_802A39E0(gScreenTwoCtx); - func_802A3730(gScreenTwoCtx); - - gSPClearGeometryMode(gDisplayListHead++, G_CLEAR_ALL_MODES); - gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); - - if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8910, gScreenTwoCtx); - func_80057FC4(9); - func_802A487C((Vtx*) D_802B8910); - func_80093A30(9); - } -} - -void func_802A5678(void) { - - init_rdp(); - func_802A39E0(gScreenThreeCtx); - func_802A3730(gScreenThreeCtx); - - gSPClearGeometryMode(gDisplayListHead++, G_CLEAR_ALL_MODES); - gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); - - if (D_800DC5B4 != 0) { - func_802A4A0C((Vtx*) D_802B8990, gScreenThreeCtx); - func_80057FC4(10); - func_802A487C((Vtx*) D_802B8990); - func_80093A30(10); - } -} - -void func_802A5760(void) { - +/** + * Creates the blank screen for player four in + * three player mode + */ +void race_blank_viewport(ScreenContext* screen) { init_rdp(); gSPClearGeometryMode(gDisplayListHead++, G_CLEAR_ALL_MODES); gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); - if (gPlayerCountSelection1 == 3) { + gDPPipeSync(gDisplayListHead++); + func_802A39E0(screen); + gDPSetCycleType(gDisplayListHead++, G_CYC_FILL); + gDPSetColorImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, + VIRTUAL_TO_PHYSICAL(gPhysicalFramebuffers[sRenderingFramebuffer])); + gDPSetFillColor(gDisplayListHead++, 0x00010001); + gDPPipeSync(gDisplayListHead++); + gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 160, 120, SCREEN_WIDTH, SCREEN_HEIGHT); + gDPFillRectangle(gDisplayListHead++, 160, 120, OTRGetDimensionFromRightEdge(320), SCREEN_HEIGHT - 1); + gDPPipeSync(gDisplayListHead++); + gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE); - gDPPipeSync(gDisplayListHead++); - func_802A39E0(gScreenFourCtx); - gDPSetCycleType(gDisplayListHead++, G_CYC_FILL); - gDPSetColorImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, - VIRTUAL_TO_PHYSICAL(gPhysicalFramebuffers[sRenderingFramebuffer])); - gDPSetFillColor(gDisplayListHead++, 0x00010001); - gDPPipeSync(gDisplayListHead++); - gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 160, 120, SCREEN_WIDTH, SCREEN_HEIGHT); - gDPFillRectangle(gDisplayListHead++, 160, 120, OTRGetDimensionFromRightEdge(320), SCREEN_HEIGHT - 1); - gDPPipeSync(gDisplayListHead++); - gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE); - - func_802A3730(gScreenFourCtx); - - } else { - func_802A3730(gScreenFourCtx); - func_802A39E0(gScreenFourCtx); - - if (D_800DC5B4 != 0) { - func_802A4A0C(D_802B8A10, gScreenFourCtx); - func_80057FC4(11); - func_802A487C(D_802B8A10); - func_80093A30(11); - } - } + race_set_viewport(screen); } -void render_screens(s32 mode, s32 cameraId, s32 playerId) { +void race_begin_viewport_4p(ScreenContext* screen) { + init_rdp(); + + gSPClearGeometryMode(gDisplayListHead++, G_CLEAR_ALL_MODES); + gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); + + race_set_viewport(screen); + func_802A39E0(screen); +} + +void render_screens(ScreenContext* screen, s32 mode, s32 someId, s32 playerId) { Mat4 matrix; + Camera* camera = screen->camera; + s32 screenId = screen - gScreenContexts; - s32 screenId = 0; - s32 screenMode = SCREEN_MODE_1P; + if (NULL == camera) { + printf("[skybox_and_splitscreen.c] Skipping rendering for screen %d. This viewport has no camera\n", screen - gScreenContexts); + return; + } - switch (mode) { - case RENDER_SCREEN_MODE_1P_PLAYER_ONE: - func_802A53A4(); - screenId = 0; - screenMode = SCREEN_MODE_1P; - break; - case RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE: - func_802A51D4(); - screenId = 0; - screenMode = SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL; - break; - case RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO: - func_802A52BC(); - screenId = 1; - screenMode = SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL; - break; - case RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE: - func_802A50EC(); - screenId = 0; - screenMode = SCREEN_MODE_2P_SPLITSCREEN_VERTICAL; - break; - case RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO: - func_802A5004(); - screenId = 1; - screenMode = SCREEN_MODE_2P_SPLITSCREEN_VERTICAL; - break; - case RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE: - func_802A54A8(); - screenId = 0; - screenMode = SCREEN_MODE_3P_4P_SPLITSCREEN; - break; - case RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO: - func_802A5590(); - screenId = 1; - screenMode = SCREEN_MODE_3P_4P_SPLITSCREEN; - break; - case RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE: - func_802A5678(); - screenId = 2; - screenMode = SCREEN_MODE_3P_4P_SPLITSCREEN; - break; - case RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR: - func_802A5760(); - screenId = 3; - screenMode = SCREEN_MODE_3P_4P_SPLITSCREEN; + switch(mode) { + case RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR: // Blank screen if (gPlayerCountSelection1 == 3) { + race_blank_viewport(screen); func_80093A5C(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR); if (D_800DC5B8 != 0) { render_hud(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR); } gNumScreens += 1; return; + } else { // Player four + race_begin_viewport_4p(screen); + + if ((CVarGetInteger("gDrawSky", true) == true)) { + CM_RaceDrawSky(screen, someId); + func_80093A30(someId); // Fill box for thunderbolt? + } + } + break; + default: + race_begin_viewport(screen, mode); + + if ((CVarGetInteger("gDrawSky", true) == true)) { + CM_RaceDrawSky(screen, someId); + func_80093A30(someId); // Fill box for thunderbolt? } break; } - ScreenContext* screen = &gScreenContexts[screenId]; - Camera* camera = screen->camera; - cameraId = camera->cameraId; - // CM_GetCamera(cameraId); - - if (NULL == camera) { - printf("NO CAMERA SELECTED\n"); - return; - } - - if (screenMode == SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL) { + if (gActiveScreenMode == SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL) { gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH); } init_rdp(); - func_802A3730(screen); + race_set_viewport(screen); gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH); gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); @@ -800,7 +664,7 @@ void render_screens(s32 mode, s32 cameraId, s32 playerId) { CM_SetViewProjection(camera); // Create a matrix for the track and game objects - FrameInterpolation_RecordOpenChild("track", TAG_TRACK((cameraId | (playerId << 2)))); + FrameInterpolation_RecordOpenChild("track", TAG_TRACK((camera->cameraId | (playerId << 2)))); Mat4 trackMatrix; mtxf_identity(trackMatrix); if (gIsMirrorMode != 0) { diff --git a/src/racing/skybox_and_splitscreen.h b/src/racing/skybox_and_splitscreen.h index f198b727e..38748f36a 100644 --- a/src/racing/skybox_and_splitscreen.h +++ b/src/racing/skybox_and_splitscreen.h @@ -12,7 +12,7 @@ void func_802A4A0C(Vtx*, ScreenContext*); void set_screen(void); void set_editor_screen(void); -void func_802A3730(ScreenContext*); +void race_set_viewport(ScreenContext*); void func_802A38AC(void); void func_802A38B4(void); void func_802A39E0(ScreenContext*); @@ -34,25 +34,10 @@ void func_802A450C(Vtx*); void func_802A487C(Vtx*); void func_802A4D18(void); void func_802A4EF4(void); -void func_802A5004(void); -void func_802A50EC(void); -void func_802A51D4(void); -void func_802A52BC(void); -void func_802A53A4(void); -void func_802A54A8(void); -void func_802A5590(void); -void func_802A5678(void); -void func_802A5760(void); -void render_player_one_1p_screen(void); -void render_player_one_2p_screen_vertical(void); -void render_player_two_2p_screen_vertical(void); -void render_player_one_2p_screen_horizontal(void); -void render_player_two_2p_screen_horizontal(void); -void render_player_one_3p_4p_screen(void); -void render_player_two_3p_4p_screen(void); -void render_player_three_3p_4p_screen(void); -void render_player_four_3p_4p_screen(void); -void render_screens(s32 mode, s32 cameraId, s32 playerId); +void race_begin_viewport(ScreenContext* screen, s32 mode); +void race_blank_viewport(ScreenContext* screen); +void race_begin_viewport_4p(ScreenContext* screen); +void render_screens(ScreenContext* screen, s32 mode, s32 someId, s32 playerId); void func_802A74BC(void); void copy_framebuffer(s32, s32, s32, s32, u16*, u16*); void func_802A7728(void); diff --git a/src/render_objects.c b/src/render_objects.c index 5e300808d..a14c3d350 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -47,6 +47,7 @@ #include "engine/Matrix.h" #include "engine/tracks/Track.h" #include "engine/TrackBrowser.h" +#include "engine/sky/Sky.h" #include "port/interpolation/FrameInterpolation.h" #include "assets/textures/tracks/sherbet_land/sherbet_land_data.h" @@ -3476,97 +3477,18 @@ void render_object_snowflakes_particles(void) { gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); } -struct ObjectInterpData { - s32 objectIndex; - s16 x, y; -}; - -struct ObjectInterpData prevObject[OBJECT_LIST_SIZE] = { 0 }; - -void render_clouds(s32 objectIndex, s16 x, s16 y) { - - // Search all recorded objects for the one we're drawing - for (size_t i = 0; i < OBJECT_LIST_SIZE; i++) { - if (objectIndex == prevObject[i].objectIndex) { - // Coincidence! - // Skip drawing the object this frame if it warped to the other side of the screen - if ((fabs(x - prevObject[i].x) > SCREEN_WIDTH / 2) || (fabs(y - prevObject[i].y) > SCREEN_HEIGHT / 2)) { - prevObject[objectIndex].x = x; - prevObject[objectIndex].y = y; - prevObject[objectIndex].objectIndex = objectIndex; - return; - } - } - } - - if (gObjectList[objectIndex].status & 0x10) { - - // @port: Tag the transform. - FrameInterpolation_RecordOpenChild("render_clouds", TAG_CLOUDS(objectIndex)); - - if (D_8018D228 != gObjectList[objectIndex].unk_0D5) { - D_8018D228 = gObjectList[objectIndex].unk_0D5; - func_80044DA0(gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].textureWidth, - gObjectList[objectIndex].textureHeight); - } - func_80042330_unchanged(x, y, 0, gObjectList[objectIndex].sizeScaling); - gSPVertex(gDisplayListHead++, gObjectList[objectIndex].vertex, 4, 0); - gSPDisplayList(gDisplayListHead++, common_rectangle_display); - - // @port Pop the transform id. - FrameInterpolation_RecordCloseChild(); - } - - // Save current cloud index and x position - prevObject[objectIndex].x = x; - prevObject[objectIndex].y = y; - prevObject[objectIndex].objectIndex = objectIndex; -} - -void func_800519D4(s32 objectIndex, s16 arg1, s16 arg2) { - if (gObjectList[objectIndex].status & 0x10) { - if (D_8018D228 != gObjectList[objectIndex].unk_0D5) { - D_8018D228 = gObjectList[objectIndex].unk_0D5; - func_80044DA0(gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].textureWidth, - gObjectList[objectIndex].textureHeight); - } - func_8004B138(0x000000FF, 0x000000FF, 0x000000FF, gObjectList[objectIndex].primAlpha); - func_80042330_unchanged(arg1, arg2, 0U, gObjectList[objectIndex].sizeScaling); - gSPVertex(gDisplayListHead++, gObjectList[objectIndex].vertex, 4, 0); - gSPDisplayList(gDisplayListHead++, common_rectangle_display); - } -} - // Render clouds -void func_80051ABC(s16 arg0, s32 arg1) { +void func_80051ABC(ScreenContext* screen, s16 arg0, s32 arg1) { s32 var_s0; s32 objectIndex; Object* object; D_8018D228 = 0xFF; gSPDisplayList(gDisplayListHead++, D_0D007A60); - if ((u8) D_8018D230 != 0) { - func_8004B414(255, 255, 255, 255); - for (var_s0 = 0; var_s0 < D_8018D1F0; var_s0++) { - objectIndex = D_8018CC80[arg1 + var_s0]; - object = &gObjectList[objectIndex]; - FrameInterpolation_RecordOpenChild("stars_cloud", TAG_OBJECT(object)); - - func_800519D4(objectIndex, object->unk_09C, arg0 - object->unk_09E); - FrameInterpolation_RecordCloseChild(); - } - } else { - func_8004B6C4(255, 255, 255); - for (var_s0 = 0; var_s0 < D_8018D1F0; var_s0++) { - objectIndex = D_8018CC80[arg1 + var_s0]; - object = &gObjectList[objectIndex]; - - render_clouds(objectIndex, object->unk_09C, arg0 - object->unk_09E); - } - } + DrawSkyActors(screen, arg0); } -void func_80051C60(s16 arg0, s32 arg1) { +void func_80051C60(ScreenContext* screen, s16 arg0, s32 arg1) { s16 var_s5; s32 var_s0; s32 objectIndex; @@ -3590,32 +3512,17 @@ void func_80051C60(s16 arg0, s32 arg1) { D_8018D228 = 0xFF; gSPDisplayList(gDisplayListHead++, D_0D007A60); - - if ((u8) D_8018D230 != 0) { - func_8004B414(255, 255, 255, 255); - for (var_s0 = 0; var_s0 < D_8018D1F0; var_s0++) { - objectIndex = D_8018CC80[arg1 + var_s0]; - object = &gObjectList[objectIndex]; - func_800519D4(objectIndex, object->unk_09C, (var_s5 - object->unk_09E) / 2); - } - } else { - func_8004B6C4(255, 255, 255); - for (var_s0 = 0; var_s0 < D_8018D1F0; var_s0++) { - objectIndex = D_8018CC80[arg1 + var_s0]; - object = &gObjectList[objectIndex]; - render_clouds(objectIndex, object->unk_09C, (var_s5 - object->unk_09E) / 2); - } - } + DrawSkyActors(screen, arg0); } -void func_80051EBC(void) { - func_80051ABC(240 - gScreenOneCtx->cameraHeight, 0); // 28 +void func_80051EBC(ScreenContext* screen) { + func_80051ABC(screen, 240 - screen->cameraHeight, 0); // 28 } -void func_80051EF8(void) { +void func_80051EF8(ScreenContext* screen) { s16 temp_a0; - temp_a0 = 0xF0 - gScreenOneCtx->cameraHeight; + temp_a0 = 0xF0 - screen->cameraHeight; if (IsKoopaTroopaBeach()) { temp_a0 = temp_a0 - 0x30; } else if (IsMooMooFarm()) { @@ -3625,13 +3532,13 @@ void func_80051EF8(void) { } else { temp_a0 = temp_a0 - 0x30; } - func_80051ABC(temp_a0, 0); + func_80051ABC(screen, temp_a0, 0); } -void func_80051F9C(void) { +void func_80051F9C(ScreenContext* screen) { s16 temp_a0; - temp_a0 = 0xF0 - gScreenTwoCtx->cameraHeight; + temp_a0 = 0xF0 - screen->cameraHeight; if (IsKoopaTroopaBeach()) { temp_a0 = temp_a0 - 0x30; } else if (IsMooMooFarm()) { @@ -3641,15 +3548,15 @@ void func_80051F9C(void) { } else { temp_a0 = temp_a0 - 0x30; } - func_80051ABC(temp_a0, D_8018D1F0); + func_80051ABC(screen, temp_a0, D_8018D1F0); } -void func_80052044(void) { - func_80051C60(240 - gScreenOneCtx->cameraHeight, 0); +void func_80052044(ScreenContext* screen) { + func_80051C60(screen, 240 - screen->cameraHeight, 0); } -void func_80052080(void) { - func_80051C60(240 - gScreenTwoCtx->cameraHeight, D_8018D1F0); +void func_80052080(ScreenContext* screen) { + func_80051C60(screen, 240 - screen->cameraHeight, D_8018D1F0); } void func_800520C0(s32 arg0) { diff --git a/src/render_objects.h b/src/render_objects.h index ff0b91303..083481776 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -3,6 +3,7 @@ #include #include "main.h" +#include "code_800029B0.h" #ifdef __cplusplus extern "C" { @@ -318,16 +319,14 @@ void func_80050E34(s32, s32); void func_800514BC(void); void render_object_leaf_particle(s32); void render_object_snowflakes_particles(void); -void render_clouds(s32, s16, s16); -void func_800519D4(s32, s16, s16); -void func_80051ABC(s16, s32); -void func_80051C60(s16, s32); -void func_80051EBC(void); -void func_80051EF8(void); -void func_80051F9C(void); +void func_80051ABC(ScreenContext* screen, s16, s32); +void func_80051C60(ScreenContext* screen, s16, s32); +void func_80051EBC(ScreenContext* screen); +void func_80051EF8(ScreenContext* screen); +void func_80051F9C(ScreenContext* screen); +void func_80052044(ScreenContext* screen); +void func_80052080(ScreenContext* screen); -void func_80052044(void); -void func_80052080(void); void func_800520C0(s32); void func_8005285C(s32); void func_800528EC(s32); diff --git a/src/update_objects.c b/src/update_objects.c index 75e1671de..a8bd556bd 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -45,6 +45,7 @@ #include #include "engine/RaceManager.h" +#include "engine/sky/Sky.h" float OTRGetAspectRatio(void); @@ -2210,123 +2211,6 @@ void update_leaf(void) { } } -void func_80077D5C(s32 arg0) { - s32 objectIndex; - s32 var_a1; - - if (D_8016559C == 0) { - for (var_a1 = 0; var_a1 < D_8018D1F0; var_a1++) { - D_8018D17C += 1; - if (D_8018D17C >= D_8018D1F0) { - D_8018D17C = 0; - } - objectIndex = D_8018CC80[arg0 + D_8018D17C]; - if (gObjectList[objectIndex].state == 0) { - init_object(objectIndex, 1); - break; - } - } - } -} - -void func_80077E20(s32 objectIndex) { - Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_rectangle); - Object* object; - - object = &gObjectList[objectIndex]; - object->activeTexture = D_0D0293D8; - object->textureList = D_0D0293D8; - //! @bug frappe snowland There's something up with the handling of common_vtx_rectangle and the loading of 0x10 - //! right here - // root function: func_80078C70 - object->vertex = vtx; - object->textureHeight = 0x10; - object->textureWidth = object->textureHeight; - object->sizeScaling = 0.15f; - set_object_flag(objectIndex, 0x00000010); - func_80086EF0(objectIndex); - object->primAlpha = 0x00FF; - object->unk_0D5 = 0; - object->type = 0; - object_next_state(objectIndex); -} - -void func_80077EB8(s32 objectIndex, u16 arg1, Camera* camera) { - s16 temp_v0; - - temp_v0 = camera->rot[1] - arg1; - if ((temp_v0 >= D_8018D210) || (D_8018D208 >= temp_v0)) { - gObjectList[objectIndex].offset[0] = D_8018D218 + (D_8018D1E8 * (f32) temp_v0); - set_object_flag(objectIndex, 0x00000010); - return; - } - clear_object_flag(objectIndex, 0x00000010); -} - -void func_80077F64(s32 objectIndex, Camera* camera) { - - f64 rand; - - switch (gObjectList[objectIndex].unk_0AE) { /* irregular */ - case 1: - gObjectList[objectIndex].direction_angle[1] = (camera->rot[1] + random_int(0x4000U)) - 0x2000; - object_origin_pos_randomize_around_y(objectIndex, 0x00B4, 0x0014U); - rand = random_int(0x0064U); - - gObjectList[objectIndex].velocity[1] = (f32) (-0.75 - (f64) (f32) (rand * 0.01)); - gObjectList[objectIndex].offset[0] = 0.0f; - gObjectList[objectIndex].offset[1] = 0.0f; - func_80086FD4(objectIndex); - return; - case 2: - func_80077EB8(objectIndex, gObjectList[objectIndex].direction_angle[1], camera); - object_add_velocity_offset_y(objectIndex); - object_calculate_new_pos_offset(objectIndex); - func_8008BFC0(objectIndex); - if (gObjectList[objectIndex].pos[1] <= 0.0f) { - func_80086FD4(objectIndex); - return; - } - case 0: - return; - case 3: - func_80086F60(objectIndex); - break; - } -} - -void func_800780CC(s32 objectIndex, Camera* camera) { - switch (gObjectList[objectIndex].state) { /* irregular */ - case 1: - func_80077E20(objectIndex); - return; - case 2: - func_80077F64(objectIndex, camera); - if (gObjectList[objectIndex].unk_0AE == 0) { - object_next_state(objectIndex); - return; - } - case 0: - return; - case 3: - func_80072428(objectIndex); - break; - } -} - -void func_80078170(s32 arg0, Camera* arg1) { - s32 objectIndex; - s32 i; - - func_80077D5C(arg0); - for (i = 0; i < D_8018D1F0; i++) { - objectIndex = D_8018CC80[arg0 + i]; - if (gObjectList[objectIndex].state != 0) { - func_800780CC(objectIndex, arg1); - } - } -} - void func_80078220(s32 objectIndex) { u8* tex = (u8*) LOAD_ASSET(D_0D0293D8); Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_rectangle); @@ -2451,119 +2335,9 @@ void update_snowflakes(void) { } } -// This function adjusted to place clouds in the sky correctly -void func_800788F8(s32 objectIndex, u16 rot, Camera* camera) { - s16 cameraRot; - // Adjustable culling factor - const float cullingFactor = OTRGetAspectRatio(); - - // Calculate the cloud's rotation relative to the camera - cameraRot = camera->rot[1] + rot; - - // Adjust bounds based on the culling factor - s16 adjustedLowerBound = (s16) (D_8018D210 * cullingFactor); - s16 adjustedUpperBound = (s16) (D_8018D208 * cullingFactor); - - // Check if the object is within the adjusted bounds - if ((cameraRot >= adjustedLowerBound) && (adjustedUpperBound >= cameraRot)) { - // Calculate and update the object's position - gObjectList[objectIndex].unk_09C = (D_8018D218 + (D_8018D1E8 * cameraRot)); - - // Mark the object as visible - set_object_flag(objectIndex, 0x10); - } else { - // If outside the bounds, mark the object as not visible - set_object_flag(objectIndex, 0x10); - } -} - -void update_clouds(s32 arg0, Camera* arg1, CloudData* cloudList) { - s32 cloudIndex; - s32 objectIndex; - CloudData* cloud; - - for (cloudIndex = 0; cloudIndex < D_8018D1F0; cloudIndex++) { - cloud = &cloudList[cloudIndex]; - objectIndex = D_8018CC80[arg0 + cloudIndex]; - func_800788F8(objectIndex, cloud->rotY, arg1); - } -} - -void update_stars(s32 arg0, Camera* camera, StarData* starList) { - s32 starIndex; - s32 objectIndex; - StarData* star; - - for (starIndex = 0; starIndex < D_8018D1F0; starIndex++) { - star = &starList[starIndex]; - objectIndex = D_8018CC80[arg0 + starIndex]; - func_800788F8(objectIndex, star->rotY, camera); - switch (starIndex % 5U) { - case 0: - func_80073CB0(objectIndex, &gObjectList[objectIndex].primAlpha, 0x00000028, 0x000000B4, 0x000000FF, 0, - -1); - break; - case 1: - func_80073CB0(objectIndex, &gObjectList[objectIndex].primAlpha, 0x00000080, 0x000000FF, 0x000000FF, 0, - -1); - break; - case 2: - func_80073CB0(objectIndex, &gObjectList[objectIndex].primAlpha, 0x00000050, 0x000000C8, 0x000000FF, 0, - -1); - break; - case 3: - func_80073CB0(objectIndex, &gObjectList[objectIndex].primAlpha, 0, 0x0000009B, 0x000000FF, 0, -1); - break; - case 4: - func_80073CB0(objectIndex, &gObjectList[objectIndex].primAlpha, 0x0000005A, 0x00000080, 0x000000FF, 0, - -1); - break; - } - } -} - -UNUSED void func_80078C68() { -} - -void func_80078C70(s32 arg0) { - s32 sp1C; - Camera* camera; - +void func_80078C70() { if (D_801657C8 == 0) { - switch (arg0) { /* switch 1 */ - case 0: /* switch 1 */ - sp1C = 0; - camera = camera1; - D_8018D200 = camera->fieldOfView + 40.0f; - break; - case 1: /* switch 1 */ - sp1C = 0; - camera = camera1; - D_8018D200 = camera->fieldOfView + 40.0f; - break; - case 2: /* switch 1 */ - camera = camera2; - sp1C = D_8018D1F0; - D_8018D200 = camera->fieldOfView + 40.0f; - break; - case 3: /* switch 1 */ - sp1C = 0; - camera = camera1; - D_8018D200 = camera->fieldOfView + 40.0f; - break; - case 4: /* switch 1 */ - camera = camera2; - sp1C = D_8018D1F0; - D_8018D200 = camera->fieldOfView + 40.0f; - break; - } - - D_8018D208 = ((D_8018D200 / 2) * 0xB6) + 0x71C; - D_8018D210 = (-(D_8018D200 / 2) * 0xB6) - 0x71C; - D_8018D1E8 = 1.7578125 / D_8018D200; - D_8018D218 = 0xA0; - - CM_TickClouds(sp1C, camera); + TickSkyActors(); } } diff --git a/src/update_objects.h b/src/update_objects.h index 228d40bf2..4db33ea7b 100644 --- a/src/update_objects.h +++ b/src/update_objects.h @@ -8,8 +8,6 @@ /** @cond */ -void func_80078170(s32 arg0, Camera* arg1); -void func_80077D5C(s32); s32 find_unused_obj_index(s32*); void delete_object(s32*); s32 func_80071FBC(void); @@ -168,17 +166,12 @@ void func_80077B14(s32); void func_80077B3C(s32); void func_80077BCC(s32); void update_leaf(void); -void func_80077E20(s32); void func_80078220(s32); void func_80078288(s32); void func_800786EC(s32); void func_80078790(void); void update_snowflakes(void); -void func_800788F8(s32, u16, Camera*); -void update_clouds(s32, Camera*, CloudData*); -void update_stars(s32, Camera*, StarData*); -void func_80078C68(void); -void func_80078C70(s32); +void func_80078C70(); void func_80078F64(void); void func_80079054(s32); void func_80079084(s32);