summaryrefslogtreecommitdiff
path: root/src/engine
diff options
context:
space:
mode:
authorMegaMech <MegaMech@users.noreply.github.com>2025-06-18 12:32:55 -0600
committerGitHub <noreply@github.com>2025-06-18 12:32:55 -0600
commit5011f932c2349d75e609612af4e5e8395c1f75eb (patch)
tree8bdb046f3aae3542b8921ce1b24b72e094c07015 /src/engine
parentd3a3e761cff650c8a4b707377dd17f70dc4e9ca0 (diff)
Interpolate hm intro (#228)
* Interpolation ApplyMatrixTransformations * Fix scenefile saving and add skybox export --------- Co-authored-by: MegaMech <7255464+MegaMech@users.noreply.github.com>
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/HM_Intro.cpp15
-rw-r--r--src/engine/Matrix.cpp1
-rw-r--r--src/engine/courses/Course.cpp11
-rw-r--r--src/engine/courses/Course.h51
-rw-r--r--src/engine/editor/SceneManager.cpp2
5 files changed, 71 insertions, 9 deletions
diff --git a/src/engine/HM_Intro.cpp b/src/engine/HM_Intro.cpp
index e27d5db0c..320ea9e45 100644
--- a/src/engine/HM_Intro.cpp
+++ b/src/engine/HM_Intro.cpp
@@ -3,6 +3,7 @@
#include "HM_Intro.h"
#include "port/Game.h"
+#include "port/interpolation/FrameInterpolation.h"
extern "C" {
#include "main.h"
@@ -64,7 +65,7 @@ void HarbourMastersIntro::HM_InitIntro() {
0x60, 20, 10, 0x49, 0x49, 0x49
);
- gEditor.AddObject("lus", &lusPos, &lusRot, &lusScale, nullptr, 1, Editor::GameObject::CollisionType::BOUNDING_BOX, 10, &DespawnValue, -1);
+ //gEditor.AddObject("lus", &lusPos, &lusRot, &lusScale, nullptr, 1, Editor::GameObject::CollisionType::BOUNDING_BOX, 10, &DespawnValue, -1);
}
void HarbourMastersIntro::HM_TickIntro() {
@@ -115,6 +116,7 @@ void HarbourMastersIntro::SpagBob(FVector& pos, IRotator& rot, f32 bobAmp, f32 b
}
void HarbourMastersIntro::HM_DrawIntro() {
+ FrameInterpolation_ShouldInterpolateFrame(false);
HarbourMastersIntro::Setup();
gSPMatrix(gDisplayListHead++, &gGfxPool->mtxScreen, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
@@ -122,21 +124,28 @@ void HarbourMastersIntro::HM_DrawIntro() {
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
gDPSetEnvColor(gDisplayListHead++, 0x00, 0x00, 0x00, 0x00);
+ FrameInterpolation_RecordOpenChild("spag_ship", 0);
Mat4 mtx_spaghettiShip;
ApplyMatrixTransformations(mtx_spaghettiShip, _pos, _rot, _scale);
render_set_position(mtx_spaghettiShip, 0);
gSPDisplayList(gDisplayListHead++, ship1_spag1_mesh);
+ FrameInterpolation_RecordCloseChild();
+ FrameInterpolation_RecordOpenChild("ship2", 0);
Mat4 mtx_ship2;
ApplyMatrixTransformations(mtx_ship2, _ship2Pos, _ship2Rot, _scale);
render_set_position(mtx_ship2, 0);
gSPDisplayList(gDisplayListHead++, ship2_SoH_mesh);
+ FrameInterpolation_RecordCloseChild();
+ FrameInterpolation_RecordOpenChild("ship3", 0);
Mat4 mtx_ship3;
ApplyMatrixTransformations(mtx_ship3, _shipPos, _shipRot, _scale);
render_set_position(mtx_ship3, 0);
gSPDisplayList(gDisplayListHead++, ship3_2Ship_mesh);
+ FrameInterpolation_RecordCloseChild();
+ FrameInterpolation_RecordOpenChild("hm_geo", 0);
Mat4 mtx_geo;
ApplyMatrixTransformations(mtx_geo, _hPos, _hRot, _hScale);
render_set_position(mtx_geo, 0);
@@ -146,13 +155,17 @@ void HarbourMastersIntro::HM_DrawIntro() {
gSPDisplayList(gDisplayListHead++, castle_map_002_mesh);
gSPDisplayList(gDisplayListHead++, road_map_001_mesh);
gSPDisplayList(gDisplayListHead++, water_water1_mesh);
+ FrameInterpolation_RecordCloseChild();
+ FrameInterpolation_RecordOpenChild("hm_lus", 0);
Mat4 lusMtx;
ApplyMatrixTransformations(lusMtx, lusPos, lusRot, lusScale);
render_set_position(lusMtx, 0);
gSPDisplayList(gDisplayListHead++, (Gfx*)"__OTR__hmintro/poweredbylus");
+ FrameInterpolation_RecordCloseChild();
HarbourMastersIntro::Sync();
+ FrameInterpolation_ShouldInterpolateFrame(true);
}
void HarbourMastersIntro::Setup() {
diff --git a/src/engine/Matrix.cpp b/src/engine/Matrix.cpp
index b55a9b89f..4c87d7eb7 100644
--- a/src/engine/Matrix.cpp
+++ b/src/engine/Matrix.cpp
@@ -74,6 +74,7 @@ void ApplyMatrixTransformations(Mat4 mtx, FVector pos, IRotator rot, FVector sca
f32 sine1, cosine1;
f32 sine2, cosine2;
f32 sine3, cosine3;
+ FrameInterpolation_ApplyMatrixTransformations((Mat4*)mtx, pos, rot, scale);
// Compute the sine and cosine of the orientation (Euler angles)
sine1 = sins(rot.pitch);
diff --git a/src/engine/courses/Course.cpp b/src/engine/courses/Course.cpp
index bbc9455fe..94d634373 100644
--- a/src/engine/courses/Course.cpp
+++ b/src/engine/courses/Course.cpp
@@ -23,12 +23,13 @@ extern "C" {
#include "render_courses.h"
#include "collision.h"
#include "actors.h"
+#include "math_util.h"
extern StaffGhost* d_mario_raceway_staff_ghost;
}
Course::Course() {
- // Props.Name = "Course Name";
- // Props.DebugName = "CName";
+ Props.SetText(Props.Name, "Blank Track", sizeof(Props.Name));
+ Props.SetText(Props.DebugName, "blnktrck", sizeof(Props.DebugName));
Props.SetText(Props.CourseLength, "100m", sizeof(Props.CourseLength));
// Props.Cup = FLOWER_CUP;
// Props.CupIndex = 3;
@@ -134,7 +135,7 @@ void Course::LoadO2R(std::string trackPath) {
}
}
-// Load stock track
+// Load stock and o2r tracks
void Course::Load() {
// Load from O2R
@@ -150,6 +151,8 @@ void Course::Load() {
ParseCourseSections(sections, size);
func_80295C6C();
Props.WaterLevel = gCourseMinY - 10.0f;
+ } else {
+ printf("Course.cpp: Custom track sections are invalid\n");
}
return;
}
@@ -337,7 +340,7 @@ void Course::Render(struct UnkStruct_800DC5EC* arg0) {
if (!TrackSectionsPtr.empty()) {
gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH);
gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING);
- // set_track_light_direction(D_800DC610, D_802B87D4, 0, 1);
+ set_track_light_direction(D_800DC610, D_802B87D4, 0, 1);
gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH);
diff --git a/src/engine/courses/Course.h b/src/engine/courses/Course.h
index 0a0eff823..a1a7d2f4b 100644
--- a/src/engine/courses/Course.h
+++ b/src/engine/courses/Course.h
@@ -96,7 +96,7 @@ typedef struct Properties {
j["Name"] = Name ? Name : "";
j["DebugName"] = DebugName ? DebugName : "";
j["CourseLength"] = CourseLength ? CourseLength : "";
- j["AIBehaviour"] = AIBehaviour ? AIBehaviour : "";
+ //j["AIBehaviour"] = AIBehaviour ? AIBehaviour : "";
j["LakituTowType"] = LakituTowType;
j["AIMaximumSeparation"] = AIMaximumSeparation;
j["AIMinimumSeparation"] = AIMinimumSeparation;
@@ -133,10 +133,22 @@ typedef struct Properties {
j["MinimapFinishlineY"] = Minimap.FinishlineY;
j["MinimapColour"] = {static_cast<int>(Minimap.Colour.r), static_cast<int>(Minimap.Colour.g), static_cast<int>(Minimap.Colour.b)};
// SkyboxColors - assuming SkyboxColors can be serialized similarly
- // j["Skybox"] = Skybox; // Implement your serialization logic here
+
+ #define TO_INT(value) static_cast<int>(value)
+ j["Skybox"] = {
+ TO_INT(Skybox.TopRight.r), TO_INT(Skybox.TopRight.g), TO_INT(Skybox.TopRight.b),
+ TO_INT(Skybox.BottomRight.r), TO_INT(Skybox.BottomRight.g), TO_INT(Skybox.BottomRight.b),
+ TO_INT(Skybox.BottomLeft.r), TO_INT(Skybox.BottomLeft.g), TO_INT(Skybox.BottomLeft.b),
+ TO_INT(Skybox.TopLeft.r), TO_INT(Skybox.TopLeft.g), TO_INT(Skybox.TopLeft.b),
+ TO_INT(Skybox.FloorTopRight.r), TO_INT(Skybox.FloorTopRight.g), TO_INT(Skybox.FloorTopRight.b),
+ TO_INT(Skybox.FloorBottomRight.r), TO_INT(Skybox.FloorBottomRight.g), TO_INT(Skybox.FloorBottomRight.b),
+ TO_INT(Skybox.FloorBottomLeft.r), TO_INT(Skybox.FloorBottomLeft.g), TO_INT(Skybox.FloorBottomLeft.b),
+ TO_INT(Skybox.FloorTopLeft.r), TO_INT(Skybox.FloorTopLeft.g), TO_INT(Skybox.FloorTopLeft.b)
+ };
j["Sequence"] = static_cast<int>(Sequence);
j["WaterLevel"] = static_cast<float>(WaterLevel);
+ #undef CAST_TO_INT
return j;
}
@@ -156,7 +168,7 @@ typedef struct Properties {
strncpy(CourseLength, j.at("CourseLength").get<std::string>().c_str(), sizeof(CourseLength) - 1);
CourseLength[sizeof(CourseLength) - 1] = '\0'; // Ensure null termination
- AIBehaviour = j.at("AIBehaviour").get<std::string>().c_str();
+ //AIBehaviour = j.at("AIBehaviour").get<std::string>().c_str();
LakituTowType = j.at("LakituTowType").get<int>();
AIMaximumSeparation = j.at("AIMaximumSeparation").get<float>();
@@ -215,6 +227,39 @@ typedef struct Properties {
Minimap.Colour.g = j.at("MinimapColour")[1].get<uint8_t>();
Minimap.Colour.b = j.at("MinimapColour")[2].get<uint8_t>();
//textures = nullptr; // Deserialize textures if present
+
+ Skybox.TopRight.r = j.at("Skybox")[0].get<uint8_t>();
+ Skybox.TopRight.g = j.at("Skybox")[1].get<uint8_t>();
+ Skybox.TopRight.b = j.at("Skybox")[2].get<uint8_t>();
+
+ Skybox.BottomRight.r = j.at("Skybox")[3].get<uint8_t>();
+ Skybox.BottomRight.g = j.at("Skybox")[4].get<uint8_t>();
+ Skybox.BottomRight.b = j.at("Skybox")[5].get<uint8_t>();
+
+ Skybox.BottomLeft.r = j.at("Skybox")[6].get<uint8_t>();
+ Skybox.BottomLeft.g = j.at("Skybox")[7].get<uint8_t>();
+ Skybox.BottomLeft.b = j.at("Skybox")[8].get<uint8_t>();
+
+ Skybox.TopLeft.r = j.at("Skybox")[9].get<uint8_t>();
+ Skybox.TopLeft.g = j.at("Skybox")[10].get<uint8_t>();
+ Skybox.TopLeft.b = j.at("Skybox")[11].get<uint8_t>();
+
+ Skybox.FloorTopRight.r = j.at("Skybox")[12].get<uint8_t>();
+ Skybox.FloorTopRight.g = j.at("Skybox")[13].get<uint8_t>();
+ Skybox.FloorTopRight.b = j.at("Skybox")[14].get<uint8_t>();
+
+ Skybox.FloorBottomRight.r = j.at("Skybox")[15].get<uint8_t>();
+ Skybox.FloorBottomRight.g = j.at("Skybox")[16].get<uint8_t>();
+ Skybox.FloorBottomRight.b = j.at("Skybox")[17].get<uint8_t>();
+
+ Skybox.FloorBottomLeft.r = j.at("Skybox")[18].get<uint8_t>();
+ Skybox.FloorBottomLeft.g = j.at("Skybox")[19].get<uint8_t>();
+ Skybox.FloorBottomLeft.b = j.at("Skybox")[20].get<uint8_t>();
+
+ Skybox.FloorTopLeft.r = j.at("Skybox")[21].get<uint8_t>();
+ Skybox.FloorTopLeft.g = j.at("Skybox")[22].get<uint8_t>();
+ Skybox.FloorTopLeft.b = j.at("Skybox")[23].get<uint8_t>();
+
Sequence = static_cast<MusicSeq>(j.at("Sequence").get<int>());
WaterLevel = j.at("WaterLevel").get<float>();
}
diff --git a/src/engine/editor/SceneManager.cpp b/src/engine/editor/SceneManager.cpp
index a2de6656c..c825431de 100644
--- a/src/engine/editor/SceneManager.cpp
+++ b/src/engine/editor/SceneManager.cpp
@@ -69,7 +69,7 @@ namespace Editor {
void LoadLevel(std::shared_ptr<Ship::Archive> archive, Course* course, std::string sceneFile) {
SceneFile = sceneFile;
- if (archive) {
+ if (archive && (course != nullptr)) {
auto initData = std::make_shared<Ship::ResourceInitData>();
initData->Parent = archive;
initData->Format = RESOURCE_FORMAT_BINARY;