mirror of
https://github.com/HarbourMasters/SpaghettiKart
synced 2026-08-27 17:07:15 -04:00
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
This commit is contained in:
@@ -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"
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ public:
|
||||
|
||||
TrackBrowser(const Registry<TrackInfo>& 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<TrackInfo>& 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);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <memory>
|
||||
#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();
|
||||
}
|
||||
|
||||
+2
-1
@@ -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<std::unique_ptr<StaticMeshActor>> StaticMeshActors;
|
||||
std::vector<std::unique_ptr<AActor>> Actors;
|
||||
std::vector<std::unique_ptr<OObject>> Objects;
|
||||
std::deque<std::unique_ptr<OObject>> Objects;
|
||||
std::vector<std::unique_ptr<ParticleEmitter>> Emitters;
|
||||
|
||||
std::unordered_map<s32, OLakitu*> Lakitus;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -213,6 +213,15 @@ void RegisterTracks(Registry<TrackInfo>& r) {
|
||||
|
||||
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<BigDonut>()); });
|
||||
|
||||
info = {
|
||||
.ResourceName = "mk:podium_ceremony",
|
||||
.Name = "podium ceremony",
|
||||
.DebugName = "podium",
|
||||
.Length = "1025m",
|
||||
};
|
||||
|
||||
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<PodiumCeremony>()); });
|
||||
|
||||
info = {
|
||||
.ResourceName = "hm:test_track",
|
||||
.Name = "test track",
|
||||
|
||||
@@ -0,0 +1,350 @@
|
||||
#include "Sky.h"
|
||||
|
||||
#include <libultraship.h>
|
||||
#include <libultra/gbi.h>
|
||||
#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<std::unique_ptr<SkyActor>>& 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<SkySnow>(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<SkyCloud>(screen, cloud->subType, cloud->posY, cloud->rotY, cloud->scalePercent));
|
||||
D_8018D230 = 0;
|
||||
break;
|
||||
}
|
||||
case Track::CloudType::STARS: {
|
||||
mSkyActors.emplace_back(std::make_unique<SkyStar>(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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef SKY_H
|
||||
#define SKY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <libultraship/libultraship.h>
|
||||
#include <libultraship/libultra/gbi.h>
|
||||
|
||||
#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<std::unique_ptr<SkyActor>>& GetSkyActors();
|
||||
private:
|
||||
Mtx mSkyboxMatrix;
|
||||
static Vtx mSkyboxScreenOne[8];
|
||||
static Vtx mSkyboxScreenTwo[8];
|
||||
static Vtx mSkyboxScreenThree[8];
|
||||
static Vtx mSkyboxScreenFour[8];
|
||||
|
||||
std::vector<std::unique_ptr<SkyActor>> 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
|
||||
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <libultraship.h>
|
||||
#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;
|
||||
};
|
||||
@@ -0,0 +1,112 @@
|
||||
#include <libultraship.h>
|
||||
#include <libultra/gbi.h>
|
||||
#include "SkyCloud.h"
|
||||
#include <vector>
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <libultraship.h>
|
||||
#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;
|
||||
};
|
||||
@@ -0,0 +1,183 @@
|
||||
#include <libultraship.h>
|
||||
#include <libultra/gbi.h>
|
||||
#include "SkySnow.h"
|
||||
#include <vector>
|
||||
#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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <libultraship.h>
|
||||
#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;
|
||||
};
|
||||
@@ -0,0 +1,165 @@
|
||||
#include <libultraship.h>
|
||||
#include <libultra/gbi.h>
|
||||
#include "SkyStar.h"
|
||||
#include <vector>
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <libultraship.h>
|
||||
#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;
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<Ship::Archive> 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();
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user