Merge branch 'main' into fix-RessourceName

This commit is contained in:
coco875 2025-12-15 22:26:57 +01:00 committed by GitHub
commit 56ab8447cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
87 changed files with 517 additions and 293 deletions

View File

@ -1 +1 @@
{"Props":{"AIDistance":[20,5,10,15,20,25,30,35,30,25,45,65,90,115,140,165,40,3,6,16,46,49,59,89,50,30,60,63,73,78,108,138],"AIMaximumSeparation":50.0,"AIMinimumSeparation":0.30000001192092896,"AISteeringSensitivity":48,"CourseLength":"100m","CurveTargetSpeed":[4.166666507720947,5.583333492279053,6.166666507720947,6.75],"NormalTargetSpeed":[3.75,5.166666507720947,5.75,6.333333492279053],"D_0D0096B8":[3.3333332538604736,3.9166667461395264,4.5,5.083333492279053],"OffTrackTargetSpeed":[3.75,5.166666507720947,5.75,6.333333492279053], "DebugName":"harbour","FarPersp":6800.0,"LakituTowType":0,"MinimapColour":[251,234,188],"MinimapFinishlineX":1.0,"MinimapFinishlineY":0.0,"MinimapPlayerScaleFactor":0.03799999877810478,"MinimapPlayerX":53,"MinimapPlayerY":48,"MinimapPosition":[273,168],"MinimapPosition2P":[5,0],"Name":"harbour","NearPersp":3.0,"Sequence":6,"Skybox":[66,179,246,255,118,118,0,198,255,0,180,255,0,96,255,0,96,255,0,96,255,0,96,255],"WaterLevel":-130.0},"StaticMeshActors":null} {"Props":{"AIDistance":[20,5,10,15,20,25,30,35,30,25,45,65,90,115,140,165,40,3,6,16,46,49,59,89,50,30,60,63,73,78,108,138],"AIMaximumSeparation":50.0,"AIMinimumSeparation":0.30000001192092896,"AISteeringSensitivity":48,"TrackLength":"100m","CurveTargetSpeed":[4.166666507720947,5.583333492279053,6.166666507720947,6.75],"NormalTargetSpeed":[3.75,5.166666507720947,5.75,6.333333492279053],"D_0D0096B8":[3.3333332538604736,3.9166667461395264,4.5,5.083333492279053],"OffTrackTargetSpeed":[3.75,5.166666507720947,5.75,6.333333492279053], "ResourceName":"hm:harbour", "DebugName":"harbour","FarPersp":6800.0,"LakituTowType":0,"MinimapColour":[251,234,188],"MinimapFinishlineX":1.0,"MinimapFinishlineY":0.0,"MinimapPlayerScaleFactor":0.03799999877810478,"MinimapPlayerX":53,"MinimapPlayerY":48,"MinimapPosition":[273,168],"MinimapPosition2P":[5,0],"Name":"harbour","NearPersp":3.0,"Sequence":6,"Skybox":[66,179,246,255,118,118,0,198,255,0,180,255,0,96,255,0,96,255,0,96,255,0,96,255],"WaterLevel":-130.0},"StaticMeshActors":null}

View File

@ -15,7 +15,7 @@ void render_actor_banana(Camera* camera, UNUSED Mat4 arg1, struct BananaActor* b
Vec3s sp7C; Vec3s sp7C;
Mat4 sp3C; Mat4 sp3C;
f32 temp = is_within_render_distance(camera->pos, banana->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], f32 temp = is_within_render_distance(camera->pos, banana->pos, camera->rot[1], 0, camera->fieldOfView,
490000.0f); 490000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp = MAX(temp, 0.0f); temp = MAX(temp, 0.0f);

View File

@ -10,15 +10,15 @@
* Actor used in Toad's Turnpike. * Actor used in Toad's Turnpike.
* His update are made in vehicle. * His update are made in vehicle.
* *
* @param arg0 * @param camera
* @param arg1 * @param arg1
*/ */
void render_actor_box_truck(Camera* arg0, struct Actor* arg1) { void render_actor_box_truck(Camera* camera, struct Actor* arg1) {
UNUSED s32 pad[6]; UNUSED s32 pad[6];
Mat4 spD8; Mat4 spD8;
UNUSED s32 pad2[32]; UNUSED s32 pad2[32];
f32 temp_f0 = f32 temp_f0 =
is_within_render_distance(arg0->pos, arg1->pos, arg0->rot[1], 2500.0f, gCameraFOV[arg0 - camera1], 9000000.0f); is_within_render_distance(camera->pos, arg1->pos, camera->rot[1], 2500.0f, camera->fieldOfView, 9000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);
} }

View File

@ -8,15 +8,15 @@
* Actor used in Toad's Turnpike. * Actor used in Toad's Turnpike.
* His update are made in vehicle. * His update are made in vehicle.
* *
* @param arg0 * @param camera
* @param arg1 * @param arg1
*/ */
void render_actor_car(Camera* arg0, struct Actor* arg1) { void render_actor_car(Camera* camera, struct Actor* arg1) {
UNUSED s32 pad[6]; UNUSED s32 pad[6];
Mat4 spC8; Mat4 spC8;
UNUSED s32 pad2[32]; UNUSED s32 pad2[32];
f32 temp_f0 = f32 temp_f0 =
is_within_render_distance(arg0->pos, arg1->pos, arg0->rot[1], 2500.0f, gCameraFOV[arg0 - camera1], 9000000.0f); is_within_render_distance(camera->pos, arg1->pos, camera->rot[1], 2500.0f, camera->fieldOfView, 9000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);
} }

View File

@ -13,7 +13,7 @@
* @param arg2 * @param arg2
*/ */
void render_actor_cow(Camera* camera, Mat4 arg1, struct Actor* arg2) { void render_actor_cow(Camera* camera, Mat4 arg1, struct Actor* arg2) {
if (is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], if (is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView,
4000000.0f) < 0 && 4000000.0f) < 0 &&
CVarGetInteger("gNoCulling", 0) == 0) { CVarGetInteger("gNoCulling", 0) == 0) {
return; return;

View File

@ -28,7 +28,7 @@ void render_actor_fake_item_box(Camera* camera, struct FakeItemBox* fakeItemBox)
// @port: Tag the transform. // @port: Tag the transform.
FrameInterpolation_RecordOpenChild("Fake Item Box", TAG_ITEM_ADDR(fakeItemBox)); FrameInterpolation_RecordOpenChild("Fake Item Box", TAG_ITEM_ADDR(fakeItemBox));
if (is_within_render_distance(camera->pos, fakeItemBox->pos, camera->rot[1], 2500.0f, gCameraFOV[camera - camera1], if (is_within_render_distance(camera->pos, fakeItemBox->pos, camera->rot[1], 2500.0f, camera->fieldOfView,
1000000.0f) < 0 && 1000000.0f) < 0 &&
CVarGetInteger("gNoCulling", 0) == 0) { CVarGetInteger("gNoCulling", 0) == 0) {
actor_not_rendered(camera, (struct Actor*) fakeItemBox); actor_not_rendered(camera, (struct Actor*) fakeItemBox);

View File

@ -21,7 +21,7 @@ void render_actor_falling_rock(Camera* camera, struct FallingRock* rock) {
return; return;
} }
height = is_within_render_distance(camera->pos, rock->pos, camera->rot[1], 400.0f, gCameraFOV[camera - camera1], height = is_within_render_distance(camera->pos, rock->pos, camera->rot[1], 400.0f, camera->fieldOfView,
4000000.0f); 4000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {

View File

@ -30,7 +30,7 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
// @port: Tag the transform. // @port: Tag the transform.
FrameInterpolation_RecordOpenChild("ItemBox", TAG_ITEM_ADDR(item_box)); FrameInterpolation_RecordOpenChild("ItemBox", TAG_ITEM_ADDR(item_box));
temp_f0 = is_within_render_distance(camera->pos, item_box->pos, camera->rot[1], 0.0f, gCameraFOV[camera - camera1], temp_f0 = is_within_render_distance(camera->pos, item_box->pos, camera->rot[1], 0.0f, camera->fieldOfView,
4000000.0f); 4000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = CLAMP(temp_f0, 0.0f, 600000.0f); temp_f0 = CLAMP(temp_f0, 0.0f, 600000.0f);

View File

@ -7,11 +7,11 @@
* @brief Renders the Mario sign actor. * @brief Renders the Mario sign actor.
* Actor used in Mario Raceway. * Actor used in Mario Raceway.
* *
* @param arg0 * @param camera
* @param arg1 * @param arg1
* @param arg2 * @param arg2
*/ */
void render_actor_mario_sign(Camera* arg0, UNUSED Mat4 arg1, struct Actor* arg2) { void render_actor_mario_sign(Camera* camera, UNUSED Mat4 arg1, struct Actor* arg2) {
Mat4 mtx; Mat4 mtx;
f32 unk; f32 unk;
s16 temp = arg2->flags; s16 temp = arg2->flags;
@ -19,7 +19,7 @@ void render_actor_mario_sign(Camera* arg0, UNUSED Mat4 arg1, struct Actor* arg2)
return; return;
} }
unk = is_within_render_distance(arg0->pos, arg2->pos, arg0->rot[1], 0, gCameraFOV[arg0 - camera1], 16000000.0f); unk = is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView, 16000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
unk = MAX(unk, 0.0f); unk = MAX(unk, 0.0f);
} }

View File

@ -12,12 +12,12 @@
* @brief Renders the paddle boat actor. * @brief Renders the paddle boat actor.
* Actor used in DK's Jungle Parkway. * Actor used in DK's Jungle Parkway.
* *
* @param arg0 * @param camera
* @param boat * @param boat
* @param arg2 * @param arg2
* @param pathCounter * @param pathCounter
*/ */
void render_actor_paddle_boat(Camera* arg0, struct PaddleWheelBoat* boat, UNUSED Mat4 arg2, u16 pathCounter) { void render_actor_paddle_boat(Camera* camera, struct PaddleWheelBoat* boat, UNUSED Mat4 arg2, u16 pathCounter) {
UNUSED s32 pad[3]; UNUSED s32 pad[3];
Vec3f sp120; Vec3f sp120;
Mat4 spE0; Mat4 spE0;
@ -29,7 +29,7 @@ void render_actor_paddle_boat(Camera* arg0, struct PaddleWheelBoat* boat, UNUSED
return; return;
} }
temp = is_within_render_distance(arg0->pos, boat->pos, arg0->rot[1], 90000.0f, gCameraFOV[arg0 - camera1], temp = is_within_render_distance(camera->pos, boat->pos, camera->rot[1], 90000.0f, camera->fieldOfView,
9000000.0f); 9000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {

View File

@ -6,11 +6,11 @@
* @brief Renders the palm tree actor. * @brief Renders the palm tree actor.
* Actor used in Koopa Troopa Beach. * Actor used in Koopa Troopa Beach.
* *
* @param arg0 * @param camera
* @param arg1 * @param arg1
* @param arg2 * @param arg2
*/ */
void render_actor_palm_tree(Camera* arg0, UNUSED Mat4 arg1, struct PalmTree* arg2) { void render_actor_palm_tree(Camera* camera, UNUSED Mat4 arg1, struct PalmTree* arg2) {
Vec3s spA8 = { 0, 0, 0 }; Vec3s spA8 = { 0, 0, 0 };
Mat4 sp68; Mat4 sp68;
f32 temp_f0; f32 temp_f0;
@ -21,7 +21,7 @@ void render_actor_palm_tree(Camera* arg0, UNUSED Mat4 arg1, struct PalmTree* arg
} }
temp_f0 = temp_f0 =
is_within_render_distance(arg0->pos, arg2->pos, arg0->rot[1], 0.0f, gCameraFOV[arg0 - camera1], 4000000.0f); is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0.0f, camera->fieldOfView, 4000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);

View File

@ -20,14 +20,14 @@ const char* sPiranhaPlantTextures[] = {
* @brief Renders the piranha plant actor. * @brief Renders the piranha plant actor.
* Actor used in Mario Raceway and Royal Raceway. * Actor used in Mario Raceway and Royal Raceway.
* *
* @param arg0 * @param camera
* @param arg1 * @param arg1
* @param arg2 * @param arg2
*/ */
void render_actor_piranha_plant(Camera* arg0, Mat4 arg1, struct PiranhaPlant* arg2) { void render_actor_piranha_plant(Camera* camera, Mat4 arg1, struct PiranhaPlant* arg2) {
UNUSED s32 pad; UNUSED s32 pad;
u8* addr; u8* addr;
s16 temp_lo = arg0 - camera1; s16 temp_lo = camera - camera1;
s16 animationFrame; // unconfirmed s16 animationFrame; // unconfirmed
s16 temp = arg2->flags; s16 temp = arg2->flags;
f32 temp_f0; f32 temp_f0;
@ -37,7 +37,7 @@ void render_actor_piranha_plant(Camera* arg0, Mat4 arg1, struct PiranhaPlant* ar
return; return;
} }
temp_f0 = is_within_render_distance(arg0->pos, arg2->pos, arg0->rot[1], 0, gCameraFOV[arg0 - camera1], 1000000.0f); temp_f0 = is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView, 1000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);

View File

@ -7,13 +7,13 @@
* @brief Renders the railroad crossing actor. * @brief Renders the railroad crossing actor.
* Actor used in Kalimari Desert. * Actor used in Kalimari Desert.
* *
* @param arg0 * @param camera
* @param rr_crossing * @param rr_crossing
*/ */
void render_actor_railroad_crossing(Camera* arg0, struct RailroadCrossing* rr_crossing) { void render_actor_railroad_crossing(Camera* camera, struct RailroadCrossing* rr_crossing) {
UNUSED Vec3s sp80 = { 0, 0, 0 }; UNUSED Vec3s sp80 = { 0, 0, 0 };
Mat4 sp40; Mat4 sp40;
f32 unk = is_within_render_distance(arg0->pos, rr_crossing->pos, arg0->rot[1], 0.0f, gCameraFOV[arg0 - camera1], f32 unk = is_within_render_distance(camera->pos, rr_crossing->pos, camera->rot[1], 0.0f, camera->fieldOfView,
4000000.0f); 4000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {

View File

@ -8,17 +8,17 @@
* Actor used in Toad's Turnpike. * Actor used in Toad's Turnpike.
* His update are made in vehicle. * His update are made in vehicle.
* *
* @param arg0 * @param camera
* @param arg1 * @param arg1
*/ */
void render_actor_school_bus(Camera* arg0, struct Actor* arg1) { void render_actor_school_bus(Camera* camera, struct Actor* arg1) {
UNUSED s32 pad[6]; UNUSED s32 pad[6];
Mat4 spC8; Mat4 spC8;
UNUSED s32 pad2[32]; UNUSED s32 pad2[32];
f32 temp_f0; f32 temp_f0;
temp_f0 = temp_f0 =
is_within_render_distance(arg0->pos, arg1->pos, arg0->rot[1], 2500.0f, gCameraFOV[arg0 - camera1], 9000000.0f); is_within_render_distance(camera->pos, arg1->pos, camera->rot[1], 2500.0f, camera->fieldOfView, 9000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);

View File

@ -15,7 +15,7 @@ void render_actor_tanker_truck(Camera* camera, struct Actor* arg1) {
Mat4 spC8; Mat4 spC8;
UNUSED s32 pad2[32]; UNUSED s32 pad2[32];
f32 temp_f0 = is_within_render_distance(camera->pos, arg1->pos, camera->rot[1], 2500.0f, f32 temp_f0 = is_within_render_distance(camera->pos, arg1->pos, camera->rot[1], 2500.0f,
gCameraFOV[camera - camera1], 9000000.0f); camera->fieldOfView, 9000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);

View File

@ -20,7 +20,7 @@ void render_actor_train_engine(Camera* camera, struct TrainCar* actor) {
Mat4 resultMtx; Mat4 resultMtx;
f32 distance = is_within_render_distance(camera->pos, actor->pos, camera->rot[1], 2500.0f, f32 distance = is_within_render_distance(camera->pos, actor->pos, camera->rot[1], 2500.0f,
gCameraFOV[camera - camera1], 9000000.0f); camera->fieldOfView, 9000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
distance = MAX(distance, 0.0f); distance = MAX(distance, 0.0f);
@ -175,7 +175,7 @@ void render_actor_train_tender(Camera* camera, struct TrainCar* actor) {
Mat4 spA0; Mat4 spA0;
f32 temp_f0 = is_within_render_distance(camera->pos, actor->pos, camera->rot[1], 625.0f, f32 temp_f0 = is_within_render_distance(camera->pos, actor->pos, camera->rot[1], 625.0f,
gCameraFOV[camera - camera1], 9000000.0f); camera->fieldOfView, 9000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);
@ -268,7 +268,7 @@ void render_actor_train_passenger_car(Camera* camera, struct TrainCar* actor) {
Mat4 spA0; Mat4 spA0;
f32 temp_f0 = is_within_render_distance(camera->pos, actor->pos, camera->rot[1], 2025.0f, f32 temp_f0 = is_within_render_distance(camera->pos, actor->pos, camera->rot[1], 2025.0f,
gCameraFOV[camera - camera1], 9000000.0f); camera->fieldOfView, 9000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);

View File

@ -22,7 +22,7 @@ void render_actor_tree_mario_raceway(Camera* camera, Mat4 arg1, struct Actor* ar
return; return;
} }
temp_f0 = is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], temp_f0 = is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView,
16000000.0f); 16000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
@ -62,7 +62,7 @@ void render_actor_tree_yoshi_valley(Camera* camera, Mat4 arg1, struct Actor* arg
} }
temp_f0 = temp_f0 =
is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 4000000.0f); is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView, 4000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);
@ -101,7 +101,7 @@ void render_actor_tree_royal_raceway(Camera* camera, Mat4 arg1, struct Actor* ar
} }
temp_f0 = temp_f0 =
is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 4000000.0f); is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView, 4000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);
@ -140,7 +140,7 @@ void render_actor_tree_moo_moo_farm(Camera* camera, Mat4 arg1, struct Actor* arg
} }
temp_f0 = temp_f0 =
is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 6250000.0f); is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView, 6250000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);
@ -172,7 +172,7 @@ void render_actor_tree_luigi_raceway(Camera* camera, Mat4 arg1, struct Actor* ar
} }
temp_f0 = temp_f0 =
is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 4000000.0f); is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView, 4000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);
@ -215,7 +215,7 @@ void render_actor_tree_peach_castle(Camera* camera, Mat4 arg1, struct Actor* arg
} }
temp_f0 = temp_f0 =
is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 4000000.0f); is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView, 4000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);
@ -254,7 +254,7 @@ void render_actor_bush_bowser_castle(Camera* camera, Mat4 arg1, struct Actor* ar
} }
temp_f0 = temp_f0 =
is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 640000.0f); is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView, 640000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);
@ -293,7 +293,7 @@ void render_actor_tree_frappe_snowland(Camera* camera, Mat4 arg1, struct Actor*
} }
temp_f0 = temp_f0 =
is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 4000000.0f); is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView, 4000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);
@ -331,7 +331,7 @@ void render_actor_tree_cactus1_kalimari_desert(Camera* camera, Mat4 arg1, struct
} }
temp_f0 = temp_f0 =
is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 4000000.0f); is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView, 4000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);
@ -369,7 +369,7 @@ void render_actor_tree_cactus2_kalimari_desert(Camera* camera, Mat4 arg1, struct
} }
temp_f0 = temp_f0 =
is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 4000000.0f); is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView, 4000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);
@ -407,7 +407,7 @@ void render_actor_tree_cactus3_kalimari_desert(Camera* camera, Mat4 arg1, struct
} }
temp_f0 = temp_f0 =
is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 4000000.0f); is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView, 4000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = MAX(temp_f0, 0.0f); temp_f0 = MAX(temp_f0, 0.0f);

View File

@ -7,13 +7,13 @@
* @brief Renders the Wario sign actor. * @brief Renders the Wario sign actor.
* Used in Wario Stadium. * Used in Wario Stadium.
* *
* @param arg0 * @param camera
* @param arg1 * @param arg1
*/ */
void render_actor_wario_sign(Camera* arg0, struct Actor* arg1) { void render_actor_wario_sign(Camera* camera, struct Actor* arg1) {
Mat4 sp38; Mat4 sp38;
f32 unk = f32 unk =
is_within_render_distance(arg0->pos, arg1->pos, arg0->rot[1], 0, gCameraFOV[arg0 - camera1], 16000000.0f); is_within_render_distance(camera->pos, arg1->pos, camera->rot[1], 0, camera->fieldOfView, 16000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
unk = MAX(unk, 0.0f); unk = MAX(unk, 0.0f);

View File

@ -8,19 +8,19 @@
* @brief Renders the Yoshi egg actor. * @brief Renders the Yoshi egg actor.
* Actor used in Yoshi Valley. * Actor used in Yoshi Valley.
* *
* @param arg0 * @param camera
* @param arg1 * @param arg1
* @param egg * @param egg
* @param arg3 * @param arg3
*/ */
void render_actor_yoshi_egg(Camera* arg0, Mat4 arg1, struct YoshiValleyEgg* egg, u16 arg3) { void render_actor_yoshi_egg(Camera* camera, Mat4 arg1, struct YoshiValleyEgg* egg, u16 arg3) {
Mat4 sp60; Mat4 sp60;
Vec3s sp5C; Vec3s sp5C;
Vec3f sp54; Vec3f sp54;
f32 temp_f0; f32 temp_f0;
if (gGamestate != CREDITS_SEQUENCE) { if (gGamestate != CREDITS_SEQUENCE) {
temp_f0 = is_within_render_distance(arg0->pos, egg->pos, arg0->rot[1], 200.0f, gCameraFOV[arg0 - camera1], temp_f0 = is_within_render_distance(camera->pos, egg->pos, camera->rot[1], 200.0f, camera->fieldOfView,
16000000.0f); 16000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {

View File

@ -163,27 +163,27 @@ void camera_init(Vec3f pos, s16 rot, u32 mode, s32 cameraId) {
if (D_80164678[cameraId] == 0) { if (D_80164678[cameraId] == 0) {
if (D_80164A28 == 1) { if (D_80164A28 == 1) {
gCameraFOV[cameraId] = 80.0f; camera->fieldOfView = 80.0f;
} else { } else {
gCameraFOV[cameraId] = 40.0f; camera->fieldOfView = 40.0f;
} }
camera->unk_B4 = gCameraFOV[cameraId]; camera->unk_B4 = camera->fieldOfView;
} }
if (D_80164678[cameraId] == 1) { if (D_80164678[cameraId] == 1) {
if (D_80164A28 == 1) { if (D_80164A28 == 1) {
gCameraFOV[cameraId] = 100.0f; camera->fieldOfView = 100.0f;
} else { } else {
gCameraFOV[cameraId] = 60.0f; camera->fieldOfView = 60.0f;
} }
camera->unk_B4 = gCameraFOV[cameraId]; camera->unk_B4 = camera->fieldOfView;
} }
if (D_80164678[cameraId] == 2) { if (D_80164678[cameraId] == 2) {
if (D_80164A28 == 1) { if (D_80164A28 == 1) {
gCameraFOV[cameraId] = 100.0f; camera->fieldOfView = 100.0f;
} else { } else {
gCameraFOV[cameraId] = 60.0f; camera->fieldOfView = 60.0f;
} }
camera->unk_B4 = gCameraFOV[cameraId]; camera->unk_B4 = camera->fieldOfView;
D_80164A38[cameraId] = 20.0f; D_80164A38[cameraId] = 20.0f;
D_80164A48[cameraId] = 1.5f; D_80164A48[cameraId] = 1.5f;
D_80164A78[cameraId] = 1.0f; D_80164A78[cameraId] = 1.0f;
@ -202,6 +202,7 @@ void freecam_init(Vec3f pos, s16 rot, u32 mode, s32 cameraId) {
return; return;
} }
camera->fieldOfView = 40.0f;
camera->mode = mode; camera->mode = mode;
sStagingTimer[cameraId] = 0; sStagingTimer[cameraId] = 0;
switch (mode) { switch (mode) {
@ -305,27 +306,27 @@ void freecam_init(Vec3f pos, s16 rot, u32 mode, s32 cameraId) {
// if (D_80164678[cameraId] == 0) { // if (D_80164678[cameraId] == 0) {
if (D_80164A28 == 1) { if (D_80164A28 == 1) {
// gCameraFOV[cameraId] = 80.0f; // camera->fieldOfView = 80.0f;
} else { } else {
// gCameraFOV[cameraId] = 40.0f; // camera->fieldOfView = 40.0f;
} }
camera->unk_B4 = gCameraFOV[cameraId]; camera->unk_B4 = camera->fieldOfView;
// } // }
// if (D_80164678[cameraId] == 1) { // if (D_80164678[cameraId] == 1) {
// if (D_80164A28 == 1) { // if (D_80164A28 == 1) {
// gCameraFOV[cameraId] = 100.0f; // camera->fieldOfView = 100.0f;
// } else { // } else {
// gCameraFOV[cameraId] = 60.0f; // camera->fieldOfView = 60.0f;
// } // }
// camera->unk_B4 = gCameraFOV[cameraId]; // camera->unk_B4 = camera->fieldOfView;
// // } // // }
// if (D_80164678[cameraId] == 2) { // if (D_80164678[cameraId] == 2) {
// if (D_80164A28 == 1) { // if (D_80164A28 == 1) {
// gCameraFOV[cameraId] = 100.0f; // camera->fieldOfView = 100.0f;
// } else { // } else {
// gCameraFOV[cameraId] = 60.0f; // camera->fieldOfView = 60.0f;
// } // }
// camera->unk_B4 = gCameraFOV[cameraId]; // camera->unk_B4 = camera->fieldOfView;
// D_80164A38[cameraId] = 20.0f; // D_80164A38[cameraId] = 20.0f;
// D_80164A48[cameraId] = 1.5f; // D_80164A48[cameraId] = 1.5f;
// D_80164A78[cameraId] = 1.0f; // D_80164A78[cameraId] = 1.0f;
@ -1129,7 +1130,7 @@ void func_8001EE98(Player* player, Camera* camera, s8 index) {
} }
} }
void func_8001F394(Player* player, f32* arg1) { void func_8001F394(Player* player) {
f32 var_f0; f32 var_f0;
UNUSED s32 pad; UNUSED s32 pad;
s32 playerIndex = player - gPlayerOne; s32 playerIndex = player - gPlayerOne;
@ -1252,15 +1253,15 @@ void func_8001F394(Player* player, f32* arg1) {
D_80164498[playerIndex] = 0.0f; D_80164498[playerIndex] = 0.0f;
} }
} }
var_f0 = func_80014EE4(*arg1, playerIndex); var_f0 = func_80014EE4(camera->fieldOfView, playerIndex);
break; break;
case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL:
case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL:
case SCREEN_MODE_3P_4P_SPLITSCREEN: case SCREEN_MODE_3P_4P_SPLITSCREEN:
var_f0 = func_80014EE4(*arg1, playerIndex); var_f0 = func_80014EE4(camera->fieldOfView, playerIndex);
break; break;
} }
*arg1 = var_f0; camera->fieldOfView = var_f0;
camera->unk_B4 = var_f0; camera->unk_B4 = var_f0;
} }

View File

@ -40,6 +40,7 @@ typedef struct {
// I think these are the "nautical angles" between pos and lookAt // I think these are the "nautical angles" between pos and lookAt
// rot[0] = roll? Does nothing?, rot[1] = yaw, rot[2] = pitch // rot[0] = roll? Does nothing?, rot[1] = yaw, rot[2] = pitch
/* 0x24 */ Vec3s rot; /* 0x24 */ Vec3s rot;
f32 fieldOfView;
/* 0x2A */ u16 someBitFlags; /* 0x2A */ u16 someBitFlags;
/* 0x2C */ s16 unk_2C; /* 0x2C */ s16 unk_2C;
/* 0x2E */ s16 unk_2E; /* 0x2E */ s16 unk_2E;
@ -85,7 +86,7 @@ void func_8001E45C(Camera*, Player*, s8);
void func_8001E8E8(Camera*, Player*, s8); void func_8001E8E8(Camera*, Player*, s8);
void func_8001EA0C(Camera*, Player*, s8); void func_8001EA0C(Camera*, Player*, s8);
void func_8001EE98(Player*, Camera*, s8); void func_8001EE98(Player*, Camera*, s8);
void func_8001F394(Player*, f32*); void func_8001F394(Player*);
void func_8001F87C(s32); void func_8001F87C(s32);
extern f32 D_800DDB30[]; extern f32 D_800DDB30[];

View File

@ -36,7 +36,7 @@ void init_camera_podium_ceremony(void) {
cameras[0].up[0] = 0.0f; cameras[0].up[0] = 0.0f;
cameras[0].up[1] = 1.0f; cameras[0].up[1] = 1.0f;
cameras[0].up[2] = 0.0f; cameras[0].up[2] = 0.0f;
gCameraFOV[0] = 40.0f; cameras[0].fieldOfView = 40.0f;
gScreenAspect = 1.33333333f; gScreenAspect = 1.33333333f;
D_80150150 = 3.0f; D_80150150 = 3.0f;
D_8015014C = 6800.0f; D_8015014C = 6800.0f;

View File

@ -455,7 +455,7 @@ void func_802830B4(CinematicCamera* arg0, s16 arg1, s16 arg2, s16 arg3) {
} }
} }
void func_80283100(CinematicCamera* arg0, f32* arg1) { void func_80283100(CinematicCamera* arg0, Camera* camera) {
if (arg0->unk60 != 0) { if (arg0->unk60 != 0) {
arg0->unk6E = (coss((u16) arg0->unk64) * arg0->unk60) / 256; arg0->unk6E = (coss((u16) arg0->unk64) * arg0->unk60) / 256;
arg0->unk64 += arg0->unk68; arg0->unk64 += arg0->unk68;
@ -463,7 +463,7 @@ void func_80283100(CinematicCamera* arg0, f32* arg1) {
} else { } else {
arg0->unk64 = 0.0f; arg0->unk64 = 0.0f;
} }
*arg1 = arg0->unk20 + (f32) arg0->unk6E; camera->fieldOfView = arg0->unk20 + (f32) arg0->unk6E;
} }
void func_80283240(s16 arg0) { void func_80283240(s16 arg0) {
@ -547,7 +547,7 @@ void init_cinematic_camera(void) {
camera->unk68 = 0.0f; camera->unk68 = 0.0f;
camera->unk6C = 0; camera->unk6C = 0;
camera->unk6E = 0; camera->unk6E = 0;
camera->unk20 = gCameraFOV[0]; camera->unk20 = 60.0f;// gCameraFOV[0];
sCutsceneShot = 0; sCutsceneShot = 0;
gCutsceneShotTimer = 0; gCutsceneShotTimer = 0;
D_802876D4 = 0; D_802876D4 = 0;
@ -633,7 +633,7 @@ s32 func_80283648(Camera* camera) {
} }
func_80282F44(0, cinematicCamera, camera); func_80282F44(0, cinematicCamera, camera);
func_80282F44(1, cinematicCamera, camera); func_80282F44(1, cinematicCamera, camera);
func_80283100(cinematicCamera, gCameraFOV); func_80283100(cinematicCamera, camera);
vec3f_copy_return_dupe(cinematicCamera->unk30, camera->pos); vec3f_copy_return_dupe(cinematicCamera->unk30, camera->pos);
vec3f_copy_return_dupe(cinematicCamera->unk24, camera->lookAt); vec3f_copy_return_dupe(cinematicCamera->unk24, camera->lookAt);
vec3f_copy_return_dupe(cinematicCamera->unk3C, camera->up); vec3f_copy_return_dupe(cinematicCamera->unk3C, camera->up);

View File

@ -140,7 +140,7 @@ void func_80282EAC(s32, CinematicCamera*, s16, s16, s16);
void func_80282F00(s16*, s16); void func_80282F00(s16*, s16);
void func_80282F44(s32, CinematicCamera*, Camera*); void func_80282F44(s32, CinematicCamera*, Camera*);
void func_802830B4(CinematicCamera*, s16, s16, s16); void func_802830B4(CinematicCamera*, s16, s16, s16);
void func_80283100(CinematicCamera*, f32*); void func_80283100(CinematicCamera*, Camera* camera);
void func_80283240(s16); void func_80283240(s16);
s32 cutscene_event(CameraEvent event, CinematicCamera*, s16, s16); s32 cutscene_event(CameraEvent event, CinematicCamera*, s16, s16);
s32 func_80283330(s32); s32 func_80283330(s32);

View File

@ -57,7 +57,7 @@ void func_80280038(Camera* camera) {
func_80057FC4(0); func_80057FC4(0);
gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH);
guPerspective(camera->perspectiveMatrix , &perspNorm, gCameraFOV[0], gScreenAspect, CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); guPerspective(camera->perspectiveMatrix , &perspNorm, camera->fieldOfView, gScreenAspect, CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f);
gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPPerspNormalize(gDisplayListHead++, perspNorm);
gSPMatrix(gDisplayListHead++, camera->perspectiveMatrix, gSPMatrix(gDisplayListHead++, camera->perspectiveMatrix,
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
@ -145,8 +145,7 @@ void load_credits(void) {
gScreenOneCtx->camera = camera; gScreenOneCtx->camera = camera;
camera->renderMode = RENDER_FULL_SCENE; camera->renderMode = RENDER_FULL_SCENE;
camera->unk_B4 = 60.0f; camera->unk_B4 = 60.0f;
gCameraFOV[0] = 60.0f; camera->fieldOfView = 60.0f;
gCurrentCourseId = gCreditsCourseId; gCurrentCourseId = gCreditsCourseId;
TrackBrowser_SetTrackByIdx(gCreditsCourseId); TrackBrowser_SetTrackByIdx(gCreditsCourseId);

View File

@ -158,7 +158,7 @@ void setup_podium_ceremony(void) {
spawn_players_and_cameras(); spawn_players_and_cameras();
gScreenOneCtx->camera->renderMode = RENDER_FULL_SCENE; gScreenOneCtx->camera->renderMode = RENDER_FULL_SCENE;
gScreenOneCtx->camera->unk_B4 = 60.0f; gScreenOneCtx->camera->unk_B4 = 60.0f;
gCameraFOV[0] = 60.0f; gScreenOneCtx->camera->fieldOfView = 60.0f;
load_kart_textures(); load_kart_textures();
init_hud(); init_hud();
func_8001C05C(); func_8001C05C();

View File

@ -74,7 +74,7 @@ void func_80281D00(void) {
} }
func_8028150C(); func_8028150C();
gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH);
guPerspective(camera->perspectiveMatrix, &perspNorm, gCameraFOV[0], gScreenAspect, CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, guPerspective(camera->perspectiveMatrix, &perspNorm, camera->fieldOfView, gScreenAspect, CM_GetProps()->NearPersp, CM_GetProps()->FarPersp,
1.0f); 1.0f);
gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPPerspNormalize(gDisplayListHead++, perspNorm);
gSPMatrix(gDisplayListHead++, camera->perspectiveMatrix, gSPMatrix(gDisplayListHead++, camera->perspectiveMatrix,

View File

@ -25,7 +25,7 @@ void AActor::BeginPlay() {
if ((nullptr != Model) && (Model[0] != '\0')) { if ((nullptr != Model) && (Model[0] != '\0')) {
// Prevent collision mesh from being generated extra times. // Prevent collision mesh from being generated extra times.
if (Triangles.size() == 0) { if (Triangles.size() == 0) {
Editor::GenerateCollisionMesh(this, (Gfx*)LOAD_ASSET_RAW(Model), 1.0f); TrackEditor::GenerateCollisionMesh(this, (Gfx*)LOAD_ASSET_RAW(Model), 1.0f);
} }
} }
} }

View File

@ -495,7 +495,7 @@ void RegisterTracks(Registry<TrackInfo>& r) {
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<BigDonut>()); }); r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<BigDonut>()); });
info = { info = {
.ResourceName = "mk:test_track", .ResourceName = "hm:test_track",
.Name = "test track", .Name = "test track",
.DebugName = "test track", .DebugName = "test track",
.Length = "100m", .Length = "100m",

View File

@ -97,6 +97,17 @@ public:
return list; return list;
} }
// Returns true if item succesfully removed
// Note that mCounter is not decremented on remove
bool Remove(const std::string& resourceName) {
auto it = mMap.find(resourceName);
if (it != mMap.end()) {
mMap.erase(it);
return true;
}
return false;
}
void Clear() { void Clear() {
mMap.clear(); mMap.clear();
mCounter = 0; mCounter = 0;

View File

@ -1,6 +1,7 @@
#include "TrackBrowser.h" #include "TrackBrowser.h"
#include "port/Engine.h" #include "port/Engine.h"
#include "engine/editor/SceneManager.h" #include "engine/editor/SceneManager.h"
#include <imgui.h>
TrackBrowser* TrackBrowser::Instance; TrackBrowser* TrackBrowser::Instance;
@ -8,61 +9,63 @@ void TrackBrowser::FindCustomTracks() {
auto manager = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager(); auto manager = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager();
auto ptr2 = manager->ListDirectories("tracks/*"); auto ptr2 = manager->ListDirectories("tracks/*");
if (ptr2) { if (!ptr2) {
auto dirs = *ptr2; return;
}
auto dirs = *ptr2;
for (const std::string& dir : dirs) { for (const std::string& dir : dirs) {
std::string name = dir.substr(dir.find_last_of('/') + 1); std::string name = dir.substr(dir.find_last_of('/') + 1);
std::string sceneFile = dir + "/scene.json"; std::string sceneFile = dir + "/scene.json";
std::string minimapFile = dir + "/minimap.png"; std::string minimapFile = dir + "/minimap.png";
// The track has a valid scene file, add it to the registry // The track has a valid scene file, add it to the registry
if (manager->HasFile(sceneFile)) { if (manager->HasFile(sceneFile)) {
auto archive = manager->GetArchiveFromFile(sceneFile); auto archive = manager->GetArchiveFromFile(sceneFile);
TrackInfo info;
info.Path = dir;
TrackEditor::LoadTrackInfo(info, archive, sceneFile);
printf("[TrackBrowser] Added custom track %s\n", info.Name.c_str());
gTrackRegistry.Add(info, [info, archive]() {
auto track = std::make_unique<Track>();
track->ResourceName = info.ResourceName;
track->Archive = archive;
GetWorld()->SetCurrentTrack(std::move(track));
});
} else { // The track does not have a valid scene file
const std::string file = dir + "/data_track_sections";
// If the track has a data_track_sections file,
// then it must at least be a valid track.
// So lets add it as an uninitialized track.
if (manager->HasFile(file)) {
printf("[TrackBrowser] [FindCustomTracks] Found a new custom track!\n");
printf(" Creating scene.json so the track can be configured in the editor\n");
TrackInfo info; TrackInfo info;
// simplification for now std::string resName = std::string("mods:") + name;
info.ResourceName = std::string("mods:") + name; info.ResourceName = resName;
info.Name = name; info.Name = name;
info.DebugName = name; info.DebugName = name;
info.Path = dir; info.Path = dir;
Editor::LoadTrackInfo(info, archive, sceneFile);
printf("Added custom track %s\n", info.Name.c_str()); // Create the track
auto archive = manager->GetArchiveFromFile(file);
auto track = std::make_unique<Track>();
track->Archive = archive;
track->ResourceName = info.ResourceName;
TrackEditor::SaveLevel(track.get(), static_cast<const TrackInfo*>(&info)); // Write scene file so it will show up in the track browser
printf("[TrackBrowser] [FindCustomTracks] Saved scene.json to new track!\n");
// Passing these through seems kinda bad. But it works?
gTrackRegistry.Add(info, [info, archive]() { gTrackRegistry.Add(info, [info, archive]() {
auto track = std::make_unique<Track>(); auto track = std::make_unique<Track>();
track->ResourceName = info.ResourceName;
track->Archive = archive; track->Archive = archive;
track->ResourceName = info.ResourceName;
GetWorld()->SetCurrentTrack(std::move(track)); GetWorld()->SetCurrentTrack(std::move(track));
}); });
} else { // The track does not have a valid scene file } else {
const std::string file = dir + "/data_track_sections"; printf("[TrackBrowser] Track '%s' missing required track files. Cannot add to game\n Missing %s/data_track_sections file\n", name.c_str(), dir.c_str());
// If the track has a data_track_sections file,
// then it must at least be a valid track.
// So lets add it as an uninitialized track.
if (manager->HasFile(file)) {
TrackInfo info;
std::string resName = std::string("mods:") + name;
info.ResourceName = resName;
info.Name = name;
info.DebugName = name;
auto archive = manager->GetArchiveFromFile(file);
//mNewTracks.push_back({info, "", dir, archive});
auto track = std::make_unique<Track>();
Editor::SaveLevel(track.get()); // Write scene file so it will show up in the track browser
gTrackRegistry.Add(info, [info, archive]() {
auto track = std::make_unique<Track>();
track->ResourceName = info.ResourceName;
track->Archive = archive;
GetWorld()->SetCurrentTrack(std::move(track));
});
} else {
printf("ContentBrowser.cpp: Track '%s' missing required track files. Cannot add to game\n Missing %s/data_track_sections file\n", name.c_str(), dir.c_str());
}
} }
} }
} }

View File

@ -50,7 +50,7 @@ void ACloud::BeginPlay() {
// Prevent collision mesh from being generated extra times. // Prevent collision mesh from being generated extra times.
if (Editor_IsEnabled()) { if (Editor_IsEnabled()) {
if (Triangles.size() == 0) { if (Triangles.size() == 0) {
Editor::GenerateCollisionMesh(this, (Gfx*)cloud_mesh, 1.0f); TrackEditor::GenerateCollisionMesh(this, (Gfx*) cloud_mesh, 1.0f);
} }
} }
} }

View File

@ -157,7 +157,7 @@ void AFallingRock::Draw(Camera* camera) {
return; return;
} }
height = is_within_render_distance(camera->pos, Pos, camera->rot[1], 400.0f, gCameraFOV[camera - camera1], height = is_within_render_distance(camera->pos, Pos, camera->rot[1], 400.0f, camera->fieldOfView,
4000000.0f); 4000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {

View File

@ -53,7 +53,7 @@ void AFinishline::BeginPlay() {
// Prevent collision mesh from being generated extra times. // Prevent collision mesh from being generated extra times.
if (Editor_IsEnabled()) { if (Editor_IsEnabled()) {
if (Triangles.size() == 0) { if (Triangles.size() == 0) {
Editor::GenerateCollisionMesh(this, (Gfx*)LOAD_ASSET_RAW(D_0D001B90), 1.0f); TrackEditor::GenerateCollisionMesh(this, (Gfx*)LOAD_ASSET_RAW(D_0D001B90), 1.0f);
} }
} }
} }

View File

@ -68,7 +68,7 @@ void AMarioSign::Draw(Camera *camera) {
return; return;
} }
unk = is_within_render_distance(camera->pos, Pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 16000000.0f); unk = is_within_render_distance(camera->pos, Pos, camera->rot[1], 0, camera->fieldOfView, 16000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
unk = MAX(unk, 0.0f); unk = MAX(unk, 0.0f);
} }

View File

@ -55,7 +55,7 @@ void AShip::BeginPlay() {
// Prevent collision mesh from being generated extra times. // Prevent collision mesh from being generated extra times.
if (Editor_IsEnabled()) { if (Editor_IsEnabled()) {
if (Triangles.size() == 0) { if (Triangles.size() == 0) {
Editor::GenerateCollisionMesh(this, (Gfx*)_skin, Scale.y); TrackEditor::GenerateCollisionMesh(this, (Gfx*) _skin, Scale.y);
} }
} }
} }

View File

@ -35,7 +35,7 @@ void AStarship::BeginPlay() {
// Prevent collision mesh from being generated extra times. // Prevent collision mesh from being generated extra times.
if (Editor_IsEnabled()) { if (Editor_IsEnabled()) {
if (Triangles.size() == 0) { if (Triangles.size() == 0) {
Editor::GenerateCollisionMesh(this, (Gfx*)Model, 1.0f); TrackEditor::GenerateCollisionMesh(this, (Gfx*)Model, 1.0f);
} }
} }
} }

View File

@ -182,7 +182,7 @@ void AText::Draw(Camera* camera) {
} }
f32 distance = is_within_render_distance(camera->pos, (float*)&Pos[0], camera->rot[1], Close, f32 distance = is_within_render_distance(camera->pos, (float*)&Pos[0], camera->rot[1], Close,
gCameraFOV[camera - camera1], Far); camera->fieldOfView, Far);
if (distance == -1.0f) { if (distance == -1.0f) {
Dist = DistanceProps::TOO_FAR; Dist = DistanceProps::TOO_FAR;

View File

@ -38,7 +38,7 @@ void ATree::Draw(Camera* camera) {
return; return;
} }
dist = is_within_render_distance(camera->pos, Pos, camera->rot[1], 0, gCameraFOV[camera - camera1], dist = is_within_render_distance(camera->pos, Pos, camera->rot[1], 0, camera->fieldOfView,
DrawDistance); DrawDistance);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {

View File

@ -48,7 +48,7 @@ void AWarioSign::Tick() {
void AWarioSign::Draw(Camera *camera) { void AWarioSign::Draw(Camera *camera) {
Mat4 sp38; Mat4 sp38;
f32 unk = f32 unk =
is_within_render_distance(camera->pos, Pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 16000000.0f); is_within_render_distance(camera->pos, Pos, camera->rot[1], 0, camera->fieldOfView, 16000000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
unk = MAX(unk, 0.0f); unk = MAX(unk, 0.0f);

View File

@ -56,7 +56,7 @@ void FreeCamera::SetViewProjection() {
// Perspective (camera movement) // Perspective (camera movement)
FrameInterpolation_RecordOpenChild("freecam_persp", FrameInterpolation_GetCameraEpoch()); FrameInterpolation_RecordOpenChild("freecam_persp", FrameInterpolation_GetCameraEpoch());
guPerspective(&PerspectiveMatrix, &perspNorm, 40, gScreenAspect, guPerspective(&PerspectiveMatrix, &perspNorm, _camera->fieldOfView, gScreenAspect,
CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f);
gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPPerspNormalize(gDisplayListHead++, perspNorm);
gSPMatrix(gDisplayListHead++, &PerspectiveMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); gSPMatrix(gDisplayListHead++, &PerspectiveMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);

View File

@ -88,7 +88,7 @@ void GameCamera::SetViewProjection() {
(FrameInterpolation_GetCameraEpoch() | ((_camera->cameraId << 8)))); (FrameInterpolation_GetCameraEpoch() | ((_camera->cameraId << 8))));
// Calculate camera perspective (camera movement/location) // Calculate camera perspective (camera movement/location)
guPerspective(&PerspectiveMatrix, &perspNorm, gCameraFOV[_camera->cameraId], gScreenAspect, guPerspective(&PerspectiveMatrix, &perspNorm, _camera->fieldOfView, gScreenAspect,
CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f);
gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPPerspNormalize(gDisplayListHead++, perspNorm);
gSPMatrix(gDisplayListHead++, &PerspectiveMatrix, gSPMatrix(gDisplayListHead++, &PerspectiveMatrix,

View File

@ -196,7 +196,7 @@ void TourCamera::SetViewProjection() {
// Perspective (camera movement) // Perspective (camera movement)
FrameInterpolation_RecordOpenChild("tourcam_persp", FrameInterpolation_GetCameraEpoch()); FrameInterpolation_RecordOpenChild("tourcam_persp", FrameInterpolation_GetCameraEpoch());
guPerspective(&PerspectiveMatrix, &perspNorm, 40, gScreenAspect, guPerspective(&PerspectiveMatrix, &perspNorm, _camera->fieldOfView, gScreenAspect,
CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f);
gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPPerspNormalize(gDisplayListHead++, perspNorm);
gSPMatrix(gDisplayListHead++, &PerspectiveMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); gSPMatrix(gDisplayListHead++, &PerspectiveMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);

View File

@ -14,7 +14,7 @@ extern "C" {
#include "assets/textures/other_textures.h" #include "assets/textures/other_textures.h"
} }
namespace Editor { namespace TrackEditor {
void GenerateCollisionMesh(std::variant<AActor*, OObject*, GameObject*> object, Gfx* model, float scale) { void GenerateCollisionMesh(std::variant<AActor*, OObject*, GameObject*> object, Gfx* model, float scale) {
int8_t opcode; int8_t opcode;
uintptr_t lo; uintptr_t lo;

View File

@ -19,7 +19,7 @@
#define EDITOR_GFX_GET_OPCODE(var) ((uint32_t) ((var) & 0xFF000000)) #define EDITOR_GFX_GET_OPCODE(var) ((uint32_t) ((var) & 0xFF000000))
namespace Editor { namespace TrackEditor {
void GenerateCollisionMesh(std::variant<AActor*, OObject*, GameObject*> object, Gfx* model, float scale); void GenerateCollisionMesh(std::variant<AActor*, OObject*, GameObject*> object, Gfx* model, float scale);
void DebugCollision(GameObject* obj, FVector pos, IRotator rot, FVector scale, const std::vector<Triangle>& triangles); void DebugCollision(GameObject* obj, FVector pos, IRotator rot, FVector scale, const std::vector<Triangle>& triangles);
} }

View File

@ -24,7 +24,7 @@ extern "C" {
#include "camera.h" #include "camera.h"
} }
namespace Editor { namespace TrackEditor {
Editor* Editor::Instance; Editor* Editor::Instance;
Editor::Editor() { Editor::Editor() {

View File

@ -12,7 +12,7 @@ extern "C" {
} }
#include "ObjectPicker.h" #include "ObjectPicker.h"
namespace Editor { namespace TrackEditor {
class ObjectPicker; class ObjectPicker;
class Editor { class Editor {
@ -54,7 +54,7 @@ private:
void Copy(MtxF* src, MtxF* dest); void Copy(MtxF* src, MtxF* dest);
void Clear(MtxF* mf); void Clear(MtxF* mf);
}; };
} // namespace Editor } // namespace TrackEditor
#endif // __cplusplus #endif // __cplusplus

View File

@ -62,7 +62,7 @@ FVector ScreenRayTrace() {
Mat4 perspMtx; Mat4 perspMtx;
u16 perspNorm; u16 perspNorm;
guPerspectiveF(perspMtx, &perspNorm, 40, OTRGetAspectRatio(), CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); guPerspectiveF(perspMtx, &perspNorm, camera->fieldOfView, OTRGetAspectRatio(), CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f);
Mat4 inversePerspMtx; Mat4 inversePerspMtx;
if (InverseMatrix((float*)&perspMtx, (float*)&inversePerspMtx) != 2) { if (InverseMatrix((float*)&perspMtx, (float*)&inversePerspMtx) != 2) {

View File

@ -1,7 +1,7 @@
#include <libultraship/libultraship.h> #include <libultraship/libultraship.h>
#include "GameObject.h" #include "GameObject.h"
namespace Editor { namespace TrackEditor {
GameObject::GameObject(FVector pos, IRotator rot, FVector scale, const char* model, std::vector<Triangle> triangles, CollisionType collision, float boundingBoxSize) { GameObject::GameObject(FVector pos, IRotator rot, FVector scale, const char* model, std::vector<Triangle> triangles, CollisionType collision, float boundingBoxSize) {
Pos = pos; Pos = pos;
@ -38,4 +38,4 @@ namespace Editor {
Scale = scale; Scale = scale;
}; };
} // namespace Editor } // namespace TrackEditor

View File

@ -16,7 +16,7 @@ extern "C" {
struct Triangle; struct Triangle;
namespace Editor { namespace TrackEditor {
class GameObject { class GameObject {
public: public:
enum class CollisionType { enum class CollisionType {

View File

@ -29,7 +29,7 @@ extern "C" {
#include "math_util.h" #include "math_util.h"
} }
namespace Editor { namespace TrackEditor {
void Gizmo::Load() { void Gizmo::Load() {
/* Translate handle collision */ /* Translate handle collision */

View File

@ -8,7 +8,7 @@
#include "engine/objects/Object.h" #include "engine/objects/Object.h"
#include <variant> #include <variant>
namespace Editor { namespace TrackEditor {
class Gizmo { class Gizmo {
public: public:

View File

@ -3,7 +3,7 @@
#include "Handles.h" #include "Handles.h"
namespace Editor { namespace TrackEditor {
Handles::Handles() { Handles::Handles() {
} }

View File

@ -4,7 +4,7 @@
#include <libultra/gbi.h> #include <libultra/gbi.h>
#include "GameObject.h" #include "GameObject.h"
namespace Editor { namespace TrackEditor {
class Handles : public GameObject { class Handles : public GameObject {
Handles(); Handles();

View File

@ -27,7 +27,7 @@ extern "C" {
#include "math_util_2.h" #include "math_util_2.h"
} }
namespace Editor { namespace TrackEditor {
size_t LightObject::NumLights = 0; size_t LightObject::NumLights = 0;

View File

@ -5,7 +5,7 @@
#include "Collision.h" #include "Collision.h"
#include "GameObject.h" #include "GameObject.h"
namespace Editor { namespace TrackEditor {
class LightObject : public GameObject { class LightObject : public GameObject {
public: public:

View File

@ -25,7 +25,7 @@ extern "C" {
#include "camera.h" #include "camera.h"
} }
namespace Editor { namespace TrackEditor {
void ObjectPicker::Load() { void ObjectPicker::Load() {
eGizmo.Load(); eGizmo.Load();
@ -230,7 +230,7 @@ std::pair<GameObject*, float> ObjectPicker::CheckEditorObjectRay(Ray ray) {
break; break;
} }
case GameObject::CollisionType::BOUNDING_SPHERE: case GameObject::CollisionType::BOUNDING_SPHERE:
printf("Editor::ObjectPicker.cpp Bounding sphere collision type not yet supported\n"); printf("[ObjectPicker] [CheckEditorObjectRay] Bounding sphere collision type not yet supported\n");
break; break;
} }
} }

View File

@ -7,7 +7,7 @@
#include "GameObject.h" #include "GameObject.h"
#include "engine/Matrix.h" #include "engine/Matrix.h"
namespace Editor { namespace TrackEditor {
class ObjectPicker { class ObjectPicker {
public: public:
void SelectObject(std::vector<GameObject*> objects); void SelectObject(std::vector<GameObject*> objects);

View File

@ -29,20 +29,31 @@ extern "C" {
#include "actors.h" #include "actors.h"
#include "actor_types.h" #include "actor_types.h"
#include "code_80005FD0.h" #include "code_80005FD0.h"
#include "code_800029B0.h"
#include "render_courses.h"
} }
namespace Editor { namespace TrackEditor {
void SaveLevel(Track* track) { void SaveLevel(Track* track, const TrackInfo* info) {
nlohmann::json data; nlohmann::json data;
/** /**
* Save track properties, static mesh actors, actors, and tour camera * Save track properties, static mesh actors, actors, and tour camera
*/ */
data["Props"] = track->Props.to_json(); try {
data["Props"] = track->Props.to_json();
data["Props"]["ResourceName"] = track->ResourceName.c_str();
} catch (...) {
SPDLOG_ERROR("[SceneManager] [SaveLevel] Failed serializing track Props");
}
nlohmann::json staticMesh; try {
SaveStaticMeshActors(staticMesh); nlohmann::json staticMesh;
data["StaticMeshActors"] = staticMesh; SaveStaticMeshActors(staticMesh);
data["StaticMeshActors"] = staticMesh;
} catch (...) {
SPDLOG_ERROR("[SceneManager] [SaveLevel] Failed serializing StaticMeshActors");
}
nlohmann::json actors; nlohmann::json actors;
@ -56,6 +67,10 @@ namespace Editor {
data["Tour"] = tour; data["Tour"] = tour;
} }
nlohmann::json fog;
SaveFog(fog);
data["Fog"] = fog;
if (nullptr == track->Archive) { if (nullptr == track->Archive) {
SPDLOG_INFO("[SceneManager] [SaveLevel] Track archive nullptr"); SPDLOG_INFO("[SceneManager] [SaveLevel] Track archive nullptr");
return; return;
@ -69,7 +84,6 @@ namespace Editor {
std::vector<uint8_t> bytes; // Turn the str into raw data std::vector<uint8_t> bytes; // Turn the str into raw data
bytes.assign(jsonStr.begin(), jsonStr.end()); bytes.assign(jsonStr.begin(), jsonStr.end());
const TrackInfo* info = gTrackRegistry.GetInfo(track->ResourceName);
std::string sceneFile = info->Path + "/scene.json"; std::string sceneFile = info->Path + "/scene.json";
// Write file to disk // Write file to disk
@ -297,6 +311,19 @@ namespace Editor {
} }
} }
void SaveFog(nlohmann::json& fog) {
fog["EnableFog"] = bFog;
if (bFog) {
fog["Colour"]["R"] = gFogColour.r;
fog["Colour"]["G"] = gFogColour.g;
fog["Colour"]["B"] = gFogColour.b;
fog["Colour"]["A"] = gFogColour.a;
fog["Min"] = gFogMin;
fog["Max"] = gFogMax;
}
}
void LoadProps(Track* track, nlohmann::json& data) { void LoadProps(Track* track, nlohmann::json& data) {
if (!data.contains("Props") || !data["Props"].is_object()) { if (!data.contains("Props") || !data["Props"].is_object()) {
SPDLOG_INFO("Track is missing props data. Is the scene.json file corrupt?"); SPDLOG_INFO("Track is missing props data. Is the scene.json file corrupt?");
@ -305,6 +332,7 @@ namespace Editor {
try { try {
track->Props.from_json(data["Props"]); track->Props.from_json(data["Props"]);
track->ResourceName = data["Props"].at("ResourceName").get<std::string>();
} catch(const std::exception& e) { } catch(const std::exception& e) {
std::cerr << " Error parsing track properties: " << e.what() << std::endl; std::cerr << " Error parsing track properties: " << e.what() << std::endl;
std::cerr << " Is your scene.json file out of date?" << std::endl; std::cerr << " Is your scene.json file out of date?" << std::endl;
@ -312,27 +340,34 @@ namespace Editor {
} }
void LoadPaths(Track* track, const std::string& trackPath) { void LoadPaths(Track* track, const std::string& trackPath) {
SPDLOG_INFO("[SceneManager] [LoadPaths] Loading Paths...");
std::string path_file = (trackPath + "/data_paths").c_str(); std::string path_file = (trackPath + "/data_paths").c_str();
auto res = std::dynamic_pointer_cast<MK64::Paths>(ResourceLoad(path_file.c_str())); auto res = std::dynamic_pointer_cast<MK64::Paths>(ResourceLoad(path_file.c_str()));
if (nullptr == res) {
SPDLOG_ERROR(" Unable to load path file (data_paths)");
SPDLOG_ERROR(" This file is required for custom tracks to work ");
SPDLOG_ERROR(" Make sure the first path point is at coordinates 0,0,0");
SPDLOG_ERROR(" In blender you may need to apply transformations and then move the point to 0,0,0");
}
if (res != nullptr) { auto& paths = res->PathList;
auto& paths = res->PathList;
size_t i = 0; size_t i = 0;
u16* ptr = &track->Props.PathSizes.unk0; u16* ptr = &track->Props.PathSizes.unk0;
for (auto& path : paths) { for (auto& path : paths) {
if (i >= ARRAY_COUNT(track->Props.PathTable2)) { if (i >= ARRAY_COUNT(track->Props.PathTable2)) {
printf("[Track.cpp] The game can only import 5 paths. Found more than 5. Skipping the rest\n"); SPDLOG_INFO(" The game can only import 5 paths. Found more than 5. Skipping the rest");
break; // Only 5 paths allowed. 4 track, 1 vehicle break; // Only 5 paths allowed. 4 track, 1 vehicle
}
ptr[i] = path.size();
track->Props.PathTable2[i] = (TrackPathPoint*) path.data();
i += 1;
} }
ptr[i] = path.size();
track->Props.PathTable2[i] = (TrackPathPoint*) path.data();
SPDLOG_INFO(" Added path {}", i);
i += 1;
} }
gVehiclePathSize = track->Props.PathSizes.unk0; // This is likely incorrect. gVehiclePathSize = track->Props.PathSizes.unk0; // This is likely incorrect.
SPDLOG_INFO("[SceneManager] [LoadPaths] Path Loading Complete!");
} }
void LoadTrackInfoData(TrackInfo& info, nlohmann::json& data) { void LoadTrackInfoData(TrackInfo& info, nlohmann::json& data) {
@ -415,4 +450,43 @@ namespace Editor {
} }
} }
} }
void LoadFog(nlohmann::json& data) {
if (!data.contains("Fog") || !data["Fog"].is_object()) {
SPDLOG_INFO(" This track does not contain fog");
return;
}
nlohmann::json& fog = data["Fog"];
bFog = fog.value("Enabled", false);
if (!bFog) return;
// Load color
if (fog.contains("Colour") && fog["Colour"].is_object()) {
nlohmann::json& c = fog["Colour"];
gFogColour.r = c.value("R", 255);
gFogColour.g = c.value("G", 255);
gFogColour.b = c.value("B", 255);
gFogColour.a = c.value("A", 255);
}
// Load min/max with safety clamps
int minVal = fog.value("Min", 0);
int maxVal = fog.value("Max", 500);
// Ensure min < max
if (minVal >= maxVal) {
minVal = maxVal - 1;
}
// Clamp to valid ranges
minVal = std::clamp(minVal, 0, 999);
maxVal = std::clamp(maxVal, 1, 1000);
gFogMin = static_cast<int16_t>(minVal);
gFogMax = static_cast<int16_t>(maxVal);
}
} }

View File

@ -6,8 +6,8 @@
#include <optional> #include <optional>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
namespace Editor { namespace TrackEditor {
void SaveLevel(Track* track); void SaveLevel(Track* track, const TrackInfo* info);
void LoadTrackDataFromJson(Track* track, const std::string& trackPath); void LoadTrackDataFromJson(Track* track, const std::string& trackPath);
void LoadTrackInfo(TrackInfo& info, std::shared_ptr<Ship::Archive> archive, std::string sceneFile); void LoadTrackInfo(TrackInfo& info, std::shared_ptr<Ship::Archive> archive, std::string sceneFile);
void Load_AddStaticMeshActor(const nlohmann::json& actorJson); void Load_AddStaticMeshActor(const nlohmann::json& actorJson);
@ -17,6 +17,7 @@ namespace Editor {
void SaveActors(nlohmann::json& actorList); void SaveActors(nlohmann::json& actorList);
void SaveStaticMeshActors(nlohmann::json& actorList); void SaveStaticMeshActors(nlohmann::json& actorList);
void SaveTour(Track* track, nlohmann::json& tour); void SaveTour(Track* track, nlohmann::json& tour);
void SaveFog(nlohmann::json& fog);
void LoadProps(Track* track, nlohmann::json& data); void LoadProps(Track* track, nlohmann::json& data);
void LoadPaths(Track* track, const std::string& trackPath); void LoadPaths(Track* track, const std::string& trackPath);
@ -24,6 +25,7 @@ namespace Editor {
void LoadActors(Track* track, nlohmann::json& data); void LoadActors(Track* track, nlohmann::json& data);
void LoadStaticMeshActors(Track* track, nlohmann::json& data); void LoadStaticMeshActors(Track* track, nlohmann::json& data);
void LoadTour(Track* track, nlohmann::json& data); void LoadTour(Track* track, nlohmann::json& data);
void LoadFog(nlohmann::json& data);
void SpawnActors(std::vector<std::pair<std::string, SpawnParams>> spawnList); void SpawnActors(std::vector<std::pair<std::string, SpawnParams>> spawnList);

View File

@ -19,14 +19,13 @@ extern "C" {
#include "audio/external.h" #include "audio/external.h"
} }
#define DEGREES_FLOAT_TO_SHORT(Degrees) ((s16)((Degrees) * (0x8000 / 180.0f)))
OTrashBin::OTrashBin(const SpawnParams& params) : OObject(params) { OTrashBin::OTrashBin(const SpawnParams& params) : OObject(params) {
Name = "Trash Bin"; Name = "Trash Bin";
ResourceName = "mk:trash_bin"; ResourceName = "mk:trash_bin";
_pos = params.Location.value_or(FVector(0, 0, 0)); _pos = params.Location.value_or(FVector(0, 0, 0));
_pos.x *= xOrientation;
_rot = params.Rotation.value_or(IRotator(0, 0, 0)); _rot = params.Rotation.value_or(IRotator(0, 0, 0));
_scale = params.Scale.value_or(FVector(0, 0, 0)).y; // Only y _scale = params.Scale.value_or(FVector(0, 0, 0)).y;
_bhv = static_cast<Behaviour>(params.Behaviour.value_or(0)); _bhv = static_cast<Behaviour>(params.Behaviour.value_or(0));
find_unused_obj_index(&_objectIndex); find_unused_obj_index(&_objectIndex);
@ -86,9 +85,9 @@ void OTrashBin::init_bb_trash_bin(s32 objectIndex) {
gObjectList[objectIndex].unk_04C = 0; gObjectList[objectIndex].unk_04C = 0;
gObjectList[objectIndex].unk_084[7] = 0; gObjectList[objectIndex].unk_084[7] = 0;
set_obj_orientation(objectIndex, 0U, 0U, 0U); set_obj_orientation(objectIndex, 0U, 0U, 0U);
gObjectList[objectIndex].orientation[0] = DEGREES_FLOAT_TO_SHORT(_rot.pitch); gObjectList[objectIndex].orientation[0] = _rot.pitch;
gObjectList[objectIndex].orientation[1] = DEGREES_FLOAT_TO_SHORT(_rot.yaw); gObjectList[objectIndex].orientation[1] = _rot.yaw;
gObjectList[objectIndex].orientation[2] = DEGREES_FLOAT_TO_SHORT(_rot.roll); gObjectList[objectIndex].orientation[2] = _rot.roll;
gObjectList[objectIndex].pos[0] = _pos.x; gObjectList[objectIndex].pos[0] = _pos.x;
if (_drawBin) { if (_drawBin) {
// Position the lid on-top of the box. // Position the lid on-top of the box.
@ -105,8 +104,6 @@ void OTrashBin::init_bb_trash_bin(s32 objectIndex) {
object_next_state(objectIndex); object_next_state(objectIndex);
} }
#undef DEGREES_FLOAT_TO_SHORT
void OTrashBin::func_8007E00C(s32 objectIndex) { void OTrashBin::func_8007E00C(s32 objectIndex) {
switch (gObjectList[objectIndex].state) { switch (gObjectList[objectIndex].state) {
case 1: case 1:

View File

@ -165,7 +165,7 @@ void BansheeBoardwalk::BeginPlay() {
} }
if (gIsMirrorMode) { if (gIsMirrorMode) {
SpawnActor<OTrashBin>(FVector(1765.0f, 45.0f, 195.0f), IRotator(0, 180, 0), 1.0f, bhv); SpawnActor<OTrashBin>(FVector(-1765.0f, 45.0f, 195.0f), IRotator(0, 180, 0), 1.0f, bhv);
} else { } else {
SpawnActor<OTrashBin>(FVector(-1765.0f, 45.0f, 70.0f), IRotator(0, 0, 0), 1.0f, bhv); SpawnActor<OTrashBin>(FVector(-1765.0f, 45.0f, 70.0f), IRotator(0, 0, 0), 1.0f, bhv);
} }

View File

@ -132,8 +132,8 @@ void ChocoMountain::Load() {
gFogColour.g = 255; gFogColour.g = 255;
gFogColour.b = 255; gFogColour.b = 255;
gFogColour.a = 255; gFogColour.a = 255;
gFogMin = 0x3E3; gFogMin = 995;
gFogMax = 0x3E8; gFogMax = 1000;
D_802B87D4 = 0x71C; D_802B87D4 = 0x71C;
D_802B87D0 = 0xE38; D_802B87D0 = 0xE38;

View File

@ -71,7 +71,7 @@ TestTrack::TestTrack() {
Props.Minimap.Colour = {255, 255, 255}; Props.Minimap.Colour = {255, 255, 255};
ResizeMinimap(&Props.Minimap); ResizeMinimap(&Props.Minimap);
ResourceName = "mk:test_track"; ResourceName = "hm:test_track";
Props.SetText(Props.Name, "Test Track", sizeof(Props.Name)); Props.SetText(Props.Name, "Test Track", sizeof(Props.Name));
Props.SetText(Props.DebugName, "test track", sizeof(Props.DebugName)); Props.SetText(Props.DebugName, "test track", sizeof(Props.DebugName));
Props.SetText(Props.TrackLength, "100m", sizeof(Props.TrackLength)); Props.SetText(Props.TrackLength, "100m", sizeof(Props.TrackLength));

View File

@ -104,7 +104,7 @@ ToadsTurnpike::ToadsTurnpike() {
Props.CloudList = gToadsTurnpikeRainbowRoadStars; Props.CloudList = gToadsTurnpikeRainbowRoadStars;
FVector finish; FVector finish;
finish.x = (gIsMirrorMode != 0) ? 100 + 138.0f : 100 - 138.0f; finish.x = -38.0f * xOrientation;
finish.y = (f32) (0 - 15); finish.y = (f32) (0 - 15);
finish.z = 16; finish.z = 16;

View File

@ -350,14 +350,13 @@ bool IsTriangleWindingInverted() {
return !gModifiedGfxSet.empty(); return !gModifiedGfxSet.empty();
} }
Track::Track() { Track::Track() {
Props.SetText(Props.Name, "Blank Track", sizeof(Props.Name)); Props.SetText(Props.Name, "Blank Track", sizeof(Props.Name));
Props.SetText(Props.DebugName, "blnktrck", sizeof(Props.DebugName)); Props.SetText(Props.DebugName, "blnktrck", sizeof(Props.DebugName));
Props.SetText(Props.TrackLength, "100m", sizeof(Props.TrackLength)); Props.SetText(Props.TrackLength, "100m", sizeof(Props.TrackLength));
// Props.Cup = FLOWER_CUP; // Props.Cup = FLOWER_CUP;
// Props.CupIndex = 3; // Props.CupIndex = 3;
ResourceName = ""; ResourceName = "mod:blank_track";
Props.Minimap.Texture = minimap_mario_raceway; Props.Minimap.Texture = minimap_mario_raceway;
Props.Minimap.Width = ResourceGetTexWidthByName(Props.Minimap.Texture); Props.Minimap.Width = ResourceGetTexWidthByName(Props.Minimap.Texture);
Props.Minimap.Height = ResourceGetTexHeightByName(Props.Minimap.Texture); Props.Minimap.Height = ResourceGetTexHeightByName(Props.Minimap.Texture);
@ -449,7 +448,7 @@ void Track::Load() {
} else { // Load custom track } else { // Load custom track
bIsMod = true; bIsMod = true;
Editor::LoadTrackDataFromJson(this, trackPath); TrackEditor::LoadTrackDataFromJson(this, trackPath);
const std::string trackSectionPath = (trackPath + "/data_track_sections"); const std::string trackSectionPath = (trackPath + "/data_track_sections");
TrackSections* sections = (TrackSections*) LOAD_ASSET_RAW(trackSectionPath.c_str()); TrackSections* sections = (TrackSections*) LOAD_ASSET_RAW(trackSectionPath.c_str());
@ -623,6 +622,19 @@ void Track::Waypoints(Player* player, int8_t playerId) {
void Track::Draw(ScreenContext* arg0) { void Track::Draw(ScreenContext* arg0) {
gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH);
gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING);
if (bFog) {
gDPSetCycleType(gDisplayListHead++, G_CYC_2CYCLE);
gDPSetRenderMode(gDisplayListHead++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2);
gSPSetGeometryMode(gDisplayListHead++, G_FOG);
gDPSetFogColor(gDisplayListHead++, gFogColour.r, gFogColour.g, gFogColour.b, gFogColour.a);
gSPFogPosition(gDisplayListHead++, gFogMin, gFogMax);
gDPPipeSync(gDisplayListHead++);
} else {
gSPClearGeometryMode(gDisplayListHead++, G_FOG);
}
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); gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH);
@ -630,10 +642,13 @@ void Track::Draw(ScreenContext* arg0) {
if (func_80290C20(arg0->camera) == 1) { if (func_80290C20(arg0->camera) == 1) {
gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE);
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
// d_course_big_donut_packed_dl_DE8
} }
const TrackInfo* info = gTrackRegistry.GetInfo(ResourceName); const TrackInfo* info = gTrackRegistry.GetInfo(ResourceName);
if (nullptr == info) {
printf("[Track] [Draw] Resource name did not return a valid TrackInfo %s\n", ResourceName.c_str());
return;
}
std::string res = info->Path + "/data_track_sections"; std::string res = info->Path + "/data_track_sections";
TrackSections* sections = (TrackSections*) LOAD_ASSET_RAW(res.c_str()); TrackSections* sections = (TrackSections*) LOAD_ASSET_RAW(res.c_str());

View File

@ -86,7 +86,6 @@ typedef struct {
} TrackSections; } TrackSections;
typedef struct Properties { typedef struct Properties {
char ResourceName[128];
char Name[128]; char Name[128];
char DebugName[128]; char DebugName[128];
char TrackLength[128]; char TrackLength[128];
@ -116,8 +115,6 @@ typedef struct Properties {
#ifdef __cplusplus #ifdef __cplusplus
nlohmann::json to_json() const { nlohmann::json to_json() const {
nlohmann::json j; nlohmann::json j;
// j["Id"] = Id ? Id : "";
j["ResourceName"] = ResourceName ? ResourceName : "";
j["Name"] = Name ? Name : ""; j["Name"] = Name ? Name : "";
j["DebugName"] = DebugName ? DebugName : ""; j["DebugName"] = DebugName ? DebugName : "";
j["TrackLength"] = TrackLength ? TrackLength : ""; j["TrackLength"] = TrackLength ? TrackLength : "";
@ -180,19 +177,12 @@ typedef struct Properties {
// Function to load struct from JSON // Function to load struct from JSON
void from_json(const nlohmann::json& j) { void from_json(const nlohmann::json& j) {
//Id = j.at("Id").get<std::string>().c_str();
// Name = j.at("Name").get<std::string>().c_str();
strncpy(ResourceName, j.at("ResourceName").get<std::string>().c_str(), sizeof(ResourceName) - 1);
ResourceName[sizeof(ResourceName) - 1] = '\0'; // Ensure null termination
strncpy(Name, j.at("Name").get<std::string>().c_str(), sizeof(Name) - 1); strncpy(Name, j.at("Name").get<std::string>().c_str(), sizeof(Name) - 1);
Name[sizeof(Name) - 1] = '\0'; // Ensure null termination Name[sizeof(Name) - 1] = '\0'; // Ensure null termination
// DebugName = j.at("DebugName").get<std::string>().c_str();
strncpy(DebugName, j.at("DebugName").get<std::string>().c_str(), sizeof(DebugName) - 1); strncpy(DebugName, j.at("DebugName").get<std::string>().c_str(), sizeof(DebugName) - 1);
DebugName[sizeof(DebugName) - 1] = '\0'; // Ensure null termination DebugName[sizeof(DebugName) - 1] = '\0'; // Ensure null termination
// TrackLength = j.at("TrackLength").get<std::string>().c_str();
strncpy(TrackLength, j.at("TrackLength").get<std::string>().c_str(), sizeof(TrackLength) - 1); strncpy(TrackLength, j.at("TrackLength").get<std::string>().c_str(), sizeof(TrackLength) - 1);
TrackLength[sizeof(TrackLength) - 1] = '\0'; // Ensure null termination TrackLength[sizeof(TrackLength) - 1] = '\0'; // Ensure null termination

View File

@ -122,7 +122,6 @@ s32 D_80150120;
s32 gGotoMode; s32 gGotoMode;
UNUSED s32 D_80150128; UNUSED s32 D_80150128;
UNUSED s32 D_8015012C; UNUSED s32 D_8015012C;
f32 gCameraFOV[NUM_CAMERAS]; // Field-of-view for each camera
UNUSED s32 D_80150140; UNUSED s32 D_80150140;
UNUSED s32 D_80150144; UNUSED s32 D_80150144;
f32 gScreenAspect; f32 gScreenAspect;

View File

@ -167,7 +167,6 @@ extern u16 D_8015011E;
extern s32 D_80150120; extern s32 D_80150120;
extern s32 gGotoMode; extern s32 gGotoMode;
extern f32 gCameraFOV[];
extern f32 gScreenAspect; extern f32 gScreenAspect;
extern f32 D_8015014C; extern f32 D_8015014C;

View File

@ -1177,7 +1177,7 @@ void splash_menu_act(struct Controller* controller, u16 controllerIdx) {
} }
case DEBUG_MENU_LAUNCH_EDITOR: { case DEBUG_MENU_LAUNCH_EDITOR: {
if (btnAndStick & (A_BUTTON | START_BUTTON)) { if (btnAndStick & (A_BUTTON | START_BUTTON)) {
Editor_Launch("mk:test_track"); Editor_Launch("hm:test_track");
play_sound2(SOUND_INTRO_ENTER_MENU); play_sound2(SOUND_INTRO_ENTER_MENU);
} }

View File

@ -1,4 +1,5 @@
#include <libultraship.h> #include <libultraship.h>
#include <typeinfo>
#include "Game.h" #include "Game.h"
#include "port/Engine.h" #include "port/Engine.h"
@ -68,7 +69,7 @@ Cup* gBattleCup;
HarbourMastersIntro gMenuIntro; HarbourMastersIntro gMenuIntro;
Editor::Editor gEditor; TrackEditor::Editor gEditor;
s32 gTrophyIndex = NULL; s32 gTrophyIndex = NULL;
@ -762,7 +763,7 @@ void CM_ActorGenerateCollision(struct Actor* actor) {
if ((nullptr != act->Model) && (act->Model[0] != '\0')) { if ((nullptr != act->Model) && (act->Model[0] != '\0')) {
if (act->Triangles.size() == 0) { if (act->Triangles.size() == 0) {
Editor::GenerateCollisionMesh(act, (Gfx*)LOAD_ASSET_RAW(act->Model), 1.0f); TrackEditor::GenerateCollisionMesh(act, (Gfx*)LOAD_ASSET_RAW(act->Model), 1.0f);
} }
} }
} }

View File

@ -25,7 +25,7 @@ extern "C" {
extern s32 gTrophyIndex; extern s32 gTrophyIndex;
#ifdef __cplusplus #ifdef __cplusplus
extern Editor::Editor gEditor; extern TrackEditor::Editor gEditor;
extern HarbourMastersIntro gMenuIntro; extern HarbourMastersIntro gMenuIntro;
extern bool bCleanWorld; extern bool bCleanWorld;
extern Registry<TrackInfo> gTrackRegistry; extern Registry<TrackInfo> gTrackRegistry;

View File

@ -29,7 +29,7 @@ extern "C" {
#include "collision.h" #include "collision.h"
} }
namespace Editor { namespace TrackEditor {
bool bIsTrainWindowOpen = false; // Global because member variables do not work in lambdas bool bIsTrainWindowOpen = false; // Global because member variables do not work in lambdas
ContentBrowserWindow::~ContentBrowserWindow() { ContentBrowserWindow::~ContentBrowserWindow() {

View File

@ -4,7 +4,7 @@
#include "engine/tracks/Track.h" #include "engine/tracks/Track.h"
#include "AllActors.h" #include "AllActors.h"
namespace Editor { namespace TrackEditor {
class ContentBrowserWindow : public Ship::GuiWindow { class ContentBrowserWindow : public Ship::GuiWindow {
public: public:
using Ship::GuiWindow::GuiWindow; using Ship::GuiWindow::GuiWindow;

View File

@ -69,21 +69,21 @@ void SetupGuiElements() {
SPDLOG_ERROR("Could not find input GfxDebuggerWindow"); SPDLOG_ERROR("Could not find input GfxDebuggerWindow");
} }
mToolsWindow = std::make_shared<Editor::ToolsWindow>("gEditorEnabled", "Tools", ImVec2(100, 100), mToolsWindow = std::make_shared<TrackEditor::ToolsWindow>("gEditorEnabled", "Tools", ImVec2(100, 100),
(ImGuiWindowFlags_NoTitleBar)); (ImGuiWindowFlags_NoTitleBar));
gui->AddGuiWindow(mToolsWindow); gui->AddGuiWindow(mToolsWindow);
mSceneExplorerWindow = std::make_shared<Editor::SceneExplorerWindow>("gEditorEnabled", "Scene Explorer"); mSceneExplorerWindow = std::make_shared<TrackEditor::SceneExplorerWindow>("gEditorEnabled", "Scene Explorer");
gui->AddGuiWindow(mSceneExplorerWindow); gui->AddGuiWindow(mSceneExplorerWindow);
mPropertiesWindow = std::make_shared<Editor::PropertiesWindow>("gEditorEnabled", "Properties"); mPropertiesWindow = std::make_shared<TrackEditor::PropertiesWindow>("gEditorEnabled", "Properties");
gui->AddGuiWindow(mPropertiesWindow); gui->AddGuiWindow(mPropertiesWindow);
mTrackPropertiesWindow = std::make_shared<Editor::TrackPropertiesWindow>("gEditorEnabled", "Track Properties"); mTrackPropertiesWindow = std::make_shared<TrackEditor::TrackPropertiesWindow>("gEditorEnabled", "Track Properties");
gui->AddGuiWindow(mTrackPropertiesWindow); gui->AddGuiWindow(mTrackPropertiesWindow);
mContentBrowserWindow = mContentBrowserWindow =
std::make_shared<Editor::ContentBrowserWindow>("gEditorEnabled", "Content Browser"); std::make_shared<TrackEditor::ContentBrowserWindow>("gEditorEnabled", "Content Browser");
gui->AddGuiWindow(mContentBrowserWindow); gui->AddGuiWindow(mContentBrowserWindow);
} }

View File

@ -23,7 +23,7 @@ extern "C" {
#include "actors.h" #include "actors.h"
} }
namespace Editor { namespace TrackEditor {
PropertiesWindow::~PropertiesWindow() { PropertiesWindow::~PropertiesWindow() {
SPDLOG_TRACE("destruct properties window"); SPDLOG_TRACE("destruct properties window");

View File

@ -3,7 +3,7 @@
#include <libultraship/libultraship.h> #include <libultraship/libultraship.h>
#include "port/Game.h" #include "port/Game.h"
namespace Editor { namespace TrackEditor {
class PropertiesWindow : public Ship::GuiWindow { class PropertiesWindow : public Ship::GuiWindow {
public: public:
using Ship::GuiWindow::GuiWindow; using Ship::GuiWindow::GuiWindow;

View File

@ -18,7 +18,7 @@ extern "C" {
#include "actors.h" #include "actors.h"
} }
namespace Editor { namespace TrackEditor {
SceneExplorerWindow::~SceneExplorerWindow() { SceneExplorerWindow::~SceneExplorerWindow() {
SPDLOG_TRACE("destruct scene explorer window"); SPDLOG_TRACE("destruct scene explorer window");

View File

@ -4,7 +4,7 @@
#include "port/Game.h" #include "port/Game.h"
namespace Editor { namespace TrackEditor {
class SceneExplorerWindow : public Ship::GuiWindow { class SceneExplorerWindow : public Ship::GuiWindow {
public: public:
using Ship::GuiWindow::GuiWindow; using Ship::GuiWindow::GuiWindow;

View File

@ -12,13 +12,14 @@
#include <defines.h> #include <defines.h>
#include "port/Game.h" #include "port/Game.h"
#include "engine/editor/SceneManager.h" #include "engine/editor/SceneManager.h"
#include "engine/TrackBrowser.h"
extern "C" { extern "C" {
#include "code_800029B0.h" #include "code_800029B0.h"
#include "code_80057C60.h" #include "code_80057C60.h"
} }
namespace Editor { namespace TrackEditor {
ToolsWindow::~ToolsWindow() { ToolsWindow::~ToolsWindow() {
SPDLOG_TRACE("destruct tools window"); SPDLOG_TRACE("destruct tools window");
@ -36,7 +37,8 @@ namespace Editor {
// Save button // Save button
if (ImGui::Button(ICON_FA_FLOPPY_O, ImVec2(50, 25))) { if (ImGui::Button(ICON_FA_FLOPPY_O, ImVec2(50, 25))) {
if (gEditor.IsPaused()) { if (gEditor.IsPaused()) {
SaveLevel(GetWorld()->GetTrack()); SaveLevel(GetWorld()->GetTrack(), gTrackRegistry.GetInfo(GetWorld()->GetTrack()->ResourceName));
TrackBrowser::Instance->Refresh(gTrackRegistry);
} else { } else {
printf("[Editor] Cannot save during simulation\n Please switch back to edit mode!\n\n"); printf("[Editor] Cannot save during simulation\n Please switch back to edit mode!\n\n");
} }
@ -140,7 +142,8 @@ namespace Editor {
ImGui::PushStyleColor(ImGuiCol_Button, defaultColor); ImGui::PushStyleColor(ImGuiCol_Button, defaultColor);
if (ImGui::Button(gEditor.IsPaused() ? ICON_FA_PLAY : ICON_FA_STOP, ImVec2(50, 25))) { if (ImGui::Button(gEditor.IsPaused() ? ICON_FA_PLAY : ICON_FA_STOP, ImVec2(50, 25))) {
if (gEditor.IsPaused()) { if (gEditor.IsPaused()) {
SaveLevel(GetWorld()->GetTrack()); SaveLevel(GetWorld()->GetTrack(), gTrackRegistry.GetInfo(GetWorld()->GetTrack()->ResourceName));
TrackBrowser::Instance->Refresh(gTrackRegistry);
CVarSetInteger("gFreecam", false); CVarSetInteger("gFreecam", false);
CM_SetFreeCamera(false); CM_SetFreeCamera(false);
} else { } else {

View File

@ -2,7 +2,7 @@
#include <libultraship/libultraship.h> #include <libultraship/libultraship.h>
namespace Editor { namespace TrackEditor {
class ToolsWindow : public Ship::GuiWindow { class ToolsWindow : public Ship::GuiWindow {
public: public:
using Ship::GuiWindow::GuiWindow; using Ship::GuiWindow::GuiWindow;

View File

@ -14,6 +14,9 @@
#include "port/Game.h" #include "port/Game.h"
#include "engine/cameras/TourCamera.h" #include "engine/cameras/TourCamera.h"
#include "engine/TrackBrowser.h"
#include "engine/editor/SceneManager.h"
#include "engine/Registry.h"
extern "C" { extern "C" {
#include "code_800029B0.h" #include "code_800029B0.h"
@ -23,26 +26,23 @@ extern "C" {
#include "render_objects.h" #include "render_objects.h"
} }
namespace Editor { namespace TrackEditor {
TrackPropertiesWindow::~TrackPropertiesWindow() { TrackPropertiesWindow::~TrackPropertiesWindow() {
SPDLOG_TRACE("destruct track properties window"); SPDLOG_TRACE("destruct track properties window");
} }
void TrackPropertiesWindow::DrawElement() { void TrackPropertiesWindow::DrawElement() {
static char idBuffer[256] = "mk:mario_raceway";
static char nameBuffer[256] = "Mario Raceway";
static char debugNameBuffer[256] = "m circuit";
static char lengthBuffer[256] = "567m";
if (nullptr == GetWorld()->GetTrack()) { if (nullptr == GetWorld()->GetTrack()) {
return; return;
} }
ImGui::InputText("ID", idBuffer, IM_ARRAYSIZE(idBuffer)); if (ImGui::Button("Edit TrackInfo")) {
ImGui::InputText("Name", GetWorld()->GetTrack()->Props.Name, IM_ARRAYSIZE(nameBuffer)); ImGui::OpenPopup("Edit TrackInfo");
ImGui::InputText("Debug Name", GetWorld()->GetTrack()->Props.DebugName, IM_ARRAYSIZE(debugNameBuffer)); }
ImGui::InputText("Track Length", GetWorld()->GetTrack()->Props.TrackLength, IM_ARRAYSIZE(lengthBuffer));
DrawResourceNameEdit();
ImGui::InputFloat("Water Level", &GetWorld()->GetTrack()->Props.WaterLevel); ImGui::InputFloat("Water Level", &GetWorld()->GetTrack()->Props.WaterLevel);
if (ImGui::CollapsingHeader("Camera")) { if (ImGui::CollapsingHeader("Camera")) {
@ -57,6 +57,7 @@ namespace Editor {
} }
if (ImGui::CollapsingHeader("Environment")) { if (ImGui::CollapsingHeader("Environment")) {
TrackPropertiesWindow::DrawFog();
TrackPropertiesWindow::DrawLight(); TrackPropertiesWindow::DrawLight();
} }
@ -174,6 +175,99 @@ namespace Editor {
TrackPropertiesWindow::DrawTourCamera(); TrackPropertiesWindow::DrawTourCamera();
} }
void TrackPropertiesWindow::DrawResourceNameEdit() {
Track* track = GetWorld()->GetTrack();
if (!track) {
return;
}
static char resourceNameBuffer[128] = {};
static char nameBuffer[128] = "blank_track";
static char debugNameBuffer[128] = "blanktrack";
static char lengthBuffer[128] = "100m";
static bool initialized = false;
static std::string oldResourceName = track->ResourceName;
// Auto-sizing fills the height of the screen for a single frame.
// Because there's no content in the window in the first frame.
// This forces the window size to prevent that
ImGui::SetNextWindowSize(ImVec2(400, 275), ImGuiCond_Always);
if (ImGui::BeginPopupModal("Edit TrackInfo", nullptr,
ImGuiWindowFlags_AlwaysAutoResize)) {
// Initialize once per popup open
if (!initialized) {
strncpy(resourceNameBuffer, track->ResourceName.c_str(), sizeof(resourceNameBuffer));
resourceNameBuffer[sizeof(resourceNameBuffer) - 1] = '\0';
oldResourceName = track->ResourceName;
initialized = true;
}
ImGui::TextWrapped(
"Changing these fields will:\n"
"- Save the current track\n"
"- Reload the track\n"
"- Update the registry\n\n"
);
gEditor.Pause();
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
ImGui::InputText("ResourceName", resourceNameBuffer, IM_ARRAYSIZE(resourceNameBuffer));
ImGui::InputText("Name", GetWorld()->GetTrack()->Props.Name, IM_ARRAYSIZE(nameBuffer));
ImGui::InputText("Debug Name", GetWorld()->GetTrack()->Props.DebugName, IM_ARRAYSIZE(debugNameBuffer));
ImGui::InputText("Track Length", GetWorld()->GetTrack()->Props.TrackLength, IM_ARRAYSIZE(lengthBuffer));
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
bool cancel = ImGui::Button("Cancel", ImVec2(120, 0));
ImGui::SameLine();
bool confirm = ImGui::Button("Confirm", ImVec2(120, 0));
if (confirm) {
if (oldResourceName != resourceNameBuffer) {
track->ResourceName = resourceNameBuffer;
const TrackInfo* oldInfo = gTrackRegistry.GetInfo(oldResourceName);
TrackInfo info;
info.ResourceName = track->ResourceName;
info.Name = track->Props.Name;
info.DebugName = track->Props.DebugName;
info.Path = oldInfo->Path;
TrackEditor::SaveLevel(track, static_cast<const TrackInfo*>(&info));
auto archive = track->Archive;
gTrackRegistry.Remove(oldResourceName);
gTrackRegistry.Add(info, [info, archive]() {
auto track = std::make_unique<Track>();
track->Archive = archive;
track->ResourceName = info.ResourceName;
GetWorld()->SetCurrentTrack(std::move(track));
});
TrackBrowser::Instance->Refresh(gTrackRegistry);
gGotoMode = RACING;
}
initialized = false;
ImGui::CloseCurrentPopup();
}
if (cancel) {
initialized = false;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
void TrackPropertiesWindow::DrawMusic() { void TrackPropertiesWindow::DrawMusic() {
const char* items[] = { const char* items[] = {
"None", "Title Screen", "Main Menu", "Wario Stadium", "Moo Moo Farm", "None", "Title Screen", "Main Menu", "Wario Stadium", "Moo Moo Farm",
@ -249,6 +343,40 @@ namespace Editor {
} }
} }
void TrackPropertiesWindow::DrawFog() {
if (ImGui::CollapsingHeader("Fog")) {
ImGui::Checkbox("Enable Fog", &bFog);
float colours[4];
// Convert rgba to floats
RGB8ToFloat((u8*)&gFogColour, colours);
colours[3] = gFogColour.a / 255.0f;
// Edit the ambient RGB colour
ImGui::ColorEdit4("Fog Colour", colours);
// Convert floats to rgba
FloatToRGB8(colours, (u8*)&gFogColour);
gFogColour.a = static_cast<u8>(colours[3] * 255.0f);
// Fog near and far planes
int val[2] = {static_cast<int>(gFogMin), static_cast<int>(gFogMax)};
ImGui::DragInt2("##MinimapPosition", &val[0], 1.0f, 0, 1000);
if (val[0] >= val[1]) {
val[0] = val[1] - 1;
}
// Clamp to allowed range just in case
val[0] = std::clamp(val[0], 0, 999);
val[1] = std::clamp(val[1], 1, 1000);
gFogMin = static_cast<int16_t>(val[0]);
gFogMax = static_cast<int16_t>(val[1]);
}
}
void TrackPropertiesWindow::DrawLight() { void TrackPropertiesWindow::DrawLight() {
// Convert and pass to ImGui ColorEdit3 // Convert and pass to ImGui ColorEdit3
@ -260,17 +388,17 @@ namespace Editor {
RGB8ToFloat((u8*)&D_800DC610[i].l->l.col, diffuse); RGB8ToFloat((u8*)&D_800DC610[i].l->l.col, diffuse);
RGB8ToFloat((u8*)&D_800DC610[i].l->l.dir, direction); RGB8ToFloat((u8*)&D_800DC610[i].l->l.dir, direction);
// Edit the ambient RGB color // Edit the ambient RGB colour
ImGui::Text("Light %d - Ambient Color", i + 1); ImGui::Text("Light %d - Ambient Colour", i + 1);
ImGui::ColorEdit3(("Ambient Color " + std::to_string(i)).c_str(), ambient); // Modify ambient color ImGui::ColorEdit3(("Ambient Colour " + std::to_string(i)).c_str(), ambient); // Modify ambient colour
// Edit the diffuse RGB colour
ImGui::Text("Light %d - Diffuse Colour", i + 1);
ImGui::ColorEdit3(("Diffuse Colour " + std::to_string(i)).c_str(), diffuse); // Modify diffuse colour
// Edit the diffuse RGB color // Edit the direction RGB colour (this could be represented as a direction vector)
ImGui::Text("Light %d - Diffuse Color", i + 1);
ImGui::ColorEdit3(("Diffuse Color " + std::to_string(i)).c_str(), diffuse); // Modify diffuse color
// Edit the direction RGB color (this could be represented as a direction vector)
ImGui::Text("Light %d - Direction", i + 1); ImGui::Text("Light %d - Direction", i + 1);
ImGui::ColorEdit3(("Direction Color " + std::to_string(i)).c_str(), direction); // Modify direction vector color ImGui::ColorEdit3(("Direction Colour " + std::to_string(i)).c_str(), direction); // Modify direction vector colour
FloatToRGB8(ambient, (u8*)&D_800DC610[i].a.l.col); FloatToRGB8(ambient, (u8*)&D_800DC610[i].a.l.col);
FloatToRGB8(ambient, (u8*)&D_800DC610[i].a.l.colc); FloatToRGB8(ambient, (u8*)&D_800DC610[i].a.l.colc);
@ -281,7 +409,7 @@ namespace Editor {
} }
} }
// Convert s16 color values to float (normalized to [0, 1] range) // Convert s16 colour values to float (normalized to [0, 1] range)
void TrackPropertiesWindow::RGB8ToFloat(const u8* src, float* dst) { void TrackPropertiesWindow::RGB8ToFloat(const u8* src, float* dst) {
for (size_t i = 0; i < 3; ++i) { for (size_t i = 0; i < 3; ++i) {
dst[i] = src[i] / 255.0f; // Normalize to the range [0.0f, 1.0f] dst[i] = src[i] / 255.0f; // Normalize to the range [0.0f, 1.0f]

View File

@ -6,7 +6,7 @@ extern "C" {
#include "sounds.h" #include "sounds.h"
} }
namespace Editor { namespace TrackEditor {
class TrackPropertiesWindow : public Ship::GuiWindow { class TrackPropertiesWindow : public Ship::GuiWindow {
public: public:
using Ship::GuiWindow::GuiWindow; using Ship::GuiWindow::GuiWindow;
@ -15,7 +15,9 @@ public:
protected: protected:
void InitElement() override {}; void InitElement() override {};
void DrawElement() override; void DrawElement() override;
void DrawResourceNameEdit();
void DrawMusic(); void DrawMusic();
void DrawFog();
void DrawLight(); void DrawLight();
void UpdateElement() override {}; void UpdateElement() override {};
void RGB8ToFloat(const u8* src, float* dst); void RGB8ToFloat(const u8* src, float* dst);

View File

@ -535,7 +535,7 @@ void render_cows(Camera* camera, Mat4 arg1) {
sp88[0] = var_s1->pos[0] * gTrackDirection; sp88[0] = var_s1->pos[0] * gTrackDirection;
sp88[1] = var_s1->pos[1]; sp88[1] = var_s1->pos[1];
sp88[2] = var_s1->pos[2]; sp88[2] = var_s1->pos[2];
temp_f0 = is_within_render_distance(camera->pos, sp88, camera->rot[1], 0.0f, gCameraFOV[camera - camera1], temp_f0 = is_within_render_distance(camera->pos, sp88, camera->rot[1], 0.0f, camera->fieldOfView,
4000000.0f); 4000000.0f);
if (temp_f0 > 0.0f) { if (temp_f0 > 0.0f) {
if (temp_f0 < D_8015F704) { if (temp_f0 < D_8015F704) {
@ -678,7 +678,7 @@ void render_palm_trees(Camera* camera, Mat4 arg1) {
spD4[1] = var_s1->pos[1]; spD4[1] = var_s1->pos[1];
spD4[2] = var_s1->pos[2]; spD4[2] = var_s1->pos[2];
if (is_within_render_distance(camera->pos, spD4, camera->rot[1], 0.0f, gCameraFOV[camera - camera1], var_f22) < if (is_within_render_distance(camera->pos, spD4, camera->rot[1], 0.0f, camera->fieldOfView, var_f22) <
0.0f && 0.0f &&
CVarGetInteger("gNoCulling", 0) == 0) { CVarGetInteger("gNoCulling", 0) == 0) {
var_s1++; var_s1++;
@ -744,7 +744,7 @@ void render_actor_shell(Camera* camera, Mat4 matrix, struct ShellActor* shell) {
FrameInterpolation_RecordOpenChild("Shell", TAG_ITEM_ADDR(shell)); FrameInterpolation_RecordOpenChild("Shell", TAG_ITEM_ADDR(shell));
f32 temp_f0 = f32 temp_f0 =
is_within_render_distance(camera->pos, shell->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 490000.0f); is_within_render_distance(camera->pos, shell->pos, camera->rot[1], 0, camera->fieldOfView, 490000.0f);
if (CVarGetInteger("gNoCulling", 0) == 1) { if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_f0 = CLAMP(temp_f0, 0.0f, 40000.0f); temp_f0 = CLAMP(temp_f0, 0.0f, 40000.0f);
} }
@ -824,7 +824,7 @@ UNUSED void func_8029ABD4(f32* pos, s16 state) {
} }
void func_8029AC18(Camera* camera, Mat4 arg1, struct Actor* arg2) { void func_8029AC18(Camera* camera, Mat4 arg1, struct Actor* arg2) {
if (is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, gCameraFOV[camera - camera1], if (is_within_render_distance(camera->pos, arg2->pos, camera->rot[1], 0, camera->fieldOfView,
4000000.0f) < 0 && 4000000.0f) < 0 &&
CVarGetInteger("gNoCulling", 0) == 0) { CVarGetInteger("gNoCulling", 0) == 0) {
return; return;

View File

@ -407,8 +407,7 @@ Mtx gIdentityMatrix2 = {
toFixedPointMatrix(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0), toFixedPointMatrix(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0),
}; };
void func_802A487C(Vtx* arg0, UNUSED ScreenContext* arg1, UNUSED s32 arg2, UNUSED s32 arg3, void func_802A487C(Vtx* arg0) {
UNUSED f32* arg4) {
init_rdp(); init_rdp();
if (!IsRainbowRoad()) { if (!IsRainbowRoad()) {
@ -425,7 +424,7 @@ void func_802A487C(Vtx* arg0, UNUSED ScreenContext* arg1, UNUSED s32 arg2, UNUSE
} }
} }
void func_802A4A0C(Vtx* vtx, ScreenContext* arg1, UNUSED s32 arg2, UNUSED s32 arg3, UNUSED f32* arg4) { void func_802A4A0C(Vtx* vtx, ScreenContext* arg1) {
Camera* camera = arg1->camera; Camera* camera = arg1->camera;
s16 temp_t5; s16 temp_t5;
f32 temp_f0; f32 temp_f0;
@ -521,22 +520,22 @@ void func_802A4D18(void) {
void func_802A4EF4(void) { void func_802A4EF4(void) {
switch (gActiveScreenMode) { switch (gActiveScreenMode) {
case SCREEN_MODE_1P: case SCREEN_MODE_1P:
func_8001F394(gPlayerOne, &gCameraFOV[0]); func_8001F394(gPlayerOne);
break; break;
case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL:
func_8001F394(gPlayerOne, &gCameraFOV[0]); func_8001F394(gPlayerOne);
func_8001F394(gPlayerTwo, &gCameraFOV[1]); func_8001F394(gPlayerTwo);
break; break;
case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL:
func_8001F394(gPlayerOne, &gCameraFOV[0]); func_8001F394(gPlayerOne);
func_8001F394(gPlayerTwo, &gCameraFOV[1]); func_8001F394(gPlayerTwo);
break; break;
case SCREEN_MODE_3P_4P_SPLITSCREEN: case SCREEN_MODE_3P_4P_SPLITSCREEN:
func_8001F394(gPlayerOne, &gCameraFOV[0]); func_8001F394(gPlayerOne);
func_8001F394(gPlayerTwo, &gCameraFOV[1]); func_8001F394(gPlayerTwo);
func_8001F394(gPlayerThree, &gCameraFOV[2]); func_8001F394(gPlayerThree);
func_8001F394(gPlayerFour, &gCameraFOV[3]); func_8001F394(gPlayerFour);
break; break;
} }
} }
@ -552,9 +551,9 @@ void func_802A5004(void) {
func_802A39E0(gScreenTwoCtx); func_802A39E0(gScreenTwoCtx);
if (D_800DC5B4 != 0) { if (D_800DC5B4 != 0) {
func_802A4A0C((Vtx*) D_802B8910, gScreenTwoCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[1]); func_802A4A0C((Vtx*) D_802B8910, gScreenTwoCtx);
func_80057FC4(2); func_80057FC4(2);
func_802A487C((Vtx*) D_802B8910, gScreenTwoCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[1]); func_802A487C((Vtx*) D_802B8910);
func_80093A30(2); func_80093A30(2);
} }
} }
@ -569,9 +568,9 @@ void func_802A50EC(void) {
func_802A39E0(gScreenOneCtx); func_802A39E0(gScreenOneCtx);
if (D_800DC5B4 != 0) { if (D_800DC5B4 != 0) {
func_802A4A0C((Vtx*) D_802B8890, gScreenOneCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[0]); func_802A4A0C((Vtx*) D_802B8890, gScreenOneCtx);
func_80057FC4(1); func_80057FC4(1);
func_802A487C((Vtx*) D_802B8890, gScreenOneCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[0]); func_802A487C((Vtx*) D_802B8890);
func_80093A30(1); func_80093A30(1);
} }
} }
@ -586,9 +585,9 @@ void func_802A51D4(void) {
gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING);
if (D_800DC5B4 != 0) { if (D_800DC5B4 != 0) {
func_802A4A0C((Vtx*) D_802B8890, gScreenOneCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[0]); func_802A4A0C((Vtx*) D_802B8890, gScreenOneCtx);
func_80057FC4(3); func_80057FC4(3);
func_802A487C((Vtx*) D_802B8890, gScreenOneCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[0]); func_802A487C((Vtx*) D_802B8890);
func_80093A30(3); func_80093A30(3);
} }
} }
@ -603,9 +602,9 @@ void func_802A52BC(void) {
gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING);
if (D_800DC5B4 != 0) { if (D_800DC5B4 != 0) {
func_802A4A0C((Vtx*) D_802B8910, gScreenTwoCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[1]); func_802A4A0C((Vtx*) D_802B8910, gScreenTwoCtx);
func_80057FC4(4); func_80057FC4(4);
func_802A487C((Vtx*) D_802B8910, gScreenTwoCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[1]); func_802A487C((Vtx*) D_802B8910);
func_80093A30(4); func_80093A30(4);
} }
} }
@ -620,11 +619,11 @@ void func_802A53A4(void) {
init_z_buffer(); init_z_buffer();
select_framebuffer(); select_framebuffer();
if (D_800DC5B4 != 0) { if (D_800DC5B4 != 0) {
func_802A4A0C((Vtx*) D_802B8890, gScreenOneCtx, 0x140, 0xF0, &gCameraFOV[0]); func_802A4A0C((Vtx*) D_802B8890, gScreenOneCtx);
if (gGamestate != CREDITS_SEQUENCE) { if (gGamestate != CREDITS_SEQUENCE) {
func_80057FC4(0); func_80057FC4(0);
} }
func_802A487C((Vtx*) D_802B8890, gScreenOneCtx, 0x140, 0xF0, &gCameraFOV[0]); func_802A487C((Vtx*) D_802B8890);
func_80093A30(0); func_80093A30(0);
} }
} }
@ -639,9 +638,9 @@ void func_802A54A8(void) {
gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING);
if (D_800DC5B4 != 0) { if (D_800DC5B4 != 0) {
func_802A4A0C((Vtx*) D_802B8890, gScreenOneCtx, 0x140, 0xF0, &gCameraFOV[0]); func_802A4A0C((Vtx*) D_802B8890, gScreenOneCtx);
func_80057FC4(8); func_80057FC4(8);
func_802A487C((Vtx*) D_802B8890, gScreenOneCtx, 0x140, 0xF0, &gCameraFOV[0]); func_802A487C((Vtx*) D_802B8890);
func_80093A30(8); func_80093A30(8);
} }
} }
@ -656,9 +655,9 @@ void func_802A5590(void) {
gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING);
if (D_800DC5B4 != 0) { if (D_800DC5B4 != 0) {
func_802A4A0C((Vtx*) D_802B8910, gScreenTwoCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[1]); func_802A4A0C((Vtx*) D_802B8910, gScreenTwoCtx);
func_80057FC4(9); func_80057FC4(9);
func_802A487C((Vtx*) D_802B8910, gScreenTwoCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[1]); func_802A487C((Vtx*) D_802B8910);
func_80093A30(9); func_80093A30(9);
} }
} }
@ -673,9 +672,9 @@ void func_802A5678(void) {
gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING); gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_SHADING_SMOOTH | G_CLIPPING);
if (D_800DC5B4 != 0) { if (D_800DC5B4 != 0) {
func_802A4A0C((Vtx*) D_802B8990, gScreenThreeCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[2]); func_802A4A0C((Vtx*) D_802B8990, gScreenThreeCtx);
func_80057FC4(10); func_80057FC4(10);
func_802A487C((Vtx*) D_802B8990, gScreenThreeCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[2]); func_802A487C((Vtx*) D_802B8990);
func_80093A30(10); func_80093A30(10);
} }
} }
@ -708,9 +707,9 @@ void func_802A5760(void) {
func_802A39E0(gScreenFourCtx); func_802A39E0(gScreenFourCtx);
if (D_800DC5B4 != 0) { if (D_800DC5B4 != 0) {
func_802A4A0C(D_802B8A10, gScreenFourCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[3]); func_802A4A0C(D_802B8A10, gScreenFourCtx);
func_80057FC4(11); func_80057FC4(11);
func_802A487C(D_802B8A10, gScreenFourCtx, SCREEN_WIDTH, SCREEN_HEIGHT, &gCameraFOV[3]); func_802A487C(D_802B8A10);
func_80093A30(11); func_80093A30(11);
} }
} }

View File

@ -9,7 +9,7 @@
/* Function Prototypes */ /* Function Prototypes */
void func_802A4A0C(Vtx*, ScreenContext*, s32, s32, f32*); void func_802A4A0C(Vtx*, ScreenContext*);
void set_screen(void); void set_screen(void);
void set_editor_screen(void); void set_editor_screen(void);
void func_802A3730(ScreenContext*); void func_802A3730(ScreenContext*);
@ -31,7 +31,7 @@ void set_viewport(void);
void select_framebuffer(void); void select_framebuffer(void);
void func_802A4300(void); void func_802A4300(void);
void func_802A450C(Vtx*); void func_802A450C(Vtx*);
void func_802A487C(Vtx*, ScreenContext*, s32, s32, f32*); void func_802A487C(Vtx*);
void func_802A4D18(void); void func_802A4D18(void);
void func_802A4EF4(void); void func_802A4EF4(void);
void func_802A5004(void); void func_802A5004(void);

View File

@ -2532,27 +2532,27 @@ void func_80078C70(s32 arg0) {
case 0: /* switch 1 */ case 0: /* switch 1 */
sp1C = 0; sp1C = 0;
camera = camera1; camera = camera1;
D_8018D200 = gCameraFOV[0] + 40.0f; D_8018D200 = camera->fieldOfView + 40.0f;
break; break;
case 1: /* switch 1 */ case 1: /* switch 1 */
sp1C = 0; sp1C = 0;
camera = camera1; camera = camera1;
D_8018D200 = gCameraFOV[0] + 40.0f; D_8018D200 = camera->fieldOfView + 40.0f;
break; break;
case 2: /* switch 1 */ case 2: /* switch 1 */
camera = camera2; camera = camera2;
sp1C = D_8018D1F0; sp1C = D_8018D1F0;
D_8018D200 = gCameraFOV[1] + 40.0f; D_8018D200 = camera->fieldOfView + 40.0f;
break; break;
case 3: /* switch 1 */ case 3: /* switch 1 */
sp1C = 0; sp1C = 0;
camera = camera1; camera = camera1;
D_8018D200 = gCameraFOV[0] + 40.0f; D_8018D200 = camera->fieldOfView + 40.0f;
break; break;
case 4: /* switch 1 */ case 4: /* switch 1 */
camera = camera2; camera = camera2;
sp1C = D_8018D1F0; sp1C = D_8018D1F0;
D_8018D200 = gCameraFOV[1] + 40.0f; D_8018D200 = camera->fieldOfView + 40.0f;
break; break;
} }