Add Interpolation (#204)
* initial work
* more work
* progress
* Fixed slow fps
* Add Lywx changes
* Interp Works
* Test default tick/logic update
* Added missing include (#202)
* Added missing include
* More missing includes
---------
Co-authored-by: MegaMech <MegaMech@users.noreply.github.com>
* test
* Revert "test"
This reverts commit 1a810d74cc.
* Interp Item box
* Actually interpolate item box
* fix clouds
* interp player?
* Test 2
* Fix mistake
* tag and fix item boxes
* tag fake item box and whatever func_800696CC is
* these aren't needed
* tag karts
* Slightly better falling rocks(still needs work)
* Tag Smoke and Dust
* Removed unneeded code from falling_rock
* tag whatever func_80051ABC is
* add missing rotate x coord
* GrandPrixBallon/kart shadow
* Green shells tag, and added comments I neglected to add before.
* doesn't compile on win
* Fixes
* Disabled camera interpolation
* Balloons fixes
* progress
* set_transform_matrix compiles
* Compile setTransformMatrix
* More transforms interp
* Add more interps
* matrix
* Matrix multi interp
* Fix interpolation camera bug
* Missing includes needed for Linux.
* Excluded access to HM64 Labs on Switch.
* interpolation tags for various objects
* Bowser castle statue flame interpolated.
* tag hedgehogs
* cloud interpolation
* Interpolated smoke particles from shells
* cloud interpolation refactor
* Interpolated snowflakes
* Interpolated penguins, also added comment tags to places I missed.
* tag Snowman interpolation
* Interpolated player reflection(sherbet land)
* Forgot to uncomment stuff while testing
* better tag
* tag leaves
* Set the default FPS to 30
* tag hud
* Fixed "Match Refresh Rate" option
* adjust draw distance
* remove innecessary rock tag
* rag rocks
* better tag
* Tagged player rank placement in HUD
* Tagged Bat, Boos, and TrashBin(Banshee Boardwalk objects)
* Refactor render_screens and fix editor raycast
* better object interpolation
* shift is not needed here
* fix tag
* fix tags
* mole comments
* comment
* Changed how shell flames are interpolated.
* interpolated ended scene fireworks.
* Tagged star particles in the ending scene
* Shell flames handled better.
* this isn't needed
* Fix multiplayer cameras
* Fixed loading battle maps.
* Tagged battle balloons
* Some fixes for battle mode
* No longer needed changes toAFinishline with the changes mega made.
* Tag finishline
* fix to make it compile with cmake 3.31
* changed mtxf_multiplication() to fix vert explosion in Desert & DK parkway.(provided by Coco.)
* fix memory leaks, avoid invalidate texture (#207)
* Fixed macos
* More stupid fixes
* update with main and update torch and lus and enable action on this branch
* Update FrameInterpolation.h
* Update FrameInterpolation.cpp
* fix some memory leak
* Update torch
* Update torch
* update torch and lus
* reduce texture import
* don't use fork of torch and lus
* Update torch
* Update torch
---------
Co-authored-by: Lywx <kiritodev01@gmail.com>
* Refactor World::Courses to unique_ptr (#211)
* wip course unique ptr
* Track unique_ptr : This probably compiles
* Finish impl Courses as unique_ptr
* Fix error
* Fixes
* More fixes
* Cleanup
* Remove old vars
---------
Co-authored-by: MegaMech <7255464+MegaMech@users.noreply.github.com>
* particle boat and train
* fix player particle interpolation
* add modify interpolation target fps in menu
* fix windows
* Update libultraship
* Fix logo interp
* Interp SetTextMatrix
* Fix freecam camera
* Clarify comment
* Clarify func
* fix linux compilation
* Update Thwomp.cpp
* Update Thwomp.h
* Update render.inc.c
* Update render.inc.c
* Update gbiMacro.c
* interp falling rock shadow
* Revert change that has no explanation
* Update code_80057C60.c
* Update code_80057C60.c
* Update GrandPrixBalloons.cpp
* Update Lakitu.cpp
* Update framebuffer_effects.c
* Update render_courses.c
---------
Co-authored-by: Sonic Dreamcaster <alejandro.asenjo88@gmail.com>
Co-authored-by: KiritoDv <kiritodev01@gmail.com>
Co-authored-by: sitton76 <58642183+sitton76@users.noreply.github.com>
Co-authored-by: MegaMech <7255464+MegaMech@users.noreply.github.com>
Co-authored-by: coco875 <59367621+coco875@users.noreply.github.com>
Co-authored-by: coco875 <pereira.jannin@gmail.com>
This commit is contained in:
parent
a67fbb6442
commit
44db9bab77
|
|
@ -2,7 +2,7 @@ name: GenerateBuilds
|
|||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
branches: ["*"]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 6a3f6cd327b99f617b623e5b9a3afeae460aac2b
|
||||
Subproject commit 47b4d7f6ae47e4ac900d080f485d1a6145985144
|
||||
|
|
@ -19,6 +19,9 @@ void render_actor_cow(Camera* camera, Mat4 arg1, struct Actor* arg2) {
|
|||
return;
|
||||
}
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("render_actor_cow", TAG_OBJECT(arg2));
|
||||
|
||||
arg1[3][0] = arg2->pos[0];
|
||||
arg1[3][1] = arg2->pos[1];
|
||||
arg1[3][2] = arg2->pos[2];
|
||||
|
|
@ -42,4 +45,7 @@ void render_actor_cow(Camera* camera, Mat4 arg1, struct Actor* arg2) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <code_800029B0.h>
|
||||
#include <libultra/gbi.h>
|
||||
#include <main.h>
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
/**
|
||||
* @brief Renders the fake item box actor.
|
||||
|
|
@ -24,6 +25,9 @@ void render_actor_fake_item_box(Camera* camera, struct FakeItemBox* fakeItemBox)
|
|||
f32 temp_f2_2;
|
||||
f32 someMultiplier;
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Fake Item Box", TAG_ITEM_ADDR(fakeItemBox));
|
||||
|
||||
if (is_within_render_distance(camera->pos, fakeItemBox->pos, camera->rot[1], 2500.0f, gCameraZoom[camera - camera1],
|
||||
1000000.0f) < 0 &&
|
||||
CVarGetInteger("gNoCulling", 0) == 0) {
|
||||
|
|
@ -61,6 +65,13 @@ void render_actor_fake_item_box(Camera* camera, struct FakeItemBox* fakeItemBox)
|
|||
|
||||
gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING);
|
||||
gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA);
|
||||
|
||||
/*
|
||||
* In the original game, the question mark texture would become corrupted. Thus, this code
|
||||
* makes it disappear to hide the issue. Since the texture no longer becomes corrupted, this
|
||||
* fix can be removed.
|
||||
*/
|
||||
#ifdef TARGET_N64
|
||||
if ((fakeItemBox->rot[1] < 0xAA1) && (fakeItemBox->rot[1] > 0)) {
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
|
||||
} else if ((fakeItemBox->rot[1] >= 0x6AA5) && (fakeItemBox->rot[1] < 0x754E)) {
|
||||
|
|
@ -70,9 +81,12 @@ void render_actor_fake_item_box(Camera* camera, struct FakeItemBox* fakeItemBox)
|
|||
} else if ((fakeItemBox->rot[1] >= 0xC711) && (fakeItemBox->rot[1] < 0xD1BA)) {
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
|
||||
} else {
|
||||
#endif
|
||||
gDPSetBlendMask(gDisplayListHead++, 0xFF);
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2);
|
||||
#ifdef TARGET_N64
|
||||
}
|
||||
#endif
|
||||
gSPDisplayList(gDisplayListHead++, D_0D003090);
|
||||
} else {
|
||||
gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING);
|
||||
|
|
@ -163,4 +177,6 @@ void render_actor_fake_item_box(Camera* camera, struct FakeItemBox* fakeItemBox)
|
|||
gSPDisplayList(gDisplayListHead++, D_0D0030F8);
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK);
|
||||
}
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <actors.h>
|
||||
#include <main.h>
|
||||
#include <assets/choco_mountain_data.h>
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
/**
|
||||
* @brief Renders the falling rock actor.
|
||||
|
|
@ -12,7 +13,7 @@
|
|||
void render_actor_falling_rock(Camera* camera, struct FallingRock* rock) {
|
||||
Vec3s sp98;
|
||||
Vec3f sp8C;
|
||||
Mat4 sp4C;
|
||||
Mat4 mtx;
|
||||
f32 height;
|
||||
UNUSED s32 pad[4];
|
||||
|
||||
|
|
@ -41,16 +42,29 @@ void render_actor_falling_rock(Camera* camera, struct FallingRock* rock) {
|
|||
sp98[1] = 0;
|
||||
sp98[2] = 0;
|
||||
sp8C[1] = height + 2.0f;
|
||||
mtxf_pos_rotation_xyz(sp4C, sp8C, sp98);
|
||||
if (render_set_position(sp4C, 0) == 0) {
|
||||
|
||||
FrameInterpolation_RecordOpenChild("rock_shadow", (uintptr_t) rock);
|
||||
mtxf_pos_rotation_xyz(mtx, sp8C, sp98);
|
||||
if (render_set_position(mtx, 0) == 0) {
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
return;
|
||||
}
|
||||
gSPDisplayList(gDisplayListHead++, d_course_choco_mountain_dl_6F88);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
mtxf_pos_rotation_xyz(sp4C, rock->pos, rock->rot);
|
||||
if (render_set_position(sp4C, 0) == 0) {
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("rock", (uintptr_t) rock);
|
||||
|
||||
mtxf_pos_rotation_xyz(mtx, rock->pos, rock->rot);
|
||||
if (render_set_position(mtx, 0) == 0) {
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
return;
|
||||
}
|
||||
gSPDisplayList(gDisplayListHead++, d_course_choco_mountain_dl_falling_rock);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <actors.h>
|
||||
#include <main.h>
|
||||
#include <macros.h>
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
/**
|
||||
* @brief Renders the item box actor.
|
||||
|
|
@ -26,6 +27,9 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
|
|||
f32 temp_f2_2;
|
||||
f32 someMultiplier;
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("ItemBox", TAG_ITEM_ADDR(item_box));
|
||||
|
||||
temp_f0 = is_within_render_distance(camera->pos, item_box->pos, camera->rot[1], 0.0f, gCameraZoom[camera - camera1],
|
||||
4000000.0f);
|
||||
if (CVarGetInteger("gNoCulling", 0) == 1) {
|
||||
|
|
@ -39,6 +43,7 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
|
|||
someVec2[0] = item_box->pos[0];
|
||||
someVec2[1] = item_box->resetDistance + 2.0f;
|
||||
someVec2[2] = item_box->pos[2];
|
||||
|
||||
mtxf_pos_rotation_xyz(someMatrix1, someVec2, someRot);
|
||||
|
||||
if (!render_set_position(someMatrix1, 0)) {
|
||||
|
|
@ -46,8 +51,10 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
|
|||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, D_0D002EE8);
|
||||
|
||||
someRot[1] = item_box->rot[1] * 2;
|
||||
someVec2[1] = item_box->pos[1];
|
||||
|
||||
mtxf_pos_rotation_xyz(someMatrix1, someVec2, someRot);
|
||||
|
||||
if (!render_set_position(someMatrix1, 0)) {
|
||||
|
|
@ -66,6 +73,7 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
|
|||
gSPDisplayList(gDisplayListHead++, itemBoxQuestionMarkModel);
|
||||
}
|
||||
if (item_box->state != 3) {
|
||||
|
||||
mtxf_pos_rotation_xyz(someMatrix1, item_box->pos, item_box->rot);
|
||||
|
||||
if (!render_set_position(someMatrix1, 0)) {
|
||||
|
|
@ -74,6 +82,13 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
|
|||
|
||||
gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING);
|
||||
gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA);
|
||||
|
||||
/*
|
||||
* In the original game, the question mark texture would become corrupted. Thus, this code
|
||||
* makes it disappear to hide the issue. Since the texture no longer becomes corrupted, this
|
||||
* fix can be removed.
|
||||
*/
|
||||
#ifdef TARGET_N64
|
||||
if ((item_box->rot[1] < 0xAA1) && (item_box->rot[1] > 0)) {
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
|
||||
} else if ((item_box->rot[1] >= 0x6AA5) && (item_box->rot[1] < 0x754E)) {
|
||||
|
|
@ -83,16 +98,21 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
|
|||
} else if ((item_box->rot[1] >= 0xC711) && (item_box->rot[1] < 0xD1BA)) {
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
|
||||
} else {
|
||||
gDPSetBlendMask(gDisplayListHead++, 0xFF);
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2);
|
||||
#endif
|
||||
gDPSetBlendMask(gDisplayListHead++, 0xFF);
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2);
|
||||
#ifdef TARGET_N64
|
||||
}
|
||||
#endif
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH);
|
||||
gSPDisplayList(gDisplayListHead++, D_0D003090);
|
||||
|
||||
} else {
|
||||
gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING);
|
||||
gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK);
|
||||
gDPSetBlendMask(gDisplayListHead++, 0xFF);
|
||||
thing = item_box->someTimer;
|
||||
|
||||
mtxf_pos_rotation_xyz(someMatrix1, item_box->pos, item_box->rot);
|
||||
if (thing < 10.0f) {
|
||||
someMultiplier = 1.0f;
|
||||
|
|
@ -116,6 +136,7 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
|
|||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, D_0D003158);
|
||||
|
||||
temp_f2_2 = 0.8f * thing;
|
||||
temp_f12 = 0.5f * thing;
|
||||
someVec1[0] = temp_f2_2;
|
||||
|
|
@ -128,10 +149,12 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
|
|||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, D_0D0031B8);
|
||||
|
||||
temp_f0_2 = -0.5f * thing;
|
||||
someVec1[0] = temp_f2_2;
|
||||
someVec1[1] = 1.2f * thing;
|
||||
someVec1[2] = temp_f0_2;
|
||||
|
||||
add_translate_mat4_vec3f(someMatrix1, someMatrix2, someVec1);
|
||||
|
||||
if (!render_set_position(someMatrix2, 0)) {
|
||||
|
|
@ -139,6 +162,7 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
|
|||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, D_0D003128);
|
||||
|
||||
if (!(item_box->someTimer & 1)) {
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
|
||||
} else {
|
||||
|
|
@ -147,6 +171,7 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
|
|||
someVec1[0] = 0.0f;
|
||||
someVec1[1] = 1.8f * thing;
|
||||
someVec1[2] = -1.0f * thing;
|
||||
|
||||
add_translate_mat4_vec3f(someMatrix1, someMatrix2, someVec1);
|
||||
|
||||
if (!render_set_position(someMatrix2, 0)) {
|
||||
|
|
@ -154,10 +179,12 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
|
|||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, D_0D0031E8);
|
||||
|
||||
temp_f0_3 = -0.8f * thing;
|
||||
someVec1[0] = temp_f0_3;
|
||||
someVec1[1] = 0.6f * thing;
|
||||
someVec1[2] = temp_f0_2;
|
||||
|
||||
add_translate_mat4_vec3f(someMatrix1, someMatrix2, someVec1);
|
||||
|
||||
if (!render_set_position(someMatrix2, 0)) {
|
||||
|
|
@ -165,9 +192,11 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
|
|||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, D_0D003188);
|
||||
|
||||
someVec1[0] = temp_f0_3;
|
||||
someVec1[1] = temp_f2;
|
||||
someVec1[2] = temp_f12;
|
||||
|
||||
add_translate_mat4_vec3f(someMatrix1, someMatrix2, someVec1);
|
||||
|
||||
if (!render_set_position(someMatrix2, 0)) {
|
||||
|
|
@ -175,8 +204,11 @@ void render_actor_item_box(Camera* camera, struct ItemBox* item_box) {
|
|||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, D_0D0030F8);
|
||||
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK);
|
||||
}
|
||||
gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
|
||||
}
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <actors.h>
|
||||
#include <main.h>
|
||||
#include <assets/mario_raceway_data.h>
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
/**
|
||||
* @brief Renders the Mario sign actor.
|
||||
|
|
@ -11,10 +12,9 @@
|
|||
* @param arg2
|
||||
*/
|
||||
void render_actor_mario_sign(Camera* arg0, UNUSED Mat4 arg1, struct Actor* arg2) {
|
||||
Mat4 sp40;
|
||||
Mat4 mtx;
|
||||
f32 unk;
|
||||
s16 temp = arg2->flags;
|
||||
|
||||
if (temp & 0x800) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -24,11 +24,16 @@ void render_actor_mario_sign(Camera* arg0, UNUSED Mat4 arg1, struct Actor* arg2)
|
|||
unk = MAX(unk, 0.0f);
|
||||
}
|
||||
if (!(unk < 0.0f)) {
|
||||
|
||||
FrameInterpolation_RecordMatrixPush(mtx);
|
||||
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH);
|
||||
gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING);
|
||||
mtxf_pos_rotation_xyz(sp40, arg2->pos, arg2->rot);
|
||||
if (render_set_position(sp40, 0) != 0) {
|
||||
mtxf_pos_rotation_xyz(mtx, arg2->pos, arg2->rot);
|
||||
if (render_set_position(mtx, 0) != 0) {
|
||||
gSPDisplayList(gDisplayListHead++, d_course_mario_raceway_dl_sign);
|
||||
}
|
||||
FrameInterpolation_RecordMatrixPop(mtx);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ void render_actor_piranha_plant(Camera* arg0, Mat4 arg1, struct PiranhaPlant* ar
|
|||
G_TX_MIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
||||
G_TX_NOLOD);
|
||||
|
||||
if (GetCourse() == GetMarioRaceway()) {
|
||||
if (IsMarioRaceway()) {
|
||||
gSPDisplayList(gDisplayListHead++, &d_course_mario_raceway_dl_piranha_plant);
|
||||
} else {
|
||||
gSPDisplayList(gDisplayListHead++, &d_course_royal_raceway_dl_piranha_plant);
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ void func_80299864(Camera* camera, Mat4 arg1, struct Actor* arg2) {
|
|||
// Unless both courses use this actor and use the same addr for the texture.
|
||||
// Just in-case changed the code into a switch to prevent future crashes.
|
||||
// This comment can be removed when this is confirmed to work.
|
||||
if (GetCourse() == GetLuigiRaceway()) {
|
||||
if (IsLuigiRaceway()) {
|
||||
gSPDisplayList(gDisplayListHead++, d_course_luigi_raceway_dl_FC70);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <actors.h>
|
||||
#include <defines.h>
|
||||
#include <main.h>
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
/**
|
||||
* @brief Renders the Yoshi egg actor.
|
||||
|
|
@ -51,6 +52,9 @@ void render_actor_yoshi_egg(Camera* arg0, Mat4 arg1, struct YoshiValleyEgg* egg,
|
|||
sp5C[0] = 0;
|
||||
sp5C[1] = egg->eggRot;
|
||||
sp5C[2] = 0;
|
||||
|
||||
FrameInterpolation_RecordMatrixPush(sp60);
|
||||
|
||||
mtxf_pos_rotation_xyz(sp60, egg->pos, sp5C);
|
||||
if (render_set_position(sp60, 0) == 0) {
|
||||
return;
|
||||
|
|
@ -58,14 +62,18 @@ void render_actor_yoshi_egg(Camera* arg0, Mat4 arg1, struct YoshiValleyEgg* egg,
|
|||
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_LIGHTING);
|
||||
gSPDisplayList(gDisplayListHead++, d_course_yoshi_valley_dl_16D70);
|
||||
FrameInterpolation_RecordMatrixPop(sp60);
|
||||
} else {
|
||||
arg1[3][0] = egg->pos[0];
|
||||
arg1[3][1] = egg->pos[1];
|
||||
arg1[3][2] = egg->pos[2];
|
||||
|
||||
FrameInterpolation_RecordMatrixPush(arg1);
|
||||
|
||||
if (render_set_position(arg1, 0) != 0) {
|
||||
gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING);
|
||||
gSPDisplayList(gDisplayListHead++, d_course_yoshi_valley_dl_egg_lod0);
|
||||
}
|
||||
FrameInterpolation_RecordMatrixPop(arg1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <libultra/gbi.h>
|
||||
#include "code_80057C60.h"
|
||||
#include "engine/Matrix.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
Vec3s sOriginalPosAnimation;
|
||||
s16 isNotTheFirst;
|
||||
|
|
@ -35,6 +36,9 @@ void convert_to_fixed_point_matrix_animation(Mtx* dest, Mat4 src) {
|
|||
}
|
||||
|
||||
void mtxf_translate_rotate2(Mat4 dest, Vec3f pos, Vec3s angle) {
|
||||
|
||||
FrameInterpolation_RecordMatrixPosRotXYZ(&dest, pos, angle);
|
||||
|
||||
f32 sx = sins(angle[0]);
|
||||
f32 cx = coss(angle[0]);
|
||||
|
||||
|
|
@ -92,7 +96,7 @@ void render_limb_or_add_mtx(Armature* arg0, s16* arg1, AnimationLimbVector arg2,
|
|||
}
|
||||
angle[i] = arg1[arg2[i].indexCycle + some_offset];
|
||||
}
|
||||
|
||||
FrameInterpolation_RecordMatrixPush(modelMatrix);
|
||||
mtxf_translate_rotate2(modelMatrix, pos, angle);
|
||||
//convert_to_fixed_point_matrix_animation(&gGfxPool->mtxHud[gMatrixHudCount], modelMatrix);
|
||||
sMatrixStackSize += 1;
|
||||
|
|
@ -104,6 +108,7 @@ void render_limb_or_add_mtx(Armature* arg0, s16* arg1, AnimationLimbVector arg2,
|
|||
model = (virtualModel);
|
||||
gSPDisplayList(gDisplayListHead++, model);
|
||||
}
|
||||
FrameInterpolation_RecordMatrixPop(modelMatrix);
|
||||
}
|
||||
|
||||
void render_armature(Armature* animation, Animation* arg1, s16 timeCycle) {
|
||||
|
|
|
|||
|
|
@ -2647,11 +2647,11 @@ void func_800C847C(u8 playerId) {
|
|||
func_800C97C4(playerId);
|
||||
D_800E9F74[playerId] = 1;
|
||||
func_800C94A4(playerId);
|
||||
if (((GetCourse() == GetChocoMountain()) || (GetCourse() == GetBowsersCastle()) ||
|
||||
(GetCourse() == GetBansheeBoardwalk()) || (GetCourse() == GetYoshiValley()) ||
|
||||
(GetCourse() == GetFrappeSnowland()) || (GetCourse() == GetKoopaTroopaBeach()) ||
|
||||
(GetCourse() == GetRoyalRaceway()) || (GetCourse() == GetSherbetLand()) ||
|
||||
(GetCourse() == GetDkJungle()) || (GetCourse() == GetBigDonut())) &&
|
||||
if (((IsChocoMountain()) || (IsBowsersCastle()) ||
|
||||
(IsBansheeBoardwalk()) || (IsYoshiValley()) ||
|
||||
(IsFrappeSnowland()) || (IsKoopaTroopaBeach()) ||
|
||||
(IsRoyalRaceway()) || (IsSherbetLand()) ||
|
||||
(IsDkJungle()) || (IsBigDonut())) &&
|
||||
(D_800EA0EC[playerId] == 0)) {
|
||||
play_sound((gPlayers[playerId].characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x05),
|
||||
&D_800E9F7C[playerId].pos, playerId, &D_800EA1D4, &D_800EA1D4,
|
||||
|
|
@ -2664,7 +2664,7 @@ void func_800C847C(u8 playerId) {
|
|||
D_800E9F74[playerId] = 2;
|
||||
func_800C94A4(playerId);
|
||||
D_800E9F74[playerId] = 0;
|
||||
if ((GetCourse() == GetKoopaTroopaBeach()) && (D_800EA0EC[playerId] == 0)) {
|
||||
if ((IsKoopaTroopaBeach()) && (D_800EA0EC[playerId] == 0)) {
|
||||
play_sound((gPlayers[playerId].characterId * 0x10) + SOUND_ARG_LOAD(0x29, 0x00, 0x80, 0x08),
|
||||
&D_800E9F7C[playerId].pos, playerId, &D_800EA1D4, &D_800EA1D4,
|
||||
(u8*) &D_800E9F7C[playerId].unk_14);
|
||||
|
|
@ -2746,7 +2746,7 @@ void func_800C89E4(void) {
|
|||
}
|
||||
|
||||
void func_800C8AE4(void) {
|
||||
if (GetCourse() == GetLuigiRaceway()) {
|
||||
if (IsLuigiRaceway()) {
|
||||
if (D_800EA184 != 0) {
|
||||
if ((u8) D_800EA16C == 0) {
|
||||
// Has to be this way, can't be D_800EA184++
|
||||
|
|
@ -2824,11 +2824,11 @@ void func_800C8CCC() {
|
|||
}
|
||||
|
||||
void play_sound2(s32 soundBits) {
|
||||
if ((soundBits == SOUND_ACTION_REV_ENGINE) && (GetCourse() == GetDkJungle())) {
|
||||
if ((soundBits == SOUND_ACTION_REV_ENGINE) && (IsDkJungle())) {
|
||||
soundBits = SOUND_ARG_LOAD(0x49, 0x00, 0x80, 0x27);
|
||||
}
|
||||
|
||||
if ((soundBits == SOUND_ACTION_REV_ENGINE_2) && (GetCourse() == GetDkJungle())) {
|
||||
if ((soundBits == SOUND_ACTION_REV_ENGINE_2) && (IsDkJungle())) {
|
||||
soundBits = SOUND_ARG_LOAD(0x49, 0x00, 0x80, 0x28);
|
||||
}
|
||||
play_sound(soundBits, &D_800EA1C8, 4, &D_800EA1D4, &D_800EA1D4, &D_800EA1DC);
|
||||
|
|
@ -3467,7 +3467,9 @@ void func_800CAEC4(u8 playerId, f32 arg1) {
|
|||
arg1 = 0.0f;
|
||||
}
|
||||
D_800EA120[playerId] = arg1;
|
||||
play_sound(gCurrentCourseId + 0x19007020, &D_800E9F7C[playerId].pos, playerId, &D_800EA1D4,
|
||||
//! @warning this used to be gCurrentCourseId + 0x19007020
|
||||
// This may not be equivallent.
|
||||
play_sound(GetCourseIndex() + 0x19007020, &D_800E9F7C[playerId].pos, playerId, &D_800EA1D4,
|
||||
&D_800EA120[playerId], (u8*) &D_800E9F7C[playerId].unk_14);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
151
src/camera.c
151
src/camera.c
|
|
@ -18,17 +18,19 @@
|
|||
#include "spawn_players.h"
|
||||
#include "enhancements/freecam/freecam_engine.h"
|
||||
#include "enhancements/freecam/freecam.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
#include "engine/GameAPI.h"
|
||||
#include "port/Game.h"
|
||||
|
||||
f32 D_800DDB30[] = { 0.4f, 0.6f, 0.275f, 0.3f };
|
||||
|
||||
Camera cameras[4];
|
||||
Camera cameras[5];
|
||||
Camera* camera1 = &cameras[0];
|
||||
Camera* camera2 = &cameras[1];
|
||||
Camera* camera3 = &cameras[2];
|
||||
Camera* camera4 = &cameras[3];
|
||||
Camera* gFreecamCamera = &cameras[4];
|
||||
|
||||
UNUSED s32 D_801649D0[2];
|
||||
|
||||
|
|
@ -193,6 +195,146 @@ void camera_init(f32 posX, f32 posY, f32 posZ, UNUSED s16 rot, u32 arg4, s32 cam
|
|||
func_802B7F7C(camera->pos, camera->lookAt, camera->rot);
|
||||
}
|
||||
|
||||
// Many arrays are hard-coded to 4. Skip those.
|
||||
void freecam_init(f32 posX, f32 posY, f32 posZ, UNUSED s16 rot, u32 arg4, s32 cameraId) {
|
||||
Player* player = gPlayerOne;
|
||||
Camera* camera = &cameras[cameraId];
|
||||
|
||||
camera->cameraId = cameraId;
|
||||
|
||||
//D_80152300[cameraId] = arg4;
|
||||
switch (arg4) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 3:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
D_80164A89 = 0;
|
||||
camera->pos[0] = posX;
|
||||
camera->pos[1] = posY;
|
||||
camera->pos[2] = posZ;
|
||||
camera->someBitFlags = 0;
|
||||
camera->lookAt[0] = 0.0f;
|
||||
camera->lookAt[2] = 150.0f;
|
||||
camera->lookAt[1] = posY - 3.0;
|
||||
camera->up[0] = 0.0f;
|
||||
camera->up[1] = 1.0f;
|
||||
camera->up[2] = 0.0f;
|
||||
camera->playerId = (s16) 0;
|
||||
camera->unk_B0 = 0;
|
||||
camera->unk_A0 = 0.0f;
|
||||
|
||||
// D_801649D8[cameraId] = 20.0f;
|
||||
// D_801649E8[cameraId] = 10.0f;
|
||||
// D_801649F8[cameraId] = 7.0f;
|
||||
// D_80164A2C = 0;
|
||||
// D_80164A30 = 30.0f;
|
||||
// D_80164A38[cameraId] = 0.0f;
|
||||
// D_80164A48[cameraId] = 0.0f;
|
||||
|
||||
// D_80164A90[cameraId] = 0.0f;
|
||||
// D_80164AA0[cameraId] = 0.0f;
|
||||
// D_80164A78[cameraId] = D_800DDB30[gActiveScreenMode];
|
||||
// D_80164A18[cameraId] = 0;
|
||||
// D_80164A08[cameraId] = 0;
|
||||
// D_80164498[cameraId] = 0.0f;
|
||||
camera->unk_94.unk_8 = 0;
|
||||
camera->unk_94.unk_0 = 0.0f;
|
||||
|
||||
player += cameraId;
|
||||
camera->unk_2C = player->rotation[1];
|
||||
camera->unk_AC = player->rotation[1];
|
||||
switch (gActiveScreenMode) {
|
||||
case SCREEN_MODE_1P:
|
||||
case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL:
|
||||
if (gModeSelection == BATTLE) {
|
||||
camera->unk_30[0] = 0.0f;
|
||||
camera->unk_30[1] = 11.6f;
|
||||
camera->unk_30[2] = -38.5f;
|
||||
camera->unk_3C[0] = 0.0f;
|
||||
camera->unk_3C[1] = 0.0f;
|
||||
camera->unk_3C[2] = 19.2f;
|
||||
D_80164A88 = 0;
|
||||
} else {
|
||||
camera->unk_30[0] = 0.0f;
|
||||
camera->unk_30[1] = 9.5f;
|
||||
camera->unk_30[2] = -50.0f;
|
||||
camera->unk_3C[0] = 0.0f;
|
||||
camera->unk_3C[1] = 0.0f;
|
||||
camera->unk_3C[2] = 70.0f;
|
||||
}
|
||||
break;
|
||||
case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL:
|
||||
if (gModeSelection == BATTLE) {
|
||||
camera->unk_30[0] = 0.0f;
|
||||
camera->unk_30[1] = 11.6f;
|
||||
camera->unk_30[2] = -38.5f;
|
||||
camera->unk_3C[0] = 0.0f;
|
||||
camera->unk_3C[1] = 0.0f;
|
||||
camera->unk_3C[2] = 19.2f;
|
||||
} else {
|
||||
camera->unk_30[0] = 0.0f;
|
||||
camera->unk_30[1] = 9.6f;
|
||||
camera->unk_30[2] = -35.0f;
|
||||
camera->unk_3C[0] = 0.0f;
|
||||
camera->unk_3C[1] = 0.0f;
|
||||
camera->unk_3C[2] = 30.0f;
|
||||
}
|
||||
break;
|
||||
case SCREEN_MODE_3P_4P_SPLITSCREEN:
|
||||
if (gModeSelection == BATTLE) {
|
||||
camera->unk_30[0] = 0.0f;
|
||||
camera->unk_30[1] = 11.6f;
|
||||
camera->unk_30[2] = -38.5f;
|
||||
camera->unk_3C[0] = 0.0f;
|
||||
camera->unk_3C[1] = 0.0f;
|
||||
camera->unk_3C[2] = 19.2f;
|
||||
} else {
|
||||
camera->unk_30[0] = 0.0f;
|
||||
camera->unk_30[1] = 9.0f;
|
||||
camera->unk_30[2] = -40.0f;
|
||||
camera->unk_3C[0] = 0.0f;
|
||||
camera->unk_3C[1] = 0.0f;
|
||||
camera->unk_3C[2] = 18.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//func_80014DE4(cameraId);
|
||||
|
||||
// if (D_80164678[cameraId] == 0) {
|
||||
if (D_80164A28 == 1) {
|
||||
// gCameraZoom[cameraId] = 80.0f;
|
||||
} else {
|
||||
// gCameraZoom[cameraId] = 40.0f;
|
||||
}
|
||||
camera->unk_B4 = gCameraZoom[0];
|
||||
// }
|
||||
// if (D_80164678[cameraId] == 1) {
|
||||
// if (D_80164A28 == 1) {
|
||||
// gCameraZoom[cameraId] = 100.0f;
|
||||
// } else {
|
||||
// gCameraZoom[cameraId] = 60.0f;
|
||||
// }
|
||||
// camera->unk_B4 = gCameraZoom[cameraId];
|
||||
// // }
|
||||
// if (D_80164678[cameraId] == 2) {
|
||||
// if (D_80164A28 == 1) {
|
||||
// gCameraZoom[cameraId] = 100.0f;
|
||||
// } else {
|
||||
// gCameraZoom[cameraId] = 60.0f;
|
||||
// }
|
||||
// camera->unk_B4 = gCameraZoom[cameraId];
|
||||
// D_80164A38[cameraId] = 20.0f;
|
||||
// D_80164A48[cameraId] = 1.5f;
|
||||
// D_80164A78[cameraId] = 1.0f;
|
||||
// }
|
||||
break;
|
||||
}
|
||||
func_802B7F7C(camera->pos, camera->lookAt, camera->rot);
|
||||
}
|
||||
|
||||
// Thwomp related
|
||||
void func_8001CA10(Camera* camera) {
|
||||
camera->unk_94.unk_8 = 0;
|
||||
|
|
@ -241,7 +383,7 @@ void func_8001CA78(UNUSED Player* player, Camera* camera, Vec3f arg2, f32* arg3,
|
|||
arg2[2] = camera->lookAt[2];
|
||||
calculate_orientation_matrix(sp74, 0, 1, 0, -0x00008000);
|
||||
mtxf_translate_vec3f_mat3(sp5C, sp74);
|
||||
if (GetCourse() == GetToadsTurnpike()) {
|
||||
if (IsToadsTurnpike()) {
|
||||
var_f14 = sp5C[0];
|
||||
} else {
|
||||
var_f14 = sp5C[0] + temp_s2->posX;
|
||||
|
|
@ -252,7 +394,7 @@ void func_8001CA78(UNUSED Player* player, Camera* camera, Vec3f arg2, f32* arg3,
|
|||
arg2[1] += (temp_f18 - camera->lookAt[1]) * 1;
|
||||
arg2[2] += (temp_f16 - camera->lookAt[2]) * 1;
|
||||
mtxf_translate_vec3f_mat3(sp68, sp74);
|
||||
if (GetCourse() == GetToadsTurnpike()) {
|
||||
if (IsToadsTurnpike()) {
|
||||
var_f14 = sp68[0];
|
||||
} else {
|
||||
var_f14 = sp68[0] + temp_s2->posX;
|
||||
|
|
@ -345,7 +487,7 @@ void func_8001CCEC(Player* player, Camera* camera, Vec3f arg2, f32* arg3, f32* a
|
|||
move_f32_towards(&D_80164AA0[index], 10, 0.02f);
|
||||
break;
|
||||
default:
|
||||
if (GetCourse() == GetYoshiValley()) {
|
||||
if (IsYoshiValley()) {
|
||||
move_f32_towards(&D_80164A90[index], 50, 0.04f);
|
||||
move_f32_towards(&D_80164AA0[index], 35, 0.04f);
|
||||
} else {
|
||||
|
|
@ -993,6 +1135,7 @@ void func_8001EE98(Player* player, Camera* camera, s8 index) {
|
|||
break;
|
||||
}
|
||||
freecam(camera, player, index); // Runs func_8001E45C when freecam is disabled
|
||||
//func_8001E45C(camera, player, index);
|
||||
break;
|
||||
case 8:
|
||||
func_8001E0C4(camera, player, index);
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ typedef struct {
|
|||
} Camera; /* size = 0xB8 */
|
||||
|
||||
void camera_init(f32, f32, f32, s16, u32, s32);
|
||||
void freecam_init(f32 posX, f32 posY, f32 posZ, s16 rot, u32 arg4, s32 cameraId);
|
||||
void func_8001CA10(Camera*);
|
||||
void func_8001CA24(Player*, f32);
|
||||
void func_8001CA78(Player*, Camera*, Vec3f, f32*, f32*, f32*, s32, s32);
|
||||
|
|
@ -81,6 +82,7 @@ extern Camera* camera1;
|
|||
extern Camera* camera2;
|
||||
extern Camera* camera3;
|
||||
extern Camera* camera4;
|
||||
extern Camera* gFreecamCamera;
|
||||
|
||||
// end of camera.c variables
|
||||
|
||||
|
|
|
|||
|
|
@ -233,16 +233,18 @@ void setup_race(void) {
|
|||
// D_8015F8D0[1] = (f32) (D_80164490->posY - 15);
|
||||
// D_8015F8D0[2] = D_80164490->posZ;
|
||||
|
||||
// if (GetCourse() == GetToadsTurnpike()) {
|
||||
// if (IsToadsTurnpike()) {
|
||||
// D_8015F8D0[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 138.0f : D_80164490->posX - 138.0f;
|
||||
// } else if (GetCourse() == GetWarioStadium()) {
|
||||
// } else if (IsWarioStadium()) {
|
||||
// D_8015F8D0[0] = (gIsMirrorMode != 0) ? D_80164490->posX + 12.0f : D_80164490->posX - 12.0f;
|
||||
// } else {
|
||||
// D_8015F8D0[0] = D_80164490->posX;
|
||||
// }
|
||||
// }
|
||||
if (!gDemoMode) {
|
||||
func_800CA008(gPlayerCountSelection1 - 1, gCurrentCourseId + 4);
|
||||
//! @warning this used to be gCurrentCourseId + 4
|
||||
// Hopefully this is equivallent.
|
||||
func_800CA008(gPlayerCountSelection1 - 1, GetCourseIndex() + 4);
|
||||
func_800CB2C4();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1076,7 +1076,7 @@ void func_80008424(s32 playerId, f32 arg1, Player* player) {
|
|||
if (!(player->effects & 0x80) && !(player->effects & 0x40) && !(player->effects & 0x20000) &&
|
||||
!(player->soundEffects & 0x400000) && !(player->soundEffects & 0x01000000) && !(player->soundEffects & 2) &&
|
||||
!(player->soundEffects & 4)) {
|
||||
if (GetCourse() == GetPodiumCeremony()) {
|
||||
if (IsPodiumCeremony()) {
|
||||
func_80007FA4(playerId, player, var_f2);
|
||||
} else if ((bStopAICrossing[playerId] == 1) && !(player->effects & (STAR_EFFECT | BOO_EFFECT))) {
|
||||
decelerate_ai_player(player, 10.0f);
|
||||
|
|
@ -1140,7 +1140,7 @@ void func_80008424(s32 playerId, f32 arg1, Player* player) {
|
|||
}
|
||||
if (var_a1 != 1) {
|
||||
if (var_f2 < arg1) {
|
||||
if ((gDemoMode == 1) && (GetCourse() != GetPodiumCeremony())) {
|
||||
if ((gDemoMode == 1) && (!IsPodiumCeremony())) {
|
||||
player_speed(player);
|
||||
} else if (D_80163330[playerId] == 1) {
|
||||
func_80007D04(playerId, player);
|
||||
|
|
@ -1448,15 +1448,15 @@ void func_8000929C(s32 playerId, Player* player) {
|
|||
D_801630E2 = 1;
|
||||
func_80008F38(playerId);
|
||||
}
|
||||
if (GetCourse() == GetPodiumCeremony()) {
|
||||
if (IsPodiumCeremony()) {
|
||||
func_8000B95C(playerId, sSomeNearestWaypoint, D_80163448);
|
||||
return;
|
||||
}
|
||||
if ((sSomeNearestWaypoint < 0x14) || ((gWaypointCountByPathIndex[D_80163448] - 0x14) < sSomeNearestWaypoint) ||
|
||||
(GetCourse() == GetKalimariDesert())) {
|
||||
(IsKalimariDesert())) {
|
||||
var_v1 = 0;
|
||||
var_t0 = 0;
|
||||
if (GetCourse() == GetKalimariDesert()) {
|
||||
if (IsKalimariDesert()) {
|
||||
D_801634EC = 0;
|
||||
if (player->effects & 0x200) {
|
||||
D_801634EC = 1;
|
||||
|
|
@ -1510,7 +1510,7 @@ void func_8000929C(s32 playerId, Player* player) {
|
|||
}
|
||||
}
|
||||
D_80163450[playerId] = tempPos2;
|
||||
if ((GetCourse() == GetYoshiValley()) && (D_801630E2 == 1)) {
|
||||
if ((IsYoshiValley()) && (D_801630E2 == 1)) {
|
||||
func_80009000(playerId);
|
||||
if (((player->type & 0x4000) == 0) || (player->type & 0x1000)) {
|
||||
func_800090F0(playerId, player);
|
||||
|
|
@ -1664,7 +1664,7 @@ void func_80009B60(s32 playerId) {
|
|||
if (!(player->unk_0CA & 2) && !(player->unk_0CA & 8)) {
|
||||
D_80163448 = gPathIndexByPlayerId[playerId];
|
||||
func_80008DC0(D_80163448);
|
||||
//if (GetCourse() == GetKalimariDesert()) {
|
||||
//if (IsKalimariDesert()) {
|
||||
CM_VehicleCollision(playerId, player);
|
||||
//func_80012DC0(playerId, player);
|
||||
if (playerId == 0) {
|
||||
|
|
@ -1672,9 +1672,9 @@ void func_80009B60(s32 playerId) {
|
|||
//func_80013054();
|
||||
}
|
||||
//}
|
||||
if (GetCourse() == GetDkJungle()) {
|
||||
if (IsDkJungle()) {
|
||||
//func_80013854(player);
|
||||
} else if (GetCourse() == GetToadsTurnpike()) {
|
||||
} else if (IsToadsTurnpike()) {
|
||||
func_800148C4(playerId, player);
|
||||
func_80014A18(playerId, player);
|
||||
func_80014B6C(playerId, player);
|
||||
|
|
@ -1685,11 +1685,11 @@ void func_80009B60(s32 playerId) {
|
|||
player->unk_044 &= ~0x0001;
|
||||
}
|
||||
func_8000929C(playerId, player);
|
||||
if ((GetCourse() != GetPodiumCeremony()) && ((D_80163240[playerId] == 1) || (playerId == 0))) {
|
||||
if ((!IsPodiumCeremony()) && ((D_80163240[playerId] == 1) || (playerId == 0))) {
|
||||
set_places();
|
||||
}
|
||||
if (player->type & 0x1000) {
|
||||
if ((D_801630E2 == 1) && (GetCourse() != GetPodiumCeremony())) {
|
||||
if ((D_801630E2 == 1) && (!IsPodiumCeremony())) {
|
||||
kart_ai_behaviour(playerId);
|
||||
}
|
||||
if ((playerId & 1) != (D_80163378 & 1)) {
|
||||
|
|
@ -1706,11 +1706,11 @@ void func_80009B60(s32 playerId) {
|
|||
break;
|
||||
}
|
||||
D_801631E0[playerId] = 0;
|
||||
if ((player->effects & 0x1000) && (GetCourse() != GetPodiumCeremony())) {
|
||||
if ((player->effects & 0x1000) && (!IsPodiumCeremony())) {
|
||||
D_801631E0[playerId] = 1;
|
||||
}
|
||||
if ((D_801646CC == 1) || (player->type & 0x800) || (GetCourse() == GetPodiumCeremony())) {
|
||||
if (GetCourse() != GetToadsTurnpike()) {
|
||||
if ((D_801646CC == 1) || (player->type & 0x800) || (IsPodiumCeremony())) {
|
||||
if (!IsToadsTurnpike()) {
|
||||
D_801634F8[playerId].unk4 = 0.0f;
|
||||
}
|
||||
D_801634F8[playerId].unkC = 0.0f;
|
||||
|
|
@ -1731,9 +1731,9 @@ void func_80009B60(s32 playerId) {
|
|||
|
||||
// Old vehicle draw method was here
|
||||
|
||||
if ((GetCourse() == GetYoshiValley()) || (GetCourse() == GetPodiumCeremony())) {
|
||||
if ((IsYoshiValley()) || (IsPodiumCeremony())) {
|
||||
D_801634F8[playerId].unk4 = 0.0f;
|
||||
} else if (GetCourse() == GetToadsTurnpike()) {
|
||||
} else if (IsToadsTurnpike()) {
|
||||
// func_8001490C(playerId);
|
||||
// func_80014A60(playerId);
|
||||
// func_80014BB4(playerId);
|
||||
|
|
@ -1840,10 +1840,10 @@ void func_80009B60(s32 playerId) {
|
|||
}
|
||||
D_801630B8[playerId] = func_8000B7E4(playerId, sSomeNearestWaypoint);
|
||||
func_8000D438(playerId, sSomeNearestWaypoint);
|
||||
if (GetCourse() != GetPodiumCeremony()) {
|
||||
if (!IsPodiumCeremony()) {
|
||||
if (D_80164450[playerId] < 0xB) {
|
||||
stackPadding1A = D_801630E0;
|
||||
if ((D_80164450[playerId] > 0) && (GetCourse() == GetToadsTurnpike())) {
|
||||
if ((D_80164450[playerId] > 0) && (IsToadsTurnpike())) {
|
||||
stackPadding1A += 0x14;
|
||||
stackPadding1A %= D_80164430;
|
||||
func_8000BBD8(stackPadding1A, 0.0f, 0);
|
||||
|
|
@ -1877,7 +1877,7 @@ void func_80009B60(s32 playerId) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (GetCourse() == GetPodiumCeremony()) {
|
||||
if (IsPodiumCeremony()) {
|
||||
switch (D_80163410[playerId]) { /* switch 3; irregular */
|
||||
case 3: /* switch 3 */
|
||||
D_80162FA0[0] = D_80163418[playerId];
|
||||
|
|
@ -2297,7 +2297,7 @@ s16 find_closest_waypoint_track_section(f32 posX, f32 posY, f32 posZ, u16 trackS
|
|||
considerWaypoint = &pathWaypoints[0];
|
||||
for (considerWaypointIndex = 0; considerWaypointIndex < pathWaypointCount;
|
||||
considerWaypointIndex++, considerWaypoint++) {
|
||||
if ((considerWaypoint->trackSectionId == trackSectionId) || (GetCourse() == GetPodiumCeremony())) {
|
||||
if ((considerWaypoint->trackSectionId == trackSectionId) || (IsPodiumCeremony())) {
|
||||
var_t1 = 1;
|
||||
x_dist = (f32) considerWaypoint->posX - posX;
|
||||
y_dist = (f32) considerWaypoint->posY - posY;
|
||||
|
|
@ -2463,7 +2463,7 @@ void func_8000CBA4(UNUSED f32 posX, f32 posY, UNUSED f32 posZ, s16* waypointInde
|
|||
s16 var_v0;
|
||||
|
||||
var_v0 = *waypointIndex;
|
||||
if ((GetCourse() == GetWarioStadium()) && (var_v0 >= 0x475) && (var_v0 < 0x480) && (posY < 0.0f)) {
|
||||
if ((IsWarioStadium()) && (var_v0 >= 0x475) && (var_v0 < 0x480) && (posY < 0.0f)) {
|
||||
var_v0 = 0x0398;
|
||||
}
|
||||
*waypointIndex = var_v0;
|
||||
|
|
@ -2666,11 +2666,11 @@ void func_8000D438(s32 arg0, u16 arg1) {
|
|||
sp2C = func_8000D3B8(arg0);
|
||||
thing = arg1;
|
||||
|
||||
if (GetCourse() == GetPodiumCeremony()) {
|
||||
if (IsPodiumCeremony()) {
|
||||
var_a2 = 1;
|
||||
} else if (GetCourse() == GetToadsTurnpike()) {
|
||||
} else if (IsToadsTurnpike()) {
|
||||
var_a2 = 7;
|
||||
} else if (GetCourse() == GetYoshiValley()) {
|
||||
} else if (IsYoshiValley()) {
|
||||
} else {
|
||||
if (temp_v1 < 6) {
|
||||
var_a2 = 8;
|
||||
|
|
@ -2908,11 +2908,11 @@ void set_bomb_kart_spawn_positions(void) {
|
|||
|
||||
for (var_s3 = 0; var_s3 < NUM_BOMB_KARTS_VERSUS; var_s3++) {
|
||||
//bombKartSpawn = &gBombKartSpawns[gCurrentCourseId][var_s3];
|
||||
if (GetCourse() == GetYoshiValley()) {
|
||||
if (IsYoshiValley()) {
|
||||
startingXPos = bombKartSpawn->startingXPos;
|
||||
startingZPos = bombKartSpawn->startingZPos;
|
||||
startingYPos = spawn_actor_on_surface(startingXPos, 2000.0f, startingZPos);
|
||||
} else if (GetCourse() == GetPodiumCeremony()) {
|
||||
} else if (IsPodiumCeremony()) {
|
||||
temp_v0 = &D_80164550[3][bombKartSpawn->waypointIndex];
|
||||
startingXPos = temp_v0->posX;
|
||||
startingYPos = temp_v0->posY;
|
||||
|
|
@ -3014,7 +3014,7 @@ void func_8000DF8C(s32 bombKartId) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (((bombKart->unk_4A != 1) || (GetCourse() == GetPodiumCeremony()))) {
|
||||
if (((bombKart->unk_4A != 1) || (IsPodiumCeremony()))) {
|
||||
var_f22 = bombKart->bombPos[0];
|
||||
var_f20 = bombKart->bombPos[1];
|
||||
var_f24 = bombKart->bombPos[2];
|
||||
|
|
@ -3025,7 +3025,7 @@ void func_8000DF8C(s32 bombKartId) {
|
|||
var_s1 = bombKart->circleTimer;
|
||||
if ((sp7E != 0) && (sp7E != 4)) {
|
||||
if (1) {}
|
||||
if (GetCourse() == GetPodiumCeremony()) {
|
||||
if (IsPodiumCeremony()) {
|
||||
if (D_8016347E == 1) {
|
||||
var_v0 = gPlayerFour;
|
||||
temp_f0 = var_f22 - var_v0->pos[0];
|
||||
|
|
@ -3049,7 +3049,7 @@ void func_8000DF8C(s32 bombKartId) {
|
|||
if ((((temp_f0 * temp_f0) + (temp_f2 * temp_f2)) + (temp_f12 * temp_f12)) < 25.0f) {
|
||||
sp7E = 4;
|
||||
var_s1 = 0;
|
||||
if (GetCourse() == GetFrappeSnowland()) {
|
||||
if (IsFrappeSnowland()) {
|
||||
var_v0->soundEffects |= 0x01000000;
|
||||
} else {
|
||||
var_v0->soundEffects |= 0x400000;
|
||||
|
|
@ -3466,7 +3466,7 @@ void func_8000F628(void) {
|
|||
D_80163050[i] = 0;
|
||||
D_80162FF8[i] = 0;
|
||||
D_80163010[i] = 0;
|
||||
if (GetCourse() != GetPodiumCeremony()) {
|
||||
if (!IsPodiumCeremony()) {
|
||||
func_8000B95C(i, 0, 0);
|
||||
}
|
||||
//! todo: @BUG this doesn't seem right. This variable is metadata.
|
||||
|
|
@ -3551,7 +3551,7 @@ void func_8000F628(void) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if ((gDemoUseController == 1) && (GetCourse() != GetPodiumCeremony())) {
|
||||
if ((gDemoUseController == 1) && (!IsPodiumCeremony())) {
|
||||
for (i = 0; i < NUM_PLAYERS; i++) {
|
||||
D_80163330[i] = 0;
|
||||
}
|
||||
|
|
@ -3635,7 +3635,7 @@ void func_800100F0(s32 pathIndex) {
|
|||
if (CM_GetProps()->AIMaximumSeparation >= 1.0f) {
|
||||
pathDest = D_80164550[pathIndex];
|
||||
bInvalidPath = 1;
|
||||
if (GetCourse() != GetPodiumCeremony()) {
|
||||
if (!IsPodiumCeremony()) {
|
||||
|
||||
TrackWaypoint* pathSrc = CM_GetProps()->PathTable2[pathIndex];
|
||||
if (pathSrc == NULL) {
|
||||
|
|
@ -3879,7 +3879,7 @@ void func_80010E6C(s32 pathIndex) {
|
|||
} else {
|
||||
break;
|
||||
}
|
||||
if (GetCourse() == GetPodiumCeremony()) {
|
||||
if (IsPodiumCeremony()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -3934,7 +3934,7 @@ s32 func_80011014(TrackWaypoint* pathDest, TrackWaypoint* path, s32 numPathPoint
|
|||
var_s0 = 0;
|
||||
temp_f20 = (f32) path[0].posX;
|
||||
temp_f22 = (f32) path[0].posZ;
|
||||
var_f28 = func_80010F40(temp_f20, 2000.0f, temp_f22, gCurrentCourseId, 0);
|
||||
var_f28 = func_80010F40(temp_f20, 2000.0f, temp_f22, 0, 0);
|
||||
|
||||
for (i = 0; i < numPathPoints; i++) {
|
||||
point1 = &path[i % numPathPoints];
|
||||
|
|
@ -3969,10 +3969,10 @@ s32 func_80011014(TrackWaypoint* pathDest, TrackWaypoint* path, s32 numPathPoint
|
|||
if (gIsMirrorMode) {
|
||||
// temp_f12 = -temp_f24_2;
|
||||
pathDest->posX = (s16) -temp_f24_2;
|
||||
var_f20_2 = func_80010FA0(-temp_f24_2, var_f28, x1_2, gCurrentCourseId, var_s0);
|
||||
var_f20_2 = func_80010FA0(-temp_f24_2, var_f28, x1_2, 0, var_s0);
|
||||
} else {
|
||||
pathDest->posX = (s16) temp_f24_2;
|
||||
var_f20_2 = func_80010FA0(temp_f24_2, var_f28, x1_2, gCurrentCourseId, var_s0);
|
||||
var_f20_2 = func_80010FA0(temp_f24_2, var_f28, x1_2, 0, var_s0);
|
||||
}
|
||||
|
||||
pathDest->posZ = (s16) temp_f22;
|
||||
|
|
@ -3982,11 +3982,11 @@ s32 func_80011014(TrackWaypoint* pathDest, TrackWaypoint* path, s32 numPathPoint
|
|||
var_f20_2 = var_f28;
|
||||
} else {
|
||||
|
||||
if (GetCourse() == GetRainbowRoad()) {
|
||||
if (IsRainbowRoad()) {
|
||||
if (var_f20_2 < (var_f28 - 15.0)) {
|
||||
var_f20_2 = (f32) var_f28 - 15.0;
|
||||
}
|
||||
} else if (GetCourse() == GetWarioStadium()) {
|
||||
} else if (IsWarioStadium()) {
|
||||
if ((var_s0 >= 1140) && (var_s0 <= 1152)) {
|
||||
var_f20_2 = var_f28;
|
||||
} else {
|
||||
|
|
@ -3994,7 +3994,7 @@ s32 func_80011014(TrackWaypoint* pathDest, TrackWaypoint* path, s32 numPathPoint
|
|||
var_f20_2 = (f32) (var_f28 - 4.0);
|
||||
}
|
||||
}
|
||||
} else if (GetCourse() == GetDkJungle()) {
|
||||
} else if (IsDkJungle()) {
|
||||
if ((var_s0 > 204) && (var_s0 < 220)) {
|
||||
var_f20_2 = var_f28;
|
||||
} else {
|
||||
|
|
@ -4628,7 +4628,7 @@ void func_80013054(void) {
|
|||
|
||||
void check_ai_crossing_distance(s32 playerId) {
|
||||
bStopAICrossing[playerId] = 0;
|
||||
if (GetCourse() == GetKalimariDesert()) {
|
||||
if (IsKalimariDesert()) {
|
||||
if ((!(D_801631E0[playerId] != 0)) ||
|
||||
(set_vehicle_render_distance_flags(gPlayers[playerId].pos, TRAIN_CROSSING_AI_DISTANCE, 0))) {
|
||||
|
||||
|
|
@ -5819,7 +5819,7 @@ void func_80016C3C(UNUSED s32 playerId, UNUSED f32 arg1, s32 cameraId) {
|
|||
D_80164688[cameraId] = -0.1f;
|
||||
}
|
||||
D_80163DD8[cameraId] = 0;
|
||||
if (GetCourse() == GetYoshiValley()) {
|
||||
if (IsYoshiValley()) {
|
||||
D_80163DD8[cameraId] = random_int(4U);
|
||||
D_80164688[cameraId] = 0.0f;
|
||||
}
|
||||
|
|
@ -5892,8 +5892,7 @@ void func_80017054(Camera* camera, UNUSED Player* player, UNUSED s32 index, s32
|
|||
D_80163238 = playerId;
|
||||
sp56 = gNearestWaypointByCameraId[cameraId];
|
||||
gNearestWaypointByCameraId[cameraId] = func_8000D33C(camera->pos[0], camera->pos[1], camera->pos[2], gNearestWaypointByCameraId[cameraId], pathIndex);
|
||||
// if (GetCourse() == GetYoshiValley()) {
|
||||
if (gCurrentCourseId == 4) {
|
||||
if (IsYoshiValley()) {
|
||||
if ((sp56 != gNearestWaypointByCameraId[cameraId]) && (gNearestWaypointByCameraId[cameraId] == 1)) {
|
||||
pathIndex = (D_80163DD8[cameraId] = random_int(4U));
|
||||
gNearestWaypointByCameraId[cameraId] = func_8000D33C(camera->pos[0], camera->pos[1], camera->pos[2], gNearestWaypointByCameraId[cameraId], pathIndex);
|
||||
|
|
@ -6574,7 +6573,7 @@ void func_80019D2C(Camera* camera, Player* player, s32 arg2) {
|
|||
s32 nearestWaypoint;
|
||||
|
||||
playerId = camera->playerId;
|
||||
if ((D_80163378 != 0) && (GetCourse() == GetLuigiRaceway())) {
|
||||
if ((D_80163378 != 0) && (IsLuigiRaceway())) {
|
||||
calculate_camera_up_vector(camera, arg2);
|
||||
nearestWaypoint = gNearestWaypointByPlayerId[playerId];
|
||||
if (((nearestWaypoint >= 0x65) && (nearestWaypoint < 0xFA)) ||
|
||||
|
|
@ -6719,7 +6718,7 @@ void func_8001A220(UNUSED s32 arg0, s32 cameraId) {
|
|||
}
|
||||
|
||||
s32 func_8001A310(s32 waypoint, s32 arg1) {
|
||||
if ((GetCourse() == GetBowsersCastle()) && (arg1 != 0) && (waypoint >= 0xE7) && (waypoint < 0x1C2)) {
|
||||
if ((IsBowsersCastle()) && (arg1 != 0) && (waypoint >= 0xE7) && (waypoint < 0x1C2)) {
|
||||
arg1 = 0;
|
||||
}
|
||||
return arg1;
|
||||
|
|
@ -7500,7 +7499,7 @@ void func_8001BE78(void) {
|
|||
void func_8001C05C(void) {
|
||||
init_segment_racing();
|
||||
gCurrentCourseId = COURSE_AWARD_CEREMONY;
|
||||
SetCourseByClass(GetPodiumCeremony());
|
||||
SelectPodiumCeremony();
|
||||
D_8016347C = 0;
|
||||
D_8016347E = 0;
|
||||
D_80163480 = 0;
|
||||
|
|
@ -7573,7 +7572,7 @@ void func_8001C14C(void) {
|
|||
}
|
||||
|
||||
void render_bomb_karts_wrap(s32 cameraId) {
|
||||
if (GetCourse() == GetPodiumCeremony()) {
|
||||
if (IsPodiumCeremony()) {
|
||||
if (gBombKarts[0].waypointIndex >= 16) {
|
||||
render_bomb_karts(PLAYER_FOUR);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include <assets/some_data.h>
|
||||
#include "port/Game.h"
|
||||
#include "engine/Matrix.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
//! @warning this macro is undef'd at the end of this file
|
||||
#define MAKE_RGB(r, g, b) (((r) << 0x10) | ((g) << 0x08) | (b << 0x00))
|
||||
|
|
@ -769,7 +770,7 @@ void render_object_for_player(s32 cameraId) {
|
|||
render_object_leaf_particle(cameraId);
|
||||
|
||||
if (D_80165730 != 0) {
|
||||
//render_balloons_grand_prix(cameraId);
|
||||
// render_balloons_grand_prix(cameraId);
|
||||
}
|
||||
if (gModeSelection == BATTLE) {
|
||||
CM_DrawBattleBombKarts(cameraId);
|
||||
|
|
@ -777,7 +778,7 @@ void render_object_for_player(s32 cameraId) {
|
|||
}
|
||||
|
||||
void render_snowing_effect(s32 playerId) {
|
||||
if (GetCourse() == GetFrappeSnowland()) {
|
||||
if (IsFrappeSnowland()) {
|
||||
if (gGamestate != 9) {
|
||||
if ((D_8015F894 == 0) && (gPlayerCountSelection1 == 1)) {
|
||||
render_object_snowflakes_particles();
|
||||
|
|
@ -938,6 +939,10 @@ void func_80058F48(void) {
|
|||
|
||||
void func_80058F78(void) {
|
||||
if (gHUDDisable == 0) {
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("HudMatrix", 0);
|
||||
|
||||
set_matrix_hud_screen();
|
||||
if ((!gDemoMode) && (gIsHUDVisible != 0) && (D_801657D8 == 0)) {
|
||||
draw_item_window(PLAYER_ONE);
|
||||
|
|
@ -950,6 +955,9 @@ void func_80058F78(void) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1555,7 +1563,7 @@ void func_8005A3C0(void) {
|
|||
}
|
||||
|
||||
void func_8005A71C(void) {
|
||||
// if (GetCourse() == GetBowsersCastle()) {
|
||||
// if (IsBowsersCastle()) {
|
||||
// func_80081210();
|
||||
//}
|
||||
}
|
||||
|
|
@ -1632,11 +1640,11 @@ void update_object(void) {
|
|||
// update_ferries_smoke_particle();
|
||||
// break;
|
||||
// }
|
||||
//if (D_80165730 != 0) {
|
||||
// if (D_80165730 != 0) {
|
||||
// func_80074EE8(); // Grand prix balloons
|
||||
//}
|
||||
func_80076F2C();
|
||||
if ((s16) GetCourse() != GetFrappeSnowland()) {
|
||||
if (!IsFrappeSnowland()) {
|
||||
update_leaf();
|
||||
}
|
||||
}
|
||||
|
|
@ -2588,8 +2596,7 @@ void func_8005CB60(s32 playerId, s32 lapCount) {
|
|||
case 1: /* switch 1 */
|
||||
CM_ActivateSecondLapLakitu(playerId); // func_80079084(playerId);
|
||||
func_800C9060(playerId, SOUND_ARG_LOAD(0x19, 0x00, 0xF0, 0x15));
|
||||
if ((GetCourse() == GetLuigiRaceway()) && (D_80165898 == 0) &&
|
||||
(gModeSelection != (s32) TIME_TRIALS)) {
|
||||
if ((IsLuigiRaceway()) && (D_80165898 == 0) && (gModeSelection != (s32) TIME_TRIALS)) {
|
||||
D_80165898 = 1;
|
||||
}
|
||||
break;
|
||||
|
|
@ -2610,7 +2617,7 @@ void func_8005CB60(s32 playerId, s32 lapCount) {
|
|||
if (D_8018D114 == 2) {
|
||||
D_80165800[playerId] = 0;
|
||||
}
|
||||
if (GetCourse() == GetYoshiValley()) {
|
||||
if (IsYoshiValley()) {
|
||||
playerHUD[playerId].unk_81 = 1;
|
||||
}
|
||||
playerHUD[playerId].lap1CompletionTimeX = 0x0140;
|
||||
|
|
@ -2927,22 +2934,22 @@ void func_8005DAF4(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8
|
|||
func_8005D794(player, &player->unk_258[10 + arg1], var_f2, var_f12, var_f14, (s8) surfaceType,
|
||||
(s8) var_t3);
|
||||
func_8005D7D8(&player->unk_258[10 + arg1], 2, 0.46f);
|
||||
if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) {
|
||||
if ((IsChocoMountain()) || (IsRoyalRaceway())) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetKalimariDesert()) {
|
||||
if (IsKalimariDesert()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetMooMooFarm()) {
|
||||
if (IsMooMooFarm()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetWarioStadium()) {
|
||||
if (IsWarioStadium()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetYoshiValley()) {
|
||||
if (IsYoshiValley()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 10, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetDkJungle()) {
|
||||
if (IsDkJungle()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 11, 0, 0x0080);
|
||||
}
|
||||
player->unk_258[10 + arg1].unk_03A = random_int(0x0010U);
|
||||
|
|
@ -2951,22 +2958,22 @@ void func_8005DAF4(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8
|
|||
func_8005D794(player, &player->unk_258[10 + arg1], var_f2, var_f12, var_f14, (s8) surfaceType,
|
||||
(s8) var_t3);
|
||||
func_8005D7D8(&player->unk_258[10 + arg1], 2, 0.46f);
|
||||
if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) {
|
||||
if ((IsChocoMountain()) || (IsRoyalRaceway())) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetKalimariDesert()) {
|
||||
if (IsKalimariDesert()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetMooMooFarm()) {
|
||||
if (IsMooMooFarm()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetWarioStadium()) {
|
||||
if (IsWarioStadium()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetYoshiValley()) {
|
||||
if (IsYoshiValley()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 10, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetDkJungle()) {
|
||||
if (IsDkJungle()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 11, 0, 0x0080);
|
||||
}
|
||||
player->unk_258[10 + arg1].unk_03A = random_int(0x0010U);
|
||||
|
|
@ -3193,44 +3200,44 @@ void func_8005ED48(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8
|
|||
((player->unk_258[10 + arg2].unk_01E > 0) || (player->unk_258[10 + arg2].unk_01C == 0))) {
|
||||
func_8005D794(player, &player->unk_258[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t3);
|
||||
func_8005D7D8(&player->unk_258[10 + arg1], 5, 0.46f);
|
||||
if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) {
|
||||
if ((IsChocoMountain()) || (IsRoyalRaceway())) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetKalimariDesert()) {
|
||||
if (IsKalimariDesert()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetMooMooFarm()) {
|
||||
if (IsMooMooFarm()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetWarioStadium()) {
|
||||
if (IsWarioStadium()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetYoshiValley()) {
|
||||
if (IsYoshiValley()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 10, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetDkJungle()) {
|
||||
if (IsDkJungle()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 11, 0, 0x0080);
|
||||
}
|
||||
player->unk_258[10 + arg1].unk_03A = random_int(0x0010U);
|
||||
} else if (player->unk_258[10 + arg2].unk_01E > 0) {
|
||||
func_8005D794(player, &player->unk_258[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t3);
|
||||
func_8005D7D8(&player->unk_258[10 + arg1], 5, 0.46f);
|
||||
if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) {
|
||||
if ((IsChocoMountain()) || (IsRoyalRaceway())) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetKalimariDesert()) {
|
||||
if (IsKalimariDesert()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetMooMooFarm()) {
|
||||
if (IsMooMooFarm()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetWarioStadium()) {
|
||||
if (IsWarioStadium()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetYoshiValley()) {
|
||||
if (IsYoshiValley()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 0x000A, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetDkJungle()) {
|
||||
if (IsDkJungle()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 0x000B, 0, 0x0080);
|
||||
}
|
||||
player->unk_258[10 + arg1].unk_03A = random_int(0x0010U);
|
||||
|
|
@ -3394,44 +3401,44 @@ void func_8005F90C(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8
|
|||
((player->unk_258[10 + arg2].unk_01E > 0) || (player->unk_258[10 + arg2].unk_01C == 0))) {
|
||||
func_8005D794(player, &player->unk_258[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1);
|
||||
func_8005D7D8(&player->unk_258[10 + arg1], 4, 0.46f);
|
||||
if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) {
|
||||
if ((IsChocoMountain()) || (IsRoyalRaceway())) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetKalimariDesert()) {
|
||||
if (IsKalimariDesert()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetMooMooFarm()) {
|
||||
if (IsMooMooFarm()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetWarioStadium()) {
|
||||
if (IsWarioStadium()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetYoshiValley()) {
|
||||
if (IsYoshiValley()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 0x000A, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetDkJungle()) {
|
||||
if (IsDkJungle()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 0x000B, 0, 0x0080);
|
||||
}
|
||||
player->unk_258[10 + arg1].unk_03A = random_int(0x0010U);
|
||||
} else if (player->unk_258[10 + arg2].unk_01E > 0) {
|
||||
func_8005D794(player, &player->unk_258[10 + arg1], var_f0, var_f2, var_f12, surfaceType, var_t1);
|
||||
func_8005D7D8(&player->unk_258[10 + arg1], 4, 0.46f);
|
||||
if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) {
|
||||
if ((IsChocoMountain()) || (IsRoyalRaceway())) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 1, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetKalimariDesert()) {
|
||||
if (IsKalimariDesert()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 7, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetMooMooFarm()) {
|
||||
if (IsMooMooFarm()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 8, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetWarioStadium()) {
|
||||
if (IsWarioStadium()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 9, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetYoshiValley()) {
|
||||
if (IsYoshiValley()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 0x000A, 0, 0x0080);
|
||||
}
|
||||
if (GetCourse() == GetDkJungle()) {
|
||||
if (IsDkJungle()) {
|
||||
func_8005DAD8(&player->unk_258[10 + arg1], 0x000B, 0, 0x0080);
|
||||
}
|
||||
player->unk_258[10 + arg1].unk_03A = random_int(0x0010U);
|
||||
|
|
@ -3630,13 +3637,13 @@ void func_800608E0(Player* player, s16 arg1, UNUSED s32 arg2, s8 arg3, UNUSED s8
|
|||
var_f0 = 0.0f;
|
||||
}
|
||||
sp4C = (D_801652A0[arg3] - player->pos[1]) - 3.0f;
|
||||
if ((player->unk_0DE & 1) && (GetCourse() != GetKoopaTroopaBeach())) {
|
||||
if ((player->unk_0DE & 1) && (!IsKoopaTroopaBeach())) {
|
||||
var_f0 = 2.5f;
|
||||
sp4C = (f32) ((f64) (D_801652A0[arg3] - player->pos[1]) + 0.1);
|
||||
}
|
||||
func_8005D794(player, &player->unk_258[arg1], 0.0f, 0.0f, 0.0f, (s8) 0, (s8) 0);
|
||||
func_8005D7D8(&player->unk_258[arg1], 3, var_f0);
|
||||
if ((GetCourse() == GetBowsersCastle()) || (GetCourse() == GetBigDonut())) {
|
||||
if ((IsBowsersCastle()) || (IsBigDonut())) {
|
||||
func_8005D800(&player->unk_258[arg1], 0, 0x00AF);
|
||||
} else {
|
||||
func_8005D800(&player->unk_258[arg1], 0x00FFFFFF, 0x00CF);
|
||||
|
|
@ -3650,7 +3657,7 @@ void func_800608E0(Player* player, s16 arg1, UNUSED s32 arg2, s8 arg3, UNUSED s8
|
|||
}
|
||||
|
||||
void func_80060B14(Player* player, s16 arg1, s32 arg2, s8 arg3, s8 arg4) {
|
||||
if ((GetCourse() != GetSkyscraper()) && (GetCourse() != GetRainbowRoad())) {
|
||||
if ((!IsSkyscraper()) && (!IsRainbowRoad())) {
|
||||
if ((arg1 == 0) && ((player->unk_258[arg2].unk_01E > 0) || (player->unk_258[arg2].unk_01C == 0))) {
|
||||
func_800608E0(player, arg1, arg2, arg3, arg4);
|
||||
} else if (player->unk_258[arg2].unk_01E > 0) {
|
||||
|
|
@ -3666,10 +3673,10 @@ void func_80060BCC(Player* player, s16 arg1, s32 arg2, UNUSED s8 arg3, UNUSED s8
|
|||
f32 sp48;
|
||||
f32 sp44;
|
||||
|
||||
if (GetCourse() == GetSkyscraper()) {
|
||||
if (IsSkyscraper()) {
|
||||
return;
|
||||
}
|
||||
if (GetCourse() == GetRainbowRoad()) {
|
||||
if (IsRainbowRoad()) {
|
||||
return;
|
||||
}
|
||||
sp54 = random_int(0x0168U) - 0xB4;
|
||||
|
|
@ -3704,7 +3711,7 @@ void func_80060F50(Player* player, s16 arg1, UNUSED s32 arg2, s8 arg3, UNUSED s8
|
|||
func_8005D794(player, &player->unk_258[arg1], 0.0f, 0.0f, 0.0f, 0, 0);
|
||||
func_8005D7D8(&player->unk_258[arg1], 5, 4.0f);
|
||||
|
||||
if ((GetCourse() == GetBowsersCastle()) || (GetCourse() == GetBigDonut())) {
|
||||
if ((IsBowsersCastle()) || (IsBigDonut())) {
|
||||
func_8005D800(&player->unk_258[arg1], 0xFF0000, 0xFF);
|
||||
} else {
|
||||
func_8005D800(&player->unk_258[arg1], 0xFFFFFF, 0xFF);
|
||||
|
|
@ -4050,22 +4057,22 @@ void func_800624D8(Player* player, UNUSED s32 arg1, UNUSED s32 arg2, UNUSED s8 a
|
|||
switch (player->surfaceType) {
|
||||
case DIRT:
|
||||
for (var_s1 = 0; var_s1 < 10; var_s1++) {
|
||||
if ((GetCourse() == GetChocoMountain()) || (GetCourse() == GetRoyalRaceway())) {
|
||||
if ((IsChocoMountain()) || (IsRoyalRaceway())) {
|
||||
func_8005DAD8(&player->unk_258[0x1E + var_s1], 1, 0, 0x00A8);
|
||||
}
|
||||
if (GetCourse() == GetKalimariDesert()) {
|
||||
if (IsKalimariDesert()) {
|
||||
func_8005DAD8(&player->unk_258[0x1E + var_s1], 7, 0, 0x00A8);
|
||||
}
|
||||
if (GetCourse() == GetMooMooFarm()) {
|
||||
if (IsMooMooFarm()) {
|
||||
func_8005DAD8(&player->unk_258[0x1E + var_s1], 8, 0, 0x00A8);
|
||||
}
|
||||
if (GetCourse() == GetWarioStadium()) {
|
||||
if (IsWarioStadium()) {
|
||||
func_8005DAD8(&player->unk_258[0x1E + var_s1], 9, 0, 0x00A8);
|
||||
}
|
||||
if (GetCourse() == GetYoshiValley()) {
|
||||
if (IsYoshiValley()) {
|
||||
func_8005DAD8(&player->unk_258[0x1E + var_s1], 0x000A, 0, 0x00A8);
|
||||
}
|
||||
if (GetCourse() == GetDkJungle()) {
|
||||
if (IsDkJungle()) {
|
||||
func_8005DAD8(&player->unk_258[0x1E + var_s1], 0x000B, 0, 0x00A8);
|
||||
}
|
||||
func_80062484(player, &player->unk_258[0x1E + var_s1], var_s1);
|
||||
|
|
@ -4620,7 +4627,7 @@ void func_80064184(Player* player, s16 arg1, s8 arg2, UNUSED s8 arg3) {
|
|||
f32 sp3C;
|
||||
|
||||
sp40 = D_801652A0[arg2] - player->pos[1] - 3.0f;
|
||||
if (((player->unk_0DE & 1) != 0) && (GetCourse() != GetKoopaTroopaBeach())) {
|
||||
if (((player->unk_0DE & 1) != 0) && (!IsKoopaTroopaBeach())) {
|
||||
sp40 = D_801652A0[arg2] - player->pos[1] + 0.1;
|
||||
}
|
||||
|
||||
|
|
@ -4968,9 +4975,8 @@ void func_800651F4(Player* player, UNUSED s8 arg1, UNUSED s8 arg2, s8 arg3) {
|
|||
|
||||
void func_800652D4(Vec3f arg0, Vec3s arg1, f32 arg2) {
|
||||
Mat4 mtx;
|
||||
|
||||
mtxf_translate_rotate(mtx, arg0, arg1);
|
||||
mtxf_scale2(mtx, arg2);
|
||||
mtxf_scale(mtx, arg2);
|
||||
// convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx);
|
||||
// gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]),
|
||||
// G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
|
@ -5098,6 +5104,7 @@ void func_80065AB0(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3) {
|
|||
spAC[0] = 0;
|
||||
spAC[1] = player->unk_048[arg3];
|
||||
spAC[2] = 0;
|
||||
|
||||
func_800652D4(spB4, spAC, player->unk_258[10 + arg2].unk_00C * player->size);
|
||||
if (var_s0 == 0) {
|
||||
gSPDisplayList(gDisplayListHead++, D_0D008DB8);
|
||||
|
|
@ -5667,6 +5674,7 @@ void func_800691B8(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3) {
|
|||
sp54[1] = player->unk_048[arg3];
|
||||
player->unk_258[30 + arg2].unk_03A += 0x1C71;
|
||||
sp54[2] = player->unk_258[30 + arg2].unk_03A;
|
||||
|
||||
func_800652D4(sp5C, sp54, player->size * 0.5);
|
||||
gSPDisplayList(gDisplayListHead++, D_0D008D58);
|
||||
gDPSetTextureLUT(gDisplayListHead++, G_TT_NONE);
|
||||
|
|
@ -5737,6 +5745,7 @@ void func_800696CC(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3, f32 arg4)
|
|||
sp54[0] = 0;
|
||||
sp54[1] = player->unk_048[arg3];
|
||||
sp54[2] = 0;
|
||||
|
||||
func_800652D4(sp5C, sp54, player->size * arg4);
|
||||
gSPDisplayList(gDisplayListHead++, D_0D008D58);
|
||||
gDPSetTextureLUT(gDisplayListHead++, G_TT_NONE);
|
||||
|
|
@ -5764,6 +5773,7 @@ void func_80069938(Player* player, UNUSED s8 arg1, s16 arg2, s8 arg3) {
|
|||
sp54[0] = 0;
|
||||
sp54[1] = player->unk_048[arg3];
|
||||
sp54[2] = player->unk_258[30 + arg2].unk_038;
|
||||
|
||||
func_800652D4(sp5C, sp54, player->unk_258[30 + arg2].unk_00C * player->size);
|
||||
gSPDisplayList(gDisplayListHead++, D_0D008D58);
|
||||
gDPSetTextureLUT(gDisplayListHead++, G_TT_NONE);
|
||||
|
|
@ -6058,8 +6068,12 @@ void render_battle_balloon(Player* player, s8 arg1, s16 arg2, s8 arg3) {
|
|||
sp12C[1] = player->unk_048[arg3];
|
||||
sp12C[2] = D_8018D7D0[arg1][arg2] - (D_8018D860[arg1][arg2] * coss(temp_t1)) -
|
||||
((D_8018D890[arg1][arg2] * 8) * sins(temp_t1));
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild((uintptr_t) player, arg1 | arg2 << 16);
|
||||
|
||||
mtxf_translate_rotate(mtx, sp134, sp12C);
|
||||
mtxf_scale2(mtx, var_f20);
|
||||
mtxf_scale(mtx, var_f20);
|
||||
// convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], sp140);
|
||||
|
||||
// gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]),
|
||||
|
|
@ -6087,6 +6101,10 @@ void render_battle_balloon(Player* player, s8 arg1, s16 arg2, s8 arg3) {
|
|||
gSPVertex(gDisplayListHead++, gBalloonVertexPlane2, 4, 0);
|
||||
gSPDisplayList(gDisplayListHead++, common_square_plain_render);
|
||||
gSPTexture(gDisplayListHead++, 0x0001, 0x0001, 0, G_TX_RENDERTILE, G_OFF);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
|
||||
gMatrixEffectCount++;
|
||||
}
|
||||
|
||||
|
|
@ -6184,7 +6202,7 @@ void render_balloon(Vec3f arg0, f32 arg1, s16 arg2, s16 arg3) {
|
|||
spF4[1] = camera1->rot[1];
|
||||
spF4[2] = arg2;
|
||||
mtxf_translate_rotate(mtx, spFC, spF4);
|
||||
mtxf_scale2(mtx, arg1);
|
||||
mtxf_scale(mtx, arg1);
|
||||
// convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], sp108);
|
||||
// gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]),
|
||||
// G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
|
@ -6566,6 +6584,9 @@ void func_8006D474(Player* player, s8 playerId, s8 screenId) {
|
|||
s16 var_s2;
|
||||
if ((player->unk_002 & (8 << (screenId * 4))) == (8 << (screenId * 4))) {
|
||||
for (var_s2 = 0; var_s2 < 10; var_s2++) {
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("SmokeDust", TAG_SMOKE_DUST((playerId << 8) + var_s2));
|
||||
|
||||
switch (player->unk_258[var_s2].unk_012) {
|
||||
case 1:
|
||||
if (gActiveScreenMode == SCREEN_MODE_3P_4P_SPLITSCREEN) {
|
||||
|
|
@ -6586,6 +6607,8 @@ void func_8006D474(Player* player, s8 playerId, s8 screenId) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
FrameInterpolation_RecordOpenChild("SmokeDust", TAG_SMOKE_DUST((playerId << 8) + var_s2 + 30));
|
||||
switch (player->unk_258[var_s2 + 30].unk_012) {
|
||||
case 1:
|
||||
case 9:
|
||||
|
|
@ -6645,6 +6668,8 @@ void func_8006D474(Player* player, s8 playerId, s8 screenId) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
FrameInterpolation_RecordOpenChild("SmokeDust", TAG_SMOKE_DUST((playerId << 8) + var_s2 + 10));
|
||||
switch (player->unk_258[var_s2 + 10].unk_012) {
|
||||
case 1:
|
||||
if (gActiveScreenMode == SCREEN_MODE_3P_4P_SPLITSCREEN) {
|
||||
|
|
@ -6686,6 +6711,8 @@ void func_8006D474(Player* player, s8 playerId, s8 screenId) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
if ((gModeSelection == BATTLE) && (player->unk_002 & (2 << (screenId * 4)))) {
|
||||
|
|
@ -6707,48 +6734,50 @@ void func_8006DC54(Player* player, s8 arg1, s8 arg2) {
|
|||
}
|
||||
}
|
||||
|
||||
void func_8006DD3C(Player* arg0, s8 arg1, s8 arg2) {
|
||||
void func_8006DD3C(Player* player, s8 playerId, s8 arg2) {
|
||||
s16 temp_s0;
|
||||
s32 temp_v0;
|
||||
|
||||
temp_v0 = 8 << (arg2 * 4);
|
||||
if (temp_v0 == (arg0->unk_002 & temp_v0)) {
|
||||
if (temp_v0 == (player->unk_002 & temp_v0)) {
|
||||
for (temp_s0 = 0; temp_s0 < 10; ++temp_s0) {
|
||||
temp_v0 = arg0->unk_258[temp_s0].unk_012;
|
||||
temp_v0 = player->unk_258[temp_s0].unk_012;
|
||||
if (temp_v0 != 3) {
|
||||
if (temp_v0 == 5) {
|
||||
func_8006A280(arg0, arg1, temp_s0, arg2);
|
||||
func_8006A280(player, playerId, temp_s0, arg2);
|
||||
}
|
||||
} else if (gActiveScreenMode == SCREEN_MODE_3P_4P_SPLITSCREEN) {
|
||||
if (arg2 == arg1) {
|
||||
func_80066998(arg0, arg1, temp_s0, arg2);
|
||||
if (arg2 == playerId) {
|
||||
func_80066998(player, playerId, temp_s0, arg2);
|
||||
}
|
||||
} else {
|
||||
func_80066998(arg0, arg1, temp_s0, arg2);
|
||||
func_80066998(player, playerId, temp_s0, arg2);
|
||||
}
|
||||
}
|
||||
|
||||
if (((arg0->type & 0x4000) == 0x4000) && (arg2 == arg1)) {
|
||||
switch (arg0->unk_258[20].unk_012) {
|
||||
if (((player->type & 0x4000) == 0x4000) && (arg2 == playerId)) {
|
||||
FrameInterpolation_RecordOpenChild("onomatopoeia", TAG_SMOKE_DUST((playerId << 8) + 20));
|
||||
switch (player->unk_258[20].unk_012) {
|
||||
case 2:
|
||||
func_80068310(arg0, arg1, arg0->unk_258[20].unk_00C, arg2, 0);
|
||||
func_80068310(player, playerId, player->unk_258[20].unk_00C, arg2, 0);
|
||||
break;
|
||||
case 3:
|
||||
func_80067964(arg0, arg1, arg0->unk_258[20].unk_00C, arg2, 0);
|
||||
func_80067964(player, playerId, player->unk_258[20].unk_00C, arg2, 0);
|
||||
break;
|
||||
case 4:
|
||||
func_80068724(arg0, arg1, arg0->unk_258[20].unk_00C, arg2, 0);
|
||||
func_80068724(player, playerId, player->unk_258[20].unk_00C, arg2, 0);
|
||||
break;
|
||||
case 5:
|
||||
func_80068AA4(arg0, arg1, arg0->unk_258[20].unk_00C, arg2, 0);
|
||||
func_80068AA4(player, playerId, player->unk_258[20].unk_00C, arg2, 0);
|
||||
break;
|
||||
case 6:
|
||||
func_80068DA0(arg0, arg1, arg0->unk_258[20].unk_00C, arg2, 0);
|
||||
func_80068DA0(player, playerId, player->unk_258[20].unk_00C, arg2, 0);
|
||||
break;
|
||||
}
|
||||
if (arg0->unk_258[21].unk_012 == 5) {
|
||||
func_80067D3C(arg0, arg2, D_8018D480, 1, 1.6f, 0xFFFFFF);
|
||||
func_8006801C(arg0, arg2, D_8018D484, 1, 1.6f, 0xFF);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
if (player->unk_258[21].unk_012 == 5) {
|
||||
func_80067D3C(player, arg2, D_8018D480, 1, 1.6f, 0xFFFFFF);
|
||||
func_8006801C(player, arg2, D_8018D484, 1, 1.6f, 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ void init_item_window(s32 objectIndex) {
|
|||
temp_v0->sizeScaling = 1.0f;
|
||||
}
|
||||
|
||||
void func_8006EEE8(s32 courseId) {
|
||||
void get_minimap_properties() {
|
||||
D_8018D240 = (uintptr_t) CM_GetProps()->Minimap.Texture;
|
||||
// This is incredibly dumb. MinimapDimensions ought to be something more like
|
||||
// `u16 MinimapDimensions[][2]` but that doesn't match for some insane reason
|
||||
|
|
@ -191,8 +191,8 @@ void func_8006F008(void) {
|
|||
xOrientation = -1.0f;
|
||||
}
|
||||
|
||||
if (GetCourse() != GetPodiumCeremony()) {
|
||||
func_8006EEE8((s32) gCurrentCourseId);
|
||||
if (!IsPodiumCeremony()) {
|
||||
get_minimap_properties();
|
||||
}
|
||||
|
||||
// Flip the minimap player markers
|
||||
|
|
@ -203,7 +203,7 @@ void func_8006F008(void) {
|
|||
switch(gPlayerCount) {
|
||||
case 2:
|
||||
// Set X coord
|
||||
if (GetCourse() != GetToadsTurnpike()) {
|
||||
if (!IsToadsTurnpike()) {
|
||||
CM_GetProps()->Minimap.Pos[PLAYER_ONE].X = 265;
|
||||
CM_GetProps()->Minimap.Pos[PLAYER_TWO].X = 265;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ void clear_object_list(void);
|
|||
u8* dma_misc_textures(u8*, u8*, u32, u32);
|
||||
void load_mario_kart_64_logo(void);
|
||||
void init_item_window(s32);
|
||||
void func_8006EEE8(s32);
|
||||
void get_minimap_properties(void);
|
||||
void func_8006EF60(void);
|
||||
void func_8006F008(void);
|
||||
void func_8006F824(s32);
|
||||
|
|
|
|||
|
|
@ -977,7 +977,7 @@ void func_80089020(s32 playerId, f32* arg1) {
|
|||
var_f2 = -*arg1;
|
||||
}
|
||||
if (player->effects & 0xC0) {
|
||||
if (GetCourse() == GetSherbetLand()) {
|
||||
if (IsSherbetLand()) {
|
||||
if (var_f2 <= 0.5) {
|
||||
var_f0 = 0.025f;
|
||||
} else if (var_f2 <= 2.0) {
|
||||
|
|
@ -998,7 +998,7 @@ void func_80089020(s32 playerId, f32* arg1) {
|
|||
var_f0 = 0.25f;
|
||||
}
|
||||
}
|
||||
} else if (GetCourse() == GetSherbetLand()) {
|
||||
} else if (IsSherbetLand()) {
|
||||
if (var_f2 <= 0.5) {
|
||||
var_f0 = 0.025f;
|
||||
} else if (var_f2 <= 2.0) {
|
||||
|
|
|
|||
|
|
@ -34,15 +34,15 @@ Light D_800E8688 = { {
|
|||
s16 D_8018EDB0;
|
||||
s16 D_8018EDB2;
|
||||
s16 D_8018EDB4;
|
||||
Vtx* D_8018EDB8;
|
||||
Vtx* D_8018EDBC;
|
||||
Vtx D_8018EDB8[480];
|
||||
Vtx D_8018EDBC[480];
|
||||
|
||||
/*** utils **/
|
||||
#define SQ(x) ((x) * (x))
|
||||
|
||||
void func_800AF9B0(void) {
|
||||
D_8018EDB8 = (void*) calloc(480, sizeof(Vtx));
|
||||
D_8018EDBC = (void*) calloc(480, sizeof(Vtx));
|
||||
// D_8018EDB8 = (void*) calloc(480, sizeof(Vtx));
|
||||
// D_8018EDBC = (void*) calloc(480, sizeof(Vtx));
|
||||
}
|
||||
|
||||
// could be a normal vertex, not a color...
|
||||
|
|
|
|||
|
|
@ -1698,7 +1698,7 @@ void func_80090178(Player* player, s8 playerId, Vec3f arg2, Vec3f arg3) {
|
|||
f32 sp18[4] = { 10.0f, -10.0f, -575.0f, 575.0f };
|
||||
f32 sp08[4] = { 575.0f, -575.0f, 10.0f, -10.0f };
|
||||
|
||||
if (GetCourse() == GetYoshiValley()) {
|
||||
if (IsYoshiValley()) {
|
||||
test = player->nearestWaypointId;
|
||||
temp_v1 = &D_80164550[gCopyPathIndexByPlayerId[playerId]][test];
|
||||
arg2[0] = temp_v1->posX;
|
||||
|
|
@ -1710,28 +1710,28 @@ void func_80090178(Player* player, s8 playerId, Vec3f arg2, Vec3f arg3) {
|
|||
arg3[0] = temp_v1->posX;
|
||||
arg3[1] = temp_v1->posY;
|
||||
arg3[2] = temp_v1->posZ;
|
||||
} else if (GetCourse() == GetBlockFort()) {
|
||||
} else if (IsBlockFort()) {
|
||||
arg2[0] = spF8[playerId];
|
||||
arg2[1] = 0.0f;
|
||||
arg2[2] = spE8[playerId];
|
||||
arg3[0] = spD8[playerId];
|
||||
arg3[1] = 0.0f;
|
||||
arg3[2] = spC8[playerId];
|
||||
} else if (GetCourse() == GetSkyscraper()) {
|
||||
} else if (IsSkyscraper()) {
|
||||
arg2[0] = spB8[playerId];
|
||||
arg2[1] = 480.0f;
|
||||
arg2[2] = spA8[playerId];
|
||||
arg3[0] = sp98[playerId];
|
||||
arg3[1] = 480.0f;
|
||||
arg3[2] = sp88[playerId];
|
||||
} else if (GetCourse() == GetDoubleDeck()) {
|
||||
} else if (IsDoubleDeck()) {
|
||||
arg2[0] = sp78[playerId];
|
||||
arg2[1] = 0.0f;
|
||||
arg2[2] = sp68[playerId];
|
||||
arg3[0] = sp58[playerId];
|
||||
arg3[1] = 0.0f;
|
||||
arg3[2] = sp48[playerId];
|
||||
} else if (GetCourse() == GetBigDonut()) {
|
||||
} else if (IsBigDonut()) {
|
||||
arg2[0] = sp38[playerId];
|
||||
arg2[1] = 200.0f;
|
||||
arg2[2] = sp28[playerId];
|
||||
|
|
@ -1799,14 +1799,14 @@ void func_80090868(Player* player) {
|
|||
player->unk_0CA |= 2;
|
||||
player->unk_0C8 = 0;
|
||||
if ((player->unk_0DE & 1) == 1) {
|
||||
if ((GetCourse() == GetBowsersCastle()) || (GetCourse() == GetBigDonut())) {
|
||||
if ((IsBowsersCastle()) || (IsBigDonut())) {
|
||||
player->unk_0CA |= 0x1000;
|
||||
} else {
|
||||
player->unk_0CA |= 0x2000;
|
||||
}
|
||||
|
||||
if ((GetCourse() == GetSherbetLand()) || (GetCourse() == GetSkyscraper()) ||
|
||||
(GetCourse() == GetRainbowRoad())) {
|
||||
if ((IsSherbetLand()) || (IsSkyscraper()) ||
|
||||
(IsRainbowRoad())) {
|
||||
player->unk_0CA &= ~0x3000;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ void setup_podium_ceremony(void) {
|
|||
Camera* camera = &cameras[0];
|
||||
|
||||
gCurrentCourseId = COURSE_ROYAL_RACEWAY;
|
||||
SetCourseByClass(GetPodiumCeremony());
|
||||
SelectPodiumCeremony();
|
||||
D_800DC5B4 = (u16) 1;
|
||||
gIsMirrorMode = 0;
|
||||
gGotoMenu = 0xFFFF;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "code_80281C40.h"
|
||||
#include "math_util.h"
|
||||
#include <string.h>
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
#include "src/port/Game.h"
|
||||
#include "engine/Matrix.h"
|
||||
|
|
@ -262,6 +263,9 @@ void render_fireworks(Vec3f arg0, f32 arg1, s32 rgb, s16 alpha) {
|
|||
void firework_update(Firework* actor) {
|
||||
s32 i;
|
||||
Vec3f pos;
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("render_fireworks", (uintptr_t) actor);
|
||||
if (actor->unk44 < 30) {
|
||||
for (i = 0; i < 10; i++) {
|
||||
pos[0] = actor->pos[0];
|
||||
|
|
@ -290,6 +294,8 @@ void firework_update(Firework* actor) {
|
|||
}
|
||||
}
|
||||
actor->unk44 += 1;
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
void unused_80280FA0(UNUSED CeremonyActor* actor) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <libultraship.h>
|
||||
#include <libultra/gbi.h>
|
||||
#include "engine/World.h"
|
||||
#include "src/port/interpolation/FrameInterpolation.h"
|
||||
|
||||
extern "C" {
|
||||
#include "common_structs.h"
|
||||
|
|
@ -9,13 +10,11 @@ extern "C" {
|
|||
}
|
||||
|
||||
void AddMatrix(std::vector<Mtx>& stack, Mat4 mtx, s32 flags) {
|
||||
// Reserve space if needed to avoid reallocation overhead
|
||||
stack.reserve(1000);
|
||||
|
||||
// Push a new matrix to the stack
|
||||
stack.emplace_back();
|
||||
|
||||
// Convert to a fixed-point matrix
|
||||
FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mtx, &stack.back());
|
||||
guMtxF2L(mtx, &stack.back());
|
||||
|
||||
// Load the matrix
|
||||
|
|
@ -37,25 +36,26 @@ void AddMatrixFixed(std::vector<Mtx>& stack, s32 flags) {
|
|||
|
||||
// Used in func_80095BD0
|
||||
Mtx* SetTextMatrix(f32 arg1, f32 arg2, f32 arg3, f32 arg4) {
|
||||
Mat4 matrix;
|
||||
matrix[0][0] = arg3;
|
||||
matrix[0][1] = 0.0f;
|
||||
matrix[0][2] = 0.0f;
|
||||
matrix[0][3] = 0.0f;
|
||||
matrix[1][0] = 0.0f;
|
||||
matrix[1][1] = arg4;
|
||||
matrix[1][2] = 0.0f;
|
||||
matrix[1][3] = 0.0f;
|
||||
matrix[2][0] = 0.0f;
|
||||
matrix[2][1] = 0.0f;
|
||||
matrix[2][2] = 1.0f;
|
||||
matrix[2][3] = 0.0f;
|
||||
matrix[3][0] = arg1;
|
||||
matrix[3][1] = arg2;
|
||||
matrix[3][2] = 0.0f;
|
||||
matrix[3][3] = 1.0f;
|
||||
Mat4 mf;
|
||||
mf[0][0] = arg3;
|
||||
mf[0][1] = 0.0f;
|
||||
mf[0][2] = 0.0f;
|
||||
mf[0][3] = 0.0f;
|
||||
mf[1][0] = 0.0f;
|
||||
mf[1][1] = arg4;
|
||||
mf[1][2] = 0.0f;
|
||||
mf[1][3] = 0.0f;
|
||||
mf[2][0] = 0.0f;
|
||||
mf[2][1] = 0.0f;
|
||||
mf[2][2] = 1.0f;
|
||||
mf[2][3] = 0.0f;
|
||||
mf[3][0] = arg1;
|
||||
mf[3][1] = arg2;
|
||||
mf[3][2] = 0.0f;
|
||||
mf[3][3] = 1.0f;
|
||||
Mtx* mtx = GetMatrix(gWorldInstance.Mtx.Effects);
|
||||
guMtxF2L(matrix, mtx);
|
||||
FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mf, mtx);
|
||||
guMtxF2L(mf, mtx);
|
||||
|
||||
return mtx;
|
||||
}
|
||||
|
|
@ -137,6 +137,14 @@ extern "C" {
|
|||
AddMatrix(gWorldInstance.Mtx.Hud, mtx, flags);
|
||||
}
|
||||
|
||||
void AddPerspMatrix(Mat4 mtx, s32 flags) {
|
||||
AddMatrix(gWorldInstance.Mtx.Persp, mtx, flags);
|
||||
}
|
||||
|
||||
void AddLookAtMatrix(Mat4 mtx, s32 flags) {
|
||||
AddMatrix(gWorldInstance.Mtx.LookAt, mtx, flags);
|
||||
}
|
||||
|
||||
void AddObjectMatrix(Mat4 mtx, s32 flags) {
|
||||
AddMatrix(gWorldInstance.Mtx.Objects, mtx, flags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "World.h"
|
||||
#include "vehicles/Train.h"
|
||||
#include "vehicles/Boat.h"
|
||||
#include <port/interpolation/FrameInterpolation.h>
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
|
|
@ -69,7 +70,6 @@ void TrainSmokeTick() {
|
|||
if (count != 0) {
|
||||
boat->SmokeTimer = 100;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -80,28 +80,31 @@ void TrainSmokeDraw(s32 cameraId) {
|
|||
|
||||
for (auto& actor : gWorldInstance.Actors) {
|
||||
if (auto train = dynamic_cast<ATrain*>(actor)) {
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007AE0);
|
||||
load_texture_block_i8_nomirror((uint8_t*)D_0D029458, 32, 32);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007AE0);
|
||||
load_texture_block_i8_nomirror((uint8_t*) D_0D029458, 32, 32);
|
||||
func_8004B72C(255, 255, 255, 255, 255, 255, 255);
|
||||
D_80183E80[0] = 0;
|
||||
D_80183E80[2] = 0x8000;
|
||||
|
||||
if ((train->SomeFlags != 0) &&
|
||||
(is_particle_on_screen(train->Locomotive.position, camera, 0x4000U) != 0)) {
|
||||
if ((train->SomeFlags != 0) && (is_particle_on_screen(train->Locomotive.position, camera, 0x4000U) != 0)) {
|
||||
for (size_t i = 0; i < 128; i++) {
|
||||
FrameInterpolation_RecordOpenChild("TrainSmokeParticle", train->SmokeParticles[i]);
|
||||
render_object_train_smoke_particle(train->SmokeParticles[i], cameraId);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
} else if (auto boat = dynamic_cast<ABoat*>(actor)) {
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007AE0);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007AE0);
|
||||
|
||||
load_texture_block_i8_nomirror((uint8_t*)D_0D029458, 32, 32);
|
||||
load_texture_block_i8_nomirror((uint8_t*) D_0D029458, 32, 32);
|
||||
func_8004B72C(255, 255, 255, 255, 255, 255, 255);
|
||||
D_80183E80[0] = 0;
|
||||
D_80183E80[2] = 0x8000;
|
||||
if ((boat->SomeFlags != 0) && (is_particle_on_screen(boat->Position, camera, 0x4000U) != 0)) {
|
||||
for (size_t i = 0; i < gObjectParticle2_SIZE; i++) {
|
||||
FrameInterpolation_RecordOpenChild("BoatSmokeParticle", boat->SmokeParticles[i]);
|
||||
render_object_paddle_boat_smoke_particle(boat->SmokeParticles[i], cameraId);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,12 +22,17 @@ extern "C" {
|
|||
}
|
||||
|
||||
World::World() {}
|
||||
World::~World() {
|
||||
CM_CleanWorld();
|
||||
}
|
||||
|
||||
Course* CurrentCourse;
|
||||
Cup* CurrentCup;
|
||||
|
||||
void World::AddCourse(Course* course) {
|
||||
gWorldInstance.Courses.push_back(course);
|
||||
Course* World::AddCourse(std::unique_ptr<Course> course) {
|
||||
Course* ptr = course.get();
|
||||
gWorldInstance.Courses.push_back(std::move(course));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void World::AddCup(Cup* cup) {
|
||||
|
|
@ -79,6 +84,10 @@ u32 World::PreviousCup() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void World::SetCupIndex(size_t index) {
|
||||
CupIndex = index;
|
||||
}
|
||||
|
||||
void World::SetCup(Cup* cup) {
|
||||
if (cup) {
|
||||
CurrentCup = cup;
|
||||
|
|
@ -90,7 +99,7 @@ void World::SetCourse(const char* name) {
|
|||
//! @todo Use content dictionary instead
|
||||
for (size_t i = 0; i < Courses.size(); i++) {
|
||||
if (strcmp(Courses[i]->Props.Name, name) == 0) {
|
||||
CurrentCourse = Courses[i];
|
||||
CurrentCourse = Courses[i].get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +112,7 @@ void World::NextCourse() {
|
|||
} else {
|
||||
CourseIndex = 0;
|
||||
}
|
||||
gWorldInstance.CurrentCourse = Courses[CourseIndex];
|
||||
gWorldInstance.CurrentCourse = Courses[CourseIndex].get();
|
||||
}
|
||||
|
||||
void World::PreviousCourse() {
|
||||
|
|
@ -112,7 +121,7 @@ void World::PreviousCourse() {
|
|||
} else {
|
||||
CourseIndex = Courses.size() - 1;
|
||||
}
|
||||
gWorldInstance.CurrentCourse = Courses[CourseIndex];
|
||||
gWorldInstance.CurrentCourse = Courses[CourseIndex].get();
|
||||
}
|
||||
|
||||
AActor* World::AddActor(AActor* actor) {
|
||||
|
|
|
|||
|
|
@ -46,12 +46,15 @@ class World {
|
|||
std::vector<Mtx> Shadows;
|
||||
std::vector<Mtx> Karts;
|
||||
std::vector<Mtx> Effects;
|
||||
std::vector<Mtx> Persp;
|
||||
std::vector<Mtx> LookAt;
|
||||
} Matrix;
|
||||
|
||||
public:
|
||||
explicit World();
|
||||
~World();
|
||||
|
||||
void AddCourse(Course* course);
|
||||
Course* AddCourse(std::unique_ptr<Course> course);
|
||||
|
||||
AActor* AddActor(AActor* actor);
|
||||
struct Actor* AddBaseActor();
|
||||
|
|
@ -80,6 +83,7 @@ public:
|
|||
|
||||
void AddCup(Cup*);
|
||||
void SetCup(Cup* cup);
|
||||
void SetCupIndex(size_t index);
|
||||
const char* GetCupName();
|
||||
u32 GetCupIndex();
|
||||
u32 NextCup();
|
||||
|
|
@ -92,6 +96,16 @@ public:
|
|||
|
||||
// These are only for browsing through the course list
|
||||
void SetCourse(const char*);
|
||||
template<typename T>
|
||||
void SetCourseByType() {
|
||||
for (const auto& course : Courses) {
|
||||
if (dynamic_cast<T*>(course.get())) {
|
||||
CurrentCourse = course.get();
|
||||
return;
|
||||
}
|
||||
}
|
||||
printf("World::SetCourseByType() No course by the type found");
|
||||
}
|
||||
void NextCourse(void);
|
||||
void PreviousCourse(void);
|
||||
|
||||
|
|
@ -118,7 +132,7 @@ public:
|
|||
std::vector<std::shared_ptr<TrainCrossing>> Crossings;
|
||||
|
||||
// Holds all available courses
|
||||
std::vector<Course*> Courses;
|
||||
std::vector<std::unique_ptr<Course>> Courses;
|
||||
size_t CourseIndex = 0; // For browsing courses.
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#include "engine/Actor.h"
|
||||
#include "World.h"
|
||||
#include "assets/common_data.h"
|
||||
#include "src/port/Game.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
|
|
@ -17,6 +19,8 @@ extern f32 gKartHopInitialVelocityTable[];
|
|||
extern f32 gKartGravityTable[];
|
||||
}
|
||||
|
||||
size_t AFinishline::_count = 0;
|
||||
|
||||
AFinishline::AFinishline(std::optional<FVector> pos) {
|
||||
Name = "Finishline";
|
||||
|
||||
|
|
@ -53,6 +57,8 @@ void AFinishline::Draw(Camera *camera) {
|
|||
return;
|
||||
}
|
||||
|
||||
FrameInterpolation_RecordOpenChild("Finishline", _count);
|
||||
|
||||
mtxf_pos_rotation_xyz(mtx, Pos, Rot);
|
||||
|
||||
maxObjectsReached = render_set_position(mtx, 0) == 0;
|
||||
|
|
@ -74,6 +80,8 @@ void AFinishline::Draw(Camera *camera) {
|
|||
} else {
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D001BD8);
|
||||
}
|
||||
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
void AFinishline::Collision(Player* player, AActor* actor) {}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ public:
|
|||
virtual void Collision(Player* player, AActor* actor) override;
|
||||
virtual bool IsMod() override;
|
||||
|
||||
static size_t _count;
|
||||
bool PickedUp = false;
|
||||
uint32_t Timer = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,11 @@ namespace Editor {
|
|||
Editor::Editor() {
|
||||
}
|
||||
|
||||
Editor::~Editor() {
|
||||
ClearObjects();
|
||||
ClearMatrixPool();
|
||||
}
|
||||
|
||||
void Editor::Load() {
|
||||
printf("Editor: Loading Editor...\n");
|
||||
eObjectPicker.Load();
|
||||
|
|
@ -58,10 +63,16 @@ namespace Editor {
|
|||
Ship::Coords mousePos = wnd->GetMousePos();
|
||||
bool isMouseDown = wnd->GetMouseState(Ship::LUS_MOUSE_BTN_LEFT);
|
||||
|
||||
eGameObjects.erase(
|
||||
std::remove_if(eGameObjects.begin(), eGameObjects.end(),
|
||||
[](const auto& object) { return (*object->DespawnFlag) == object->DespawnValue; }),
|
||||
eGameObjects.end());
|
||||
auto it = std::remove_if(eGameObjects.begin(), eGameObjects.end(),
|
||||
[](auto& object) {
|
||||
if (*object->DespawnFlag == object->DespawnValue) {
|
||||
delete object; // Free the pointed-to memory
|
||||
return true; // Remove the pointer from the vector
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
eGameObjects.erase(it, eGameObjects.end());
|
||||
|
||||
if (isMouseDown && !wasMouseDown) {
|
||||
// Mouse just pressed (Pressed state)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ namespace Editor {
|
|||
class Editor {
|
||||
public:
|
||||
Editor();
|
||||
~Editor();
|
||||
|
||||
ObjectPicker eObjectPicker;
|
||||
std::vector<GameObject*> eGameObjects;
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ bool IsInGameScreen() {
|
|||
|
||||
// Define viewport boundaries
|
||||
auto gfx_current_game_window_viewport = GetInterpreter()->mGameWindowViewport;
|
||||
int left = gfx_current_game_window_viewport.width;
|
||||
int left = gfx_current_game_window_viewport.x;
|
||||
int right = left + OTRGetGameRenderWidth();
|
||||
int top = gfx_current_game_window_viewport.height;
|
||||
int top = gfx_current_game_window_viewport.y;
|
||||
int bottom = top + OTRGetGameRenderHeight();
|
||||
|
||||
// Check if the mouse is within the game render area
|
||||
|
|
@ -46,8 +46,8 @@ FVector ScreenRayTrace() {
|
|||
|
||||
Ship::Coords mouse = wnd->GetMousePos();
|
||||
auto gfx_current_game_window_viewport = GetInterpreter()->mGameWindowViewport;
|
||||
mouse.x -= gfx_current_game_window_viewport.width;
|
||||
mouse.y -= gfx_current_game_window_viewport.height;
|
||||
mouse.x -= gfx_current_game_window_viewport.x;
|
||||
mouse.y -= gfx_current_game_window_viewport.y;
|
||||
// Get screen dimensions
|
||||
uint32_t width = OTRGetGameViewportWidth();
|
||||
uint32_t height = OTRGetGameViewportHeight();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "Bat.h"
|
||||
#include "World.h"
|
||||
#include "CoreMath.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
extern "C" {
|
||||
#include "render_objects.h"
|
||||
|
|
@ -22,7 +23,7 @@ OBat::OBat(const FVector& pos, const IRotator& rot) {
|
|||
Name = "Bat";
|
||||
find_unused_obj_index(&_objectIndex);
|
||||
|
||||
init_texture_object(_objectIndex, (uint8_t*)d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U,
|
||||
init_texture_object(_objectIndex, (uint8_t*) d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U,
|
||||
(u16) 0x00000040);
|
||||
gObjectList[_objectIndex].orientation[0] = rot.pitch;
|
||||
gObjectList[_objectIndex].orientation[1] = rot.roll;
|
||||
|
|
@ -101,43 +102,56 @@ void OBat::Tick() {
|
|||
}
|
||||
|
||||
void OBat::Draw(s32 cameraId) {
|
||||
s32 var_s2;
|
||||
s32 objectIndex;
|
||||
Camera* temp_s7;
|
||||
s32 i;
|
||||
s32 objectIndex = _objectIndex;
|
||||
Camera* cam = &camera1[cameraId];
|
||||
|
||||
objectIndex = _objectIndex;
|
||||
temp_s7 = &camera1[cameraId];
|
||||
OBat::func_80046F60((u8*)gObjectList[objectIndex].activeTLUT, (u8*)gObjectList[objectIndex].activeTexture, 0x00000020, 0x00000040,
|
||||
5);
|
||||
OBat::func_80046F60((u8*) gObjectList[objectIndex].activeTLUT, (u8*) gObjectList[objectIndex].activeTexture,
|
||||
0x00000020, 0x00000040, 5);
|
||||
D_80183E80[0] = gObjectList[objectIndex].orientation[0];
|
||||
D_80183E80[2] = gObjectList[objectIndex].orientation[2];
|
||||
|
||||
if ((D_8018CFB0 != 0) || (D_8018CFC8 != 0)) {
|
||||
for (var_s2 = 0; var_s2 < 40; var_s2++) {
|
||||
objectIndex = gObjectParticle2[var_s2];
|
||||
for (i = 0; i < 40; i++) {
|
||||
objectIndex = gObjectParticle2[i];
|
||||
if (objectIndex == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((gObjectList[objectIndex].state >= 2) && (gMatrixHudCount < 0x2EF)) {
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Bat set 1", (uintptr_t) &gObjectList[objectIndex]);
|
||||
|
||||
D_80183E80[1] =
|
||||
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], temp_s7->pos);
|
||||
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], cam->pos);
|
||||
func_800431B0(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling,
|
||||
(Vtx*)D_0D0062B0);
|
||||
(Vtx*) D_0D0062B0);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((D_8018CFE8 != 0) || (D_8018D000 != 0)) {
|
||||
for (var_s2 = 0; var_s2 < 30; var_s2++) {
|
||||
objectIndex = gObjectParticle3[var_s2];
|
||||
for (i = 0; i < 30; i++) {
|
||||
|
||||
objectIndex = gObjectParticle3[i];
|
||||
if (objectIndex == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((gObjectList[objectIndex].state >= 2) && (gMatrixHudCount < 0x2EF)) {
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Bat set 2", (uintptr_t) &gObjectList[objectIndex]);
|
||||
|
||||
D_80183E80[1] =
|
||||
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], temp_s7->pos);
|
||||
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], cam->pos);
|
||||
func_800431B0(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling,
|
||||
(Vtx*)D_0D0062B0);
|
||||
(Vtx*) D_0D0062B0);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -145,7 +159,7 @@ void OBat::Draw(s32 cameraId) {
|
|||
}
|
||||
|
||||
void OBat::func_80046F60(u8* tlut, u8* arg1, s32 arg2, s32 arg3, s32 arg4) {
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007D78);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007D78);
|
||||
gDPLoadTLUT_pal256(gDisplayListHead++, tlut);
|
||||
rsp_load_texture_mask(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void OBombKart::Tick() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (((Unk_4A != 1) || (GetCourse() == GetPodiumCeremony()))) {
|
||||
if (((Unk_4A != 1) || (IsPodiumCeremony()))) {
|
||||
newPos[0] = Pos[0];
|
||||
newPos[1] = Pos[1];
|
||||
newPos[2] = Pos[2];
|
||||
|
|
@ -128,7 +128,7 @@ void OBombKart::Tick() {
|
|||
bounceTimer = BounceTimer;
|
||||
circleTimer = CircleTimer;
|
||||
if ((state != States::DISABLED) && (state != States::EXPLODE)) {
|
||||
if (GetCourse() == GetPodiumCeremony()) {
|
||||
if (IsPodiumCeremony()) {
|
||||
if (D_8016347E == 1) {
|
||||
player = gPlayerFour;
|
||||
temp_f0 = newPos[0] - player->pos[0];
|
||||
|
|
@ -152,7 +152,7 @@ void OBombKart::Tick() {
|
|||
if ((((temp_f0 * temp_f0) + (temp_f2 * temp_f2)) + (temp_f12 * temp_f12)) < 25.0f) {
|
||||
state = States::EXPLODE;
|
||||
circleTimer = 0;
|
||||
if (GetCourse() == GetFrappeSnowland()) {
|
||||
if (IsFrappeSnowland()) {
|
||||
player->soundEffects |= 0x01000000;
|
||||
} else {
|
||||
player->soundEffects |= 0x400000;
|
||||
|
|
@ -346,7 +346,7 @@ void OBombKart::Draw(s32 cameraId) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (GetCourse() == GetPodiumCeremony()) {
|
||||
if (IsPodiumCeremony()) {
|
||||
if ((_idx == 0) && (WaypointIndex < 16)) {
|
||||
return;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "Boos.h"
|
||||
#include "World.h"
|
||||
#include "CoreMath.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
extern "C" {
|
||||
#include "render_objects.h"
|
||||
|
|
@ -88,9 +89,16 @@ void OBoos::Draw(s32 cameraId) {
|
|||
if (CVarGetInteger("gNoCulling", 0) == 1) {
|
||||
temp_s2 = MIN(temp_s2, 0x15F91U);
|
||||
}
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Boo", (uintptr_t)&gObjectList[objectIndex]);
|
||||
|
||||
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
|
||||
func_800523B8(objectIndex, cameraId, temp_s2);
|
||||
}
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "port/Game.h"
|
||||
#include "assets/other_textures.h"
|
||||
#include "assets/common_data.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
extern "C" {
|
||||
#include "update_objects.h"
|
||||
|
|
@ -73,7 +74,7 @@ void OGrandPrixBalloons::Draw(s32 cameraId) {
|
|||
return;
|
||||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007E98);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007E98);
|
||||
gDPLoadTLUT_pal256(gDisplayListHead++, gTLUTOnomatopoeia);
|
||||
func_8004B614(0, 0, 0, 0, 0, 0, 0);
|
||||
gDPSetAlphaCompare(gDisplayListHead++, G_AC_THRESHOLD);
|
||||
|
|
@ -84,14 +85,14 @@ void OGrandPrixBalloons::Draw(s32 cameraId) {
|
|||
GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA));
|
||||
D_80183E80[0] = 0;
|
||||
D_80183E80[1] = 0x8000;
|
||||
rsp_load_texture((uint8_t*)gTextureBalloon1, 64, 32);
|
||||
rsp_load_texture((uint8_t*) gTextureBalloon1, 64, 32);
|
||||
for (var_s1 = 0; var_s1 < _numBalloons; var_s1++) {
|
||||
objectIndex = gObjectParticle3[var_s1];
|
||||
if ((objectIndex != NULL_OBJECT_ID) && (gObjectList[objectIndex].state >= 2)) {
|
||||
OGrandPrixBalloons::func_80053D74(objectIndex, cameraId, 0);
|
||||
}
|
||||
}
|
||||
rsp_load_texture((uint8_t*)gTextureBalloon2, 64, 32);
|
||||
rsp_load_texture((uint8_t*) gTextureBalloon2, 64, 32);
|
||||
for (var_s1 = 0; var_s1 < _numBalloons; var_s1++) {
|
||||
objectIndex = gObjectParticle3[var_s1];
|
||||
if ((objectIndex != NULL_OBJECT_ID) && (gObjectList[objectIndex].state >= 2)) {
|
||||
|
|
@ -105,15 +106,24 @@ void OGrandPrixBalloons::func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 ver
|
|||
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog);
|
||||
|
||||
size_t i = 0;
|
||||
if (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX) {
|
||||
object = &gObjectList[objectIndex];
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Balloon",
|
||||
TAG_ITEM_ADDR((objectIndex << 32) + i++)); // Not working properly just yet
|
||||
|
||||
D_80183E80[2] = (s16) (object->unk_084[6] + 0x8000);
|
||||
rsp_set_matrix_transformation(object->pos, (u16*) D_80183E80, object->sizeScaling);
|
||||
set_color_render((s32) object->unk_084[0], (s32) object->unk_084[1], (s32) object->unk_084[2],
|
||||
(s32) object->unk_084[3], (s32) object->unk_084[4], (s32) object->unk_084[5],
|
||||
(s32) object->primAlpha);
|
||||
gSPVertex(gDisplayListHead++, (uintptr_t)&vtx[vertexIndex], 4, 0);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)common_rectangle_display);
|
||||
gSPVertex(gDisplayListHead++, (uintptr_t) &vtx[vertexIndex], 4, 0);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*) common_rectangle_display);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -128,7 +138,7 @@ void OGrandPrixBalloons::func_80074924(s32 objectIndex) {
|
|||
object = &gObjectList[objectIndex];
|
||||
object->sizeScaling = 0.15f;
|
||||
|
||||
if (GetCourse() == GetMarioRaceway()) {
|
||||
if (IsMarioRaceway()) {
|
||||
sp2C = random_int(0x00C8U);
|
||||
sp28 = random_int(_numBalloons3);
|
||||
sp24 = random_int(0x0096U);
|
||||
|
|
@ -136,7 +146,7 @@ void OGrandPrixBalloons::func_80074924(s32 objectIndex) {
|
|||
object->origin_pos[0] = (f32) ((((f64) Pos.x + 100.0) - (f64) sp2C) * (f64) xOrientation);
|
||||
object->origin_pos[1] = (f32) (Pos.y + sp28);
|
||||
object->origin_pos[2] = (f32) (((f64) Pos.z + 200.0) - (f64) sp24);
|
||||
} else if (GetCourse() == GetRoyalRaceway()) {
|
||||
} else if (IsRoyalRaceway()) {
|
||||
sp2C = random_int(0x0168U);
|
||||
sp28 = random_int(_numBalloons3);
|
||||
sp24 = random_int(0x00B4U);
|
||||
|
|
@ -144,7 +154,7 @@ void OGrandPrixBalloons::func_80074924(s32 objectIndex) {
|
|||
object->origin_pos[0] = (f32) ((((f64) Pos.x + 180.0) - (f64) sp2C) * (f64) xOrientation);
|
||||
object->origin_pos[1] = (f32) (Pos.y + sp28);
|
||||
object->origin_pos[2] = (f32) (((f64) Pos.z + 200.0) - (f64) sp24);
|
||||
} else if (GetCourse() == GetLuigiRaceway()) {
|
||||
} else if (IsLuigiRaceway()) {
|
||||
sp2C = random_int(0x012CU);
|
||||
sp28 = random_int(_numBalloons3);
|
||||
sp24 = random_int(0x0096U);
|
||||
|
|
@ -187,7 +197,10 @@ void OGrandPrixBalloons::func_80074924(s32 objectIndex) {
|
|||
|
||||
void OGrandPrixBalloons::func_80074D94(s32 objectIndex) {
|
||||
if (gObjectList[objectIndex].unk_0AE == 1) {
|
||||
if ((_numBalloons2 <= gObjectList[objectIndex].offset[1]) &&
|
||||
//! @warning this fades out the balloons. Original game uses _numBalloons3 here but they disappear before
|
||||
//! off-screen.
|
||||
// So _numBalloons replaces it for now.
|
||||
if ((_numBalloons <= gObjectList[objectIndex].offset[1]) &&
|
||||
(s16_step_down_towards(&gObjectList[objectIndex].primAlpha, 0, 8) != 0)) {
|
||||
func_80086F60(objectIndex);
|
||||
}
|
||||
|
|
@ -209,7 +222,8 @@ void OGrandPrixBalloons::func_80074E28(s32 objectIndex) {
|
|||
case 0:
|
||||
break;
|
||||
case 3:
|
||||
OGrandPrixBalloons::func_80041480(&gObjectList[objectIndex].unk_084[6], -0x1000, 0x1000, &gObjectList[objectIndex].unk_084[7]);
|
||||
OGrandPrixBalloons::func_80041480(&gObjectList[objectIndex].unk_084[6], -0x1000, 0x1000,
|
||||
&gObjectList[objectIndex].unk_084[7]);
|
||||
if (gObjectList[objectIndex].unk_0AE == 0) {
|
||||
func_80072428(objectIndex);
|
||||
}
|
||||
|
|
@ -228,4 +242,4 @@ void OGrandPrixBalloons::func_80041480(s16* arg0, s16 arg1, s16 arg2, s16* arg3)
|
|||
*arg0 = arg1;
|
||||
*arg3 = -*arg3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ extern "C" {
|
|||
#include "code_80086E70.h"
|
||||
#include "code_80057C60.h"
|
||||
}
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
size_t OHedgehog::_count = 0;
|
||||
|
||||
|
|
@ -25,7 +26,7 @@ OHedgehog::OHedgehog(const FVector& pos, const FVector2D& patrolPoint, s16 unk)
|
|||
gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = pos.x * xOrientation;
|
||||
gObjectList[objectId].pos[1] = gObjectList[objectId].surfaceHeight = pos.y + 6.0;
|
||||
gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = pos.z;
|
||||
gObjectList[objectId].unk_0D5 = (u8)unk;
|
||||
gObjectList[objectId].unk_0D5 = (u8) unk;
|
||||
gObjectList[objectId].unk_09C = patrolPoint.x * xOrientation;
|
||||
gObjectList[objectId].unk_09E = patrolPoint.z;
|
||||
|
||||
|
|
@ -38,10 +39,10 @@ void OHedgehog::Tick() {
|
|||
OHedgehog::func_800833D0(objectIndex, _idx);
|
||||
OHedgehog::func_80083248(objectIndex);
|
||||
OHedgehog::func_80083474(objectIndex);
|
||||
|
||||
|
||||
// This func clears a bit from all hedgehogs. This results in setting the height of all hedgehogs to zero.
|
||||
// The solution is to only clear the bit from the current instance; `self` or `this`
|
||||
//func_80072120(indexObjectList2, NUM_HEDGEHOGS);
|
||||
// func_80072120(indexObjectList2, NUM_HEDGEHOGS);
|
||||
clear_object_flag(objectIndex, 0x00600000); // The fix
|
||||
}
|
||||
|
||||
|
|
@ -78,7 +79,8 @@ void OHedgehog::func_800555BC(s32 objectIndex, s32 cameraId) {
|
|||
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos);
|
||||
draw_2d_texture_at(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation,
|
||||
gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT,
|
||||
(u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 64, 64, 64, 32);
|
||||
(u8*) gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 64, 64, 64,
|
||||
32);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,13 +94,20 @@ void OHedgehog::func_8004A870(s32 objectIndex, f32 arg1) {
|
|||
D_80183E50[0] = object->pos[0];
|
||||
D_80183E50[1] = object->surfaceHeight + 0.8;
|
||||
D_80183E50[2] = object->pos[2];
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("hedgehog", (uintptr_t) &gObjectList[objectIndex]);
|
||||
|
||||
set_transform_matrix(mtx, object->unk_01C, D_80183E50, 0U, arg1);
|
||||
// convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], mtx);
|
||||
// gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]),
|
||||
// G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
||||
AddHudMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007B98);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007B98);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +117,8 @@ void OHedgehog::func_8008311C(s32 objectIndex, s32 arg1) {
|
|||
Object* object;
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog);
|
||||
|
||||
init_texture_object(objectIndex, (u8*)d_course_yoshi_valley_hedgehog_tlut, sHedgehogTexList, 0x40U, (u16) 0x00000040);
|
||||
init_texture_object(objectIndex, (u8*) d_course_yoshi_valley_hedgehog_tlut, sHedgehogTexList, 0x40U,
|
||||
(u16) 0x00000040);
|
||||
object = &gObjectList[objectIndex];
|
||||
object->activeTLUT = d_course_yoshi_valley_hedgehog_tlut;
|
||||
object->activeTexture = d_course_yoshi_valley_hedgehog;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ OHotAirBalloon::OHotAirBalloon(const FVector& pos) {
|
|||
D_80165898 = 0;
|
||||
|
||||
// Spawn balloon on second lap.
|
||||
if (GetCourse() == GetLuigiRaceway()) {
|
||||
if (IsLuigiRaceway()) {
|
||||
_visible = (bool*)&D_80165898;
|
||||
} else { // Spawn balloon on race start
|
||||
bool mod = true;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <libultra/gbi.h>
|
||||
#include "Lakitu.h"
|
||||
#include <vector>
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
#include "port/Game.h"
|
||||
|
||||
|
|
@ -10,6 +11,7 @@ extern "C" {
|
|||
#include "main.h"
|
||||
#include "actors.h"
|
||||
#include "math_util.h"
|
||||
#include "math_util_2.h"
|
||||
#include "sounds.h"
|
||||
#include "update_objects.h"
|
||||
#include "render_player.h"
|
||||
|
|
@ -21,7 +23,6 @@ extern "C" {
|
|||
#include "code_80057C60.h"
|
||||
#include "defines.h"
|
||||
#include "code_80005FD0.h"
|
||||
#include "math_util_2.h"
|
||||
#include "collision.h"
|
||||
#include "assets/bowsers_castle_data.h"
|
||||
#include "ceremony_and_credits.h"
|
||||
|
|
@ -95,6 +96,8 @@ void OLakitu::Draw(s32 cameraId) {
|
|||
s32 objectIndex;
|
||||
Object* object;
|
||||
|
||||
FrameInterpolation_RecordOpenChild("Lakitu",(uintptr_t) this);
|
||||
|
||||
objectIndex = gIndexLakituList[cameraId];
|
||||
camera = &camera1[cameraId];
|
||||
if (is_obj_flag_status_active(objectIndex, 0x00000010) != 0) {
|
||||
|
|
@ -126,6 +129,7 @@ void OLakitu::Draw(s32 cameraId) {
|
|||
}
|
||||
}
|
||||
}
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
void OLakitu::func_80079114(s32 objectIndex, s32 playerId, s32 arg2) {
|
||||
|
|
@ -293,7 +297,7 @@ void OLakitu::func_800729EC(s32 objectIndex) {
|
|||
D_8018D2BC = 1;
|
||||
D_8018D2A4 = 1;
|
||||
|
||||
if (GetCourse() != GetYoshiValley()) {
|
||||
if (!IsYoshiValley()) {
|
||||
for (i = 0; i < gPlayerCount; i++) {
|
||||
playerHUD[i].unk_81 = temp_v1;
|
||||
}
|
||||
|
|
@ -362,7 +366,7 @@ void OLakitu::func_800797AC(s32 playerId) {
|
|||
|
||||
objectIndex = gIndexLakituList[playerId];
|
||||
player = &gPlayerOne[playerId];
|
||||
//if ((GetCourse() == GetSherbetLand()) && (player->unk_0CA & 1)) {
|
||||
//if ((IsSherbetLand()) && (player->unk_0CA & 1)) {
|
||||
if ((CM_GetProps()->LakituTowType == LakituTowType::ICE) && (player->unk_0CA & 1)) {
|
||||
init_object(objectIndex, 7);
|
||||
player->unk_0CA |= 0x10;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ extern "C" {
|
|||
#include "sounds.h"
|
||||
#include "external.h"
|
||||
}
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
size_t OMole::_count = 0;
|
||||
|
||||
|
|
@ -145,7 +146,7 @@ void OMole::func_80081AFC(s32 objectIndex, s32 arg1) {
|
|||
// sp2C = D_8018D1B8;
|
||||
// break;
|
||||
// }
|
||||
//sp2C[object->type] = 0;
|
||||
// sp2C[object->type] = 0;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
|
|
@ -179,20 +180,20 @@ void OMole::func_8008153C(s32 objectIndex) {
|
|||
}
|
||||
|
||||
u8* mole = (u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_dirt);
|
||||
init_object(loopObjectIndex, 0);
|
||||
gObjectList[loopObjectIndex].activeTLUT = d_course_moo_moo_farm_mole_dirt;
|
||||
gObjectList[loopObjectIndex].tlutList = mole;
|
||||
gObjectList[loopObjectIndex].sizeScaling = 0.15f;
|
||||
gObjectList[loopObjectIndex].velocity[1] = random_int(0x000AU);
|
||||
gObjectList[loopObjectIndex].velocity[1] = (gObjectList[loopObjectIndex].velocity[1] * 0.1) + 4.8;
|
||||
gObjectList[loopObjectIndex].unk_034 = random_int(5U);
|
||||
gObjectList[loopObjectIndex].unk_034 = (gObjectList[loopObjectIndex].unk_034 * 0.01) + 0.8;
|
||||
gObjectList[loopObjectIndex].orientation[1] = (0x10000 / sp70) * var_s1;
|
||||
gObjectList[loopObjectIndex].origin_pos[0] = gObjectList[objectIndex].origin_pos[0];
|
||||
gObjectList[loopObjectIndex].origin_pos[1] = gObjectList[objectIndex].origin_pos[1] - 13.0;
|
||||
gObjectList[loopObjectIndex].origin_pos[2] = gObjectList[objectIndex].origin_pos[2];
|
||||
break;
|
||||
}
|
||||
init_object(loopObjectIndex, 0);
|
||||
gObjectList[loopObjectIndex].activeTLUT = d_course_moo_moo_farm_mole_dirt;
|
||||
gObjectList[loopObjectIndex].tlutList = mole;
|
||||
gObjectList[loopObjectIndex].sizeScaling = 0.15f;
|
||||
gObjectList[loopObjectIndex].velocity[1] = random_int(0x000AU);
|
||||
gObjectList[loopObjectIndex].velocity[1] = (gObjectList[loopObjectIndex].velocity[1] * 0.1) + 4.8;
|
||||
gObjectList[loopObjectIndex].unk_034 = random_int(5U);
|
||||
gObjectList[loopObjectIndex].unk_034 = (gObjectList[loopObjectIndex].unk_034 * 0.01) + 0.8;
|
||||
gObjectList[loopObjectIndex].orientation[1] = (0x10000 / sp70) * var_s1;
|
||||
gObjectList[loopObjectIndex].origin_pos[0] = gObjectList[objectIndex].origin_pos[0];
|
||||
gObjectList[loopObjectIndex].origin_pos[1] = gObjectList[objectIndex].origin_pos[1] - 13.0;
|
||||
gObjectList[loopObjectIndex].origin_pos[2] = gObjectList[objectIndex].origin_pos[2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -243,21 +244,15 @@ void OMole::func_80081D34(s32 objectIndex) {
|
|||
}
|
||||
|
||||
static const char* frames[] = {
|
||||
gTextureMole1,
|
||||
gTextureMole2,
|
||||
gTextureMole3,
|
||||
gTextureMole4,
|
||||
gTextureMole5,
|
||||
gTextureMole6,
|
||||
gTextureMole7,
|
||||
d_course_moo_moo_farm_mole_dirt,
|
||||
gTextureMole1, gTextureMole2, gTextureMole3, gTextureMole4,
|
||||
gTextureMole5, gTextureMole6, gTextureMole7, d_course_moo_moo_farm_mole_dirt,
|
||||
};
|
||||
|
||||
|
||||
void OMole::func_80081848(s32 objectIndex) {
|
||||
init_texture_object(objectIndex, (u8*)d_course_moo_moo_farm_mole_tlut, (const char**) frames, 0x20U, (u16) 0x00000040);
|
||||
//gObjectList[objectIndex].activeTexture = (const char*)d_course_moo_moo_farm_mole_frames;
|
||||
//gObjectList[objectIndex].activeTLUT = (const char*)d_course_moo_moo_farm_mole_tlut;
|
||||
init_texture_object(objectIndex, (u8*) d_course_moo_moo_farm_mole_tlut, (const char**) frames, 0x20U,
|
||||
(u16) 0x00000040);
|
||||
// gObjectList[objectIndex].activeTexture = (const char*)d_course_moo_moo_farm_mole_frames;
|
||||
// gObjectList[objectIndex].activeTLUT = (const char*)d_course_moo_moo_farm_mole_tlut;
|
||||
|
||||
gObjectList[objectIndex].sizeScaling = 0.15f;
|
||||
gObjectList[objectIndex].textureListIndex = 0;
|
||||
|
|
@ -270,7 +265,6 @@ void OMole::func_80081848(s32 objectIndex) {
|
|||
object_next_state(objectIndex);
|
||||
}
|
||||
|
||||
|
||||
void OMole::func_80081924(s32 objectIndex) {
|
||||
switch (gObjectList[objectIndex].unk_0AE) {
|
||||
case 1:
|
||||
|
|
@ -307,7 +301,6 @@ void OMole::func_80081924(s32 objectIndex) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void OMole::func_80081A88(s32 objectIndex) {
|
||||
switch (gObjectList[objectIndex].unk_0DD) { /* irregular */
|
||||
case 0:
|
||||
|
|
@ -330,9 +323,14 @@ void OMole::func_800821AC(s32 objectIndex, s32 arg1) {
|
|||
}
|
||||
}
|
||||
|
||||
// Holes
|
||||
void OMole::func_80054E10(s32 objectIndex) {
|
||||
if (gObjectList[objectIndex].state > 0) {
|
||||
if (is_obj_flag_status_active(objectIndex, 0x00800000) != 0) {
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("func_80054E10", TAG_OBJECT(&gObjectList[objectIndex]));
|
||||
|
||||
D_80183E50[0] = gObjectList[objectIndex].pos[0];
|
||||
D_80183E50[1] = gObjectList[objectIndex].surfaceHeight + 0.8;
|
||||
D_80183E50[2] = gObjectList[objectIndex].pos[2];
|
||||
|
|
@ -340,6 +338,9 @@ void OMole::func_80054E10(s32 objectIndex) {
|
|||
D_80183E70[1] = gObjectList[objectIndex].velocity[1];
|
||||
D_80183E70[2] = gObjectList[objectIndex].velocity[2];
|
||||
func_8004A9B8(gObjectList[objectIndex].sizeScaling);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -348,8 +349,8 @@ void OMole::func_80054E10(s32 objectIndex) {
|
|||
void OMole::func_80054EB8() {
|
||||
s32 someIndex;
|
||||
|
||||
//for (someIndex = 0; someIndex < NUM_TOTAL_MOLES; someIndex++) {
|
||||
func_80054E10(_moleIndex);
|
||||
// for (someIndex = 0; someIndex < NUM_TOTAL_MOLES; someIndex++) {
|
||||
func_80054E10(_moleIndex);
|
||||
//}
|
||||
}
|
||||
|
||||
|
|
@ -360,36 +361,52 @@ void OMole::func_80054D00(s32 objectIndex, s32 cameraId) {
|
|||
if (gObjectList[objectIndex].state >= 3) {
|
||||
func_8008A364(objectIndex, cameraId, 0x2AABU, 0x0000012C);
|
||||
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("func_80054D00", (uintptr_t)&gObjectList[objectIndex]);
|
||||
|
||||
D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0];
|
||||
D_80183E80[1] =
|
||||
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos);
|
||||
D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2];
|
||||
func_80048130(gObjectList[objectIndex].pos, (u16*) D_80183E80, gObjectList[objectIndex].sizeScaling,
|
||||
(u8*) gObjectList[objectIndex].activeTLUT, (u8*)gObjectList[objectIndex].activeTexture,
|
||||
(Vtx*)LOAD_ASSET_RAW(D_0D0062B0), 0x00000020, 0x00000040, 0x00000020, 0x00000040, 5);
|
||||
(u8*) gObjectList[objectIndex].activeTLUT, (u8*) gObjectList[objectIndex].activeTexture,
|
||||
(Vtx*) LOAD_ASSET_RAW(D_0D0062B0), 0x00000020, 0x00000040, 0x00000020, 0x00000040, 5);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mole rocks
|
||||
void OMole::func_80054F04(s32 cameraId) {
|
||||
Camera* camera = &camera1[cameraId];
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0079C8);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D0079C8);
|
||||
load_texture_block_rgba16_mirror((u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_dirt), 0x00000010, 0x00000010);
|
||||
|
||||
if (_idx == 0) {
|
||||
for (size_t i = 0; i < gObjectParticle2_SIZE; i++) {
|
||||
s32 objectIndex = gObjectParticle2[i];
|
||||
Object* object = &gObjectList[objectIndex];
|
||||
if (object->state > 0) {
|
||||
func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000000C8);
|
||||
if ((is_obj_flag_status_active(objectIndex, VISIBLE) != 0) && (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) {
|
||||
object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos);
|
||||
rsp_set_matrix_gObjectList(objectIndex);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D006980);
|
||||
if (_idx == 0) {
|
||||
for (size_t i = 0; i < gObjectParticle2_SIZE; i++) {
|
||||
s32 objectIndex = gObjectParticle2[i];
|
||||
Object* object = &gObjectList[objectIndex];
|
||||
if (object->state > 0) {
|
||||
func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000000C8);
|
||||
if ((is_obj_flag_status_active(objectIndex, VISIBLE) != 0) &&
|
||||
(gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) {
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("func_80054F04", TAG_OBJECT(object) | (i << 32));
|
||||
|
||||
object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos);
|
||||
rsp_set_matrix_gObjectList(objectIndex);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D006980);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ extern "C" {
|
|||
#include "code_80086E70.h"
|
||||
#include "code_80057C60.h"
|
||||
}
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
static const char* sSnowmanHeadList[] = { d_course_frappe_snowland_snowman_head };
|
||||
|
||||
|
|
@ -27,7 +28,7 @@ OSnowman::OSnowman(const FVector& pos) {
|
|||
gObjectList[_headIndex].origin_pos[0] = pos.x * xOrientation;
|
||||
gObjectList[_headIndex].origin_pos[1] = pos.y + 5.0 + 3.0;
|
||||
gObjectList[_headIndex].origin_pos[2] = pos.z;
|
||||
gObjectList[_headIndex].pos[0] = pos.x * xOrientation;
|
||||
gObjectList[_headIndex].pos[0] = pos.x * xOrientation;
|
||||
gObjectList[_headIndex].pos[1] = pos.y + 5.0 + 3.0;
|
||||
gObjectList[_headIndex].pos[2] = pos.z;
|
||||
|
||||
|
|
@ -38,7 +39,7 @@ OSnowman::OSnowman(const FVector& pos) {
|
|||
gObjectList[_bodyIndex].origin_pos[2] = pos.z;
|
||||
gObjectList[_bodyIndex].unk_0D5 = 0; // Section Id no longer used.
|
||||
|
||||
gObjectList[_bodyIndex].pos[0] = pos.x * xOrientation;
|
||||
gObjectList[_bodyIndex].pos[0] = pos.x * xOrientation;
|
||||
gObjectList[_bodyIndex].pos[1] = pos.y + 3.0;
|
||||
gObjectList[_bodyIndex].pos[2] = pos.z;
|
||||
|
||||
|
|
@ -71,14 +72,15 @@ void OSnowman::Tick() {
|
|||
}
|
||||
}
|
||||
|
||||
//for (var_s0 = 0; var_s0 < NUM_SNOWMEN; var_s0++) {
|
||||
// for (var_s0 = 0; var_s0 < NUM_SNOWMEN; var_s0++) {
|
||||
var_s4 = _bodyIndex;
|
||||
var_s3 = _headIndex;
|
||||
OSnowman::func_80083A94(var_s3); // snowman head
|
||||
OSnowman::func_80083C04(var_s4); // snowman body
|
||||
if (is_obj_index_flag_status_inactive(var_s4, 0x00001000) != 0) {
|
||||
object = &gObjectList[var_s4];
|
||||
if ((are_players_in_course_section(object->unk_0D5 - 1, object->unk_0D5 + 1) != 0) && (func_80089B50(var_s4) != 0)) {
|
||||
if ((are_players_in_course_section(object->unk_0D5 - 1, object->unk_0D5 + 1) != 0) &&
|
||||
(func_80089B50(var_s4) != 0)) {
|
||||
set_object_flag(var_s4, 0x00001000);
|
||||
clear_object_flag(var_s4, 0x00000010);
|
||||
func_800726CC(var_s4, 0x0000000A);
|
||||
|
|
@ -93,6 +95,7 @@ void OSnowman::Tick() {
|
|||
}
|
||||
|
||||
void OSnowman::Draw(s32 cameraId) {
|
||||
|
||||
OSnowman::DrawHead(cameraId);
|
||||
OSnowman::DrawBody(cameraId);
|
||||
}
|
||||
|
|
@ -117,23 +120,29 @@ void OSnowman::DrawHead(s32 cameraId) {
|
|||
if (gObjectList[objectIndex].state >= 2) {
|
||||
func_8008A364(objectIndex, cameraId, 0x2AABU, 0x00000258);
|
||||
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("OSnowman::DrawHead", (uintptr_t) &gObjectList[objectIndex]);
|
||||
|
||||
D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0];
|
||||
D_80183E80[1] =
|
||||
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos);
|
||||
D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2];
|
||||
if (is_obj_flag_status_active(objectIndex, 0x00000010) != 0) {
|
||||
draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80,
|
||||
gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT,
|
||||
(u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex,
|
||||
0x00000040, 0x00000040, 0x00000040, 0x00000020);
|
||||
gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT,
|
||||
(u8*) gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex,
|
||||
0x00000040, 0x00000040, 0x00000040, 0x00000020);
|
||||
}
|
||||
objectIndex = _headIndex;
|
||||
D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0];
|
||||
D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2];
|
||||
draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80,
|
||||
gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT,
|
||||
(u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 0x00000040,
|
||||
0x00000040, 0x00000040, 0x00000020);
|
||||
draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80, gObjectList[objectIndex].sizeScaling,
|
||||
(u8*) gObjectList[objectIndex].activeTLUT, (u8*) gObjectList[objectIndex].activeTexture,
|
||||
gObjectList[objectIndex].vertex, 0x00000040, 0x00000040, 0x00000040, 0x00000020);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -146,7 +155,8 @@ void OSnowman::DrawBody(s32 cameraId) {
|
|||
Object* object;
|
||||
|
||||
sp44 = &camera1[cameraId];
|
||||
load_texture_and_tlut((u8*)d_course_frappe_snowland_snow_tlut, (u8*)d_course_frappe_snowland_snow, 0x00000020, 0x00000020);
|
||||
load_texture_and_tlut((u8*) d_course_frappe_snowland_snow_tlut, (u8*) d_course_frappe_snowland_snow, 0x00000020,
|
||||
0x00000020);
|
||||
|
||||
//! @todo quick hack to add the snow particles on hit. Need to separate into its own class
|
||||
if (_idx == 0) {
|
||||
|
|
@ -157,9 +167,16 @@ void OSnowman::DrawBody(s32 cameraId) {
|
|||
if (object->state > 0) {
|
||||
func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000001F4);
|
||||
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("OSnowman::DrawBody", (uintptr_t) object);
|
||||
|
||||
object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], sp44->pos);
|
||||
rsp_set_matrix_gObjectList(objectIndex);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0069E0);
|
||||
gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D0069E0);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -215,7 +232,8 @@ void OSnowman::func_80083BE4(s32 objectIndex) {
|
|||
void OSnowman::func_80083868(s32 objectIndex) {
|
||||
Object* object;
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(D_0D0061B0);
|
||||
init_texture_object(objectIndex, (u8*)d_course_frappe_snowland_snowman_tlut, (const char**)sSnowmanHeadList, 0x40U, (u16) 0x00000040);
|
||||
init_texture_object(objectIndex, (u8*) d_course_frappe_snowland_snowman_tlut, (const char**) sSnowmanHeadList,
|
||||
0x40U, (u16) 0x00000040);
|
||||
object = &gObjectList[objectIndex];
|
||||
object->vertex = vtx;
|
||||
object->sizeScaling = 0.1f;
|
||||
|
|
@ -259,7 +277,8 @@ void OSnowman::func_80083948(s32 objectIndex) {
|
|||
break;
|
||||
}
|
||||
object_calculate_new_pos_offset(objectIndex);
|
||||
OSnowman::func_80073D0C(objectIndex, &gObjectList[objectIndex].primAlpha, -0x00001000, 0x00001000, 0x00000400, 1, -1);
|
||||
OSnowman::func_80073D0C(objectIndex, &gObjectList[objectIndex].primAlpha, -0x00001000, 0x00001000, 0x00000400, 1,
|
||||
-1);
|
||||
gObjectList[objectIndex].orientation[2] = gObjectList[objectIndex].primAlpha + 0x8000;
|
||||
}
|
||||
|
||||
|
|
@ -285,7 +304,8 @@ static const char* sSnowmanBodyList[] = { d_course_frappe_snowland_snowman_body
|
|||
|
||||
void OSnowman::func_80083B0C(s32 objectIndex) {
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog);
|
||||
init_texture_object(objectIndex, (u8*)d_course_frappe_snowland_snowman_tlut, (const char**)sSnowmanBodyList, 0x40U, (u16) 0x00000040);
|
||||
init_texture_object(objectIndex, (u8*) d_course_frappe_snowland_snowman_tlut, (const char**) sSnowmanBodyList,
|
||||
0x40U, (u16) 0x00000040);
|
||||
gObjectList[objectIndex].vertex = vtx;
|
||||
gObjectList[objectIndex].sizeScaling = 0.1f;
|
||||
gObjectList[objectIndex].textureListIndex = 0;
|
||||
|
|
@ -299,16 +319,15 @@ void OSnowman::func_80083B0C(s32 objectIndex) {
|
|||
set_object_flag(objectIndex, 0x04000210);
|
||||
}
|
||||
|
||||
|
||||
void OSnowman::func_80083538(s32 objectIndex, Vec3f arg1, s32 arg2, s32 arg3) {
|
||||
Object* object;
|
||||
|
||||
init_object(objectIndex, 0);
|
||||
object = &gObjectList[objectIndex];
|
||||
object->activeTexture = (const char*)d_course_frappe_snowland_snow;
|
||||
object->textureList = (const char**)d_course_frappe_snowland_snow;
|
||||
object->activeTexture = (const char*) d_course_frappe_snowland_snow;
|
||||
object->textureList = (const char**) d_course_frappe_snowland_snow;
|
||||
object->activeTLUT = d_course_frappe_snowland_snow_tlut;
|
||||
object->tlutList = (u8*)d_course_frappe_snowland_snow_tlut;
|
||||
object->tlutList = (u8*) d_course_frappe_snowland_snow_tlut;
|
||||
object->sizeScaling = random_int(0x0064U);
|
||||
object->sizeScaling = (object->sizeScaling * 0.001) + 0.05;
|
||||
object->velocity[1] = random_int(0x0014U);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ f32 D_800E594C[][2] = {
|
|||
s16 D_800E597C[] = { 0x0000, 0x0000, 0x4000, 0x8000, 0x8000, 0xc000 };
|
||||
|
||||
size_t OThwomp::_count = 0;
|
||||
size_t OThwomp::_rand = 0;
|
||||
|
||||
OThwomp::OThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize) {
|
||||
Name = "Thwomp";
|
||||
|
|
@ -88,6 +89,7 @@ void OThwomp::Tick60fps() { // func_80081210
|
|||
if (_idx == 0) {
|
||||
D_80165834[0] += 0x100;
|
||||
D_80165834[1] += 0x200;
|
||||
_rand += 1;
|
||||
}
|
||||
|
||||
if (gObjectList[_objectIndex].state != 0) {
|
||||
|
|
@ -131,26 +133,26 @@ void OThwomp::Tick60fps() { // func_80081210
|
|||
}
|
||||
OThwomp::func_8007542C(3);
|
||||
|
||||
if (func_80072320(_objectIndex, 0x00000020) == 0) {
|
||||
return;
|
||||
if (func_80072320(_objectIndex, 0x00000020)) {
|
||||
func_800722CC(_objectIndex, 0x00000020);
|
||||
OThwomp::AddParticles(_objectIndex);
|
||||
}
|
||||
|
||||
func_800722CC(_objectIndex, 0x00000020);
|
||||
OThwomp::AddParticles(_objectIndex);
|
||||
|
||||
for (var_s4 = 0; var_s4 < gObjectParticle2_SIZE; var_s4++) {
|
||||
objectIndex = gObjectParticle2[var_s4];
|
||||
if (objectIndex == DELETED_OBJECT_ID) {
|
||||
return;
|
||||
if (_idx == 0) {
|
||||
for (var_s4 = 0; var_s4 < gObjectParticle2_SIZE; var_s4++) {
|
||||
objectIndex = gObjectParticle2[var_s4];
|
||||
if (objectIndex == DELETED_OBJECT_ID) {
|
||||
continue;
|
||||
}
|
||||
if (gObjectList[objectIndex].state == 0) {
|
||||
continue;
|
||||
}
|
||||
OThwomp::func_800810F4(objectIndex);
|
||||
if (gObjectList[objectIndex].state != 0) {
|
||||
continue;
|
||||
}
|
||||
delete_object_wrapper(&gObjectParticle2[var_s4]);
|
||||
}
|
||||
if (gObjectList[objectIndex].state == 0) {
|
||||
return;
|
||||
}
|
||||
OThwomp::func_800810F4(objectIndex);
|
||||
if (gObjectList[objectIndex].state != 0) {
|
||||
return;
|
||||
}
|
||||
delete_object_wrapper(&gObjectParticle2[var_s4]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -361,14 +363,16 @@ void OThwomp::func_8007F8D8() {
|
|||
|
||||
s32 OThwomp::func_8007F75C(s32 playerId) {
|
||||
s32 someIndex;
|
||||
s32 temp_s7;
|
||||
static s32 temp_s7 = 0; // Must be static to sync far travelling thwomp instances
|
||||
s32 var_s6;
|
||||
s32 waypoint;
|
||||
|
||||
waypoint = gNearestWaypointByPlayerId[playerId];
|
||||
var_s6 = 0;
|
||||
if ((waypoint >= 0xAA) && (waypoint < 0xB5)) {
|
||||
temp_s7 = random_int(0x0032U) + 0x32;
|
||||
if (_idx == 0) {
|
||||
temp_s7 = random_int(0x0032U) + 0x32;
|
||||
}
|
||||
if (gObjectList[_objectIndex].unk_0D5 == 3) {
|
||||
var_s6 = 1;
|
||||
OThwomp::func_8007F660(_objectIndex, playerId, temp_s7);
|
||||
|
|
@ -928,9 +932,9 @@ void OThwomp::func_8007FA08(s32 objectIndex) {
|
|||
set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f);
|
||||
set_obj_direction_angle(objectIndex, 0U, 0U, 0U);
|
||||
if (gIsMirrorMode != 0) {
|
||||
set_obj_orientation(objectIndex, 0U, 0xC000U, 0U);
|
||||
set_obj_orientation(objectIndex, 0U, _faceDirection, 0U);
|
||||
} else {
|
||||
set_obj_orientation(objectIndex, 0U, 0x4000U, 0U);
|
||||
set_obj_orientation(objectIndex, 0U, -_faceDirection, 0U);
|
||||
}
|
||||
object->velocity[0] = 0.0f;
|
||||
object->direction_angle[1] = object->orientation[1];
|
||||
|
|
@ -970,7 +974,7 @@ void OThwomp::func_8007FB48(s32 objectIndex) {
|
|||
gObjectList[objectIndex].velocity[0] = player->unk_094 * xOrientation * 1.25;
|
||||
if (gObjectList[objectIndex].unk_048 >= gObjectList[objectIndex].unk_0B0) {
|
||||
if (gObjectList[objectIndex].unk_0B0 == gObjectList[objectIndex].unk_048) {
|
||||
if (D_8018D400 & 1) {
|
||||
if (_rand & 1) { // D_8018D400 & 1
|
||||
gObjectList[objectIndex].velocity[2] = 1.5f;
|
||||
} else {
|
||||
gObjectList[objectIndex].velocity[2] = -1.5f;
|
||||
|
|
@ -1169,9 +1173,9 @@ void OThwomp::func_800802C0(s32 objectIndex) {
|
|||
object->offset[1] = 10.0f;
|
||||
object->unk_01C[1] = 10.0f;
|
||||
if (gIsMirrorMode != 0) {
|
||||
set_obj_orientation(objectIndex, 0U, 0x4000U, 0U);
|
||||
set_obj_orientation(objectIndex, 0U, -_faceDirection, 0U);
|
||||
} else {
|
||||
set_obj_orientation(objectIndex, 0U, 0xC000U, 0U);
|
||||
set_obj_orientation(objectIndex, 0U, _faceDirection, 0U);
|
||||
}
|
||||
object->offset[0] = 0.0f;
|
||||
object->offset[2] = 0.0f;
|
||||
|
|
@ -1195,7 +1199,7 @@ void OThwomp::SlidingBehaviour(s32 objectIndex) { // func_800808CC
|
|||
OThwomp::func_8008085C(objectIndex);
|
||||
func_80073514(objectIndex);
|
||||
if (gGamestate != 9) {
|
||||
if ((D_8018D40C == 0) && (gObjectList[objectIndex].state == 2)) {
|
||||
if (((_rand & 0x3F) == 0) && (gObjectList[objectIndex].state == 2)) { // D_8018D40C == 0 &&
|
||||
func_800C98B8(gObjectList[objectIndex].pos, gObjectList[objectIndex].velocity,
|
||||
SOUND_ARG_LOAD(0x19, 0x03, 0x60, 0x45));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ public:
|
|||
void func_8007E63C(s32 objectIndex);
|
||||
private:
|
||||
static size_t _count;
|
||||
static size_t _rand;
|
||||
s32 _idx;
|
||||
s16 _faceDirection;
|
||||
//! @todo Write this better. This effects the squish size and the bounding box size.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "TrashBin.h"
|
||||
#include "World.h"
|
||||
#include "port/Game.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
extern "C" {
|
||||
#include "main.h"
|
||||
|
|
@ -31,7 +32,7 @@ OTrashBin::OTrashBin(const FVector& pos, const IRotator& rotation, f32 scale, OT
|
|||
|
||||
init_object(_objectIndex, 0);
|
||||
|
||||
if (GetCourse() != GetBansheeBoardwalk()) {
|
||||
if (!IsBansheeBoardwalk()) {
|
||||
_drawBin = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -62,11 +63,18 @@ void OTrashBin::Draw(s32 cameraId) {
|
|||
Mat4 mtx;
|
||||
Vec3f Pos = { _pos.x + 63, _pos.y + 12, _pos.z + 25 };
|
||||
Vec3s Rot = { 0, 0x4000, 0 };
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("OTrashBin", (uintptr_t) object);
|
||||
|
||||
mtxf_pos_rotation_xyz(mtx, Pos, Rot);
|
||||
//mtxf_scale(mtx, 1.0f);
|
||||
if (render_set_position(mtx, 0) != 0) {
|
||||
gSPDisplayList(gDisplayListHead++, BinMod);
|
||||
}
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
|
||||
#include "StarEmitter.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
extern "C" {
|
||||
#include "render_objects.h"
|
||||
|
|
@ -107,9 +108,13 @@ void StarEmitter::Draw(s32 cameraId) { // func_80054BE8
|
|||
D_80183E80[0] = 0;
|
||||
for (var_s0 = 0; var_s0 < gObjectParticle3_SIZE; var_s0++) {
|
||||
temp_a0 = ObjectIndex[var_s0];
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Ceremony Stars", (uintptr_t) &ObjectIndex[var_s0]);
|
||||
if ((temp_a0 != -1) && (gObjectList[temp_a0].state >= 2)) {
|
||||
StarEmitter::func_80054AFC(temp_a0, camera->pos);
|
||||
}
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#include "code_800029B0.h"
|
||||
#include "mk64.h"
|
||||
#include "main.h"
|
||||
#include <port/interpolation/FrameInterpolation.h>
|
||||
#include <port/interpolation/matrix.h>
|
||||
|
||||
#include "collision_viewer.h"
|
||||
#include "math_util.h"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "port/Game.h"
|
||||
#include <controller/controldevice/controller/mapping/keyboard/KeyboardScancodes.h>
|
||||
#include <window/Window.h>
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
extern "C" {
|
||||
#include <macros.h>
|
||||
|
|
@ -86,6 +87,8 @@ void freecam(Camera* camera, Player* player, s8 index) {
|
|||
freecam_loop(camera, player, index);
|
||||
} else {
|
||||
func_8001E45C(camera, player, index);
|
||||
// Required if freecam were to use its own camera instead of borrowing the player camera
|
||||
//func_8001EE98(gPlayerOneCopy, camera, index);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +107,6 @@ void freecam_loop(Camera* camera, Player* player, s8 index) {
|
|||
// Toggle freecam
|
||||
CVarSetInteger("gFreecam", !CVarGetInteger("gFreecam", 0));
|
||||
}
|
||||
|
||||
// Calculate forward direction
|
||||
freecam_calculate_forward_vector_allow_rotation(camera, freeCam.forwardVector);
|
||||
|
||||
|
|
@ -389,24 +391,33 @@ void freecam_update_controller(void) {
|
|||
// Note that D Pad as stick code has been removed. So if it's needed, it needs to be put back in.
|
||||
}
|
||||
|
||||
void freecam_render_setup(void) {
|
||||
Mtx fPersp;
|
||||
Mtx fLookAt;
|
||||
void freecam_render_setup(Camera* camera) {
|
||||
u16 perspNorm;
|
||||
Mat4 matrix;
|
||||
init_rdp();
|
||||
func_802A53A4();
|
||||
init_rdp();
|
||||
func_80057FC4(0);
|
||||
|
||||
Mat4 persp;
|
||||
Mat4 lookAt;
|
||||
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH);
|
||||
gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK | G_CULL_BOTH | G_CULL_FRONT);
|
||||
guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect,
|
||||
|
||||
// Perspective (camera movement)
|
||||
FrameInterpolation_RecordOpenChild("freecam_persp", FrameInterpolation_GetCameraEpoch());
|
||||
guPerspective(&fPersp, &perspNorm, gCameraZoom[0], gScreenAspect,
|
||||
CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f);
|
||||
gSPPerspNormalize(gDisplayListHead++, perspNorm);
|
||||
gSPMatrix(gDisplayListHead++, (&gGfxPool->mtxPersp[0]), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
guLookAt(&gGfxPool->mtxLookAt[0], camera1->pos[0], camera1->pos[1], camera1->pos[2], camera1->lookAt[0],
|
||||
camera1->lookAt[1], camera1->lookAt[2], camera1->up[0], camera1->up[1], camera1->up[2]);
|
||||
gSPMatrix(gDisplayListHead++, (&gGfxPool->mtxLookAt[0]), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
||||
mtxf_identity(matrix);
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK);
|
||||
render_set_position(matrix, 0);
|
||||
init_rdp();
|
||||
gSPMatrix(gDisplayListHead++, (&fPersp), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
|
||||
// LookAt (camera rotation)
|
||||
FrameInterpolation_RecordOpenChild("freecam_lookAt", FrameInterpolation_GetCameraEpoch());
|
||||
guLookAt(&fLookAt, camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0],
|
||||
camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]);
|
||||
gSPMatrix(gDisplayListHead++, (&fLookAt), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ void on_freecam(void);
|
|||
void off_freecam(void);
|
||||
void freecam_loop(Camera*, Player*, s8);
|
||||
void freecam_update_controller(void);
|
||||
void freecam_render_setup(void);
|
||||
void freecam_render_setup(Camera* camera);
|
||||
void freecam_mouse_manager(Camera*, Vec3f);
|
||||
void freecam_keyboard_manager(Camera*, Vec3f);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@
|
|||
#include <camera.h>
|
||||
#include "freecam_engine.h"
|
||||
|
||||
FreeCam freeCam;
|
||||
|
||||
#include <math.h>
|
||||
|
||||
FreeCam freeCam;
|
||||
|
||||
f32 gDampValue = 0.99f;
|
||||
f32 gRotDampValue = 0.96f;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "main.h"
|
||||
#include <mk64.h>
|
||||
#include <assets/common_data.h>
|
||||
#include "src/port/interpolation/matrix.h"
|
||||
|
||||
#include "math_util.h"
|
||||
|
||||
|
|
|
|||
32
src/main.c
32
src/main.c
|
|
@ -44,6 +44,7 @@
|
|||
#include "buffers/gfx_output_buffer.h"
|
||||
#include <bridge/gfxdebuggerbridge.h>
|
||||
#include "enhancements/freecam/freecam.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
#include "engine/wasm.h"
|
||||
#include "port/Game.h"
|
||||
#include "engine/Matrix.h"
|
||||
|
|
@ -636,6 +637,12 @@ void game_init_clear_framebuffer(void) {
|
|||
clear_framebuffer(0);
|
||||
}
|
||||
|
||||
//! @deprecated
|
||||
// This function was made to tick the game logic at native 60 fps.
|
||||
// However, many game objects are not in that special tick loop and run at native 30fps.
|
||||
// Thus adding `if (gTickVisuals) { // stuff here }` would prevent double speed and allow ticking visuals once every 30 fps.
|
||||
// This does not however, create extra interpolated frames. Whereas a possible solution, it is not the best solution.
|
||||
// This function should be cleaned up and removed, since frame interpolation now exists.
|
||||
void calculate_updaterate(void) {
|
||||
static u32 prevtime = 0;
|
||||
static u32 remainder = 0;
|
||||
|
|
@ -647,7 +654,7 @@ void calculate_updaterate(void) {
|
|||
s32 total;
|
||||
|
||||
// Get target FPS from configuration variable
|
||||
s32 targetFPS = CVarGetInteger("gInterpolationFPS", 30);
|
||||
s32 targetFPS = 30;
|
||||
|
||||
if (targetFPS < 60) {
|
||||
targetFPS = 30;
|
||||
|
|
@ -686,7 +693,7 @@ void calculate_updaterate(void) {
|
|||
if (targetFPS < 60) {
|
||||
gTickLogic = 2;
|
||||
} else {
|
||||
gTickLogic = 1; // Perform logic update
|
||||
gTickLogic = 2; // Perform logic update
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -694,8 +701,9 @@ void calculate_updaterate(void) {
|
|||
visualsAccumulator += total; // Increment for each frame
|
||||
if (visualsAccumulator >= visualsUpdateInterval) { // Check if it's time to update visuals
|
||||
visualsAccumulator -= visualsUpdateInterval;
|
||||
gTickVisuals = 1; // Perform visual update
|
||||
// gTickVisuals <-- Goes here to use the native 60fps system
|
||||
}
|
||||
gTickVisuals = 1; // Perform visual update
|
||||
}
|
||||
|
||||
void display_debug_info(void) {
|
||||
|
|
@ -758,9 +766,20 @@ void process_game_tick(void) {
|
|||
func_800382DC();
|
||||
}
|
||||
|
||||
// Editor requires this for camera movement.
|
||||
func_8001EE98(gPlayerOneCopy, camera1, 0);
|
||||
|
||||
// tick camera
|
||||
// This looks like it should be in the switch.
|
||||
// But it needs to be here for player 1 to work in all modes.
|
||||
func_8001EE98(gPlayerOneCopy, camera1, 0);
|
||||
// Required if freecam was to have a new camera
|
||||
//if (CVarGetInteger("gFreecam", 0) == true) {
|
||||
// freecam(gFreecamCamera, gPlayerOneCopy, 0);
|
||||
//} else {
|
||||
|
||||
//func_8001EE98(gPlayerOneCopy, camera1, 0);
|
||||
//}
|
||||
|
||||
// Editor requires this so the camera keeps moving while the game is paused.
|
||||
if (gIsEditorPaused == true) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -930,6 +949,8 @@ void race_logic_loop(void) {
|
|||
*/
|
||||
|
||||
void game_state_handler(void) {
|
||||
FrameInterpolation_StartRecord();
|
||||
|
||||
#if DVDL
|
||||
if ((gControllerOne->button & L_TRIG) && (gControllerOne->button & R_TRIG) && (gControllerOne->button & Z_TRIG) &&
|
||||
(gControllerOne->button & A_BUTTON)) {
|
||||
|
|
@ -966,6 +987,7 @@ void game_state_handler(void) {
|
|||
credits_loop();
|
||||
break;
|
||||
}
|
||||
FrameInterpolation_StopRecord();
|
||||
}
|
||||
|
||||
void interrupt_gfx_sptask(void) {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,13 @@
|
|||
|
||||
#include "port/Engine.h"
|
||||
#include "engine/Matrix.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
#pragma intrinsic(sqrtf)
|
||||
|
||||
Mat4 sInterpolationMatrixStack[0x1000];
|
||||
Mat4* gInterpolationMatrix = &sInterpolationMatrixStack[0];
|
||||
|
||||
UNUSED void operator_or(s32* arg0, s32 arg1) {
|
||||
*arg0 = (s32) (*arg0 | arg1);
|
||||
}
|
||||
|
|
@ -600,7 +604,6 @@ void func_80041D24(void) {
|
|||
}
|
||||
|
||||
void guOrtho(Mtx*, f32, f32, f32, f32, f32, f32, f32); /* extern */
|
||||
extern s8 D_801658FE;
|
||||
|
||||
void func_80041D34(void) {
|
||||
guOrtho(&D_80183D60, 0.0f, 320.0f, 240.0f, 0.0f, -1.0f, 1.0f, 1.0f);
|
||||
|
|
@ -687,13 +690,13 @@ UNUSED void func_800421FC(s32 x, s32 y, f32 scale) {
|
|||
|
||||
void func_80042330(s32 x, s32 y, u16 angle, f32 scale) {
|
||||
Mat4 matrix;
|
||||
//printf("panel %d %d %d\n", x, (s32)OTRGetDimensionFromLeftEdge(x), (s32)OTRGetDimensionFromLeftEdge(0));
|
||||
// printf("panel %d %d %d\n", x, (s32)OTRGetDimensionFromLeftEdge(x), (s32)OTRGetDimensionFromLeftEdge(0));
|
||||
|
||||
if (gHUDModes != 2) {
|
||||
if (x < (SCREEN_WIDTH / 2)) {
|
||||
x = (s32)OTRGetDimensionFromLeftEdge(x);
|
||||
x = (s32) OTRGetDimensionFromLeftEdge(x);
|
||||
} else {
|
||||
x = (s32)OTRGetDimensionFromRightEdge(x);
|
||||
x = (s32) OTRGetDimensionFromRightEdge(x);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -707,7 +710,7 @@ void func_80042330(s32 x, s32 y, u16 angle, f32 scale) {
|
|||
|
||||
void func_80042330_unchanged(s32 x, s32 y, u16 angle, f32 scale) {
|
||||
Mat4 matrix;
|
||||
//printf("panel %d %d %d\n", x, (s32)OTRGetDimensionFromLeftEdge(x), (s32)OTRGetDimensionFromLeftEdge(0));
|
||||
// printf("panel %d %d %d\n", x, (s32)OTRGetDimensionFromLeftEdge(x), (s32)OTRGetDimensionFromLeftEdge(0));
|
||||
|
||||
mtxf_translation_x_y_rotate_z_scale_x_y(matrix, x, y, angle, scale);
|
||||
// convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix);
|
||||
|
|
@ -720,13 +723,13 @@ void func_80042330_unchanged(s32 x, s32 y, u16 angle, f32 scale) {
|
|||
// Allows a different way of lining up the portraits at the end of race sequence
|
||||
void func_80042330_portrait(s32 x, s32 y, u16 angle, f32 scale, s16 lapCount) {
|
||||
Mat4 matrix;
|
||||
//printf("panel %d %d %d\n", x, (s32)OTRGetDimensionFromLeftEdge(x), (s32)OTRGetDimensionFromLeftEdge(0));
|
||||
// printf("panel %d %d %d\n", x, (s32)OTRGetDimensionFromLeftEdge(x), (s32)OTRGetDimensionFromLeftEdge(0));
|
||||
|
||||
if ((gHUDModes != 2) && (D_801657E2 == 0) || (CVarGetInteger("gImprovements", 0) == true)) {
|
||||
if (x < (SCREEN_WIDTH / 2)) {
|
||||
x = (s32)OTRGetDimensionFromLeftEdge(x);
|
||||
x = (s32) OTRGetDimensionFromLeftEdge(x);
|
||||
} else {
|
||||
x = (s32)OTRGetDimensionFromRightEdge(x);
|
||||
x = (s32) OTRGetDimensionFromRightEdge(x);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -742,9 +745,9 @@ void func_80042330_wide(s32 x, s32 y, u16 angle, f32 scale) {
|
|||
Mat4 matrix;
|
||||
|
||||
if (x < (SCREEN_WIDTH / 2)) {
|
||||
x = (s32)OTRGetDimensionFromLeftEdge(x);
|
||||
x = (s32) OTRGetDimensionFromLeftEdge(x);
|
||||
} else {
|
||||
x = (s32)OTRGetDimensionFromRightEdge(x);
|
||||
x = (s32) OTRGetDimensionFromRightEdge(x);
|
||||
}
|
||||
|
||||
mtxf_translation_x_y_rotate_z_scale_x_y(matrix, x, y, angle, scale);
|
||||
|
|
@ -805,27 +808,28 @@ UNUSED void func_8004252C(Mat4 arg0, u16 arg1, u16 arg2) {
|
|||
arg0[2][2] = sp28 * cos_theta_y;
|
||||
}
|
||||
|
||||
void mtxf_set_matrix_transformation(Mat4 transformMatrix, Vec3f translationVector, Vec3su rotationVector,
|
||||
f32 scalingFactor) {
|
||||
f32 sinX = sins(rotationVector[0]);
|
||||
f32 cosX = coss(rotationVector[0]);
|
||||
f32 sinY = sins(rotationVector[1]);
|
||||
f32 cosY = coss(rotationVector[1]);
|
||||
f32 sinZ = sins(rotationVector[2]);
|
||||
f32 cosZ = coss(rotationVector[2]);
|
||||
void mtxf_set_matrix_transformation(Mat4 transformMatrix, Vec3f location, Vec3su rotation, f32 scale) {
|
||||
|
||||
transformMatrix[0][0] = ((cosY * cosZ) + (sinX * sinY * sinZ)) * scalingFactor;
|
||||
transformMatrix[1][0] = ((-cosY * sinZ) + (sinX * sinY * cosZ)) * scalingFactor;
|
||||
transformMatrix[2][0] = (cosX * sinY) * scalingFactor;
|
||||
transformMatrix[3][0] = translationVector[0];
|
||||
transformMatrix[0][1] = cosX * sinZ * scalingFactor;
|
||||
transformMatrix[1][1] = cosX * cosZ * scalingFactor;
|
||||
transformMatrix[2][1] = -sinX * scalingFactor;
|
||||
transformMatrix[3][1] = translationVector[1];
|
||||
transformMatrix[0][2] = ((-sinY * cosZ) + (sinX * cosY * sinZ)) * scalingFactor;
|
||||
transformMatrix[1][2] = ((sinY * sinZ) + (sinX * cosY * cosZ)) * scalingFactor;
|
||||
transformMatrix[2][2] = cosX * cosY * scalingFactor;
|
||||
transformMatrix[3][2] = translationVector[2];
|
||||
FrameInterpolation_RecordSetMatrixTransformation(transformMatrix, location, rotation, scale);
|
||||
f32 sinX = sins(rotation[0]);
|
||||
f32 cosX = coss(rotation[0]);
|
||||
f32 sinY = sins(rotation[1]);
|
||||
f32 cosY = coss(rotation[1]);
|
||||
f32 sinZ = sins(rotation[2]);
|
||||
f32 cosZ = coss(rotation[2]);
|
||||
|
||||
transformMatrix[0][0] = ((cosY * cosZ) + (sinX * sinY * sinZ)) * scale;
|
||||
transformMatrix[1][0] = ((-cosY * sinZ) + (sinX * sinY * cosZ)) * scale;
|
||||
transformMatrix[2][0] = (cosX * sinY) * scale;
|
||||
transformMatrix[3][0] = location[0];
|
||||
transformMatrix[0][1] = cosX * sinZ * scale;
|
||||
transformMatrix[1][1] = cosX * cosZ * scale;
|
||||
transformMatrix[2][1] = -sinX * scale;
|
||||
transformMatrix[3][1] = location[1];
|
||||
transformMatrix[0][2] = ((-sinY * cosZ) + (sinX * cosY * sinZ)) * scale;
|
||||
transformMatrix[1][2] = ((sinY * sinZ) + (sinX * cosY * cosZ)) * scale;
|
||||
transformMatrix[2][2] = cosX * cosY * scale;
|
||||
transformMatrix[3][2] = location[2];
|
||||
transformMatrix[0][3] = 0.0f;
|
||||
transformMatrix[1][3] = 0.0f;
|
||||
transformMatrix[2][3] = 0.0f;
|
||||
|
|
@ -859,7 +863,13 @@ void mtxf_set_matrix_scale_transl(Mat4 transformMatrix, Vec3f vec1, Vec3f vec2,
|
|||
* @param arg1
|
||||
**/
|
||||
|
||||
void mtxf_set_matrix_gObjectList(s32 objectIndex, Mat4 transformMatrix) {
|
||||
struct ObjectInterpData2 {
|
||||
s32 objectIndex;
|
||||
f32 x, y;
|
||||
};
|
||||
struct ObjectInterpData2 prevObject2[OBJECT_LIST_SIZE] = { 0 };
|
||||
|
||||
s32 mtxf_set_matrix_gObjectList(s32 objectIndex, Mat4 transformMatrix) {
|
||||
f32 sinX;
|
||||
Object* object = &gObjectList[objectIndex];
|
||||
f32 sinY;
|
||||
|
|
@ -891,6 +901,26 @@ void mtxf_set_matrix_gObjectList(s32 objectIndex, Mat4 transformMatrix) {
|
|||
transformMatrix[1][3] = 0.0f;
|
||||
transformMatrix[2][3] = 0.0f;
|
||||
transformMatrix[3][3] = 1.0f;
|
||||
|
||||
// Search all recorded objects for the one we're drawing
|
||||
for (int i = 0; i < OBJECT_LIST_SIZE; i++) {
|
||||
if (objectIndex == prevObject2[i].objectIndex) {
|
||||
// Coincidence!
|
||||
// Skip drawing the object this frame if it warped to the other side of the screen
|
||||
if ((fabsf(object->pos[0] - prevObject2[i].x) > 20) || (fabsf(object->pos[1] - prevObject2[i].y) > 20)) {
|
||||
prevObject2[objectIndex].x = object->pos[0];
|
||||
prevObject2[objectIndex].y = object->pos[1];
|
||||
prevObject2[objectIndex].objectIndex = objectIndex;
|
||||
// printf("IDX: %d X: %f Y: %f Z: %f\n", objectIndex, object->pos[0], object->pos[1], object->pos[2]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
prevObject2[objectIndex].x = object->pos[0];
|
||||
prevObject2[objectIndex].y = object->pos[1];
|
||||
prevObject2[objectIndex].objectIndex = objectIndex;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UNUSED void mtxf_mult_first_column(Mat4 arg0, f32 arg1) {
|
||||
|
|
@ -917,6 +947,7 @@ void set_transform_matrix(Mat4 dest, Vec3f orientationVector, Vec3f positionVect
|
|||
Vec3f sp38;
|
||||
Vec3f sp2C;
|
||||
|
||||
FrameInterpolation_RecordSetTransformMatrix(dest, orientationVector, positionVector, rotationAngle, scaleFactor);
|
||||
vec3f_set_xyz(sp44, sins(rotationAngle), 0.0f, coss(rotationAngle));
|
||||
vec3f_normalize(orientationVector);
|
||||
vec3f_cross_product(sp38, orientationVector, sp44);
|
||||
|
|
@ -1059,7 +1090,9 @@ void rsp_set_matrix_transl_rot_scale(Vec3f arg0, Vec3f arg1, f32 arg2) {
|
|||
void rsp_set_matrix_gObjectList(s32 transformIndex) {
|
||||
Mat4 matrix;
|
||||
|
||||
mtxf_set_matrix_gObjectList(transformIndex, matrix);
|
||||
if (mtxf_set_matrix_gObjectList(transformIndex, matrix)) {
|
||||
return;
|
||||
}
|
||||
// convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], matrix);
|
||||
|
||||
// gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
#include <common_structs.h>
|
||||
#include "camera.h"
|
||||
|
||||
extern Mat4* gInterpolationMatrix;
|
||||
|
||||
/* Function Prototypes */
|
||||
|
||||
// Unused functions
|
||||
|
|
@ -74,15 +76,13 @@ void func_80042330_portrait(s32, s32, u16, f32, s16);
|
|||
void func_80042330_wide(s32, s32, u16, f32);
|
||||
void mtxf_set_matrix_transformation(Mat4, Vec3f, Vec3su, f32);
|
||||
void mtxf_set_matrix_scale_transl(Mat4, Vec3f, Vec3f, f32);
|
||||
void mtxf_set_matrix_gObjectList(s32, Mat4);
|
||||
void set_transform_matrix(Mat4, Vec3f, Vec3f, u16, f32);
|
||||
s32 mtxf_set_matrix_gObjectList(s32, Mat4);
|
||||
void set_transform_matrix(Mat4 dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle,
|
||||
f32 scaleFactor);
|
||||
void vec3f_rotate_x_y(Vec3f, Vec3f, Vec3s);
|
||||
void rsp_set_matrix_transformation(Vec3f, Vec3su, f32);
|
||||
void rsp_set_matrix_transformation_inverted_x_y_orientation(Vec3f, Vec3su, f32);
|
||||
void rsp_set_matrix_transl_rot_scale(Vec3f, Vec3f, f32);
|
||||
void rsp_set_matrix_gObjectList(s32);
|
||||
|
||||
/* This is where I'd put my static data, if I had any */
|
||||
extern s8 D_801658FE;
|
||||
|
||||
#endif // MATH_UTIL_2_H
|
||||
|
|
|
|||
|
|
@ -2528,12 +2528,15 @@ void func_80095574(void) {
|
|||
} else {
|
||||
debug_print_str2(0x000000AA, 0x00000064, "off");
|
||||
}
|
||||
if ((gCurrentCourseId >= (NUM_COURSES - 1)) || (gCurrentCourseId < 0)) {
|
||||
gCurrentCourseId = 0;
|
||||
}
|
||||
|
||||
// This reset is not necessary. It wraps around automatically.
|
||||
// if ((GetCourseIndex() >= (NUM_COURSES - 1)) || (GetCourseIndex() < 0)) {
|
||||
// gCurrentCourseId = 0;
|
||||
// }
|
||||
print_str_num(0x00000050, 0x0000006E, "map_number", GetCourseIndex());
|
||||
// This isn't functionally equivallent, but who cares.
|
||||
if (gCurrentCourseId < COURSE_TOADS_TURNPIKE) {
|
||||
|
||||
// Bump the text over by 1 character width when the track id becomes two digits (10, 11, 12 etc.)
|
||||
if (GetCourseIndex() < 10) {
|
||||
var_v0 = 0;
|
||||
} else {
|
||||
var_v0 = 8;
|
||||
|
|
@ -4889,7 +4892,7 @@ void func_8009CE64(s32 arg0) {
|
|||
gCCSelection = (s32) 1;
|
||||
switch (gNextDemoId) { /* switch 4 */
|
||||
case 0: /* switch 4 */
|
||||
SetCourseByClass(GetMarioRaceway());
|
||||
SelectMarioRaceway();
|
||||
CM_SetCup(GetFlowerCup());
|
||||
SetCupCursorPosition(COURSE_FOUR);
|
||||
gCurrentCourseId = 0;
|
||||
|
|
@ -4900,7 +4903,7 @@ void func_8009CE64(s32 arg0) {
|
|||
gModeSelection = 0;
|
||||
break;
|
||||
case 1: /* switch 4 */
|
||||
SetCourseByClass(GetLuigiRaceway());
|
||||
SelectLuigiRaceway();
|
||||
CM_SetCup(GetMushroomCup());
|
||||
SetCupCursorPosition(COURSE_ONE);
|
||||
gCurrentCourseId = (s16) 1;
|
||||
|
|
@ -4912,7 +4915,7 @@ void func_8009CE64(s32 arg0) {
|
|||
gModeSelection = 2;
|
||||
break;
|
||||
case 2: /* switch 4 */
|
||||
SetCourseByClass(GetKalimariDesert());
|
||||
SelectKalimariDesert();
|
||||
CM_SetCup(GetMushroomCup());
|
||||
SetCupCursorPosition(COURSE_FOUR);
|
||||
gCurrentCourseId = COURSE_KALIMARI_DESERT;
|
||||
|
|
@ -4923,7 +4926,7 @@ void func_8009CE64(s32 arg0) {
|
|||
gModeSelection = 0;
|
||||
break;
|
||||
case 3: /* switch 4 */
|
||||
SetCourseByClass(GetWarioStadium());
|
||||
SelectWarioStadium();
|
||||
CM_SetCup(GetStarCup());
|
||||
SetCupCursorPosition(COURSE_ONE);
|
||||
gCurrentCourseId = 0x000E;
|
||||
|
|
@ -4936,7 +4939,7 @@ void func_8009CE64(s32 arg0) {
|
|||
gModeSelection = (s32) 2;
|
||||
break;
|
||||
case 4: /* switch 4 */
|
||||
SetCourseByClass(GetBowsersCastle());
|
||||
SelectBowsersCastle();
|
||||
CM_SetCup(GetStarCup());
|
||||
SetCupCursorPosition(COURSE_FOUR);
|
||||
gCurrentCourseId = 2;
|
||||
|
|
@ -4947,7 +4950,7 @@ void func_8009CE64(s32 arg0) {
|
|||
gModeSelection = 0;
|
||||
break;
|
||||
case 5: /* switch 4 */
|
||||
SetCourseByClass(GetSherbetLand());
|
||||
SelectSherbetLand();
|
||||
CM_SetCup(GetFlowerCup());
|
||||
SetCupCursorPosition(COURSE_TWO);
|
||||
gCurrentCourseId = 0x000C;
|
||||
|
|
@ -5034,8 +5037,8 @@ void func_8009CE64(s32 arg0) {
|
|||
}
|
||||
}
|
||||
|
||||
if (GetCourse() == GetBlockFort() || GetCourse() == GetSkyscraper() || GetCourse() == GetDoubleDeck() ||
|
||||
GetCourse() == GetBigDonut()) {
|
||||
if (IsBlockFort() || IsSkyscraper() || IsDoubleDeck() ||
|
||||
IsBigDonut()) {
|
||||
|
||||
gModeSelection = BATTLE;
|
||||
if (gPlayerCountSelection1 == 1) {
|
||||
|
|
@ -8230,7 +8233,9 @@ void func_800A6034(MenuItem* arg0) {
|
|||
set_text_color(TEXT_BLUE_GREEN_RED_CYCLE_2);
|
||||
print_text1_center_mode_2(arg0->column + 0x41, arg0->row + 0xA0, text, 0, 0.85f, 1.0f);
|
||||
text = CM_GetProps()->Name;
|
||||
set_text_color((s32) gCurrentCourseId % 4);
|
||||
//! @warning this used to be gCurrentCourseId % 4
|
||||
// Hopefully this is equivallent.
|
||||
set_text_color((s32) GetCourseIndex() % 4);
|
||||
print_text1_center_mode_2(arg0->column + 0x41, arg0->row + 0xC3, text, 0, 0.65f, 0.85f);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2005,6 +2005,7 @@ void load_menu_states(s32 menuSelection) {
|
|||
CM_SetCup(GetBattleCup());
|
||||
// gCupSelection = BATTLE_CUP;
|
||||
D_800DC540 = 4;
|
||||
CM_SetCupIndex(BATTLE_CUP);
|
||||
gSubMenuSelection = SUB_MENU_MAP_SELECT_BATTLE_COURSE;
|
||||
} else {
|
||||
if (GetCup() == GetBattleCup()) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
**************************************************************************/
|
||||
|
||||
#include "libultra_internal.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
void guLookAtF(float mf[4][4], float xEye, float yEye, float zEye, float xAt, float yAt, float zAt, float xUp,
|
||||
float yUp, float zUp) {
|
||||
|
|
@ -75,5 +76,6 @@ void guLookAt(Mtx* m, float xEye, float yEye, float zEye, float xAt, float yAt,
|
|||
|
||||
guLookAtF(mf, xEye, yEye, zEye, xAt, yAt, zAt, xUp, yUp, zUp);
|
||||
|
||||
FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mf, m);
|
||||
guMtxF2L(mf, m);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "libultra_internal.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
void guOrthoF(float m[4][4], float left, float right, float bottom, float top, float near, float far, float scale) {
|
||||
int row;
|
||||
|
|
@ -19,7 +20,8 @@ void guOrthoF(float m[4][4], float left, float right, float bottom, float top, f
|
|||
}
|
||||
|
||||
void guOrtho(Mtx* m, float left, float right, float bottom, float top, float near, float far, float scale) {
|
||||
float sp28[4][4];
|
||||
guOrthoF(sp28, left, right, bottom, top, near, far, scale);
|
||||
guMtxF2L(sp28, m);
|
||||
float mf[4][4];
|
||||
guOrthoF(mf, left, right, bottom, top, near, far, scale);
|
||||
FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*) mf, m);
|
||||
guMtxF2L(mf, m);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "libultra_internal.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
void guPerspectiveF(float mf[4][4], u16* perspNorm, float fovy, float aspect, float near, float far, float scale) {
|
||||
float yscale;
|
||||
|
|
@ -36,5 +37,6 @@ void guPerspectiveF(float mf[4][4], u16* perspNorm, float fovy, float aspect, fl
|
|||
void guPerspective(Mtx* m, u16* perspNorm, float fovy, float aspect, float near, float far, float scale) {
|
||||
float mat[4][4];
|
||||
guPerspectiveF(mat, perspNorm, fovy, aspect, near, far, scale);
|
||||
FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mat, m);
|
||||
guMtxF2L(mat, m);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "libultra_internal.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
void guRotateF(float m[4][4], float a, float x, float y, float z) {
|
||||
float sin_a;
|
||||
|
|
@ -38,5 +39,6 @@ void guRotateF(float m[4][4], float a, float x, float y, float z) {
|
|||
void guRotate(Mtx* m, float a, float x, float y, float z) {
|
||||
float mf[4][4];
|
||||
guRotateF(mf, a, x, y, z);
|
||||
FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*) mf, m);
|
||||
guMtxF2L(mf, m);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "libultra_internal.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
void guScaleF(float mf[4][4], float x, float y, float z) {
|
||||
guMtxIdentF(mf);
|
||||
|
|
@ -11,5 +12,6 @@ void guScaleF(float mf[4][4], float x, float y, float z) {
|
|||
void guScale(Mtx* m, float x, float y, float z) {
|
||||
float mf[4][4];
|
||||
guScaleF(mf, x, y, z);
|
||||
FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*) mf, m);
|
||||
guMtxF2L(mf, m);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "libultra_internal.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
void guTranslateF(float m[4][4], float x, float y, float z) {
|
||||
guMtxIdentF(m);
|
||||
|
|
@ -10,5 +11,6 @@ void guTranslateF(float m[4][4], float x, float y, float z) {
|
|||
void guTranslate(Mtx* m, float x, float y, float z) {
|
||||
float mf[4][4];
|
||||
guTranslateF(mf, x, y, z);
|
||||
FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*) mf, m);
|
||||
guMtxF2L(mf, m);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1711,7 +1711,7 @@ void func_8002C11C(Player* player) {
|
|||
}
|
||||
|
||||
void func_8002C17C(Player* player, s8 playerId) {
|
||||
if (GetCourse() == GetYoshiValley()) {
|
||||
if (IsYoshiValley()) {
|
||||
if ((player->collision.surfaceDistance[2] >= 600.0f) && (D_80165330[playerId] == 0)) {
|
||||
D_80165330[playerId] = 1;
|
||||
gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId];
|
||||
|
|
@ -1724,7 +1724,7 @@ void func_8002C17C(Player* player, s8 playerId) {
|
|||
D_80165330[playerId] = 0;
|
||||
}
|
||||
}
|
||||
} else if (GetCourse() == GetFrappeSnowland()) {
|
||||
} else if (IsFrappeSnowland()) {
|
||||
if ((player->surfaceType == SNOW_OFFROAD) && (D_80165330[playerId] == 0)) {
|
||||
D_80165330[playerId] = 1;
|
||||
gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId];
|
||||
|
|
@ -1734,7 +1734,7 @@ void func_8002C17C(Player* player, s8 playerId) {
|
|||
gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId];
|
||||
gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId];
|
||||
}
|
||||
} else if (GetCourse() == GetRoyalRaceway()) {
|
||||
} else if (IsRoyalRaceway()) {
|
||||
if (((player->effects & BOOST_RAMP_ASPHALT_EFFECT) != 0) && (D_80165330[playerId] == 0)) {
|
||||
D_80165330[playerId] = 1;
|
||||
gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId];
|
||||
|
|
@ -1744,7 +1744,7 @@ void func_8002C17C(Player* player, s8 playerId) {
|
|||
gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId];
|
||||
gCopyPathIndexByPlayerId[playerId] = gPathIndexByPlayerId[playerId];
|
||||
}
|
||||
} else if (GetCourse() == GetRainbowRoad()) {
|
||||
} else if (IsRainbowRoad()) {
|
||||
if ((player->collision.surfaceDistance[2] >= 600.0f) && (D_80165330[playerId] == 0)) {
|
||||
D_80165330[playerId] = 1;
|
||||
gCopyNearestWaypointByPlayerId[playerId] = gNearestWaypointByPlayerId[playerId];
|
||||
|
|
@ -1778,9 +1778,9 @@ void func_8002C4F8(Player* player, s8 arg1) {
|
|||
if ((player->unk_0DE & 4) != 4) {
|
||||
player->unk_0DE |= 8;
|
||||
player->unk_0DE |= 4;
|
||||
if ((GetCourse() != GetKoopaTroopaBeach()) && (GetCourse() != GetSkyscraper()) &&
|
||||
(GetCourse() != GetRainbowRoad()) && ((player->type & PLAYER_HUMAN) == PLAYER_HUMAN)) {
|
||||
if ((GetCourse() == GetBowsersCastle()) || (GetCourse() == GetBigDonut())) {
|
||||
if ((!IsKoopaTroopaBeach()) && (!IsSkyscraper()) &&
|
||||
(!IsRainbowRoad()) && ((player->type & PLAYER_HUMAN) == PLAYER_HUMAN)) {
|
||||
if ((IsBowsersCastle()) || (IsBigDonut())) {
|
||||
func_800C9060((u8) arg1, 0x1900801CU);
|
||||
} else {
|
||||
func_800C9060((u8) arg1, 0x19008008U);
|
||||
|
|
@ -1788,8 +1788,8 @@ void func_8002C4F8(Player* player, s8 arg1) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if ((GetCourse() == GetKoopaTroopaBeach()) || (GetCourse() == GetSkyscraper()) ||
|
||||
(GetCourse() == GetRainbowRoad())) {
|
||||
if ((IsKoopaTroopaBeach()) || (IsSkyscraper()) ||
|
||||
(IsRainbowRoad())) {
|
||||
player->unk_0DE &= ~0x000C;
|
||||
}
|
||||
if ((player->boundingBoxSize < (D_801652A0[arg1] - player->pos[1])) &&
|
||||
|
|
@ -2254,7 +2254,7 @@ void func_8002D268(Player* player, UNUSED Camera* camera, s8 screenId, s8 player
|
|||
player->unk_DB4.unkC = 1.5f;
|
||||
if (((player->type & PLAYER_HUMAN) == PLAYER_HUMAN) &&
|
||||
((player->type & PLAYER_INVISIBLE_OR_BOMB) != PLAYER_INVISIBLE_OR_BOMB)) {
|
||||
if (((player->unk_0C2 < 0xB) && (player->unk_0C2 >= 4)) && (GetCourse() == GetBowsersCastle())) {
|
||||
if (((player->unk_0C2 < 0xB) && (player->unk_0C2 >= 4)) && (IsBowsersCastle())) {
|
||||
func_800CADD0((u8) playerId, player->unk_0C2 / 14.0f);
|
||||
} else {
|
||||
func_800CADD0((u8) playerId, player->unk_0C2 / 25.0f);
|
||||
|
|
|
|||
|
|
@ -24,9 +24,10 @@
|
|||
#include "window/gui/resource/FontFactory.h"
|
||||
#include "SpaghettiGui.h"
|
||||
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
#include <graphic/Fast3D/Fast3dWindow.h>
|
||||
#include <graphic/Fast3D/interpreter.h>
|
||||
//#include <Fast3D/gfx_rendering_api.h>
|
||||
// #include <Fast3D/gfx_rendering_api.h>
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <utility>
|
||||
|
|
@ -51,9 +52,9 @@ float gInterpolationStep = 0.0f;
|
|||
|
||||
Fast::Interpreter* GetInterpreter() {
|
||||
return static_pointer_cast<Fast::Fast3dWindow>(Ship::Context::GetInstance()->GetWindow())
|
||||
->GetInterpreterWeak()
|
||||
.lock()
|
||||
.get();
|
||||
->GetInterpreterWeak()
|
||||
.lock()
|
||||
.get();
|
||||
}
|
||||
|
||||
GameEngine* GameEngine::Instance;
|
||||
|
|
@ -62,7 +63,7 @@ GameEngine::GameEngine() {
|
|||
|
||||
const std::string main_path = Ship::Context::GetPathRelativeToAppDirectory("mk64.o2r");
|
||||
const std::string assets_path = Ship::Context::LocateFileAcrossAppDirs("spaghetti.o2r");
|
||||
|
||||
|
||||
std::vector<std::string> archiveFiles;
|
||||
|
||||
#ifdef __SWITCH__
|
||||
|
|
@ -70,7 +71,6 @@ GameEngine::GameEngine() {
|
|||
Ship::Switch::Init(Ship::PostInitPhase);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
AllocConsole();
|
||||
#endif
|
||||
|
|
@ -79,7 +79,7 @@ GameEngine::GameEngine() {
|
|||
archiveFiles.push_back(main_path);
|
||||
} else {
|
||||
if (ShowYesNoBox("No O2R Files", "No O2R files found. Generate one now?") == IDYES) {
|
||||
if(!GenAssetFile()){
|
||||
if (!GenAssetFile()) {
|
||||
ShowMessage("Error", "An error occured, no O2R file was generated.\n\nExiting...");
|
||||
exit(1);
|
||||
} else {
|
||||
|
|
@ -106,11 +106,11 @@ GameEngine::GameEngine() {
|
|||
}
|
||||
}
|
||||
|
||||
this->context =
|
||||
Ship::Context::CreateUninitializedInstance("Spaghetti Kart", "spaghettify", "spaghettify.cfg.json");
|
||||
this->context = Ship::Context::CreateUninitializedInstance("Spaghetti Kart", "spaghettify", "spaghettify.cfg.json");
|
||||
|
||||
this->context->InitConfiguration(); // without this line InitConsoleVariables fails at Config::Reload()
|
||||
this->context->InitConsoleVariables(); // without this line the controldeck constructor failes in ShipDeviceIndexMappingManager::UpdateControllerNamesFromConfig()
|
||||
this->context->InitConfiguration(); // without this line InitConsoleVariables fails at Config::Reload()
|
||||
this->context->InitConsoleVariables(); // without this line the controldeck constructor failes in
|
||||
// ShipDeviceIndexMappingManager::UpdateControllerNamesFromConfig()
|
||||
|
||||
auto controlDeck = std::make_shared<LUS::ControlDeck>();
|
||||
|
||||
|
|
@ -120,8 +120,8 @@ GameEngine::GameEngine() {
|
|||
auto gui = std::make_shared<Ship::SpaghettiGui>(std::vector<std::shared_ptr<Ship::GuiWindow>>({}));
|
||||
auto wnd = std::make_shared<Fast::Fast3dWindow>(gui);
|
||||
|
||||
//auto wnd = std::make_shared<Fast::Fast3dWindow>(std::vector<std::shared_ptr<Ship::GuiWindow>>({}));
|
||||
//auto wnd = std::dynamic_pointer_cast<Fast::Fast3dWindow>(Ship::Context::GetInstance()->GetWindow());
|
||||
// auto wnd = std::make_shared<Fast::Fast3dWindow>(std::vector<std::shared_ptr<Ship::GuiWindow>>({}));
|
||||
// auto wnd = std::dynamic_pointer_cast<Fast::Fast3dWindow>(Ship::Context::GetInstance()->GetWindow());
|
||||
|
||||
this->context->Init(archiveFiles, {}, 3, { 26800, 512, 1100 }, wnd, controlDeck);
|
||||
|
||||
|
|
@ -158,8 +158,9 @@ GameEngine::GameEngine() {
|
|||
loader->RegisterResourceFactory(std::make_shared<Fast::ResourceFactoryXMLVertexV0>(), RESOURCE_FORMAT_XML, "Vertex",
|
||||
static_cast<uint32_t>(Fast::ResourceType::Vertex), 0);
|
||||
|
||||
loader->RegisterResourceFactory(std::make_shared<Fast::ResourceFactoryBinaryDisplayListV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"DisplayList", static_cast<uint32_t>(Fast::ResourceType::DisplayList), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<Fast::ResourceFactoryBinaryDisplayListV0>(),
|
||||
RESOURCE_FORMAT_BINARY, "DisplayList",
|
||||
static_cast<uint32_t>(Fast::ResourceType::DisplayList), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<Fast::ResourceFactoryXMLDisplayListV0>(), RESOURCE_FORMAT_XML,
|
||||
"DisplayList", static_cast<uint32_t>(Fast::ResourceType::DisplayList), 0);
|
||||
|
||||
|
|
@ -178,24 +179,21 @@ GameEngine::GameEngine() {
|
|||
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryTrackSectionsV0>(),
|
||||
RESOURCE_FORMAT_BINARY, "TrackSections",
|
||||
static_cast<uint32_t>(MK64::ResourceType::TrackSection), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryXMLTrackSectionsV0>(),
|
||||
RESOURCE_FORMAT_XML, "TrackSections",
|
||||
static_cast<uint32_t>(MK64::ResourceType::TrackSection), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryXMLTrackSectionsV0>(), RESOURCE_FORMAT_XML,
|
||||
"TrackSections", static_cast<uint32_t>(MK64::ResourceType::TrackSection), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryTrackWaypointsV0>(),
|
||||
RESOURCE_FORMAT_BINARY, "Waypoints",
|
||||
static_cast<uint32_t>(MK64::ResourceType::Waypoints), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryXMLTrackWaypointsV0>(),
|
||||
RESOURCE_FORMAT_XML, "Paths",
|
||||
static_cast<uint32_t>(MK64::ResourceType::Waypoints), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryXMLTrackWaypointsV0>(), RESOURCE_FORMAT_XML,
|
||||
"Paths", static_cast<uint32_t>(MK64::ResourceType::Waypoints), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryActorSpawnDataV0>(),
|
||||
RESOURCE_FORMAT_BINARY, "SpawnData",
|
||||
static_cast<uint32_t>(MK64::ResourceType::SpawnData), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryUnkActorSpawnDataV0>(),
|
||||
RESOURCE_FORMAT_BINARY, "UnkSpawnData",
|
||||
static_cast<uint32_t>(MK64::ResourceType::UnkSpawnData), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryMinimapV0>(),
|
||||
RESOURCE_FORMAT_BINARY, "Minimap",
|
||||
static_cast<uint32_t>(MK64::ResourceType::Minimap), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryMinimapV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"Minimap", static_cast<uint32_t>(MK64::ResourceType::Minimap), 0);
|
||||
|
||||
fontMono = CreateFontWithSize(16.0f, "fonts/Inconsolata-Regular.ttf");
|
||||
fontMonoLarger = CreateFontWithSize(20.0f, "fonts/Inconsolata-Regular.ttf");
|
||||
|
|
@ -216,15 +214,38 @@ bool GameEngine::GenAssetFile() {
|
|||
|
||||
auto game = extractor->ValidateChecksum();
|
||||
if (!game.has_value()) {
|
||||
ShowMessage("Unsupported ROM", "The provided ROM is not supported.\n\nCheck the readme for a list of supported versions.");
|
||||
ShowMessage("Unsupported ROM",
|
||||
"The provided ROM is not supported.\n\nCheck the readme for a list of supported versions.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ShowMessage(("Found " + game.value()).c_str(), "The extraction process will now begin.\n\nThis may take a few minutes.", SDL_MESSAGEBOX_INFORMATION);
|
||||
ShowMessage(("Found " + game.value()).c_str(),
|
||||
"The extraction process will now begin.\n\nThis may take a few minutes.", SDL_MESSAGEBOX_INFORMATION);
|
||||
|
||||
return extractor->GenerateOTR();
|
||||
}
|
||||
|
||||
uint32_t GameEngine::GetInterpolationFPS() {
|
||||
if (CVarGetInteger("gMatchRefreshRate", 0)) {
|
||||
return Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate();
|
||||
|
||||
} else if (CVarGetInteger("gVsyncEnabled", 1) ||
|
||||
!Ship::Context::GetInstance()->GetWindow()->CanDisableVerticalSync()) {
|
||||
return std::min<uint32_t>(Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(),
|
||||
CVarGetInteger("gInterpolationFPS", 30));
|
||||
}
|
||||
|
||||
return CVarGetInteger("gInterpolationFPS", 30);
|
||||
}
|
||||
|
||||
uint32_t GameEngine::GetInterpolationFrameCount() {
|
||||
return ceil((float) GetInterpolationFPS() / (60.0f / 2 /*gVIsPerFrame*/));
|
||||
}
|
||||
|
||||
extern "C" uint32_t GameEngine_GetInterpolationFrameCount() {
|
||||
return GameEngine::GetInterpolationFrameCount();
|
||||
}
|
||||
|
||||
void GameEngine::ShowMessage(const char* title, const char* message, SDL_MessageBoxFlags type) {
|
||||
#if defined(__SWITCH__)
|
||||
SPDLOG_ERROR(message);
|
||||
|
|
@ -275,6 +296,9 @@ void GameEngine::Destroy() {
|
|||
#ifdef __SWITCH__
|
||||
Ship::Switch::Exit();
|
||||
#endif
|
||||
GameUI::Destroy();
|
||||
delete GameEngine::Instance;
|
||||
GameEngine::Instance = nullptr;
|
||||
}
|
||||
|
||||
bool ShouldClearTextureCacheAtEndOfFrame = false;
|
||||
|
|
@ -301,16 +325,24 @@ void GameEngine::StartFrame() const {
|
|||
// Instance->context->GetWindow()->MainLoop(run_one_game_iter);
|
||||
// }
|
||||
|
||||
void GameEngine::RunCommands(Gfx* Commands) {
|
||||
void GameEngine::RunCommands(Gfx* Commands, const std::vector<std::unordered_map<Mtx*, MtxF>>& mtx_replacements) {
|
||||
auto wnd = std::dynamic_pointer_cast<Fast::Fast3dWindow>(Ship::Context::GetInstance()->GetWindow());
|
||||
|
||||
if (nullptr == wnd) {
|
||||
if (wnd == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto interpreter = wnd->GetInterpreterWeak().lock().get();
|
||||
|
||||
// Process window events for resize, mouse, keyboard events
|
||||
wnd->HandleEvents();
|
||||
|
||||
wnd->DrawAndRunGraphicsCommands(Commands, {});
|
||||
interpreter->mInterpolationIndex = 0;
|
||||
|
||||
for (const auto& m : mtx_replacements) {
|
||||
wnd->DrawAndRunGraphicsCommands(Commands, m);
|
||||
interpreter->mInterpolationIndex++;
|
||||
}
|
||||
|
||||
bool curAltAssets = CVarGetInteger("gEnhancements.Mods.AlternateAssets", 0);
|
||||
if (prevAltAssets != curAltAssets) {
|
||||
|
|
@ -321,12 +353,49 @@ void GameEngine::RunCommands(Gfx* Commands) {
|
|||
}
|
||||
|
||||
void GameEngine::ProcessGfxCommands(Gfx* commands) {
|
||||
std::vector<std::unordered_map<Mtx*, MtxF>> mtx_replacements;
|
||||
int target_fps = GameEngine::Instance->GetInterpolationFPS();
|
||||
if (CVarGetInteger("gModifyInterpolationTargetFPS", 0)) {
|
||||
target_fps = CVarGetInteger("gInterpolationTargetFPS", 60);
|
||||
}
|
||||
static int last_fps;
|
||||
static int last_update_rate;
|
||||
static int time;
|
||||
int fps = target_fps;
|
||||
int original_fps = 60 / 2 /*gVIsPerFrame*/;
|
||||
|
||||
if (target_fps == 30 || original_fps > target_fps) {
|
||||
fps = original_fps;
|
||||
}
|
||||
|
||||
if (last_fps != fps || last_update_rate != 2 /*gVIsPerFrame*/) {
|
||||
time = 0;
|
||||
}
|
||||
|
||||
// time_base = fps * original_fps (one second)
|
||||
int next_original_frame = fps;
|
||||
|
||||
while (time + original_fps <= next_original_frame) {
|
||||
time += original_fps;
|
||||
if (time != next_original_frame) {
|
||||
mtx_replacements.push_back(FrameInterpolation_Interpolate((float) time / next_original_frame));
|
||||
} else {
|
||||
mtx_replacements.emplace_back();
|
||||
}
|
||||
}
|
||||
// printf("mtxf size: %d\n", mtx_replacements.size());
|
||||
|
||||
time -= fps;
|
||||
|
||||
auto wnd = std::dynamic_pointer_cast<Fast::Fast3dWindow>(Ship::Context::GetInstance()->GetWindow());
|
||||
if (wnd != nullptr) {
|
||||
wnd->SetTargetFps(CVarGetInteger("gInterpolationFPS", 30));
|
||||
wnd->SetTargetFps(GetInterpolationFPS());
|
||||
wnd->SetMaximumFrameLatency(1);
|
||||
}
|
||||
RunCommands(commands);
|
||||
RunCommands(commands, mtx_replacements);
|
||||
|
||||
last_fps = fps;
|
||||
last_update_rate = 2;
|
||||
}
|
||||
|
||||
// Audio
|
||||
|
|
@ -444,7 +513,9 @@ ImFont* GameEngine::CreateFontWithSize(float size, std::string fontPath) {
|
|||
initData->Path = fontPath;
|
||||
std::shared_ptr<Ship::Font> fontData = std::static_pointer_cast<Ship::Font>(
|
||||
Ship::Context::GetInstance()->GetResourceManager()->LoadResource(fontPath, false, initData));
|
||||
font = mImGuiIo->Fonts->AddFontFromMemoryTTF(fontData->Data, fontData->DataSize, size);
|
||||
char* fontDataPtr = (char*) malloc(fontData->DataSize);
|
||||
memcpy(fontDataPtr, fontData->Data, fontData->DataSize);
|
||||
font = mImGuiIo->Fonts->AddFontFromMemoryTTF(fontDataPtr, fontData->DataSize, size);
|
||||
}
|
||||
// FontAwesome fonts need to have their sizes reduced by 2.0f/3.0f in order to align correctly
|
||||
float iconFontSize = size * 2.0f / 3.0f;
|
||||
|
|
@ -635,14 +706,14 @@ extern "C" int16_t OTRGetRectDimensionFromRightEdge(float v) {
|
|||
|
||||
/**
|
||||
* Centers an item in a given area.
|
||||
*
|
||||
*
|
||||
* Adds the number of extended screen pixels to the location to center.
|
||||
* This allows stretching the game window really wide, and the item will stay in-place.
|
||||
*
|
||||
*
|
||||
* This is not for centering in the direct center of the screen.
|
||||
*
|
||||
*
|
||||
* How to use:
|
||||
*
|
||||
*
|
||||
* s32 center = OTRCalculateCenterOfAreaFromRightEdge((SCREEN_WIDTH / 4) + (SCREEN_WIDTH / 2));
|
||||
* x = center - (texWidth / 2)
|
||||
* x2 = center + (texWidth / 2)
|
||||
|
|
|
|||
|
|
@ -59,8 +59,10 @@ class GameEngine {
|
|||
static void EndAudioFrame();
|
||||
static void AudioExit();
|
||||
|
||||
static uint32_t GetInterpolationFPS();
|
||||
static uint32_t GetInterpolationFrameCount();
|
||||
void StartFrame() const;
|
||||
static void RunCommands(Gfx* Commands);
|
||||
static void RunCommands(Gfx* Commands, const std::vector<std::unordered_map<Mtx*, MtxF>>& mtx_replacements);
|
||||
void ProcessFrame(void (*run_one_game_iter)()) const;
|
||||
static void Destroy();
|
||||
static void ProcessGfxCommands(Gfx* commands);
|
||||
|
|
|
|||
|
|
@ -69,29 +69,7 @@ extern "C" void Timer_Update();
|
|||
// Create the world instance
|
||||
World gWorldInstance;
|
||||
|
||||
MarioRaceway* gMarioRaceway;
|
||||
ChocoMountain* gChocoMountain;
|
||||
BowsersCastle* gBowsersCastle;
|
||||
BansheeBoardwalk* gBansheeBoardwalk;
|
||||
YoshiValley* gYoshiValley;
|
||||
FrappeSnowland* gFrappeSnowland;
|
||||
KoopaTroopaBeach* gKoopaTroopaBeach;
|
||||
RoyalRaceway* gRoyalRaceway;
|
||||
LuigiRaceway* gLuigiRaceway;
|
||||
MooMooFarm* gMooMooFarm;
|
||||
ToadsTurnpike* gToadsTurnpike;
|
||||
KalimariDesert* gKalimariDesert;
|
||||
SherbetLand* gSherbetLand;
|
||||
RainbowRoad* gRainbowRoad;
|
||||
WarioStadium* gWarioStadium;
|
||||
BlockFort* gBlockFort;
|
||||
Skyscraper* gSkyscraper;
|
||||
DoubleDeck* gDoubleDeck;
|
||||
DKJungle* gDkJungle;
|
||||
BigDonut* gBigDonut;
|
||||
PodiumCeremony* gPodiumCeremony;
|
||||
Harbour* gHarbour;
|
||||
TestCourse* gTestCourse;
|
||||
std::unique_ptr<PodiumCeremony> gPodiumCeremony;
|
||||
|
||||
Cup* gMushroomCup;
|
||||
Cup* gFlowerCup;
|
||||
|
|
@ -108,65 +86,52 @@ Editor::Editor gEditor;
|
|||
s32 gTrophyIndex = NULL;
|
||||
|
||||
void CustomEngineInit() {
|
||||
|
||||
gMarioRaceway = new MarioRaceway();
|
||||
gChocoMountain = new ChocoMountain();
|
||||
gBowsersCastle = new BowsersCastle();
|
||||
gBansheeBoardwalk = new BansheeBoardwalk();
|
||||
gYoshiValley = new YoshiValley();
|
||||
gFrappeSnowland = new FrappeSnowland();
|
||||
gKoopaTroopaBeach = new KoopaTroopaBeach();
|
||||
gRoyalRaceway = new RoyalRaceway();
|
||||
gLuigiRaceway = new LuigiRaceway();
|
||||
gMooMooFarm = new MooMooFarm();
|
||||
gToadsTurnpike = new ToadsTurnpike();
|
||||
gKalimariDesert = new KalimariDesert();
|
||||
gSherbetLand = new SherbetLand();
|
||||
gRainbowRoad = new RainbowRoad();
|
||||
gWarioStadium = new WarioStadium();
|
||||
gBlockFort = new BlockFort();
|
||||
gSkyscraper = new Skyscraper();
|
||||
gDoubleDeck = new DoubleDeck();
|
||||
gDkJungle = new DKJungle();
|
||||
gBigDonut = new BigDonut();
|
||||
gPodiumCeremony = new PodiumCeremony();
|
||||
gHarbour = new Harbour();
|
||||
gTestCourse = new TestCourse();
|
||||
|
||||
/* Add all courses to the global course list */
|
||||
gWorldInstance.AddCourse(gMarioRaceway);
|
||||
gWorldInstance.AddCourse(gChocoMountain);
|
||||
gWorldInstance.AddCourse(gBowsersCastle);
|
||||
gWorldInstance.AddCourse(gBansheeBoardwalk);
|
||||
gWorldInstance.AddCourse(gYoshiValley);
|
||||
gWorldInstance.AddCourse(gFrappeSnowland);
|
||||
gWorldInstance.AddCourse(gKoopaTroopaBeach);
|
||||
gWorldInstance.AddCourse(gRoyalRaceway);
|
||||
gWorldInstance.AddCourse(gLuigiRaceway);
|
||||
gWorldInstance.AddCourse(gMooMooFarm);
|
||||
gWorldInstance.AddCourse(gToadsTurnpike);
|
||||
gWorldInstance.AddCourse(gKalimariDesert);
|
||||
gWorldInstance.AddCourse(gSherbetLand);
|
||||
gWorldInstance.AddCourse(gRainbowRoad);
|
||||
gWorldInstance.AddCourse(gWarioStadium);
|
||||
gWorldInstance.AddCourse(gBlockFort);
|
||||
gWorldInstance.AddCourse(gSkyscraper);
|
||||
gWorldInstance.AddCourse(gDoubleDeck);
|
||||
gWorldInstance.AddCourse(gDkJungle);
|
||||
gWorldInstance.AddCourse(gBigDonut);
|
||||
gWorldInstance.AddCourse(gHarbour);
|
||||
gWorldInstance.AddCourse(gTestCourse);
|
||||
Course* mario = gWorldInstance.AddCourse(std::make_unique<MarioRaceway>());
|
||||
Course* choco = gWorldInstance.AddCourse(std::make_unique<ChocoMountain>());
|
||||
Course* bowser = gWorldInstance.AddCourse(std::make_unique<BowsersCastle>());
|
||||
Course* banshee = gWorldInstance.AddCourse(std::make_unique<BansheeBoardwalk>());
|
||||
Course* yoshi = gWorldInstance.AddCourse(std::make_unique<YoshiValley>());
|
||||
Course* frappe = gWorldInstance.AddCourse(std::make_unique<FrappeSnowland>());
|
||||
Course* koopa = gWorldInstance.AddCourse(std::make_unique<KoopaTroopaBeach>());
|
||||
Course* royal = gWorldInstance.AddCourse(std::make_unique<RoyalRaceway>());
|
||||
Course* luigi = gWorldInstance.AddCourse(std::make_unique<LuigiRaceway>());
|
||||
Course* mooMoo = gWorldInstance.AddCourse(std::make_unique<MooMooFarm>());
|
||||
Course* toads = gWorldInstance.AddCourse(std::make_unique<ToadsTurnpike>());
|
||||
Course* kalimari = gWorldInstance.AddCourse(std::make_unique<KalimariDesert>());
|
||||
Course* sherbet = gWorldInstance.AddCourse(std::make_unique<SherbetLand>());
|
||||
Course* rainbow = gWorldInstance.AddCourse(std::make_unique<RainbowRoad>());
|
||||
Course* wario = gWorldInstance.AddCourse(std::make_unique<WarioStadium>());
|
||||
Course* block = gWorldInstance.AddCourse(std::make_unique<BlockFort>());
|
||||
Course* skyscraper = gWorldInstance.AddCourse(std::make_unique<Skyscraper>());
|
||||
Course* doubleDeck = gWorldInstance.AddCourse(std::make_unique<DoubleDeck>());
|
||||
Course* dkJungle = gWorldInstance.AddCourse(std::make_unique<DKJungle>());
|
||||
Course* bigDonut = gWorldInstance.AddCourse(std::make_unique<BigDonut>());
|
||||
Course* harbour = gWorldInstance.AddCourse(std::make_unique<Harbour>());
|
||||
Course* testCourse = gWorldInstance.AddCourse(std::make_unique<TestCourse>());
|
||||
|
||||
gMushroomCup = new Cup("mk:mushroom_cup", "mushroom cup",
|
||||
std::vector<Course*>{ gLuigiRaceway, gMooMooFarm, gKoopaTroopaBeach, gKalimariDesert });
|
||||
gFlowerCup = new Cup("mk:flower_cup", "flower cup",
|
||||
std::vector<Course*>{ gToadsTurnpike, gFrappeSnowland, gChocoMountain, gMarioRaceway });
|
||||
gStarCup = new Cup("mk:star_cup", "star cup",
|
||||
std::vector<Course*>{ gWarioStadium, gSherbetLand, gRoyalRaceway, gBowsersCastle });
|
||||
gSpecialCup = new Cup("mk:special_cup", "special cup",
|
||||
std::vector<Course*>{ gDkJungle, gYoshiValley, gBansheeBoardwalk, gRainbowRoad });
|
||||
gBattleCup =
|
||||
new Cup("mk:battle_cup", "battle", std::vector<Course*>{ gBigDonut, gBlockFort, gDoubleDeck, gSkyscraper });
|
||||
gPodiumCeremony = std::make_unique<PodiumCeremony>();
|
||||
|
||||
// Construct cups with vectors of Course* (non-owning references)
|
||||
gMushroomCup = new Cup("mk:mushroom_cup", "Mushroom Cup", {
|
||||
luigi, mooMoo, koopa, kalimari
|
||||
});
|
||||
|
||||
gFlowerCup = new Cup("mk:flower_cup", "Flower Cup", {
|
||||
toads, frappe, choco, mario
|
||||
});
|
||||
|
||||
gStarCup = new Cup("mk:star_cup", "Star Cup", {
|
||||
wario, sherbet, royal, bowser
|
||||
});
|
||||
|
||||
gSpecialCup = new Cup("mk:special_cup", "Special Cup", {
|
||||
dkJungle, yoshi, banshee, rainbow
|
||||
});
|
||||
|
||||
gBattleCup = new Cup("mk:battle_cup", "Battle Cup", {
|
||||
bigDonut, block, doubleDeck, skyscraper
|
||||
});
|
||||
|
||||
/* Instantiate Cups */
|
||||
gWorldInstance.AddCup(gMushroomCup);
|
||||
|
|
@ -176,7 +141,7 @@ void CustomEngineInit() {
|
|||
gWorldInstance.AddCup(gBattleCup);
|
||||
|
||||
/* Set default course; mario raceway */
|
||||
gWorldInstance.CurrentCourse = gMarioRaceway;
|
||||
SelectMarioRaceway();
|
||||
gWorldInstance.CurrentCup = gMushroomCup;
|
||||
gWorldInstance.CurrentCup->CursorPosition = 3;
|
||||
gWorldInstance.CupIndex = 0;
|
||||
|
|
@ -198,6 +163,14 @@ void CustomEngineInit() {
|
|||
// gModelLoader.Load();
|
||||
}
|
||||
|
||||
void CustomEngineDestroy() {
|
||||
delete gMushroomCup;
|
||||
delete gFlowerCup;
|
||||
delete gStarCup;
|
||||
delete gSpecialCup;
|
||||
delete gBattleCup;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
void HM_InitIntro() {
|
||||
|
|
@ -244,6 +217,10 @@ u32 GetCupIndex(void) {
|
|||
return gWorldInstance.GetCupIndex();
|
||||
}
|
||||
|
||||
void CM_SetCupIndex(size_t index) {
|
||||
gWorldInstance.SetCupIndex(index);
|
||||
}
|
||||
|
||||
const char* GetCupName(void) {
|
||||
return gWorldInstance.CurrentCup->Name;
|
||||
}
|
||||
|
|
@ -275,7 +252,7 @@ void SetCourseById(s32 course) {
|
|||
return;
|
||||
}
|
||||
gWorldInstance.CourseIndex = course;
|
||||
gWorldInstance.CurrentCourse = gWorldInstance.Courses[gWorldInstance.CourseIndex];
|
||||
gWorldInstance.CurrentCourse = gWorldInstance.Courses[gWorldInstance.CourseIndex].get();
|
||||
}
|
||||
|
||||
void CM_VehicleCollision(s32 playerId, Player* player) {
|
||||
|
|
@ -394,10 +371,11 @@ void CM_BeginPlay() {
|
|||
|
||||
if (course) {
|
||||
// Do not spawn finishline in credits or battle mode. And if bSpawnFinishline.
|
||||
if ((gGamestate != CREDITS_SEQUENCE) && (gGamestate != BATTLE) && (course->bSpawnFinishline)) {
|
||||
gWorldInstance.AddActor(new AFinishline(course->FinishlineSpawnPoint));
|
||||
if ((gGamestate != CREDITS_SEQUENCE) && (gModeSelection != BATTLE)) {
|
||||
if (course->bSpawnFinishline) {
|
||||
gWorldInstance.AddActor(new AFinishline(course->FinishlineSpawnPoint));
|
||||
}
|
||||
}
|
||||
|
||||
gEditor.AddLight("Sun", nullptr, D_800DC610[1].l->l.dir);
|
||||
|
||||
course->BeginPlay();
|
||||
|
|
@ -723,89 +701,51 @@ f32 CM_GetWaterLevel(Vec3f pos, Collision* collision) {
|
|||
return gWorldInstance.CurrentCourse->GetWaterLevel(fPos, collision);
|
||||
}
|
||||
|
||||
void* GetMarioRaceway(void) {
|
||||
return gMarioRaceway;
|
||||
}
|
||||
// clang-format off
|
||||
bool IsMarioRaceway() { return dynamic_cast<MarioRaceway*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsLuigiRaceway() { return dynamic_cast<LuigiRaceway*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsChocoMountain() { return dynamic_cast<ChocoMountain*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsBowsersCastle() { return dynamic_cast<BowsersCastle*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsBansheeBoardwalk() { return dynamic_cast<BansheeBoardwalk*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsYoshiValley() { return dynamic_cast<YoshiValley*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsFrappeSnowland() { return dynamic_cast<FrappeSnowland*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsKoopaTroopaBeach() { return dynamic_cast<KoopaTroopaBeach*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsRoyalRaceway() { return dynamic_cast<RoyalRaceway*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsMooMooFarm() { return dynamic_cast<MooMooFarm*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsToadsTurnpike() { return dynamic_cast<ToadsTurnpike*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsKalimariDesert() { return dynamic_cast<KalimariDesert*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsSherbetLand() { return dynamic_cast<SherbetLand*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsRainbowRoad() { return dynamic_cast<RainbowRoad*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsWarioStadium() { return dynamic_cast<WarioStadium*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsBlockFort() { return dynamic_cast<BlockFort*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsSkyscraper() { return dynamic_cast<Skyscraper*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsDoubleDeck() { return dynamic_cast<DoubleDeck*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsDkJungle() { return dynamic_cast<DKJungle*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsBigDonut() { return dynamic_cast<BigDonut*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
bool IsPodiumCeremony() { return dynamic_cast<PodiumCeremony*>(gWorldInstance.CurrentCourse) != nullptr; }
|
||||
|
||||
void* GetLuigiRaceway(void) {
|
||||
return gLuigiRaceway;
|
||||
}
|
||||
|
||||
void* GetChocoMountain(void) {
|
||||
return gChocoMountain;
|
||||
}
|
||||
|
||||
void* GetBowsersCastle(void) {
|
||||
return gBowsersCastle;
|
||||
}
|
||||
|
||||
void* GetBansheeBoardwalk(void) {
|
||||
return gBansheeBoardwalk;
|
||||
}
|
||||
|
||||
void* GetYoshiValley(void) {
|
||||
return gYoshiValley;
|
||||
}
|
||||
|
||||
void* GetFrappeSnowland(void) {
|
||||
return gFrappeSnowland;
|
||||
}
|
||||
|
||||
void* GetKoopaTroopaBeach(void) {
|
||||
return gKoopaTroopaBeach;
|
||||
}
|
||||
|
||||
void* GetRoyalRaceway(void) {
|
||||
return gRoyalRaceway;
|
||||
}
|
||||
|
||||
void* GetMooMooFarm(void) {
|
||||
return gMooMooFarm;
|
||||
}
|
||||
|
||||
void* GetToadsTurnpike(void) {
|
||||
return gToadsTurnpike;
|
||||
}
|
||||
|
||||
void* GetKalimariDesert(void) {
|
||||
return gKalimariDesert;
|
||||
}
|
||||
|
||||
void* GetSherbetLand(void) {
|
||||
return gSherbetLand;
|
||||
}
|
||||
|
||||
void* GetRainbowRoad(void) {
|
||||
return gRainbowRoad;
|
||||
}
|
||||
|
||||
void* GetWarioStadium(void) {
|
||||
return gWarioStadium;
|
||||
}
|
||||
|
||||
void* GetBlockFort(void) {
|
||||
return gBlockFort;
|
||||
}
|
||||
|
||||
void* GetSkyscraper(void) {
|
||||
return gSkyscraper;
|
||||
}
|
||||
|
||||
void* GetDoubleDeck(void) {
|
||||
return gDoubleDeck;
|
||||
}
|
||||
|
||||
void* GetDkJungle(void) {
|
||||
return gDkJungle;
|
||||
}
|
||||
|
||||
void* GetBigDonut(void) {
|
||||
return gBigDonut;
|
||||
}
|
||||
|
||||
void* GetPodiumCeremony(void) {
|
||||
return gPodiumCeremony;
|
||||
}
|
||||
void SelectMarioRaceway() { gWorldInstance.SetCourseByType<MarioRaceway>(); }
|
||||
void SelectLuigiRaceway() { gWorldInstance.SetCourseByType<LuigiRaceway>(); }
|
||||
void SelectChocoMountain() { gWorldInstance.SetCourseByType<ChocoMountain>(); }
|
||||
void SelectBowsersCastle() { gWorldInstance.SetCourseByType<BowsersCastle>(); }
|
||||
void SelectBansheeBoardwalk() { gWorldInstance.SetCourseByType<BansheeBoardwalk>(); }
|
||||
void SelectYoshiValley() { gWorldInstance.SetCourseByType<YoshiValley>(); }
|
||||
void SelectFrappeSnowland() { gWorldInstance.SetCourseByType<FrappeSnowland>(); }
|
||||
void SelectKoopaTroopaBeach() { gWorldInstance.SetCourseByType<KoopaTroopaBeach>(); }
|
||||
void SelectRoyalRaceway() { gWorldInstance.SetCourseByType<RoyalRaceway>(); }
|
||||
void SelectMooMooFarm() { gWorldInstance.SetCourseByType<MooMooFarm>(); }
|
||||
void SelectToadsTurnpike() { gWorldInstance.SetCourseByType<ToadsTurnpike>(); }
|
||||
void SelectKalimariDesert() { gWorldInstance.SetCourseByType<KalimariDesert>(); }
|
||||
void SelectSherbetLand() { gWorldInstance.SetCourseByType<SherbetLand>(); }
|
||||
void SelectRainbowRoad() { gWorldInstance.SetCourseByType<RainbowRoad>(); }
|
||||
void SelectWarioStadium() { gWorldInstance.SetCourseByType<WarioStadium>(); }
|
||||
void SelectBlockFort() { gWorldInstance.SetCourseByType<BlockFort>(); }
|
||||
void SelectSkyscraper() { gWorldInstance.SetCourseByType<Skyscraper>(); }
|
||||
void SelectDoubleDeck() { gWorldInstance.SetCourseByType<DoubleDeck>(); }
|
||||
void SelectDkJungle() { gWorldInstance.SetCourseByType<DKJungle>(); }
|
||||
void SelectBigDonut() { gWorldInstance.SetCourseByType<BigDonut>(); }
|
||||
void SelectPodiumCeremony() { gWorldInstance.CurrentCourse = gPodiumCeremony.get(); }
|
||||
// clang-format on
|
||||
|
||||
void* GetMushroomCup(void) {
|
||||
return gMushroomCup;
|
||||
|
|
@ -868,6 +808,7 @@ extern "C"
|
|||
while (WindowIsRunning()) {
|
||||
push_frame();
|
||||
}
|
||||
CustomEngineDestroy();
|
||||
// GameEngine::Instance->ProcessFrame(push_frame);
|
||||
GameEngine::Instance->Destroy();
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ void PreviousCourse();
|
|||
|
||||
void CM_SetCup(void*);
|
||||
|
||||
void CM_SetCupIndex(size_t index);
|
||||
|
||||
void CM_LoadTextures();
|
||||
|
||||
void CM_RenderCourse(struct UnkStruct_800DC5EC* arg0);
|
||||
|
|
@ -155,47 +157,49 @@ void CM_CleanWorld(void);
|
|||
|
||||
f32 CM_GetWaterLevel(Vec3f pos, Collision* collision);
|
||||
|
||||
void* GetMarioRaceway(void);
|
||||
bool IsMarioRaceway();
|
||||
bool IsLuigiRaceway();
|
||||
bool IsChocoMountain();
|
||||
bool IsBowsersCastle();
|
||||
bool IsBansheeBoardwalk();
|
||||
bool IsYoshiValley();
|
||||
bool IsFrappeSnowland();
|
||||
bool IsKoopaTroopaBeach();
|
||||
bool IsRoyalRaceway();
|
||||
bool IsMooMooFarm();
|
||||
bool IsToadsTurnpike();
|
||||
bool IsKalimariDesert();
|
||||
bool IsSherbetLand();
|
||||
bool IsRainbowRoad();
|
||||
bool IsWarioStadium();
|
||||
bool IsBlockFort();
|
||||
bool IsSkyscraper();
|
||||
bool IsDoubleDeck();
|
||||
bool IsDkJungle();
|
||||
bool IsBigDonut();
|
||||
bool IsPodiumCeremony();
|
||||
|
||||
void* GetLuigiRaceway(void);
|
||||
|
||||
void* GetChocoMountain(void);
|
||||
|
||||
void* GetBowsersCastle(void);
|
||||
|
||||
void* GetBansheeBoardwalk(void);
|
||||
|
||||
void* GetYoshiValley(void);
|
||||
|
||||
void* GetFrappeSnowland(void);
|
||||
|
||||
void* GetKoopaTroopaBeach(void);
|
||||
|
||||
void* GetRoyalRaceway(void);
|
||||
|
||||
void* GetMooMooFarm(void);
|
||||
|
||||
void* GetToadsTurnpike(void);
|
||||
|
||||
void* GetKalimariDesert(void);
|
||||
|
||||
void* GetSherbetLand(void);
|
||||
|
||||
void* GetRainbowRoad(void);
|
||||
|
||||
void* GetWarioStadium(void);
|
||||
|
||||
void* GetBlockFort(void);
|
||||
|
||||
void* GetSkyscraper(void);
|
||||
|
||||
void* GetDoubleDeck(void);
|
||||
|
||||
void* GetDkJungle(void);
|
||||
|
||||
void* GetBigDonut(void);
|
||||
|
||||
void* GetPodiumCeremony(void);
|
||||
void SelectMarioRaceway();
|
||||
void SelectLuigiRaceway();
|
||||
void SelectChocoMountain();
|
||||
void SelectBowsersCastle();
|
||||
void SelectBansheeBoardwalk();
|
||||
void SelectYoshiValley();
|
||||
void SelectFrappeSnowland();
|
||||
void SelectKoopaTroopaBeach();
|
||||
void SelectRoyalRaceway();
|
||||
void SelectMooMooFarm();
|
||||
void SelectToadsTurnpike();
|
||||
void SelectKalimariDesert();
|
||||
void SelectSherbetLand();
|
||||
void SelectRainbowRoad();
|
||||
void SelectWarioStadium();
|
||||
void SelectBlockFort();
|
||||
void SelectSkyscraper();
|
||||
void SelectDoubleDeck();
|
||||
void SelectDkJungle();
|
||||
void SelectBigDonut();
|
||||
void SelectPodiumCeremony();
|
||||
|
||||
void* GetMushroomCup(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,806 @@
|
|||
#include <libultraship/bridge.h>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <math.h>
|
||||
#include "port/Engine.h"
|
||||
#include "FrameInterpolation.h"
|
||||
#include "matrix.h"
|
||||
|
||||
extern "C" {
|
||||
#include "math_util.h"
|
||||
#include "math_util_2.h"
|
||||
#include "render_player.h"
|
||||
|
||||
extern Mat4* gInterpolationMatrix;
|
||||
void mtxf_translate(Mat4, Vec3f);
|
||||
}
|
||||
/*
|
||||
Frame interpolation.
|
||||
|
||||
The idea of this code is to interpolate all matrices.
|
||||
|
||||
The code contains two approaches. The first is to interpolate
|
||||
all inputs in transformations, such as angles, scale and distances,
|
||||
and then perform the same transformations with the interpolated values.
|
||||
After evaluation for some reason some animations such rolling look strange.
|
||||
|
||||
The second approach is to simply interpolate the final matrices. This will
|
||||
more or less simply interpolate the world coordinates for movements.
|
||||
This will however make rotations ~180 degrees get the "paper effect".
|
||||
The mitigation is to identify this case for actors and interpolate the
|
||||
matrix but in model coordinates instead, by "removing" the rotation-
|
||||
translation before interpolating, create a rotation matrix with the
|
||||
interpolated angle which is then applied to the matrix.
|
||||
|
||||
Currently the code contains both methods but only the second one is currently
|
||||
used.
|
||||
|
||||
Both approaches build a tree of instructions, containing matrices
|
||||
at leaves. Every node is built from OPEN_DISPS/CLOSE_DISPS and manually
|
||||
inserted FrameInterpolation_OpenChild/FrameInterpolation_Close child calls.
|
||||
These nodes contain information that should suffice to identify the matrix,
|
||||
so we can find it in an adjacent frame.
|
||||
|
||||
We can interpolate an arbitrary amount of frames between two original frames,
|
||||
given a specific interpolation factor (0=old frame, 0.5=average of frames,
|
||||
1.0=new frame).
|
||||
*/
|
||||
|
||||
static bool invert_matrix(const float m[16], float invOut[16]);
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" {
|
||||
extern Mat4* gInterpolationMatrix;
|
||||
void mtxf_translate(Mat4, Vec3f);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
enum class Op {
|
||||
Marker,
|
||||
OpenChild,
|
||||
CloseChild,
|
||||
|
||||
MatrixPush,
|
||||
MatrixPop,
|
||||
MatrixPut,
|
||||
MatrixMult,
|
||||
MatrixTranslate,
|
||||
MatrixScale,
|
||||
MatrixRotate1Coord,
|
||||
MatrixMult4x4,
|
||||
MatrixPosRotXYZ,
|
||||
MatrixMultVec3fNoTranslate,
|
||||
MatrixMultVec3f,
|
||||
MatrixMtxFToMtx,
|
||||
MatrixToMtx,
|
||||
MatrixRotateAxis,
|
||||
SkinMatrixMtxFToMtx,
|
||||
SetTransformMatrix,
|
||||
SetMatrixTransformation,
|
||||
SetTranslateRotate
|
||||
};
|
||||
|
||||
typedef pair<const void*, uintptr_t> label;
|
||||
|
||||
union Data {
|
||||
Data() {
|
||||
}
|
||||
|
||||
struct {
|
||||
Mat4** matrix;
|
||||
} matrix_ptr;
|
||||
|
||||
struct {
|
||||
const char* file;
|
||||
int line;
|
||||
} marker;
|
||||
|
||||
struct {
|
||||
Mat4* matrix;
|
||||
MtxF mf;
|
||||
u8 mode;
|
||||
} matrix_mult;
|
||||
|
||||
struct {
|
||||
Mat4* matrix;
|
||||
Vec3fInterp b;
|
||||
} matrix_translate;
|
||||
|
||||
struct {
|
||||
Mat4* matrix;
|
||||
f32 scale;
|
||||
} matrix_scale;
|
||||
|
||||
struct {
|
||||
Mat4* matrix;
|
||||
u32 coord;
|
||||
s16 value;
|
||||
} matrix_rotate_1_coord;
|
||||
|
||||
struct {
|
||||
Mat4* matrix;
|
||||
Vec3f src;
|
||||
Vec3f dest;
|
||||
} matrix_vec_translate;
|
||||
|
||||
struct {
|
||||
Mat4* matrix;
|
||||
Vec3f src;
|
||||
Vec3f dest;
|
||||
} matrix_vec_no_translate;
|
||||
|
||||
struct {
|
||||
Mat4* dest;
|
||||
Mat4 mtx1;
|
||||
Mat4 mtx2;
|
||||
} matrix_mult_4x4;
|
||||
|
||||
struct {
|
||||
Vec3fInterp pos;
|
||||
Vec3sInterp orientation;
|
||||
} matrix_pos_rot_xyz;
|
||||
|
||||
struct {
|
||||
Mat4* matrix;
|
||||
Vec3f translation;
|
||||
Vec3s rotation;
|
||||
} matrix_translate_rotate_zyx;
|
||||
|
||||
struct {
|
||||
Mat4* matrix;
|
||||
f32 translateX, translateY, translateZ;
|
||||
Vec3s rot;
|
||||
// MtxF mtx;
|
||||
bool has_mtx;
|
||||
} matrix_set_translate_rotate_yxz;
|
||||
|
||||
struct {
|
||||
MtxF src;
|
||||
Mtx* dest;
|
||||
} matrix_mtxf_to_mtx;
|
||||
|
||||
struct {
|
||||
Mtx* dest;
|
||||
MtxF src;
|
||||
bool has_adjusted;
|
||||
} matrix_to_mtx;
|
||||
|
||||
struct {
|
||||
MtxF mf;
|
||||
} matrix_replace_rotation;
|
||||
|
||||
struct {
|
||||
f32 angle;
|
||||
Vec3f axis;
|
||||
u8 mode;
|
||||
} matrix_rotate_axis;
|
||||
|
||||
struct {
|
||||
Mat4* dest;
|
||||
Vec3f orientationVector;
|
||||
Vec3f positionVector;
|
||||
u16 rotationAngle;
|
||||
f32 scaleFactor;
|
||||
} set_transform_matrix_data;
|
||||
|
||||
struct {
|
||||
Mat4* dest;
|
||||
Vec3f location;
|
||||
Vec3su rotation;
|
||||
f32 scale;
|
||||
} set_matrix_transformation_data;
|
||||
|
||||
struct {
|
||||
Mat4* dest;
|
||||
Vec3f location;
|
||||
Vec3s rotation;
|
||||
} set_translate_rotate_data;
|
||||
|
||||
struct {
|
||||
Mat3* dest;
|
||||
f32 arg1;
|
||||
f32 arg2;
|
||||
f32 arg3;
|
||||
s16 rot;
|
||||
} set_orientation_matrix_data;
|
||||
|
||||
struct {
|
||||
label key;
|
||||
size_t idx;
|
||||
} open_child;
|
||||
};
|
||||
|
||||
struct Path {
|
||||
map<label, vector<Path>> children;
|
||||
map<Op, vector<Data>> ops;
|
||||
vector<pair<Op, size_t>> items;
|
||||
};
|
||||
|
||||
struct Recording {
|
||||
Path root_path;
|
||||
};
|
||||
|
||||
bool is_recording;
|
||||
vector<Path*> current_path;
|
||||
uint32_t camera_epoch;
|
||||
uint32_t previous_camera_epoch;
|
||||
Recording current_recording;
|
||||
Recording previous_recording;
|
||||
|
||||
bool next_is_actor_pos_rot_matrix;
|
||||
bool has_inv_actor_mtx;
|
||||
MtxF inv_actor_mtx;
|
||||
size_t inv_actor_mtx_path_index;
|
||||
|
||||
Data& append(Op op) {
|
||||
auto& m = current_path.back()->ops[op];
|
||||
current_path.back()->items.emplace_back(op, m.size());
|
||||
return m.emplace_back();
|
||||
}
|
||||
|
||||
MtxF* Matrix_GetCurrent() {
|
||||
return (MtxF*) gInterpolationMatrix;
|
||||
}
|
||||
|
||||
struct InterpolateCtx {
|
||||
float step;
|
||||
float w;
|
||||
unordered_map<Mtx*, MtxF> mtx_replacements;
|
||||
MtxF tmp_mtxf, tmp_mtxf2;
|
||||
Mat3 tmp_mat3;
|
||||
Vec3f tmp_vec3f, tmp_vec3f2;
|
||||
Vec3s tmp_vec3s;
|
||||
MtxF actor_mtx;
|
||||
|
||||
MtxF* new_replacement(Mtx* addr) {
|
||||
return &mtx_replacements[addr];
|
||||
}
|
||||
|
||||
void interpolate_mtxf(MtxF* res, MtxF* o, MtxF* n) {
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
for (size_t j = 0; j < 4; j++) {
|
||||
res->mf[i][j] = w * o->mf[i][j] + step * n->mf[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float lerp(f32 o, f32 n) {
|
||||
return w * o + step * n;
|
||||
}
|
||||
|
||||
s16 lerp_s16(s16 o, s16 n) {
|
||||
return w * o + step * n;
|
||||
}
|
||||
|
||||
void lerp_vec3s(Vec3s* res, Vec3s o, Vec3s n) {
|
||||
*res[0] = lerp_s16(o[0], n[0]);
|
||||
*res[1] = lerp_s16(o[1], n[1]);
|
||||
*res[2] = lerp_s16(o[2], n[2]);
|
||||
}
|
||||
|
||||
void lerp_vec3f(Vec3f* res, Vec3f* o, Vec3f* n) {
|
||||
*res[0] = lerp(*o[0], *n[0]);
|
||||
*res[1] = lerp(*o[1], *n[1]);
|
||||
*res[2] = lerp(*o[2], *n[2]);
|
||||
}
|
||||
|
||||
float interpolate_angle(f32 o, f32 n) {
|
||||
if (o == n)
|
||||
return n;
|
||||
o = fmodf(o, 2 * M_PI);
|
||||
if (o < 0.0f) {
|
||||
o += 2 * M_PI;
|
||||
}
|
||||
n = fmodf(n, 2 * M_PI);
|
||||
if (n < 0.0f) {
|
||||
n += 2 * M_PI;
|
||||
}
|
||||
if (fabsf(o - n) > M_PI) {
|
||||
if (o < n) {
|
||||
o += 2 * M_PI;
|
||||
} else {
|
||||
n += 2 * M_PI;
|
||||
}
|
||||
}
|
||||
if (fabsf(o - n) > M_PI / 2) {
|
||||
// return n;
|
||||
}
|
||||
return lerp(o, n);
|
||||
}
|
||||
|
||||
s16 interpolate_angle(s16 os, s16 ns) {
|
||||
if (os == ns)
|
||||
return ns;
|
||||
int o = (u16) os;
|
||||
int n = (u16) ns;
|
||||
u16 res;
|
||||
int diff = o - n;
|
||||
if (-0x8000 <= diff && diff <= 0x8000) {
|
||||
if (diff < -0x4000 || diff > 0x4000) {
|
||||
return ns;
|
||||
}
|
||||
res = (u16) (w * o + step * n);
|
||||
} else {
|
||||
if (o < n) {
|
||||
o += 0x10000;
|
||||
} else {
|
||||
n += 0x10000;
|
||||
}
|
||||
diff = o - n;
|
||||
if (diff < -0x4000 || diff > 0x4000) {
|
||||
return ns;
|
||||
}
|
||||
res = (u16) (w * o + step * n);
|
||||
}
|
||||
if (os / 327 == ns / 327 && (s16) res / 327 != os / 327) {
|
||||
int bp = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void interpolate_vecs(Vec3f* res, Vec3f* o, Vec3f* n) {
|
||||
*res[0] = interpolate_angle(*o[0], *n[0]);
|
||||
*res[1] = interpolate_angle(*o[1], *n[1]);
|
||||
*res[2] = interpolate_angle(*o[2], *n[2]);
|
||||
}
|
||||
|
||||
void interpolate_angles(Vec3s* res, Vec3s* o, Vec3s* n) {
|
||||
*res[0] = interpolate_angle(*o[0], *n[0]);
|
||||
*res[1] = interpolate_angle(*o[1], *n[1]);
|
||||
*res[2] = interpolate_angle(*o[2], *n[2]);
|
||||
}
|
||||
|
||||
void interpolate_branch(Path* old_path, Path* new_path) {
|
||||
for (auto& item : new_path->items) {
|
||||
Data& new_op = new_path->ops[item.first][item.second];
|
||||
|
||||
if (item.first == Op::OpenChild) {
|
||||
if (auto it = old_path->children.find(new_op.open_child.key);
|
||||
it != old_path->children.end() && new_op.open_child.idx < it->second.size()) {
|
||||
interpolate_branch(&it->second[new_op.open_child.idx],
|
||||
&new_path->children.find(new_op.open_child.key)->second[new_op.open_child.idx]);
|
||||
} else {
|
||||
interpolate_branch(&new_path->children.find(new_op.open_child.key)->second[new_op.open_child.idx],
|
||||
&new_path->children.find(new_op.open_child.key)->second[new_op.open_child.idx]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto it = old_path->ops.find(item.first); it != old_path->ops.end()) {
|
||||
if (item.second < it->second.size()) {
|
||||
Data& old_op = it->second[item.second];
|
||||
switch (item.first) {
|
||||
case Op::OpenChild:
|
||||
case Op::CloseChild:
|
||||
case Op::Marker:
|
||||
break;
|
||||
|
||||
case Op::MatrixPush:
|
||||
Matrix_Push((Matrix**) &gInterpolationMatrix);
|
||||
break;
|
||||
|
||||
case Op::MatrixPop:
|
||||
Matrix_Pop((Matrix**) &gInterpolationMatrix);
|
||||
break;
|
||||
|
||||
// Unused on SF64
|
||||
// case Op::MatrixPut:
|
||||
// interpolate_mtxf(&tmp_mtxf, &old_op.matrix_put.src, &new_op.matrix_put.src);
|
||||
// Matrix_Put(&tmp_mtxf);
|
||||
// break;
|
||||
|
||||
case Op::MatrixMult:
|
||||
interpolate_mtxf(&tmp_mtxf, &old_op.matrix_mult.mf, &new_op.matrix_mult.mf);
|
||||
mtxf_multiplication(*gInterpolationMatrix, tmp_mtxf.mf, new_op.matrix_mult.mf.mf);
|
||||
// Matrix_Mult(gInterpolationMatrix, (Matrix*) &tmp_mtxf, new_op.matrix_mult.mode);
|
||||
break;
|
||||
|
||||
case Op::MatrixTranslate:
|
||||
|
||||
Vec3f temp;
|
||||
|
||||
temp[0] = lerp(old_op.matrix_translate.b.x, new_op.matrix_translate.b.x);
|
||||
temp[1] = lerp(old_op.matrix_translate.b.y, new_op.matrix_translate.b.y);
|
||||
temp[2] = lerp(old_op.matrix_translate.b.z, new_op.matrix_translate.b.z);
|
||||
|
||||
mtxf_translate(*gInterpolationMatrix, temp);
|
||||
break;
|
||||
case Op::MatrixPosRotXYZ:
|
||||
Vec3f tempF;
|
||||
Vec3s tempS;
|
||||
|
||||
tempF[0] = lerp(old_op.matrix_pos_rot_xyz.pos.x, new_op.matrix_pos_rot_xyz.pos.x);
|
||||
tempF[1] = lerp(old_op.matrix_pos_rot_xyz.pos.y, new_op.matrix_pos_rot_xyz.pos.y);
|
||||
tempF[2] = lerp(old_op.matrix_pos_rot_xyz.pos.z, new_op.matrix_pos_rot_xyz.pos.z);
|
||||
|
||||
tempS[0] =
|
||||
lerp(old_op.matrix_pos_rot_xyz.orientation.x, new_op.matrix_pos_rot_xyz.orientation.x);
|
||||
tempS[1] =
|
||||
lerp(old_op.matrix_pos_rot_xyz.orientation.y, new_op.matrix_pos_rot_xyz.orientation.y);
|
||||
tempS[2] =
|
||||
lerp(old_op.matrix_pos_rot_xyz.orientation.z, new_op.matrix_pos_rot_xyz.orientation.z);
|
||||
|
||||
mtxf_pos_rotation_xyz(*gInterpolationMatrix, tempF, tempS);
|
||||
break;
|
||||
|
||||
case Op::MatrixScale:
|
||||
mtxf_scale(*gInterpolationMatrix, lerp(old_op.matrix_scale.scale, new_op.matrix_scale.scale));
|
||||
break;
|
||||
|
||||
case Op::MatrixRotate1Coord: {
|
||||
s16 v = interpolate_angle(old_op.matrix_rotate_1_coord.value,
|
||||
new_op.matrix_rotate_1_coord.value);
|
||||
switch (new_op.matrix_rotate_1_coord.coord) {
|
||||
case 0:
|
||||
mtxf_rotate_x(*gInterpolationMatrix, v);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
mtxf_rotate_y(*gInterpolationMatrix, v);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
mtxf_s16_rotate_z(*gInterpolationMatrix, v);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Op::MatrixMultVec3fNoTranslate: {
|
||||
interpolate_vecs(&tmp_vec3f, &old_op.matrix_vec_no_translate.src,
|
||||
&new_op.matrix_vec_no_translate.src);
|
||||
interpolate_vecs(&tmp_vec3f2, &old_op.matrix_vec_no_translate.dest,
|
||||
&new_op.matrix_vec_no_translate.dest);
|
||||
// Matrix_MultVec3fNoTranslate(gInterpolationMatrix, &tmp_vec3f, &tmp_vec3f2);
|
||||
break;
|
||||
}
|
||||
case Op::MatrixMultVec3f: {
|
||||
interpolate_vecs(&tmp_vec3f, &old_op.matrix_vec_translate.src,
|
||||
&new_op.matrix_vec_translate.src);
|
||||
interpolate_vecs(&tmp_vec3f2, &old_op.matrix_vec_translate.dest,
|
||||
&new_op.matrix_vec_translate.dest);
|
||||
// Matrix_MultVec3f(gInterpolationMatrix, &tmp_vec3f, &tmp_vec3f2);
|
||||
break;
|
||||
}
|
||||
|
||||
case Op::MatrixMtxFToMtx:
|
||||
interpolate_mtxf(new_replacement(new_op.matrix_mtxf_to_mtx.dest),
|
||||
&old_op.matrix_mtxf_to_mtx.src, &new_op.matrix_mtxf_to_mtx.src);
|
||||
break;
|
||||
|
||||
case Op::MatrixToMtx: {
|
||||
//*new_replacement(new_op.matrix_to_mtx.dest) = *Matrix_GetCurrent();
|
||||
if (old_op.matrix_to_mtx.has_adjusted && new_op.matrix_to_mtx.has_adjusted) {
|
||||
interpolate_mtxf(&tmp_mtxf, &old_op.matrix_to_mtx.src, &new_op.matrix_to_mtx.src);
|
||||
// Matrix_MtxFMtxFMult(&actor_mtx, &tmp_mtxf,
|
||||
// new_replacement(new_op.matrix_to_mtx.dest));
|
||||
} else {
|
||||
interpolate_mtxf(new_replacement(new_op.matrix_to_mtx.dest), &old_op.matrix_to_mtx.src,
|
||||
&new_op.matrix_to_mtx.src);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Op::MatrixRotateAxis: {
|
||||
lerp_vec3f(&tmp_vec3f, &old_op.matrix_rotate_axis.axis, &new_op.matrix_rotate_axis.axis);
|
||||
auto tmp =
|
||||
interpolate_angle(old_op.matrix_rotate_axis.angle, new_op.matrix_rotate_axis.angle);
|
||||
// Matrix_RotateAxis((Matrix*) &tmp_vec3f, tmp, 1.0f, 1.0f, 1.0f,
|
||||
// new_op.matrix_rotate_axis.mode);
|
||||
break;
|
||||
}
|
||||
|
||||
case Op::SetTransformMatrix: {
|
||||
lerp_vec3f(&tmp_vec3f, &old_op.set_transform_matrix_data.orientationVector,
|
||||
&new_op.set_transform_matrix_data.orientationVector);
|
||||
|
||||
lerp_vec3f(&tmp_vec3f2, &old_op.set_transform_matrix_data.positionVector,
|
||||
&new_op.set_transform_matrix_data.positionVector);
|
||||
|
||||
u16 rotationAngleTemp = lerp_s16(old_op.set_transform_matrix_data.rotationAngle,
|
||||
new_op.set_transform_matrix_data.rotationAngle);
|
||||
f32 scaleFactorTemp = lerp(old_op.set_transform_matrix_data.scaleFactor, new_op.set_transform_matrix_data.scaleFactor);
|
||||
|
||||
set_transform_matrix(*gInterpolationMatrix, tmp_vec3f, tmp_vec3f2, rotationAngleTemp, scaleFactorTemp);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Op::SetMatrixTransformation: {
|
||||
|
||||
lerp_vec3f(&tmp_vec3f, &old_op.set_matrix_transformation_data.location,
|
||||
&new_op.set_matrix_transformation_data.location);
|
||||
|
||||
lerp_vec3s(&tmp_vec3s, *(Vec3s*)&old_op.set_matrix_transformation_data.rotation,
|
||||
*(Vec3s*)&new_op.set_matrix_transformation_data.rotation);
|
||||
|
||||
f32 scaleFactorTemp = lerp(old_op.set_matrix_transformation_data.scale, new_op.set_matrix_transformation_data.scale);
|
||||
|
||||
mtxf_set_matrix_transformation(*gInterpolationMatrix, tmp_vec3f, *(Vec3su*)&tmp_vec3s, scaleFactorTemp);
|
||||
break;
|
||||
}
|
||||
|
||||
case Op::SetTranslateRotate: {
|
||||
lerp_vec3f(&tmp_vec3f, &old_op.set_translate_rotate_data.location,
|
||||
&new_op.set_translate_rotate_data.location);
|
||||
|
||||
lerp_vec3s(&tmp_vec3s, old_op.set_translate_rotate_data.rotation,
|
||||
new_op.set_translate_rotate_data.rotation);
|
||||
|
||||
mtxf_translate_rotate(*gInterpolationMatrix, tmp_vec3f, tmp_vec3s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
unordered_map<Mtx*, MtxF> FrameInterpolation_Interpolate(float step) {
|
||||
InterpolateCtx ctx;
|
||||
ctx.step = step;
|
||||
ctx.w = 1.0f - step;
|
||||
ctx.interpolate_branch(&previous_recording.root_path, ¤t_recording.root_path);
|
||||
return ctx.mtx_replacements;
|
||||
}
|
||||
|
||||
bool camera_interpolation = true;
|
||||
|
||||
void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate) {
|
||||
camera_interpolation = shouldInterpolate;
|
||||
is_recording = shouldInterpolate;
|
||||
}
|
||||
|
||||
void FrameInterpolation_StartRecord(void) {
|
||||
previous_recording = move(current_recording);
|
||||
current_recording = {};
|
||||
current_path.clear();
|
||||
current_path.push_back(¤t_recording.root_path);
|
||||
if (!camera_interpolation) {
|
||||
// default to interpolating
|
||||
camera_interpolation = true;
|
||||
is_recording = false;
|
||||
return;
|
||||
}
|
||||
if (GameEngine::GetInterpolationFPS() != 30) {
|
||||
is_recording = true;
|
||||
}
|
||||
}
|
||||
|
||||
void FrameInterpolation_StopRecord(void) {
|
||||
previous_camera_epoch = camera_epoch;
|
||||
is_recording = false;
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordOpenChild(const void* a, uintptr_t b) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
label key = { a, b };
|
||||
auto& m = current_path.back()->children[key];
|
||||
append(Op::OpenChild).open_child = { key, m.size() };
|
||||
current_path.push_back(&m.emplace_back());
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordCloseChild(void) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
// append(Op::CloseChild);
|
||||
if (has_inv_actor_mtx && current_path.size() == inv_actor_mtx_path_index) {
|
||||
has_inv_actor_mtx = false;
|
||||
}
|
||||
current_path.pop_back();
|
||||
}
|
||||
|
||||
void FrameInterpolation_DontInterpolateCamera(void) {
|
||||
camera_epoch = previous_camera_epoch + 1;
|
||||
}
|
||||
|
||||
int FrameInterpolation_GetCameraEpoch(void) {
|
||||
return (int) camera_epoch;
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordActorPosRotMatrix(void) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
next_is_actor_pos_rot_matrix = true;
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixPush(Mat4* matrix) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
|
||||
append(Op::MatrixPush).matrix_ptr = { (Mat4**) matrix };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMarker(const char* file, int line) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
|
||||
append(Op::Marker).marker = { file, line };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixPop(Mat4* matrix) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixPop).matrix_ptr = { (Mat4**) matrix };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixPut(MtxF* src) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
// append(Op::MatrixPut).matrix_put = { matrix, *src };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixMult(Mat4* matrix, MtxF* mf, u8 mode) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixMult).matrix_mult = { matrix, *mf, mode };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixTranslate(Mat4* matrix, Vec3f b) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
|
||||
append(Op::MatrixTranslate).matrix_translate = { matrix, *((Vec3fInterp*) &b) };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixScale(Mat4* matrix, f32 scale) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixScale).matrix_scale = { matrix, scale };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixMultVec3fNoTranslate(Mat4* matrix, Vec3f src, Vec3f dest) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
// append(Op::MatrixMultVec3fNoTranslate).matrix_vec_no_translate = { matrix, src, dest };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordSetTransformMatrix(Mat4* dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle,
|
||||
f32 scaleFactor) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::SetTransformMatrix).set_transform_matrix_data = { dest, {orientationVector[0], orientationVector[1], orientationVector[2]}, { positionVector[0], positionVector[1], positionVector[2] }, rotationAngle, scaleFactor};
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordTranslateRotate(Mat4* dest, Vec3f pos, Vec3s rotation) {
|
||||
if (!is_recording) { return; }
|
||||
|
||||
append(Op::SetTranslateRotate).set_translate_rotate_data = { dest, {pos[0], pos[1], pos[2]}, { rotation[0], rotation[1], rotation[2] }};
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordSetMatrixTransformation(Mat4* dest, Vec3f location, Vec3su rotation, f32 scale) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::SetMatrixTransformation).set_matrix_transformation_data = { dest, {location[0], location[1], location[2]}, { rotation[0], rotation[1], rotation[2] }, scale};
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordCalculateOrientationMatrix(Mat3* dest, f32 x, f32 y, f32 z, s16 rot) {
|
||||
if (!is_recording) return;
|
||||
|
||||
// append(Op::SetMatrixTransformation).set_calculate_orientation_matrix_data = { dest, x, y, z, rot};
|
||||
}
|
||||
|
||||
// Make a template for deref
|
||||
|
||||
void FrameInterpolation_RecordMatrixPosRotXYZ(Mat4 out, Vec3f pos, Vec3s orientation) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixPosRotXYZ).matrix_pos_rot_xyz = { *((Vec3fInterp*) &pos), *((Vec3sInterp*) &orientation) };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixMultVec3f(Mat4* matrix, Vec3f src, Vec3f dest) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
// append(Op::MatrixMultVec3f).matrix_vec_translate = { matrix, src, dest };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixRotate1Coord(Mat4* matrix, u32 coord, s16 value) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixRotate1Coord).matrix_rotate_1_coord = { matrix, coord, value };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixMtxFToMtx(MtxF* src, Mtx* dest) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixMtxFToMtx).matrix_mtxf_to_mtx = { *src, dest };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixToMtx(Mtx* dest, char* file, s32 line) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
auto& d = append(Op::MatrixToMtx).matrix_to_mtx = { dest };
|
||||
if (has_inv_actor_mtx) {
|
||||
d.has_adjusted = true;
|
||||
// Matrix_MtxFMtxFMult(&inv_actor_mtx, Matrix_GetCurrent(), &d.src);
|
||||
} else {
|
||||
d.src = *Matrix_GetCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixRotateAxis(f32 angle, Vec3f* axis, u8 mode) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
// append(Op::MatrixRotateAxis).matrix_rotate_axis = { angle, axis, mode };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordSkinMatrixMtxFToMtx(MtxF* src, Mtx* dest) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
FrameInterpolation_RecordMatrixMtxFToMtx(src, dest);
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix
|
||||
static bool invert_matrix(const float m[16], float invOut[16]) {
|
||||
float inv[16], det;
|
||||
int i;
|
||||
|
||||
inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] + m[9] * m[7] * m[14] +
|
||||
m[13] * m[6] * m[11] - m[13] * m[7] * m[10];
|
||||
|
||||
inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] - m[8] * m[7] * m[14] -
|
||||
m[12] * m[6] * m[11] + m[12] * m[7] * m[10];
|
||||
|
||||
inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] + m[8] * m[7] * m[13] +
|
||||
m[12] * m[5] * m[11] - m[12] * m[7] * m[9];
|
||||
|
||||
inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] - m[8] * m[6] * m[13] -
|
||||
m[12] * m[5] * m[10] + m[12] * m[6] * m[9];
|
||||
|
||||
inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] - m[9] * m[3] * m[14] -
|
||||
m[13] * m[2] * m[11] + m[13] * m[3] * m[10];
|
||||
|
||||
inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] + m[8] * m[3] * m[14] +
|
||||
m[12] * m[2] * m[11] - m[12] * m[3] * m[10];
|
||||
|
||||
inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] - m[8] * m[3] * m[13] -
|
||||
m[12] * m[1] * m[11] + m[12] * m[3] * m[9];
|
||||
|
||||
inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] + m[8] * m[2] * m[13] +
|
||||
m[12] * m[1] * m[10] - m[12] * m[2] * m[9];
|
||||
|
||||
inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] + m[5] * m[3] * m[14] +
|
||||
m[13] * m[2] * m[7] - m[13] * m[3] * m[6];
|
||||
|
||||
inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] - m[4] * m[3] * m[14] -
|
||||
m[12] * m[2] * m[7] + m[12] * m[3] * m[6];
|
||||
|
||||
inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] + m[4] * m[3] * m[13] +
|
||||
m[12] * m[1] * m[7] - m[12] * m[3] * m[5];
|
||||
|
||||
inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] - m[4] * m[2] * m[13] -
|
||||
m[12] * m[1] * m[6] + m[12] * m[2] * m[5];
|
||||
|
||||
inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] - m[5] * m[3] * m[10] -
|
||||
m[9] * m[2] * m[7] + m[9] * m[3] * m[6];
|
||||
|
||||
inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] + m[4] * m[3] * m[10] +
|
||||
m[8] * m[2] * m[7] - m[8] * m[3] * m[6];
|
||||
|
||||
inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] - m[4] * m[3] * m[9] -
|
||||
m[8] * m[1] * m[7] + m[8] * m[3] * m[5];
|
||||
|
||||
inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] + m[4] * m[2] * m[9] + m[8] * m[1] * m[6] -
|
||||
m[8] * m[2] * m[5];
|
||||
|
||||
det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
|
||||
|
||||
if (det == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
det = 1.0 / det;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
invOut[i] = inv[i] * det;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
#ifndef __FRAME_INTERPOLATION_H
|
||||
#define __FRAME_INTERPOLATION_H
|
||||
|
||||
// #include "sf64math.h"
|
||||
#include <libultraship.h>
|
||||
#include <common_structs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
|
||||
std::unordered_map<Mtx*, MtxF> FrameInterpolation_Interpolate(float step);
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TAG_ITEM_ADDR(x) ((u32) 0x10000000 | (u32)x)
|
||||
#define TAG_SMOKE_DUST(x) ((u32) 0x20000000 | (u32) (x))
|
||||
#define TAG_LETTER(x) ((u32)0x30000000 | (u32) (x))
|
||||
#define TAG_OBJECT(x) ((u32)0x40000000 | (u32) (uintptr_t) (x))
|
||||
|
||||
void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate);
|
||||
|
||||
void FrameInterpolation_StartRecord(void);
|
||||
|
||||
void FrameInterpolation_StopRecord(void);
|
||||
|
||||
void FrameInterpolation_RecordMarker(const char* file, int line);
|
||||
|
||||
void FrameInterpolation_RecordOpenChild(const void* a, uintptr_t b);
|
||||
|
||||
void FrameInterpolation_RecordCloseChild(void);
|
||||
|
||||
void FrameInterpolation_DontInterpolateCamera(void);
|
||||
|
||||
int FrameInterpolation_GetCameraEpoch(void);
|
||||
|
||||
void FrameInterpolation_RecordActorPosRotMatrix(void);
|
||||
|
||||
void FrameInterpolation_RecordMatrixPosRotXYZ(Mat4 out, Vec3f pos, Vec3s orientation);
|
||||
|
||||
void FrameInterpolation_RecordMatrixPush(Mat4* matrix);
|
||||
|
||||
void FrameInterpolation_RecordMatrixPop(Mat4* matrix);
|
||||
|
||||
void FrameInterpolation_RecordMatrixMult(Mat4* matrix, MtxF* mf, u8 mode);
|
||||
|
||||
void FrameInterpolation_RecordMatrixTranslate(Mat4* matrix, Vec3f b);
|
||||
|
||||
void FrameInterpolation_RecordMatrixScale(Mat4* matrix, f32 scale);
|
||||
|
||||
void FrameInterpolation_RecordMatrixRotate1Coord(Mat4* matrix, u32 coord, s16 value);
|
||||
|
||||
void FrameInterpolation_RecordMatrixMtxFToMtx(MtxF* src, Mtx* dest);
|
||||
|
||||
void FrameInterpolation_RecordMatrixToMtx(Mtx* dest, char* file, s32 line);
|
||||
|
||||
void FrameInterpolation_RecordMatrixReplaceRotation(MtxF* mf);
|
||||
|
||||
//void FrameInterpolation_RecordMatrixRotateAxis(f32 angle, Vec3f* axis, u8 mode);
|
||||
|
||||
void FrameInterpolation_RecordSkinMatrixMtxFToMtx(MtxF* src, Mtx* dest);
|
||||
|
||||
//void FrameInterpolation_RecordMatrixMultVec3f(Matrix* matrix, Vec3f src, Vec3f dest);
|
||||
|
||||
//void FrameInterpolation_RecordMatrixMultVec3fNoTranslate(Matrix* matrix, Vec3f src, Vec3f dest);
|
||||
|
||||
void FrameInterpolation_RecordSetTransformMatrix(Mat4* dest, Vec3f orientationVector, Vec3f positionVector, u16 rotationAngle,
|
||||
f32 scaleFactor);
|
||||
|
||||
void FrameInterpolation_RecordSetMatrixTransformation(Mat4* dest, Vec3f location, Vec3su rotation, f32 scale);
|
||||
|
||||
void FrameInterpolation_RecordCalculateOrientationMatrix(Mat3*, f32, f32, f32, s16);
|
||||
|
||||
void FrameInterpolation_RecordTranslateRotate(Mat4* dest, Vec3f pos, Vec3s rotation);
|
||||
|
||||
//void FrameInterpolation_func_80062B18(f32* arg0, f32* arg1, f32* arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __FRAME_INTERPOLATION_H
|
||||
|
|
@ -0,0 +1,451 @@
|
|||
#include <libultraship.h>
|
||||
#include <math.h>
|
||||
#include "matrix.h"
|
||||
#include "common_structs.h"
|
||||
#include "FrameInterpolation.h"
|
||||
|
||||
Mtx gIdentityMtx = gdSPDefMtx(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
Matrix gIdentityMatrix = { {
|
||||
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 1.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 1.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 1.0f },
|
||||
} };
|
||||
|
||||
Matrix* gGfxMatrix;
|
||||
Matrix sGfxMatrixStack[0x20];
|
||||
Matrix* gCalcMatrix;
|
||||
Matrix sCalcMatrixStack[0x20];
|
||||
|
||||
Mtx gMainMatrixStack[0x480];
|
||||
Mtx* gGfxMtx;
|
||||
|
||||
void Matrix_InitPerspective(Gfx** dList) {
|
||||
u16 norm;
|
||||
float near = 10.0f;
|
||||
float far = 12800.0f;
|
||||
float fov = 45.0f;
|
||||
|
||||
guPerspective(gGfxMtx, &norm, fov, 320.0f / 240.0f, near, far, 1.0f);
|
||||
gSPPerspNormalize((*dList)++, norm);
|
||||
gSPMatrix((*dList)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
guLookAt(gGfxMtx, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -12800.0f, 0.0f, 1.0f, 0.0f);
|
||||
gSPMatrix((*dList)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
||||
Matrix_Copy(gGfxMatrix, &gIdentityMatrix);
|
||||
}
|
||||
|
||||
void Matrix_InitOrtho(Gfx** dList) {
|
||||
FrameInterpolation_RecordOpenChild("ortho", 0);
|
||||
FrameInterpolation_RecordMarker(__FILE__, __LINE__);
|
||||
guOrtho(gGfxMtx, -320.0f / 2, 320.0f / 2, -240.0f / 2, 240.0f / 2, 0.0f, 5.0f, 1.0f);
|
||||
gSPMatrix((*dList)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
guLookAt(gGfxMtx, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -12800.0f, 0.0f, 1.0f, 0.0f);
|
||||
gSPMatrix((*dList)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
||||
Matrix_Copy(gGfxMatrix, &gIdentityMatrix);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
|
||||
// Copies src Matrix into dst
|
||||
void Matrix_Copy(Matrix* dst, Matrix* src) {
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
dst->mf[i][0] = src->mf[i][0];
|
||||
dst->mf[i][1] = src->mf[i][1];
|
||||
dst->mf[i][2] = src->mf[i][2];
|
||||
dst->mf[i][3] = src->mf[i][3];
|
||||
}
|
||||
}
|
||||
|
||||
// Makes a copy of the stack's current matrix and puts it on the top of the stack
|
||||
void Matrix_Push(Matrix** mtxStack) {
|
||||
Matrix_Copy(*mtxStack + 1, *mtxStack);
|
||||
(*mtxStack)++;
|
||||
}
|
||||
|
||||
// Removes the top matrix of the stack
|
||||
void Matrix_Pop(Matrix** mtxStack) {
|
||||
(*mtxStack)--;
|
||||
}
|
||||
|
||||
// Copies tf into mtx (MTXF_NEW) or applies it to mtx (MTXF_APPLY)
|
||||
void Matrix_Mult(Matrix* mtx, Matrix* tf, u8 mode) {
|
||||
f32 rx;
|
||||
f32 ry;
|
||||
f32 rz;
|
||||
f32 rw;
|
||||
s32 i0;
|
||||
s32 i1;
|
||||
s32 i2;
|
||||
s32 i3;
|
||||
|
||||
if (mode == 1) {
|
||||
rx = mtx->mf[0][0];
|
||||
ry = mtx->mf[1][0];
|
||||
rz = mtx->mf[2][0];
|
||||
rw = mtx->mf[3][0];
|
||||
|
||||
for (i0 = 0; i0 < 4; i0++) {
|
||||
mtx->mf[i0][0] = (rx * tf->mf[i0][0]) + (ry * tf->mf[i0][1]) + (rz * tf->mf[i0][2]) + (rw * tf->mf[i0][3]);
|
||||
}
|
||||
|
||||
rx = mtx->mf[0][1];
|
||||
ry = mtx->mf[1][1];
|
||||
rz = mtx->mf[2][1];
|
||||
rw = mtx->mf[3][1];
|
||||
|
||||
for (i1 = 0; i1 < 4; i1++) {
|
||||
mtx->mf[i1][1] = (rx * tf->mf[i1][0]) + (ry * tf->mf[i1][1]) + (rz * tf->mf[i1][2]) + (rw * tf->mf[i1][3]);
|
||||
}
|
||||
|
||||
rx = mtx->mf[0][2];
|
||||
ry = mtx->mf[1][2];
|
||||
rz = mtx->mf[2][2];
|
||||
rw = mtx->mf[3][2];
|
||||
|
||||
for (i2 = 0; i2 < 4; i2++) {
|
||||
mtx->mf[i2][2] = (rx * tf->mf[i2][0]) + (ry * tf->mf[i2][1]) + (rz * tf->mf[i2][2]) + (rw * tf->mf[i2][3]);
|
||||
}
|
||||
|
||||
rx = mtx->mf[0][3];
|
||||
ry = mtx->mf[1][3];
|
||||
rz = mtx->mf[2][3];
|
||||
rw = mtx->mf[3][3];
|
||||
|
||||
for (i3 = 0; i3 < 4; i3++) {
|
||||
mtx->mf[i3][3] = (rx * tf->mf[i3][0]) + (ry * tf->mf[i3][1]) + (rz * tf->mf[i3][2]) + (rw * tf->mf[i3][3]);
|
||||
}
|
||||
} else {
|
||||
Matrix_Copy(mtx, tf);
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a translation matrix in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY)
|
||||
void Matrix_Translate(Matrix* mtx, f32 x, f32 y, f32 z, u8 mode) {
|
||||
f32 rx;
|
||||
f32 ry;
|
||||
s32 i;
|
||||
|
||||
if (mode == 1) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
rx = mtx->mf[0][i];
|
||||
ry = mtx->mf[1][i];
|
||||
|
||||
mtx->mf[3][i] += (rx * x) + (ry * y) + (mtx->mf[2][i] * z);
|
||||
}
|
||||
} else {
|
||||
mtx->mf[3][0] = x;
|
||||
mtx->mf[3][1] = y;
|
||||
mtx->mf[3][2] = z;
|
||||
mtx->mf[0][1] = mtx->mf[0][2] = mtx->mf[0][3] = mtx->mf[1][0] = mtx->mf[1][2] = mtx->mf[1][3] = mtx->mf[2][0] =
|
||||
mtx->mf[2][1] = mtx->mf[2][3] = 0.0f;
|
||||
mtx->mf[0][0] = mtx->mf[1][1] = mtx->mf[2][2] = mtx->mf[3][3] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a scale matrix in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY)
|
||||
void Matrix_Scale(Matrix* mtx, f32 xScale, f32 yScale, f32 zScale, u8 mode) {
|
||||
f32 rx;
|
||||
f32 ry;
|
||||
s32 i;
|
||||
|
||||
if (mode == 1) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
rx = mtx->mf[0][i];
|
||||
ry = mtx->mf[1][i];
|
||||
|
||||
mtx->mf[0][i] = rx * xScale;
|
||||
mtx->mf[1][i] = ry * yScale;
|
||||
mtx->mf[2][i] *= zScale;
|
||||
}
|
||||
} else {
|
||||
mtx->mf[0][0] = xScale;
|
||||
mtx->mf[1][1] = yScale;
|
||||
mtx->mf[2][2] = zScale;
|
||||
mtx->mf[0][1] = mtx->mf[0][2] = mtx->mf[0][3] = mtx->mf[1][0] = mtx->mf[1][2] = mtx->mf[1][3] = mtx->mf[2][0] =
|
||||
mtx->mf[2][1] = mtx->mf[2][3] = mtx->mf[3][0] = mtx->mf[3][1] = mtx->mf[3][2] = 0.0f;
|
||||
mtx->mf[3][3] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates rotation matrix about the X axis in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY)
|
||||
void Matrix_RotateX(Matrix* mtx, f32 angle, u8 mode) {
|
||||
f32 cs;
|
||||
f32 sn;
|
||||
f32 ry;
|
||||
f32 rz;
|
||||
s32 i;
|
||||
|
||||
sn = sinf(angle);
|
||||
cs = cosf(angle);
|
||||
if (mode == 1) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
ry = mtx->mf[1][i];
|
||||
rz = mtx->mf[2][i];
|
||||
|
||||
mtx->mf[1][i] = (ry * cs) + (rz * sn);
|
||||
mtx->mf[2][i] = (rz * cs) - (ry * sn);
|
||||
}
|
||||
} else {
|
||||
mtx->mf[1][1] = mtx->mf[2][2] = cs;
|
||||
mtx->mf[1][2] = sn;
|
||||
mtx->mf[2][1] = -sn;
|
||||
mtx->mf[0][0] = mtx->mf[3][3] = 1.0f;
|
||||
mtx->mf[0][1] = mtx->mf[0][2] = mtx->mf[0][3] = mtx->mf[1][0] = mtx->mf[1][3] = mtx->mf[2][0] = mtx->mf[2][3] =
|
||||
mtx->mf[3][0] = mtx->mf[3][1] = mtx->mf[3][2] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates rotation matrix about the Y axis in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY)
|
||||
void Matrix_RotateY(Matrix* mtx, f32 angle, u8 mode) {
|
||||
f32 cs;
|
||||
f32 sn;
|
||||
f32 rx;
|
||||
f32 rz;
|
||||
s32 i;
|
||||
|
||||
sn = sinf(angle);
|
||||
cs = cosf(angle);
|
||||
if (mode == 1) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
rx = mtx->mf[0][i];
|
||||
rz = mtx->mf[2][i];
|
||||
|
||||
mtx->mf[0][i] = (rx * cs) - (rz * sn);
|
||||
mtx->mf[2][i] = (rx * sn) + (rz * cs);
|
||||
}
|
||||
} else {
|
||||
mtx->mf[0][0] = mtx->mf[2][2] = cs;
|
||||
mtx->mf[0][2] = -sn;
|
||||
mtx->mf[2][0] = sn;
|
||||
mtx->mf[1][1] = mtx->mf[3][3] = 1.0f;
|
||||
mtx->mf[0][1] = mtx->mf[0][3] = mtx->mf[1][0] = mtx->mf[1][2] = mtx->mf[1][3] = mtx->mf[2][1] = mtx->mf[2][3] =
|
||||
mtx->mf[3][0] = mtx->mf[3][1] = mtx->mf[3][2] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates rotation matrix about the Z axis in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY)
|
||||
void Matrix_RotateZ(Matrix* mtx, f32 angle, u8 mode) {
|
||||
f32 cs;
|
||||
f32 sn;
|
||||
f32 rx;
|
||||
f32 ry;
|
||||
s32 i;
|
||||
|
||||
sn = sinf(angle);
|
||||
cs = cosf(angle);
|
||||
if (mode == 1) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
rx = mtx->mf[0][i];
|
||||
ry = mtx->mf[1][i];
|
||||
|
||||
mtx->mf[0][i] = (rx * cs) + (ry * sn);
|
||||
mtx->mf[1][i] = (ry * cs) - (rx * sn);
|
||||
}
|
||||
} else {
|
||||
mtx->mf[0][0] = mtx->mf[1][1] = cs;
|
||||
mtx->mf[0][1] = sn;
|
||||
mtx->mf[1][0] = -sn;
|
||||
mtx->mf[2][2] = mtx->mf[3][3] = 1.0f;
|
||||
mtx->mf[0][2] = mtx->mf[0][3] = mtx->mf[1][2] = mtx->mf[1][3] = mtx->mf[2][0] = mtx->mf[2][1] = mtx->mf[2][3] =
|
||||
mtx->mf[3][0] = mtx->mf[3][1] = mtx->mf[3][2] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates rotation matrix about a given vector axis in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY).
|
||||
// The vector specifying the axis does not need to be a unit vector.
|
||||
void Matrix_RotateAxis(Matrix* mtx, f32 angle, f32 axisX, f32 axisY, f32 axisZ, u8 mode) {
|
||||
f32 rx;
|
||||
f32 ry;
|
||||
f32 rz;
|
||||
f32 norm;
|
||||
f32 cxx;
|
||||
f32 cyx;
|
||||
f32 czx;
|
||||
f32 cxy;
|
||||
f32 cyy;
|
||||
f32 czy;
|
||||
f32 cxz;
|
||||
f32 cyz;
|
||||
f32 czz;
|
||||
f32 xx;
|
||||
f32 yy;
|
||||
f32 zz;
|
||||
f32 xy;
|
||||
f32 yz;
|
||||
f32 xz;
|
||||
f32 sinA;
|
||||
f32 cosA;
|
||||
|
||||
norm = sqrtf((axisX * axisX) + (axisY * axisY) + (axisZ * axisZ));
|
||||
if (norm != 0.0) {
|
||||
axisX /= norm;
|
||||
axisY /= norm;
|
||||
axisZ /= norm;
|
||||
sinA = sinf(angle);
|
||||
cosA = cosf(angle);
|
||||
xx = axisX * axisX;
|
||||
yy = axisY * axisY;
|
||||
zz = axisZ * axisZ;
|
||||
xy = axisX * axisY;
|
||||
yz = axisY * axisZ;
|
||||
xz = axisX * axisZ;
|
||||
|
||||
if (mode == 1) {
|
||||
cxx = (1.0f - xx) * cosA + xx;
|
||||
cyx = (1.0f - cosA) * xy + axisZ * sinA;
|
||||
czx = (1.0f - cosA) * xz - axisY * sinA;
|
||||
|
||||
cxy = (1.0f - cosA) * xy - axisZ * sinA;
|
||||
cyy = (1.0f - yy) * cosA + yy;
|
||||
czy = (1.0f - cosA) * yz + axisX * sinA;
|
||||
|
||||
cxz = (1.0f - cosA) * xz + axisY * sinA;
|
||||
cyz = (1.0f - cosA) * yz - axisX * sinA;
|
||||
czz = (1.0f - zz) * cosA + zz;
|
||||
|
||||
// loop doesn't seem to work here.
|
||||
rx = mtx->mf[0][0];
|
||||
ry = mtx->mf[0][1];
|
||||
rz = mtx->mf[0][2];
|
||||
mtx->mf[0][0] = (rx * cxx) + (ry * cxy) + (rz * cxz);
|
||||
mtx->mf[0][1] = (rx * cyx) + (ry * cyy) + (rz * cyz);
|
||||
mtx->mf[0][2] = (rx * czx) + (ry * czy) + (rz * czz);
|
||||
|
||||
rx = mtx->mf[1][0];
|
||||
ry = mtx->mf[1][1];
|
||||
rz = mtx->mf[1][2];
|
||||
mtx->mf[1][0] = (rx * cxx) + (ry * cxy) + (rz * cxz);
|
||||
mtx->mf[1][1] = (rx * cyx) + (ry * cyy) + (rz * cyz);
|
||||
mtx->mf[1][2] = (rx * czx) + (ry * czy) + (rz * czz);
|
||||
|
||||
rx = mtx->mf[2][0];
|
||||
ry = mtx->mf[2][1];
|
||||
rz = mtx->mf[2][2];
|
||||
mtx->mf[2][0] = (rx * cxx) + (ry * cxy) + (rz * cxz);
|
||||
mtx->mf[2][1] = (rx * cyx) + (ry * cyy) + (rz * cyz);
|
||||
mtx->mf[2][2] = (rx * czx) + (ry * czy) + (rz * czz);
|
||||
} else {
|
||||
mtx->mf[0][0] = (1.0f - xx) * cosA + xx;
|
||||
mtx->mf[0][1] = (1.0f - cosA) * xy + axisZ * sinA;
|
||||
mtx->mf[0][2] = (1.0f - cosA) * xz - axisY * sinA;
|
||||
mtx->mf[0][3] = 0.0f;
|
||||
|
||||
mtx->mf[1][0] = (1.0f - cosA) * xy - axisZ * sinA;
|
||||
mtx->mf[1][1] = (1.0f - yy) * cosA + yy;
|
||||
mtx->mf[1][2] = (1.0f - cosA) * yz + axisX * sinA;
|
||||
mtx->mf[1][3] = 0.0f;
|
||||
|
||||
mtx->mf[2][0] = (1.0f - cosA) * xz + axisY * sinA;
|
||||
mtx->mf[2][1] = (1.0f - cosA) * yz - axisX * sinA;
|
||||
mtx->mf[2][2] = (1.0f - zz) * cosA + zz;
|
||||
mtx->mf[2][3] = 0.0f;
|
||||
|
||||
mtx->mf[3][0] = mtx->mf[3][1] = mtx->mf[3][2] = 0.0f;
|
||||
mtx->mf[3][3] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Converts the current Gfx matrix to a Mtx
|
||||
void Matrix_ToMtx(Mtx* dest) {
|
||||
// LTODO: We need to validate this
|
||||
guMtxF2L(gGfxMatrix->mf, dest);
|
||||
}
|
||||
|
||||
// Converts the Mtx src to a Matrix, putting the result in dest
|
||||
void Matrix_FromMtx(Mtx* src, Matrix* dest) {
|
||||
guMtxF2L(src->m, dest->mf);
|
||||
}
|
||||
|
||||
// Applies the transform matrix mtx to the vector src, putting the result in dest
|
||||
void Matrix_MultVec3f(Matrix* mtx, Vec3f* src, Vec3f* dest) {
|
||||
*dest[0] = (mtx->mf[0][0] * *src[0]) + (mtx->mf[1][0] * *src[1]) + (mtx->mf[2][0] * *src[2]) + mtx->mf[3][0];
|
||||
*dest[1] = (mtx->mf[0][1] * *src[0]) + (mtx->mf[1][1] * *src[1]) + (mtx->mf[2][1] * *src[2]) + mtx->mf[3][1];
|
||||
*dest[2] = (mtx->mf[0][2] * *src[0]) + (mtx->mf[1][2] * *src[1]) + (mtx->mf[2][2] * *src[2]) + mtx->mf[3][2];
|
||||
}
|
||||
|
||||
// Applies the linear part of the transformation matrix mtx to the vector src, ignoring any translation that mtx might
|
||||
// have. Puts the result in dest.
|
||||
void Matrix_MultVec3fNoTranslate(Matrix* mtx, Vec3f* src, Vec3f* dest) {
|
||||
*dest[0] = (mtx->mf[0][0] * *src[0]) + (mtx->mf[1][0] * *src[1]) + (mtx->mf[2][0] * *src[2]);
|
||||
*dest[1] = (mtx->mf[0][1] * *src[0]) + (mtx->mf[1][1] * *src[1]) + (mtx->mf[2][1] * *src[2]);
|
||||
*dest[2] = (mtx->mf[0][2] * *src[0]) + (mtx->mf[1][2] * *src[1]) + (mtx->mf[2][2] * *src[2]);
|
||||
}
|
||||
|
||||
// Expresses the rotational part of the transform mtx as Tait-Bryan angles, in the yaw-pitch-roll (intrinsic YXZ)
|
||||
// convention used in worldspace calculations
|
||||
void Matrix_GetYRPAngles(Matrix* mtx, Vec3f* rot) {
|
||||
Matrix invYP;
|
||||
Vec3f origin = { 0.0f, 0.0f, 0.0f };
|
||||
Vec3f originP;
|
||||
Vec3f zHat = { 0.0f, 0.0f, 1.0f };
|
||||
Vec3f zHatP;
|
||||
Vec3f xHat = { 1.0f, 0.0f, 0.0f };
|
||||
Vec3f xHatP;
|
||||
|
||||
Matrix_MultVec3fNoTranslate(mtx, &origin, &originP);
|
||||
Matrix_MultVec3fNoTranslate(mtx, &zHat, &zHatP);
|
||||
Matrix_MultVec3fNoTranslate(mtx, &xHat, &xHatP);
|
||||
zHatP[0] -= originP[0];
|
||||
zHatP[1] -= originP[1];
|
||||
zHatP[2] -= originP[2];
|
||||
xHatP[0] -= originP[0];
|
||||
xHatP[1] -= originP[1];
|
||||
xHatP[2] -= originP[2];
|
||||
*rot[1] = atan2f(zHatP[0], zHatP[2]);
|
||||
*rot[0] = -atan2f(zHatP[1], sqrtf(SQ(zHatP[0]) + SQ(zHatP[2])));
|
||||
Matrix_RotateX(&invYP, -*rot[0], MTXF_NEW);
|
||||
Matrix_RotateY(&invYP, -*rot[1], MTXF_APPLY);
|
||||
Matrix_MultVec3fNoTranslate(&invYP, &xHatP, &xHat);
|
||||
*rot[0] *= M_RTOD;
|
||||
*rot[1] *= M_RTOD;
|
||||
*rot[2] = atan2f(xHat[1], xHat[0]) * M_RTOD;
|
||||
}
|
||||
|
||||
// Expresses the rotational part of the transform mtx as Tait-Bryan angles, in the extrinsic XYZ convention used in
|
||||
// modelspace calculations
|
||||
void Matrix_GetXYZAngles(Matrix* mtx, Vec3f* rot) {
|
||||
Matrix invYZ;
|
||||
Vec3f origin = { 0.0f, 0.0f, 0.0f };
|
||||
Vec3f originP;
|
||||
Vec3f xHat = { 1.0f, 0.0f, 0.0f };
|
||||
Vec3f xHatP;
|
||||
Vec3f yHat = { 0.0f, 1.0f, 0.0f };
|
||||
Vec3f yHatP;
|
||||
|
||||
Matrix_MultVec3fNoTranslate(mtx, &origin, &originP);
|
||||
Matrix_MultVec3fNoTranslate(mtx, &xHat, &xHatP);
|
||||
Matrix_MultVec3fNoTranslate(mtx, &yHat, &yHatP);
|
||||
xHatP[0] -= originP[0];
|
||||
xHatP[1] -= originP[1];
|
||||
xHatP[2] -= originP[2];
|
||||
yHatP[0] -= originP[0];
|
||||
yHatP[1] -= originP[1];
|
||||
yHatP[2] -= originP[2];
|
||||
*rot[2] = atan2f(xHatP[1], xHatP[0]);
|
||||
*rot[1] = -atan2f(xHatP[2], sqrtf(SQ(xHatP[0]) + SQ(xHatP[1])));
|
||||
Matrix_RotateY(&invYZ, -*rot[1], MTXF_NEW);
|
||||
Matrix_RotateZ(&invYZ, -*rot[2], MTXF_APPLY);
|
||||
Matrix_MultVec3fNoTranslate(&invYZ, &yHatP, &yHat);
|
||||
*rot[0] = atan2f(yHat[2], yHat[1]) * M_RTOD;
|
||||
*rot[1] *= M_RTOD;
|
||||
*rot[2] *= M_RTOD;
|
||||
}
|
||||
|
||||
// Creates a look-at matrix from Eye, At, and Up in mtx (MTXF_NEW) or applies one to mtx (MTXF_APPLY).
|
||||
// A look-at matrix is a rotation-translation matrix that maps y to Up, z to (At - Eye), and translates to Eye
|
||||
void Matrix_LookAt(Matrix* mtx, f32 xEye, f32 yEye, f32 zEye, f32 xAt, f32 yAt, f32 zAt, f32 xUp, f32 yUp, f32 zUp,
|
||||
u8 mode) {
|
||||
Matrix lookAt;
|
||||
|
||||
guLookAtF(lookAt.mf, xEye, yEye, zEye, xAt, yAt, zAt, xUp, yUp, zUp);
|
||||
Matrix_Mult(mtx, &lookAt, mode);
|
||||
}
|
||||
|
||||
// Converts the current Gfx matrix to a Mtx and sets it to the display list
|
||||
void Matrix_SetGfxMtx(Gfx** gfx) {
|
||||
Matrix_ToMtx(gGfxMtx);
|
||||
gSPMatrix((*gfx)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
#pragma once
|
||||
|
||||
#define MTXF_NEW 0
|
||||
#define MTXF_APPLY 1
|
||||
#include "common_structs.h"
|
||||
|
||||
typedef struct {
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
} Color;
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} Vec3fInterp;
|
||||
|
||||
typedef struct {
|
||||
s16 x;
|
||||
s16 y;
|
||||
s16 z;
|
||||
} Vec3sInterp;
|
||||
|
||||
typedef struct {
|
||||
f32 m1; f32 m2; f32 m3; f32 m4;
|
||||
f32 m5; f32 m6; f32 m7; f32 m8;
|
||||
} Mat4Interp;
|
||||
|
||||
#define M_PI 3.14159265358979323846f
|
||||
#define M_RTOD (180.0f / M_PI)
|
||||
#define SQ(val) ((val) * (val))
|
||||
|
||||
#define qs1616(e) ((s32) ((e) *0x00010000))
|
||||
|
||||
#define IPART(x) ((qs1616(x) >> 16) & 0xFFFF)
|
||||
#define FPART(x) (qs1616(x) & 0xFFFF)
|
||||
|
||||
#define gdSPDefMtx(xx, yx, zx, wx, xy, yy, zy, wy, xz, yz, zz, wz, xw, yw, zw, ww) \
|
||||
{ \
|
||||
{ \
|
||||
(IPART(xx) << 0x10) | IPART(xy), (IPART(xz) << 0x10) | IPART(xw), (IPART(yx) << 0x10) | IPART(yy), \
|
||||
(IPART(yz) << 0x10) | IPART(yw), (IPART(zx) << 0x10) | IPART(zy), (IPART(zz) << 0x10) | IPART(zw), \
|
||||
(IPART(wx) << 0x10) | IPART(wy), (IPART(wz) << 0x10) | IPART(ww), (FPART(xx) << 0x10) | FPART(xy), \
|
||||
(FPART(xz) << 0x10) | FPART(xw), (FPART(yx) << 0x10) | FPART(yy), (FPART(yz) << 0x10) | FPART(yw), \
|
||||
(FPART(zx) << 0x10) | FPART(zy), (FPART(zz) << 0x10) | FPART(zw), (FPART(wx) << 0x10) | FPART(wy), \
|
||||
(FPART(wz) << 0x10) | FPART(ww), \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
typedef MtxF Matrix;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern Mtx gIdentityMtx;
|
||||
extern Matrix gIdentityMatrix;
|
||||
|
||||
extern Matrix* gGfxMatrix;
|
||||
extern Matrix sGfxMatrixStack[];
|
||||
extern Matrix* gCalcMatrix;
|
||||
extern Matrix sCalcMatrixStack[];
|
||||
|
||||
extern Mtx gMainMatrixStack[];
|
||||
extern Mtx* gGfxMtx;
|
||||
|
||||
void Matrix_InitPerspective(Gfx** dList);
|
||||
void Matrix_InitOrtho(Gfx** dList);
|
||||
void Matrix_Copy(Matrix* dst, Matrix* src);
|
||||
void Matrix_Push(Matrix** mtxStack);
|
||||
void Matrix_Pop(Matrix** mtxStack);
|
||||
void Matrix_Mult(Matrix* mtx, Matrix* tf, u8 mode);
|
||||
void Matrix_Translate(Matrix* mtx, f32 x, f32 y, f32 z, u8 mode);
|
||||
void Matrix_Scale(Matrix* mtx, f32 xScale, f32 yScale, f32 zScale, u8 mode);
|
||||
void Matrix_RotateX(Matrix* mtx, f32 angle, u8 mode);
|
||||
void Matrix_RotateY(Matrix* mtx, f32 angle, u8 mode);
|
||||
void Matrix_RotateZ(Matrix* mtx, f32 angle, u8 mode);
|
||||
void Matrix_RotateAxis(Matrix* mtx, f32 angle, f32 axisX, f32 axisY, f32 axisZ, u8 mode);
|
||||
void Matrix_ToMtx(Mtx* dest);
|
||||
void Matrix_FromMtx(Mtx* src, Matrix* dest);
|
||||
void Matrix_MultVec3f(Matrix* mtx, Vec3f* src, Vec3f* dest);
|
||||
void Matrix_MultVec3fNoTranslate(Matrix* mtx, Vec3f* src, Vec3f* dest);
|
||||
void Matrix_GetYRPAngles(Matrix* mtx, Vec3f* rot);
|
||||
void Matrix_GetXYZAngles(Matrix* mtx, Vec3f* rot);
|
||||
void Matrix_LookAt(Matrix* mtx, f32 xEye, f32 yEye, f32 zEye, f32 xAt, f32 yAt, f32 zAt, f32 xUp, f32 yUp, f32 zUp,
|
||||
u8 mode);
|
||||
void Matrix_SetGfxMtx(Gfx** gfx);
|
||||
void Lights_SetOneLight(Gfx** dList, s32 dirX, s32 dirY, s32 dirZ, s32 colR, s32 colG, s32 colB, s32 ambR, s32 ambG, s32 ambB);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -21,6 +21,7 @@ SM64::AudioBankFactoryV0::ReadResource(std::shared_ptr<Ship::File> file,
|
|||
auto* instrument = new Instrument();
|
||||
bool valid = reader->ReadUByte();
|
||||
if(!valid){
|
||||
delete instrument;
|
||||
bank->instruments.push_back(nullptr);
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,4 +8,21 @@ CtlEntry* AudioBank::GetPointer() {
|
|||
size_t AudioBank::GetPointerSize() {
|
||||
return sizeof(mData);
|
||||
}
|
||||
AudioBank::~AudioBank() {
|
||||
for (auto& instrument : instruments) {
|
||||
if (instrument != nullptr) {
|
||||
if (instrument->envelope != nullptr) {
|
||||
delete[] instrument->envelope;
|
||||
instrument->envelope = nullptr;
|
||||
}
|
||||
delete instrument;
|
||||
}
|
||||
|
||||
}
|
||||
for (auto& drum : drums) {
|
||||
delete drum;
|
||||
}
|
||||
instruments.clear();
|
||||
drums.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -47,6 +47,7 @@ class AudioBank : public Ship::Resource<CtlEntry> {
|
|||
using Resource::Resource;
|
||||
|
||||
AudioBank() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {}
|
||||
~AudioBank() override;
|
||||
|
||||
CtlEntry* GetPointer();
|
||||
size_t GetPointerSize();
|
||||
|
|
|
|||
|
|
@ -8,4 +8,18 @@ AudioBankSample* AudioSample::GetPointer() {
|
|||
size_t AudioSample::GetPointerSize() {
|
||||
return sizeof(mData);
|
||||
}
|
||||
AudioSample::~AudioSample() {
|
||||
if (mData.sampleAddr != nullptr) {
|
||||
// delete[] mData.sampleAddr;
|
||||
mData.sampleAddr = nullptr;
|
||||
}
|
||||
if (mData.book->book != nullptr) {
|
||||
delete[] mData.book->book;
|
||||
mData.book->book = nullptr;
|
||||
}
|
||||
if (mData.loop->state != nullptr) {
|
||||
delete[] mData.loop->state;
|
||||
mData.loop->state = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ class AudioSample : public Ship::Resource<AudioBankSample> {
|
|||
using Resource::Resource;
|
||||
|
||||
AudioSample() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {}
|
||||
~AudioSample() override;
|
||||
|
||||
AudioBankSample* GetPointer();
|
||||
size_t GetPointerSize();
|
||||
|
|
|
|||
|
|
@ -147,12 +147,13 @@ namespace Editor {
|
|||
}
|
||||
}
|
||||
|
||||
// When resetting the known content, we need to also pop the custom courses
|
||||
// out of World::Courses vector. Otherwise, duplicate courses would show up for users.
|
||||
void ContentBrowserWindow::RemoveCustomTracksFromTrackList() {
|
||||
for (auto& track : Tracks) {
|
||||
auto it = gWorldInstance.Courses.begin();
|
||||
while (it != gWorldInstance.Courses.end()) {
|
||||
if (track.course == *it) {
|
||||
delete *it;
|
||||
if (track.course == it->get()) {
|
||||
it = gWorldInstance.Courses.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
|
|
@ -233,27 +234,31 @@ namespace Editor {
|
|||
std::string name = dir.substr(dir.find_last_of('/') + 1);
|
||||
std::string sceneFile = dir + "/scene.json";
|
||||
std::string minimapFile = dir + "/minimap.png";
|
||||
// The track has a valid scene file
|
||||
if (manager->HasFile(sceneFile)) {
|
||||
auto archive = manager->GetArchiveFromFile(sceneFile);
|
||||
|
||||
Course* course = new Course();
|
||||
auto course = std::make_unique<Course>();
|
||||
course->LoadO2R(dir);
|
||||
gWorldInstance.Courses.push_back(course);
|
||||
LoadLevel(archive, course, sceneFile);
|
||||
LoadMinimap(archive, course, minimapFile);
|
||||
Tracks.push_back({course, sceneFile, name, dir, archive});
|
||||
} else {
|
||||
gWorldInstance.Courses.push_back(std::move(course));
|
||||
LoadLevel(archive, course.get(), sceneFile);
|
||||
LoadMinimap(archive, course.get(), minimapFile);
|
||||
Tracks.push_back({course.get(), sceneFile, name, dir, archive});
|
||||
} 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)) {
|
||||
|
||||
Course* course = new Course();
|
||||
auto course = std::make_unique<Course>();
|
||||
course->Id = (std::string("mods:") + name).c_str();
|
||||
course->Props.SetText(course->Props.Name, name.c_str(), sizeof(course->Props.Name));
|
||||
course->Props.SetText(course->Props.DebugName, name.c_str(), sizeof(course->Props.Name));
|
||||
|
||||
auto archive = manager->GetArchiveFromFile(file);
|
||||
Tracks.push_back({course, "", name, dir, archive});
|
||||
Tracks.push_back({course.get(), "", name, dir, archive});
|
||||
} 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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@
|
|||
#endif
|
||||
|
||||
extern "C" {
|
||||
extern s32 gGamestateNext;
|
||||
extern s32 gMenuSelection;
|
||||
#include "audio/external.h"
|
||||
#include "defines.h"
|
||||
extern s32 gGamestateNext;
|
||||
extern s32 gMenuSelection;
|
||||
#include "audio/external.h"
|
||||
#include "defines.h"
|
||||
}
|
||||
|
||||
namespace GameUI {
|
||||
|
|
@ -158,9 +158,8 @@ void PortMenu::AddSettings() {
|
|||
.IsPercentage());
|
||||
AddWidget(path, "Main Music Volume: %.0f%%", WIDGET_CVAR_SLIDER_FLOAT)
|
||||
.CVar("gMainMusicVolume")
|
||||
.Callback([](WidgetInfo& info) {
|
||||
audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f));
|
||||
})
|
||||
.Callback(
|
||||
[](WidgetInfo& info) { audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f)); })
|
||||
.Options(FloatSliderOptions()
|
||||
.Tooltip("Adjust the background music volume.")
|
||||
.ShowButtons(false)
|
||||
|
|
@ -168,16 +167,17 @@ void PortMenu::AddSettings() {
|
|||
.IsPercentage());
|
||||
AddWidget(path, "Sound Effects Volume: %.0f%%", WIDGET_CVAR_SLIDER_FLOAT)
|
||||
.CVar("gSFXMusicVolume")
|
||||
.Callback([](WidgetInfo& info) {
|
||||
audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f));
|
||||
})
|
||||
.Options(
|
||||
FloatSliderOptions().Tooltip("Adjust the sound effects volume.").ShowButtons(false).Format("").IsPercentage());
|
||||
.Callback(
|
||||
[](WidgetInfo& info) { audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f)); })
|
||||
.Options(FloatSliderOptions()
|
||||
.Tooltip("Adjust the sound effects volume.")
|
||||
.ShowButtons(false)
|
||||
.Format("")
|
||||
.IsPercentage());
|
||||
AddWidget(path, "Sound Effects Volume: %.0f%%", WIDGET_CVAR_SLIDER_FLOAT)
|
||||
.CVar("gEnvironmentVolume")
|
||||
.Callback([](WidgetInfo& info) {
|
||||
audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f));
|
||||
})
|
||||
.Callback(
|
||||
[](WidgetInfo& info) { audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f)); })
|
||||
.Options(FloatSliderOptions()
|
||||
.Tooltip("Adjust the environment volume.")
|
||||
.ShowButtons(false)
|
||||
|
|
@ -244,25 +244,25 @@ void PortMenu::AddSettings() {
|
|||
.DefaultValue(1));
|
||||
#endif
|
||||
|
||||
// AddWidget(path, "Current FPS: %d", WIDGET_CVAR_SLIDER_INT)
|
||||
// .CVar("gInterpolationFPS")
|
||||
// .Callback([](WidgetInfo& info) {
|
||||
// int32_t defaultValue = std::static_pointer_cast<IntSliderOptions>(info.options)->defaultValue;
|
||||
// if (CVarGetInteger(info.cVar, defaultValue) == defaultValue) {
|
||||
// info.name = "Current FPS: Original (%d)";
|
||||
// } else {
|
||||
// info.name = "Current FPS: %d";
|
||||
// }
|
||||
// })
|
||||
// .PreFunc([](WidgetInfo& info) {
|
||||
// if (mPortMenu->disabledMap.at(DISABLE_FOR_MATCH_REFRESH_RATE_ON).active)
|
||||
// info.activeDisables.push_back(DISABLE_FOR_MATCH_REFRESH_RATE_ON);
|
||||
// })
|
||||
// .Options(IntSliderOptions().Tooltip(tooltip).Min(20).Max(maxFps).DefaultValue(20));
|
||||
AddWidget(path, "Current FPS: %d", WIDGET_CVAR_SLIDER_INT)
|
||||
.CVar("gInterpolationFPS")
|
||||
.Callback([](WidgetInfo& info) {
|
||||
int32_t defaultValue = std::static_pointer_cast<IntSliderOptions>(info.options)->defaultValue;
|
||||
if (CVarGetInteger(info.cVar, defaultValue) == defaultValue) {
|
||||
info.name = "Current FPS: Original (%d)";
|
||||
} else {
|
||||
info.name = "Current FPS: %d";
|
||||
}
|
||||
})
|
||||
.PreFunc([](WidgetInfo& info) {
|
||||
if (mPortMenu->disabledMap.at(DISABLE_FOR_MATCH_REFRESH_RATE_ON).active)
|
||||
info.activeDisables.push_back(DISABLE_FOR_MATCH_REFRESH_RATE_ON);
|
||||
})
|
||||
.Options(IntSliderOptions().Tooltip(tooltip).Min(30).Max(maxFps).DefaultValue(30));
|
||||
AddWidget(path, "Match Refresh Rate", WIDGET_BUTTON)
|
||||
.Callback([](WidgetInfo& info) {
|
||||
int hz = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate();
|
||||
if (hz >= 20 && hz <= 360) {
|
||||
if (hz >= 30 && hz <= 360) {
|
||||
CVarSetInteger("gInterpolationFPS", hz);
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
|
|
@ -332,31 +332,36 @@ void PortMenu::AddEnhancements() {
|
|||
AddMenuEntry("Enhancements", "gSettings.Menu.EnhancementsSidebarSection");
|
||||
WidgetPath path = { "Enhancements", "General", SECTION_COLUMN_1 };
|
||||
AddSidebarEntry("Enhancements", "General", 3);
|
||||
//UIWidgets::WindowButton("Multiplayer", "gMultiplayerWindowEnabled", GameUI::mMultiplayerWindow,
|
||||
// { .tooltip = "Shows the multiplayer window" });
|
||||
// UIWidgets::WindowButton("Freecam", "gFreecam", GameUI::mFreecamWindow,
|
||||
// { .tooltip = "Allows you to fly around the course" });
|
||||
// UIWidgets::WindowButton("Multiplayer", "gMultiplayerWindowEnabled", GameUI::mMultiplayerWindow,
|
||||
// { .tooltip = "Shows the multiplayer window" });
|
||||
// UIWidgets::WindowButton("Freecam", "gFreecam", GameUI::mFreecamWindow,
|
||||
// { .tooltip = "Allows you to fly around the course" });
|
||||
AddWidget(path, "No multiplayer feature cuts", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar("gMultiplayerNoFeatureCuts")
|
||||
.Options(CheckboxOptions().Tooltip("Allows full train and jumbotron in multiplayer, etc."));
|
||||
AddWidget(path, "General Improvements", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar("gImprovements").Options(CheckboxOptions().Tooltip("General improvements to the game experience."));
|
||||
.CVar("gImprovements")
|
||||
.Options(CheckboxOptions().Tooltip("General improvements to the game experience."));
|
||||
AddWidget(path, "No Level of Detail (LOD)", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar("gDisableLod")
|
||||
.Options(CheckboxOptions().Tooltip("Disable Level of Detail (LOD) to avoid models using lower poly versions at a distance"));
|
||||
.Options(CheckboxOptions().Tooltip(
|
||||
"Disable Level of Detail (LOD) to avoid models using lower poly versions at a distance"));
|
||||
AddWidget(path, "Disable Culling", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar("gNoCulling").Options(CheckboxOptions().Tooltip("Disable original culling of mk64"));
|
||||
.CVar("gNoCulling")
|
||||
.Options(CheckboxOptions().Tooltip("Disable original culling of mk64"));
|
||||
AddWidget(path, "Far Frustrum", WIDGET_CVAR_SLIDER_FLOAT)
|
||||
.CVar("gFarFrustrum")
|
||||
.Options(FloatSliderOptions().Min(0.0f).Max(10000.0f).DefaultValue(10000.0f)
|
||||
.Tooltip("Say how Far the Frustrum are when 'Disable Culling' are enable").Step(10.0f));
|
||||
.Options(FloatSliderOptions()
|
||||
.Min(0.0f)
|
||||
.Max(10000.0f)
|
||||
.DefaultValue(10000.0f)
|
||||
.Tooltip("Say how Far the Frustrum are when 'Disable Culling' are enable")
|
||||
.Step(10.0f));
|
||||
|
||||
path = { "Enhancements", "Cheats", SECTION_COLUMN_1 };
|
||||
AddSidebarEntry("Enhancements", "Cheats", 3);
|
||||
AddWidget(path, "Moon Jump", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar("gEnableMoonJump");
|
||||
AddWidget(path, "Enable Custom CC", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar("gEnableCustomCC");
|
||||
AddWidget(path, "Moon Jump", WIDGET_CVAR_CHECKBOX).CVar("gEnableMoonJump");
|
||||
AddWidget(path, "Enable Custom CC", WIDGET_CVAR_CHECKBOX).CVar("gEnableCustomCC");
|
||||
AddWidget(path, "Custom CC", WIDGET_CVAR_SLIDER_FLOAT)
|
||||
.CVar("gCustomCC")
|
||||
.Options(FloatSliderOptions().Min(0.0f).Max(1000.0f).DefaultValue(150.0f).Step(10.0f));
|
||||
|
|
@ -365,21 +370,23 @@ void PortMenu::AddEnhancements() {
|
|||
.Options(CheckboxOptions().Tooltip("Disable wall collision."));
|
||||
AddWidget(path, "Min Height", WIDGET_CVAR_SLIDER_FLOAT)
|
||||
.CVar("gMinHeight")
|
||||
.Options(FloatSliderOptions().Min(-50.0f).Max(50.0f).DefaultValue(0.0f)
|
||||
.Tooltip("When Disable Wall Collision are enable what is the minimal height you can get."));
|
||||
.Options(FloatSliderOptions().Min(-50.0f).Max(50.0f).DefaultValue(0.0f).Tooltip(
|
||||
"When Disable Wall Collision are enable what is the minimal height you can get."));
|
||||
|
||||
#if not defined(__SWITCH__) and not defined(__WIIU__)
|
||||
path = { "Enhancements", "HM64 Lab", SECTION_COLUMN_1 };
|
||||
AddSidebarEntry("Enhancements", "HM64 Lab", 4);
|
||||
AddWidget(path, "Enable HM64 Labs", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar("gEditorEnabled")
|
||||
.Callback([](WidgetInfo& info) {
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Tools")->ToggleVisibility();
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Scene Explorer")->ToggleVisibility();
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Content Browser")->ToggleVisibility();
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Track Properties")->ToggleVisibility();
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Properties")->ToggleVisibility();
|
||||
})
|
||||
.Options(UIWidgets::CheckboxOptions({{ .tooltip = "Edit the universe!"}}));
|
||||
.CVar("gEditorEnabled")
|
||||
.Callback([](WidgetInfo& info) {
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Tools")->ToggleVisibility();
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Scene Explorer")->ToggleVisibility();
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Content Browser")->ToggleVisibility();
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Track Properties")->ToggleVisibility();
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Properties")->ToggleVisibility();
|
||||
})
|
||||
.Options(UIWidgets::CheckboxOptions({ { .tooltip = "Edit the universe!" } }));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __SWITCH__
|
||||
|
|
@ -400,11 +407,11 @@ void PortMenu::AddDevTools() {
|
|||
WidgetPath path = { "Developer", "General", SECTION_COLUMN_1 };
|
||||
#ifdef __SWITCH__
|
||||
AddWidget(path, "Switch CPU Profile", WIDGET_CVAR_COMBOBOX)
|
||||
.CVar("gSwitchPerfMode")
|
||||
.Options(ComboboxOptions()
|
||||
.Tooltip("Switches the CPU profile to a different one")
|
||||
.ComboMap(switchCPUProfiles)
|
||||
.DefaultIndex(Ship::SwitchProfiles::STOCK))
|
||||
.CVar("gSwitchPerfMode")
|
||||
.Options(ComboboxOptions()
|
||||
.Tooltip("Switches the CPU profile to a different one")
|
||||
.ComboMap(switchCPUProfiles)
|
||||
.DefaultIndex(Ship::SwitchProfiles::STOCK))
|
||||
.Callback([](WidgetInfo& info) { Ship::Switch::ApplyOverclock(); });
|
||||
#endif
|
||||
AddWidget(path, "Popout Menu", WIDGET_CVAR_CHECKBOX)
|
||||
|
|
@ -413,6 +420,17 @@ void PortMenu::AddDevTools() {
|
|||
AddWidget(path, "Debug Mode", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar("gEnableDebugMode")
|
||||
.Options(CheckboxOptions().Tooltip("Enables Debug Mode."));
|
||||
AddWidget(path, "Modify Interpolation Target FPS", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar("gModifyInterpolationTargetFPS")
|
||||
.Options(CheckboxOptions().Tooltip("Enables Debug Mode."));
|
||||
AddWidget(path, "Interpolation Target FPS", WIDGET_CVAR_SLIDER_INT)
|
||||
.CVar("gInterpolationTargetFPS")
|
||||
.PreFunc([](WidgetInfo& info) { info.isHidden = !CVarGetInteger("gModifyInterpolationTargetFPS", 0); })
|
||||
.Options(IntSliderOptions()
|
||||
.Tooltip("Sets the target FPS for interpolation. When Modify Interpolation Target FPS are enable")
|
||||
.Min(15)
|
||||
.Max(360)
|
||||
.DefaultValue(60));
|
||||
AddWidget(path, "Render Collision", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar("gRenderCollisionMesh")
|
||||
.Options(CheckboxOptions().Tooltip("Renders the collision mesh instead of the course mesh"));
|
||||
|
|
@ -429,7 +447,8 @@ void PortMenu::AddDevTools() {
|
|||
AddSidebarEntry("Developer", "Stats", 1);
|
||||
AddWidget(path, "Popout Stats", WIDGET_WINDOW_BUTTON)
|
||||
.CVar("gStatsEnabled")
|
||||
.Options(ButtonOptions().Tooltip("Shows the stats window, with your FPS and frametimes, and the OS you're playing on"))
|
||||
.Options(ButtonOptions().Tooltip(
|
||||
"Shows the stats window, with your FPS and frametimes, and the OS you're playing on"))
|
||||
.WindowName("Stats");
|
||||
|
||||
path = { "Developer", "Console", SECTION_COLUMN_1 };
|
||||
|
|
@ -445,9 +464,9 @@ PortMenu::PortMenu(const std::string& consoleVariable, const std::string& name)
|
|||
: Menu(consoleVariable, name, 0, UIWidgets::Colors::LightBlue) {
|
||||
}
|
||||
|
||||
//bool CheckNetworkConnected(disabledInfo& info) {
|
||||
// return gNetwork.isConnected;
|
||||
//}
|
||||
// bool CheckNetworkConnected(disabledInfo& info) {
|
||||
// return gNetwork.isConnected;
|
||||
// }
|
||||
|
||||
void PortMenu::InitElement() {
|
||||
Ship::Menu::InitElement();
|
||||
|
|
@ -531,4 +550,4 @@ void PortMenu::Draw() {
|
|||
void PortMenu::DrawElement() {
|
||||
Ship::Menu::DrawElement();
|
||||
}
|
||||
} // namespace BenGui
|
||||
} // namespace GameUI
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <assets/wario_stadium_data.h>
|
||||
#include <assets/frappe_snowland_data.h>
|
||||
#include "port/Game.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
// Appears to be textures
|
||||
// or tluts
|
||||
|
|
@ -509,6 +510,7 @@ void render_cows(Camera* camera, Mat4 arg1) {
|
|||
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_TEX_EDGE, G_RM_AA_ZB_TEX_EDGE2);
|
||||
var_s5 = NULL;
|
||||
var_s1 = var_t1;
|
||||
|
||||
while (var_s1->pos[0] != END_OF_SPAWN_DATA) {
|
||||
sp88[0] = var_s1->pos[0] * gCourseDirection;
|
||||
sp88[1] = var_s1->pos[1];
|
||||
|
|
@ -523,6 +525,12 @@ void render_cows(Camera* camera, Mat4 arg1) {
|
|||
arg1[3][0] = sp88[0];
|
||||
arg1[3][1] = sp88[1];
|
||||
arg1[3][2] = sp88[2];
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("render_actor_cow", ((var_s1->pos[0] & 0xFFFF) << 32) |
|
||||
((var_s1->pos[1] & 0xFFFF) << 16) |
|
||||
(var_s1->pos[2] & 0xFFFF));
|
||||
|
||||
if ((gMatrixObjectCount < MTX_OBJECT_POOL_SIZE) && (render_set_position(arg1, 0) != 0)) {
|
||||
switch (var_s1->someId) {
|
||||
case 0:
|
||||
|
|
@ -544,6 +552,9 @@ void render_cows(Camera* camera, Mat4 arg1) {
|
|||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
var_s1++;
|
||||
}
|
||||
|
|
@ -654,6 +665,11 @@ void render_palm_trees(Camera* camera, Mat4 arg1) {
|
|||
continue;
|
||||
}
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("render_actor_cow", ((var_s1->pos[0] & 0xFFFF) << 32) |
|
||||
((var_s1->pos[1] & 0xFFFF) << 16) |
|
||||
(var_s1->pos[2] & 0xFFFF));
|
||||
|
||||
test &= 0xF;
|
||||
test = (s16) test;
|
||||
if (test == 6) {
|
||||
|
|
@ -690,6 +706,8 @@ void render_palm_trees(Camera* camera, Mat4 arg1) {
|
|||
}
|
||||
var_s1++;
|
||||
}
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -708,6 +726,9 @@ void render_actor_shell(Camera* camera, Mat4 matrix, struct ShellActor* shell) {
|
|||
// Is it doing this by modifying a an address?
|
||||
uintptr_t phi_t3;
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Shell", TAG_ITEM_ADDR(shell));
|
||||
|
||||
f32 temp_f0 =
|
||||
is_within_render_distance(camera->pos, shell->pos, camera->rot[1], 0, gCameraZoom[camera - camera1], 490000.0f);
|
||||
if (CVarGetInteger("gNoCulling", 0) == 1) {
|
||||
|
|
@ -749,6 +770,9 @@ void render_actor_shell(Camera* camera, Mat4 matrix, struct ShellActor* shell) {
|
|||
} else {
|
||||
gSPDisplayList(gDisplayListHead++, D_0D005368);
|
||||
}
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
UNUSED s16 D_802B8808[] = { 0x0014, 0x0028, 0x0000, 0x0000 };
|
||||
|
|
@ -920,15 +944,15 @@ void spawn_foliage(struct ActorSpawnData* actor) {
|
|||
position[2] = var_s3->pos[2];
|
||||
position[1] = var_s3->pos[1];
|
||||
|
||||
if (GetCourse() == GetMarioRaceway()) {
|
||||
if (IsMarioRaceway()) {
|
||||
actorType = 2;
|
||||
} else if (GetCourse() == GetBowsersCastle()) {
|
||||
} else if (IsBowsersCastle()) {
|
||||
actorType = 0x0021;
|
||||
} else if (GetCourse() == GetYoshiValley()) {
|
||||
} else if (IsYoshiValley()) {
|
||||
actorType = 3;
|
||||
} else if (GetCourse() == GetFrappeSnowland()) {
|
||||
} else if (IsFrappeSnowland()) {
|
||||
actorType = 0x001D;
|
||||
} else if (GetCourse() == GetRoyalRaceway()) {
|
||||
} else if (IsRoyalRaceway()) {
|
||||
switch (var_s3->signedSomeId) {
|
||||
case 6:
|
||||
actorType = 0x001C;
|
||||
|
|
@ -937,11 +961,11 @@ void spawn_foliage(struct ActorSpawnData* actor) {
|
|||
actorType = 4;
|
||||
break;
|
||||
}
|
||||
} else if (GetCourse() == GetLuigiRaceway()) {
|
||||
} else if (IsLuigiRaceway()) {
|
||||
actorType = 0x001A;
|
||||
} else if (GetCourse() == GetMooMooFarm()) {
|
||||
} else if (IsMooMooFarm()) {
|
||||
actorType = 0x0013;
|
||||
} else if (GetCourse() == GetKalimariDesert()) {
|
||||
} else if (IsKalimariDesert()) {
|
||||
switch (var_s3->signedSomeId) {
|
||||
case 5:
|
||||
actorType = 0x001E;
|
||||
|
|
@ -1682,8 +1706,8 @@ bool collision_tree(Player* player, struct Actor* actor) {
|
|||
actorPos[0] = actor->pos[0];
|
||||
actorPos[1] = actor->pos[1];
|
||||
actorPos[2] = actor->pos[2];
|
||||
if (((GetCourse() == GetMarioRaceway()) || (GetCourse() == GetYoshiValley()) ||
|
||||
(GetCourse() == GetRoyalRaceway()) || (GetCourse() == GetLuigiRaceway())) &&
|
||||
if (((IsMarioRaceway()) || (IsYoshiValley()) ||
|
||||
(IsRoyalRaceway()) || (IsLuigiRaceway())) &&
|
||||
(player->unk_094 > 1.0f)) {
|
||||
spawn_leaf(actorPos, 0);
|
||||
}
|
||||
|
|
@ -2437,11 +2461,15 @@ void render_course_actors(struct UnkStruct_800DC5EC* arg0) {
|
|||
if (actor->flags == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FrameInterpolation_RecordOpenChild(actor, i);
|
||||
|
||||
switch (actor->type) {
|
||||
default: // Draw custom actor
|
||||
CM_DrawActors(D_800DC5EC->camera, actor);
|
||||
break;
|
||||
case ACTOR_TREE_MARIO_RACEWAY:
|
||||
|
||||
render_actor_tree_mario_raceway(camera, sBillBoardMtx, actor);
|
||||
break;
|
||||
case ACTOR_TREE_YOSHI_VALLEY:
|
||||
|
|
@ -2541,10 +2569,11 @@ void render_course_actors(struct UnkStruct_800DC5EC* arg0) {
|
|||
render_actor_yoshi_egg(camera, sBillBoardMtx, (struct YoshiValleyEgg*) actor, pathCounter);
|
||||
break;
|
||||
}
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
if (GetCourse() == GetMooMooFarm()) {
|
||||
if (IsMooMooFarm()) {
|
||||
render_cows(camera, sBillBoardMtx);
|
||||
} else if (GetCourse() == GetDkJungle()) {
|
||||
} else if (IsDkJungle()) {
|
||||
render_palm_trees(camera, sBillBoardMtx);
|
||||
}
|
||||
}
|
||||
|
|
@ -2645,7 +2674,7 @@ void update_course_actors(void) {
|
|||
}
|
||||
|
||||
const char* get_actor_name(s32 id) {
|
||||
switch(id) {
|
||||
switch (id) {
|
||||
case ACTOR_FALLING_ROCK:
|
||||
return "Falling Rock";
|
||||
case ACTOR_GREEN_SHELL:
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "mk64.h"
|
||||
#include <assets/common_data.h>
|
||||
#include "port/Engine.h"
|
||||
#include "port/interpolation/matrix.h"
|
||||
#include "math_util.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,16 +8,18 @@
|
|||
#include "math.h"
|
||||
#include "memory.h"
|
||||
#include "engine/Matrix.h"
|
||||
#include "course.h"
|
||||
#include "port/Game.h"
|
||||
|
||||
#include <port/interpolation/FrameInterpolation.h>
|
||||
#include <port/interpolation/matrix.h>
|
||||
#pragma intrinsic(sqrtf, fabs)
|
||||
|
||||
s32 D_802B91C0[2] = { 13, 13 };
|
||||
Vec3f D_802B91C8 = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
Mtx gIdentityMatrix = {
|
||||
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),
|
||||
};
|
||||
// Mtx gIdentityMatrix = {
|
||||
// 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),
|
||||
// };
|
||||
|
||||
// This functions looks similar to a segment of code from func_802A4A0C in skybox_and_splitscreen.c
|
||||
UNUSED s32 func_802B4F60(UNUSED s32 arg0, Vec3f arg1, UNUSED s32 arg2, UNUSED f32 arg3, UNUSED f32 arg4) {
|
||||
|
|
@ -53,7 +55,7 @@ s32 render_set_position(Mat4 mtx, s32 arg1) {
|
|||
if (gMatrixObjectCount >= MTX_OBJECT_POOL_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
//mtxf_to_mtx(&gGfxPool->mtxObject[gMatrixObjectCount], arg0);
|
||||
// mtxf_to_mtx(&gGfxPool->mtxObject[gMatrixObjectCount], arg0);
|
||||
switch (arg1) { /* irregular */
|
||||
case 0:
|
||||
AddObjectMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
|
@ -188,6 +190,7 @@ void mtxf_identity(Mat4 mtx) {
|
|||
// Add a translation vector to a matrix, mat is the matrix to add, dest is the destination matrix, pos is the
|
||||
// translation vector
|
||||
void add_translate_mat4_vec3f(Mat4 mat, Mat4 dest, Vec3f pos) {
|
||||
FrameInterpolation_RecordMatrixTranslate(dest, pos);
|
||||
dest[3][0] = mat[3][0] + pos[0];
|
||||
dest[3][1] = mat[3][1] + pos[1];
|
||||
dest[3][2] = mat[3][2] + pos[2];
|
||||
|
|
@ -222,6 +225,7 @@ UNUSED void add_translate_mat4_vec3f_lite(Mat4 mat, Mat4 dest, Vec3f pos) {
|
|||
|
||||
// create a translation matrix
|
||||
void mtxf_translate(Mat4 dest, Vec3f b) {
|
||||
FrameInterpolation_RecordMatrixTranslate(dest, b);
|
||||
mtxf_identity(dest);
|
||||
dest[3][0] = b[0];
|
||||
dest[3][1] = b[1];
|
||||
|
|
@ -329,6 +333,7 @@ void func_802B5794(Mat4 mtx, Vec3f from, Vec3f to) {
|
|||
|
||||
// create a rotation matrix around the x axis
|
||||
void mtxf_rotate_x(Mat4 mat, s16 angle) {
|
||||
FrameInterpolation_RecordMatrixRotate1Coord(&mat, 0, angle);
|
||||
f32 sin_theta = sins(angle);
|
||||
f32 cos_theta = coss(angle);
|
||||
|
||||
|
|
@ -348,6 +353,7 @@ void mtxf_rotate_x(Mat4 mat, s16 angle) {
|
|||
|
||||
// create a rotation matrix around the y axis
|
||||
void mtxf_rotate_y(Mat4 mat, s16 angle) {
|
||||
FrameInterpolation_RecordMatrixRotate1Coord(&mat, 1, angle);
|
||||
f32 sin_theta = sins(angle);
|
||||
f32 cos_theta = coss(angle);
|
||||
|
||||
|
|
@ -367,6 +373,7 @@ void mtxf_rotate_y(Mat4 mat, s16 angle) {
|
|||
|
||||
// create a rotation matrix around the z axis
|
||||
void mtxf_s16_rotate_z(Mat4 mat, s16 angle) {
|
||||
FrameInterpolation_RecordMatrixRotate1Coord(&mat, 2, angle);
|
||||
f32 sin_theta = sins(angle);
|
||||
f32 cos_theta = coss(angle);
|
||||
|
||||
|
|
@ -384,39 +391,6 @@ void mtxf_s16_rotate_z(Mat4 mat, s16 angle) {
|
|||
*/
|
||||
}
|
||||
|
||||
void func_802B5B14(Vec3f b, Vec3s rotate) {
|
||||
Mat4 mtx;
|
||||
Vec3f copy;
|
||||
|
||||
f32 sx = sins(rotate[0]);
|
||||
f32 cx = coss(rotate[0]);
|
||||
|
||||
f32 sy = sins(rotate[1]);
|
||||
f32 cy = coss(rotate[1]);
|
||||
|
||||
f32 sz = sins(rotate[2]);
|
||||
f32 cz = coss(rotate[2]);
|
||||
|
||||
copy[0] = b[0];
|
||||
copy[1] = b[1];
|
||||
|
||||
mtx[0][0] = cy * cz + sx * sy * sz;
|
||||
mtx[1][0] = -cy * sz + sx * sy * cz;
|
||||
mtx[2][0] = cx * sy;
|
||||
|
||||
mtx[0][1] = cx * sz;
|
||||
mtx[1][1] = cx * cz;
|
||||
mtx[2][1] = -sx;
|
||||
|
||||
mtx[0][2] = -sy * cz + sx * cy * sz;
|
||||
mtx[1][2] = sy * sz + sx * cy * cz;
|
||||
mtx[2][2] = cx * cy;
|
||||
|
||||
b[0] = copy[0] * mtx[0][0] + copy[1] * mtx[0][1] + copy[1] * mtx[0][2];
|
||||
b[1] = copy[0] * mtx[1][0] + copy[1] * mtx[1][1] + copy[1] * mtx[1][2];
|
||||
b[2] = copy[0] * mtx[2][0] + copy[1] * mtx[2][1] + copy[1] * mtx[2][2];
|
||||
}
|
||||
|
||||
void func_802B5CAC(s16 arg0, s16 arg1, Vec3f arg2) {
|
||||
f32 sp2C = sins(arg1);
|
||||
f32 sp28 = coss(arg1);
|
||||
|
|
@ -460,6 +434,7 @@ void set_track_light_direction(Lights1* addr, s16 pitch, s16 yaw, s32 numLights)
|
|||
|
||||
// multiply a matrix with a number
|
||||
void mtxf_scale(Mat4 mat, f32 coef) {
|
||||
FrameInterpolation_RecordMatrixScale(mat, coef);
|
||||
mat[0][0] *= coef;
|
||||
mat[1][0] *= coef;
|
||||
mat[2][0] *= coef;
|
||||
|
|
@ -479,6 +454,7 @@ void mtxf_pos_rotation_xyz(Mat4 out, Vec3f pos, Vec3s orientation) {
|
|||
f32 cosine2;
|
||||
f32 sine3;
|
||||
f32 cosine3;
|
||||
FrameInterpolation_RecordMatrixPosRotXYZ(out, pos, orientation);
|
||||
|
||||
sine1 = sins(orientation[0]);
|
||||
cosine1 = coss(orientation[0]);
|
||||
|
|
@ -623,7 +599,9 @@ void func_802B64C4(Vec3f arg0, s16 arg1) {
|
|||
arg0[2] = sp2C * temp1 + (temp_f0 * temp3);
|
||||
}
|
||||
|
||||
void calculate_orientation_matrix(Mat3 dest, f32 arg1, f32 arg2, f32 arg3, s16 rotationAngle) {
|
||||
// Rotates the object around the Y axis.
|
||||
// x,y,z is a direction (not a rotator).
|
||||
void calculate_orientation_matrix(Mat3 dest, f32 x, f32 y, f32 z, s16 rotationAngle) {
|
||||
Mat3 mtx_rot_y;
|
||||
Mat3 matrix;
|
||||
s32 i, j;
|
||||
|
|
@ -634,6 +612,7 @@ void calculate_orientation_matrix(Mat3 dest, f32 arg1, f32 arg2, f32 arg3, s16 r
|
|||
UNUSED s32 pad[3];
|
||||
f32 sinValue;
|
||||
f32 cossValue;
|
||||
FrameInterpolation_RecordCalculateOrientationMatrix(dest, x, y, z, rotationAngle);
|
||||
|
||||
sinValue = sins(rotationAngle);
|
||||
cossValue = coss(rotationAngle);
|
||||
|
|
@ -649,7 +628,7 @@ void calculate_orientation_matrix(Mat3 dest, f32 arg1, f32 arg2, f32 arg3, s16 r
|
|||
mtx_rot_y[1][0] = 0;
|
||||
mtx_rot_y[0][1] = 0;
|
||||
|
||||
if (arg2 == 1) { // set matrix to identity
|
||||
if (y == 1) { // set matrix to identity
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
|
|
@ -657,7 +636,7 @@ void calculate_orientation_matrix(Mat3 dest, f32 arg1, f32 arg2, f32 arg3, s16 r
|
|||
}
|
||||
}
|
||||
|
||||
} else if (arg2 == -1) { // set matrix to identity with the second column negative
|
||||
} else if (y == -1) { // set matrix to identity with the second column negative
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
|
|
@ -668,10 +647,10 @@ void calculate_orientation_matrix(Mat3 dest, f32 arg1, f32 arg2, f32 arg3, s16 r
|
|||
matrix[1][1] = -1;
|
||||
|
||||
} else {
|
||||
a = (f32) - (360.0 - ((f64) (calculate_vector_angle_xy(arg2) * 180.0f) / M_PI));
|
||||
b = -arg3 / sqrtf((arg1 * arg1) + (arg3 * arg3));
|
||||
a = (f32) - (360.0 - ((f64) (calculate_vector_angle_xy(y) * 180.0f) / M_PI));
|
||||
b = -z / sqrtf((x * x) + (z * z));
|
||||
c = 0;
|
||||
d = arg1 / sqrtf((arg1 * arg1) + (arg3 * arg3));
|
||||
d = x / sqrtf((x * x) + (z * z));
|
||||
calculate_rotation_matrix(matrix, a, b, c, d);
|
||||
}
|
||||
dest[0][0] = (mtx_rot_y[0][0] * matrix[0][0]) + (mtx_rot_y[0][1] * matrix[1][0]) + (mtx_rot_y[0][2] * matrix[2][0]);
|
||||
|
|
@ -752,7 +731,7 @@ void calculate_rotation_matrix(Mat3 destMatrix, s16 rotationAngle, f32 rotationX
|
|||
destMatrix[0][1] = temp + (rotationZ * sinValue);
|
||||
}
|
||||
|
||||
void func_802B6BC0(Mat4 arg0, s16 arg1, f32 arg2, f32 arg3, f32 arg4) {
|
||||
UNUSED void func_802B6BC0(Mat4 arg0, s16 arg1, f32 arg2, f32 arg3, f32 arg4) {
|
||||
f32 sine;
|
||||
f32 cosine;
|
||||
f32 temp_f0;
|
||||
|
|
@ -823,40 +802,40 @@ void func_802B6D58(Mat4 arg0, Vec3f arg1, Vec3f arg2) {
|
|||
}
|
||||
|
||||
void mtxf_multiplication(Mat4 dest, Mat4 mat1, Mat4 mat2) {
|
||||
Mat4 product;
|
||||
product[0][0] =
|
||||
FrameInterpolation_RecordMatrixMult(dest, dest, 0);
|
||||
|
||||
dest[0][0] =
|
||||
(mat1[0][0] * mat2[0][0]) + (mat1[0][1] * mat2[1][0]) + (mat1[0][2] * mat2[2][0]) + (mat1[0][3] * mat2[3][0]);
|
||||
product[0][1] =
|
||||
dest[0][1] =
|
||||
(mat1[0][0] * mat2[0][1]) + (mat1[0][1] * mat2[1][1]) + (mat1[0][2] * mat2[2][1]) + (mat1[0][3] * mat2[3][1]);
|
||||
product[0][2] =
|
||||
dest[0][2] =
|
||||
(mat1[0][0] * mat2[0][2]) + (mat1[0][1] * mat2[1][2]) + (mat1[0][2] * mat2[2][2]) + (mat1[0][3] * mat2[3][2]);
|
||||
product[0][3] =
|
||||
dest[0][3] =
|
||||
(mat1[0][0] * mat2[0][3]) + (mat1[0][1] * mat2[1][3]) + (mat1[0][2] * mat2[2][3]) + (mat1[0][3] * mat2[3][3]);
|
||||
product[1][0] =
|
||||
dest[1][0] =
|
||||
(mat1[1][0] * mat2[0][0]) + (mat1[1][1] * mat2[1][0]) + (mat1[1][2] * mat2[2][0]) + (mat1[1][3] * mat2[3][0]);
|
||||
product[1][1] =
|
||||
dest[1][1] =
|
||||
(mat1[1][0] * mat2[0][1]) + (mat1[1][1] * mat2[1][1]) + (mat1[1][2] * mat2[2][1]) + (mat1[1][3] * mat2[3][1]);
|
||||
product[1][2] =
|
||||
dest[1][2] =
|
||||
(mat1[1][0] * mat2[0][2]) + (mat1[1][1] * mat2[1][2]) + (mat1[1][2] * mat2[2][2]) + (mat1[1][3] * mat2[3][2]);
|
||||
product[1][3] =
|
||||
dest[1][3] =
|
||||
(mat1[1][0] * mat2[0][3]) + (mat1[1][1] * mat2[1][3]) + (mat1[1][2] * mat2[2][3]) + (mat1[1][3] * mat2[3][3]);
|
||||
product[2][0] =
|
||||
dest[2][0] =
|
||||
(mat1[2][0] * mat2[0][0]) + (mat1[2][1] * mat2[1][0]) + (mat1[2][2] * mat2[2][0]) + (mat1[2][3] * mat2[3][0]);
|
||||
product[2][1] =
|
||||
dest[2][1] =
|
||||
(mat1[2][0] * mat2[0][1]) + (mat1[2][1] * mat2[1][1]) + (mat1[2][2] * mat2[2][1]) + (mat1[2][3] * mat2[3][1]);
|
||||
product[2][2] =
|
||||
dest[2][2] =
|
||||
(mat1[2][0] * mat2[0][2]) + (mat1[2][1] * mat2[1][2]) + (mat1[2][2] * mat2[2][2]) + (mat1[2][3] * mat2[3][2]);
|
||||
product[2][3] =
|
||||
dest[2][3] =
|
||||
(mat1[2][0] * mat2[0][3]) + (mat1[2][1] * mat2[1][3]) + (mat1[2][2] * mat2[2][3]) + (mat1[2][3] * mat2[3][3]);
|
||||
product[3][0] =
|
||||
dest[3][0] =
|
||||
(mat1[3][0] * mat2[0][0]) + (mat1[3][1] * mat2[1][0]) + (mat1[3][2] * mat2[2][0]) + (mat1[3][3] * mat2[3][0]);
|
||||
product[3][1] =
|
||||
dest[3][1] =
|
||||
(mat1[3][0] * mat2[0][1]) + (mat1[3][1] * mat2[1][1]) + (mat1[3][2] * mat2[2][1]) + (mat1[3][3] * mat2[3][1]);
|
||||
product[3][2] =
|
||||
dest[3][2] =
|
||||
(mat1[3][0] * mat2[0][2]) + (mat1[3][1] * mat2[1][2]) + (mat1[3][2] * mat2[2][2]) + (mat1[3][3] * mat2[3][2]);
|
||||
product[3][3] =
|
||||
dest[3][3] =
|
||||
(mat1[3][0] * mat2[0][3]) + (mat1[3][1] * mat2[1][3]) + (mat1[3][2] * mat2[2][3]) + (mat1[3][3] * mat2[3][3]);
|
||||
mtxf_copy_n_element((s32*) dest, (s32*) product, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1121,16 +1100,22 @@ s32 is_visible_between_angle(u16 arg0, u16 arg1, u16 arg2) {
|
|||
f32 is_within_render_distance(Vec3f cameraPos, Vec3f objectPos, u16 orientationY, f32 minDistance, f32 fov,
|
||||
f32 maxDistance) {
|
||||
u16 angleObject;
|
||||
UNUSED u16 pad;
|
||||
u16 temp_v0;
|
||||
f32 distanceX;
|
||||
f32 distance;
|
||||
f32 distanceY;
|
||||
f32 scaleFov;
|
||||
f32 maxDistance2;
|
||||
s32 plus_fov_angle;
|
||||
s32 minus_fov_angle;
|
||||
u16 temp;
|
||||
UNUSED s32 pad2[3];
|
||||
u16 extended_fov = ((u16) fov * 0xB6);
|
||||
s32 count = 0;
|
||||
|
||||
maxDistance *= 6.5f;
|
||||
maxDistance2 = 1.0f;
|
||||
scaleFov = 1.25;
|
||||
|
||||
f32 extended_fov = ((f32) fov * 0xB6 * scaleFov); // Sets the Culling for objects on the left and right
|
||||
|
||||
distanceX = objectPos[0] - cameraPos[0];
|
||||
distanceX = distanceX * distanceX;
|
||||
|
|
@ -1159,14 +1144,23 @@ f32 is_within_render_distance(Vec3f cameraPos, Vec3f objectPos, u16 orientationY
|
|||
|
||||
if (minDistance == 0.0f) {
|
||||
if (is_visible_between_angle((orientationY + extended_fov), (orientationY - extended_fov), angleObject) == 1) {
|
||||
return distance;
|
||||
if (IsKalimariDesert()) {
|
||||
return distance / 6.5f; // set for better DD settings in Desert
|
||||
} else {
|
||||
return distance / 10.0f; // Items
|
||||
}
|
||||
}
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
if (is_visible_between_angle((u16) plus_fov_angle, (u16) minus_fov_angle, angleObject) == 1) {
|
||||
return distance;
|
||||
if (IsKalimariDesert()) {
|
||||
return distance / 2.0f;
|
||||
} else {
|
||||
return distance / 10.0f; // DD Vhicles
|
||||
}
|
||||
}
|
||||
|
||||
temp_v0 = func_802B7CA8(minDistance / distance);
|
||||
temp = angleObject + temp_v0;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@
|
|||
// #define min(a, b) ((a) <= (b) ? (a) : (b))
|
||||
// #define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define sqr(x) ((x) * (x))
|
||||
|
||||
// Here to appease the pragma gods
|
||||
|
|
@ -38,7 +42,6 @@ void func_802B5794(Mat4, Vec3f, Vec3f);
|
|||
void mtxf_rotate_x(Mat4, s16);
|
||||
void mtxf_rotate_y(Mat4, s16);
|
||||
void mtxf_s16_rotate_z(Mat4, s16);
|
||||
void func_802B5B14(Vec3f b, Vec3s rotate); // unused
|
||||
void func_802B5CAC(s16, s16, Vec3f);
|
||||
void func_802B5D30(s16, s16, s32);
|
||||
void set_track_light_direction(Lights1*, s16, s16, s32);
|
||||
|
|
@ -70,6 +73,10 @@ f32 is_within_render_distance(Vec3f, Vec3f, u16, f32, f32, f32);
|
|||
|
||||
extern s32 D_802B91C0[];
|
||||
extern Vec3f D_802B91C8;
|
||||
extern Mtx gIdentityMatrix;
|
||||
//extern Mtx gIdentityMatrix;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MATH_UTIL_H
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ void func_8028EC38(s32 arg0) {
|
|||
|
||||
void func_8028EC98(s32 arg0) {
|
||||
|
||||
// We want music in mutilplayer
|
||||
// We want music in multiplayer, so this was removed
|
||||
//if (gScreenModeSelection == SCREEN_MODE_3P_4P_SPLITSCREEN) {
|
||||
// return;
|
||||
//}
|
||||
|
|
@ -897,9 +897,9 @@ void func_8028FCBC(void) {
|
|||
func_8028F914();
|
||||
if (D_802BA034 == 1.0f) {
|
||||
if (gActiveScreenMode != SCREEN_MODE_1P) {
|
||||
if (GetCourse() == GetLuigiRaceway()) {
|
||||
if (IsLuigiRaceway()) {
|
||||
func_802A7940();
|
||||
} else if (GetCourse() == GetWarioStadium()) {
|
||||
} else if (IsWarioStadium()) {
|
||||
func_802A7728();
|
||||
}
|
||||
}
|
||||
|
|
@ -909,7 +909,9 @@ void func_8028FCBC(void) {
|
|||
CM_SpawnStarterLakitu(); // func_80078F64();
|
||||
if ((gModeSelection == TIME_TRIALS) && (D_80162DD6 == 0)) {
|
||||
phi_v0_4 = 0x1;
|
||||
for (i = 0; i < gCurrentCourseId; i++) {
|
||||
//! @warning this used to be < gCurrentCourseId
|
||||
// Hopefully this is equivallent.
|
||||
for (i = 0; i < GetCourseIndex(); i++) {
|
||||
phi_v0_4 <<= 1;
|
||||
}
|
||||
if ((D_8015F890 == 0) && (!(D_800DC5AC & phi_v0_4))) {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <course.h>
|
||||
#include "../camera.h"
|
||||
#include "framebuffer_effects.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
#include "render_courses.h"
|
||||
#include "code_800029B0.h"
|
||||
|
|
@ -132,7 +133,7 @@ void render_course_segments(const char* addr[], struct UnkStruct_800DC5EC* arg1)
|
|||
index = sp1E;
|
||||
}
|
||||
} else {
|
||||
if (GetCourse() == GetBowsersCastle()) {
|
||||
if (IsBowsersCastle()) {
|
||||
if ((temp_v0_3 >= 0x11) && (temp_v0_3 < 0x18)) {
|
||||
index = temp_v0_3;
|
||||
} else if ((temp_v0_3 == 255) && (sp1E != 255)) {
|
||||
|
|
@ -142,7 +143,7 @@ void render_course_segments(const char* addr[], struct UnkStruct_800DC5EC* arg1)
|
|||
} else {
|
||||
index = arg1->pathCounter;
|
||||
}
|
||||
} else if (GetCourse() == GetChocoMountain()) {
|
||||
} else if (IsChocoMountain()) {
|
||||
if ((temp_v0_3 >= 0xE) && (temp_v0_3 < 0x16)) {
|
||||
index = temp_v0_3;
|
||||
} else if ((temp_v0_3 == 255) && (sp1E != 255)) {
|
||||
|
|
@ -175,7 +176,7 @@ void render_course_segments(const char* addr[], struct UnkStruct_800DC5EC* arg1)
|
|||
index = ((index - 1) * 4) + direction;
|
||||
gSPDisplayList(gDisplayListHead++, addr[index]);
|
||||
|
||||
if (CVarGetInteger("gDisableLod", 1) == 1 && (GetCourse() == GetBowsersCastle()) &&
|
||||
if (CVarGetInteger("gDisableLod", 1) == 1 && (IsBowsersCastle()) &&
|
||||
(index < 20 || index > 99)) { // always render higher version of bowser statue
|
||||
gDisplayListHead--;
|
||||
gSPDisplayList(gDisplayListHead++, d_course_bowsers_castle_dl_9148); // use credit version of the course
|
||||
|
|
@ -240,9 +241,14 @@ void func_8029122C(struct UnkStruct_800DC5EC* arg0, s32 playerId) {
|
|||
G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
||||
break;
|
||||
}
|
||||
|
||||
FrameInterpolation_RecordOpenChild("track_water", playerId);
|
||||
|
||||
mtxf_identity(matrix);
|
||||
render_set_position(matrix, 0);
|
||||
|
||||
CM_DrawWater(arg0, pathCounter, cameraRot, playerDirection);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
// switch (gCurrentCourseId) {
|
||||
// case COURSE_BOWSER_CASTLE:
|
||||
// if (gActiveScreenMode != SCREEN_MODE_1P) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
#include "engine/courses/Course.h"
|
||||
#include "port/Game.h"
|
||||
#include "math_util.h"
|
||||
#include "src/enhancements/freecam/freecam.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
Vp D_802B8880[] = {
|
||||
{ { { 640, 480, 511, 0 }, { 640, 480, 511, 0 } } },
|
||||
|
|
@ -397,11 +399,15 @@ void func_802A450C(Vtx* skybox) {
|
|||
skybox[7].v.cn[2] = prop->FloorTopLeft.b;
|
||||
}
|
||||
|
||||
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),
|
||||
};
|
||||
|
||||
void func_802A487C(Vtx* arg0, UNUSED struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, UNUSED s32 arg3,
|
||||
UNUSED f32* arg4) {
|
||||
|
||||
init_rdp();
|
||||
if (GetCourse() != GetRainbowRoad()) {
|
||||
if (!IsRainbowRoad()) {
|
||||
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
|
||||
gSPClearGeometryMode(gDisplayListHead++, G_ZBUFFER | G_LIGHTING);
|
||||
|
|
@ -409,7 +415,7 @@ void func_802A487C(Vtx* arg0, UNUSED struct UnkStruct_800DC5EC* arg1, UNUSED s32
|
|||
gSPPerspNormalize(gDisplayListHead++, 0xFFFF);
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxScreen),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
gSPMatrix(gDisplayListHead++, &gIdentityMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPMatrix(gDisplayListHead++, &gIdentityMatrix2, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPVertex(gDisplayListHead++, &arg0[4], 4, 0);
|
||||
gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0);
|
||||
}
|
||||
|
|
@ -476,10 +482,10 @@ void func_802A4A0C(Vtx* vtx, struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, U
|
|||
gSPPerspNormalize(gDisplayListHead++, 0xFFFF);
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxScreen),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
gSPMatrix(gDisplayListHead++, &gIdentityMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPMatrix(gDisplayListHead++, &gIdentityMatrix2, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPVertex(gDisplayListHead++, &vtx[0], 4, 0);
|
||||
gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0);
|
||||
if (GetCourse() == GetRainbowRoad()) {
|
||||
if (IsRainbowRoad()) {
|
||||
gSPVertex(gDisplayListHead++, &vtx[4], 4, 0);
|
||||
gSP2Triangles(gDisplayListHead++, 0, 3, 1, 0, 1, 3, 2, 0);
|
||||
}
|
||||
|
|
@ -750,11 +756,35 @@ void func_802A5760(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void render_screens(s32 mode, s32 cameraId, s32 playerId) {
|
||||
UNUSED s32 pad[4];
|
||||
// Setup the cameras perspective and lookAt (movement/rotation)
|
||||
void setup_camera(Camera* camera, s32 playerId, s32 cameraId, struct UnkStruct_800DC5EC* screen) {
|
||||
Mat4 matrix;
|
||||
u16 perspNorm;
|
||||
UNUSED s32 pad2[2];
|
||||
UNUSED s32 pad3;
|
||||
|
||||
// This allows freecam to create a new separate camera
|
||||
// if (CVarGetInteger("gFreecam", 0) == true) {
|
||||
// freecam_render_setup(gFreecamCamera);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Setup perspective (camera movement)
|
||||
FrameInterpolation_RecordOpenChild("camera",
|
||||
(FrameInterpolation_GetCameraEpoch() | (((playerId | cameraId) << 8))));
|
||||
guPerspective(&gGfxPool->mtxPersp[cameraId], &perspNorm, gCameraZoom[cameraId], gScreenAspect,
|
||||
CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f);
|
||||
gSPPerspNormalize(gDisplayListHead++, perspNorm);
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[cameraId]),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
|
||||
// Setup lookAt (camera rotation)
|
||||
guLookAt(&gGfxPool->mtxLookAt[cameraId], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0],
|
||||
camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]);
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]),
|
||||
G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
void render_screens(s32 mode, s32 cameraId, s32 playerId) {
|
||||
Mat4 matrix;
|
||||
|
||||
s32 screenId = 0;
|
||||
|
|
@ -817,8 +847,16 @@ void render_screens(s32 mode, s32 cameraId, s32 playerId) {
|
|||
}
|
||||
|
||||
struct UnkStruct_800DC5EC* screen = &D_8015F480[screenId];
|
||||
Camera* camera = &cameras[cameraId];
|
||||
Camera* camera;
|
||||
|
||||
// Required for freecam to have its own camera
|
||||
//if (CVarGetInteger("gFreecam", 0) == true) {
|
||||
// camera = &gFreecamCamera;
|
||||
// cameraId = 4;
|
||||
//} else {
|
||||
camera = &cameras[cameraId];
|
||||
//}
|
||||
|
||||
if (screenMode == SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL) {
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH);
|
||||
}
|
||||
|
|
@ -828,34 +866,21 @@ void render_screens(s32 mode, s32 cameraId, s32 playerId) {
|
|||
gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH);
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
|
||||
|
||||
guPerspective(&gGfxPool->mtxPersp[cameraId], &perspNorm, gCameraZoom[cameraId], gScreenAspect,
|
||||
CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f);
|
||||
// Setup camera perspective and lookAt
|
||||
setup_camera(camera, playerId, cameraId, screen);
|
||||
|
||||
gSPPerspNormalize(gDisplayListHead++, perspNorm);
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxPersp[cameraId]),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
// Create a matrix for the track and game objects
|
||||
FrameInterpolation_RecordOpenChild("track", (playerId | cameraId) << 8);
|
||||
Mat4 trackMatrix;
|
||||
mtxf_identity(trackMatrix);
|
||||
render_set_position(trackMatrix, 0);
|
||||
|
||||
guLookAt(&gGfxPool->mtxLookAt[cameraId], camera->pos[0], camera->pos[1], camera->pos[2], camera->lookAt[0],
|
||||
camera->lookAt[1], camera->lookAt[2], camera->up[0], camera->up[1], camera->up[2]);
|
||||
if (D_800DC5C8 == 0) {
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]),
|
||||
G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
||||
mtxf_identity(matrix);
|
||||
render_set_position(matrix, 0);
|
||||
} else {
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
}
|
||||
// Draw course and game objects
|
||||
render_course(screen);
|
||||
if (D_800DC5C8 == 1) {
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]),
|
||||
G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
||||
mtxf_identity(matrix);
|
||||
render_set_position(matrix, 0);
|
||||
}
|
||||
render_course_actors(screen);
|
||||
CM_DrawStaticMeshActors();
|
||||
render_object(mode);
|
||||
|
||||
switch (screenId) {
|
||||
case 0:
|
||||
render_players_on_screen_one();
|
||||
|
|
@ -902,6 +927,7 @@ void render_screens(s32 mode, s32 cameraId, s32 playerId) {
|
|||
if (mode != RENDER_SCREEN_MODE_1P_PLAYER_ONE) {
|
||||
gNumScreens += 1;
|
||||
}
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
void func_802A74BC(void) {
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@
|
|||
#include "engine/courses/Course.h"
|
||||
#include "engine/Matrix.h"
|
||||
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
Lights1 D_800E45C0[] = {
|
||||
gdSPDefLights1(100, 0, 0, 100, 0, 0, 0, -120, 0),
|
||||
gdSPDefLights1(100, 100, 0, 255, 255, 0, 0, -120, 0),
|
||||
|
|
@ -1679,7 +1681,7 @@ void render_texture_rectangle_wide_left(s32 x, s32 y, s32 width, s32 height, s32
|
|||
if (gPlayerCount == 3) {
|
||||
// Center item in area of screen
|
||||
s32 center = (s32) ((OTRGetDimensionFromLeftEdge(SCREEN_WIDTH) - SCREEN_WIDTH) / 2) +
|
||||
((SCREEN_WIDTH / 4) + (SCREEN_WIDTH / 2));
|
||||
((SCREEN_WIDTH / 4) + (SCREEN_WIDTH / 2));
|
||||
s32 coordX = (s32) (center - (width / 2)) << 2;
|
||||
s32 coordX2 = (s32) (center + (width / 2)) << 2;
|
||||
gSPWideTextureRectangle(gDisplayListHead++, coordX, yl, coordX2, yh2, G_TX_RENDERTILE, arg4 << 5,
|
||||
|
|
@ -2627,6 +2629,8 @@ void draw_simplified_lap_count(s32 playerId) {
|
|||
}
|
||||
|
||||
void func_8004E800(s32 playerId) {
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Player place HUD", playerId);
|
||||
if (playerHUD[playerId].unk_81 != 0) {
|
||||
if (playerHUD[playerId].lapCount != 3) {
|
||||
func_8004A384(playerHUD[playerId].rankX + playerHUD[playerId].slideRankX,
|
||||
|
|
@ -2642,6 +2646,8 @@ void func_8004E800(s32 playerId) {
|
|||
0x00000040, 0x00000080, 0x00000040);
|
||||
}
|
||||
}
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
void func_8004E998(s32 playerId) {
|
||||
|
|
@ -2682,23 +2688,25 @@ void func_8004EB38(s32 playerId) {
|
|||
}
|
||||
if ((u8) temp_s0->unk_7E != 0) {
|
||||
func_8004C9D8_wide((s32) temp_s0->lapAfterImage1X, temp_s0->lapY + 3, 0x00000080, (u8*) common_texture_hud_lap,
|
||||
0x00000020, 8, 0x00000020, 8);
|
||||
0x00000020, 8, 0x00000020, 8);
|
||||
func_8004C9D8_wide(temp_s0->lapAfterImage1X + 0x1C, (s32) temp_s0->lapY, 0x00000080,
|
||||
(u8*) gHudLapTextures[temp_s0->alsoLapCount], 0x00000020, 0x00000010, 0x00000020, 0x00000010);
|
||||
(u8*) gHudLapTextures[temp_s0->alsoLapCount], 0x00000020, 0x00000010, 0x00000020,
|
||||
0x00000010);
|
||||
}
|
||||
if ((u8) temp_s0->unk_7F != 0) {
|
||||
func_8004C9D8_wide((s32) temp_s0->lapAfterImage2X, temp_s0->lapY + 3, 0x00000050, (u8*) common_texture_hud_lap,
|
||||
0x00000020, 8, 0x00000020, 8);
|
||||
0x00000020, 8, 0x00000020, 8);
|
||||
func_8004C9D8_wide(temp_s0->lapAfterImage2X + 0x1C, (s32) temp_s0->lapY, 0x00000050,
|
||||
(u8*) gHudLapTextures[temp_s0->alsoLapCount], 0x00000020, 0x00000010, 0x00000020, 0x00000010);
|
||||
(u8*) gHudLapTextures[temp_s0->alsoLapCount], 0x00000020, 0x00000010, 0x00000020,
|
||||
0x00000010);
|
||||
}
|
||||
}
|
||||
|
||||
void func_8004ED40(s32 arg0) {
|
||||
func_8004A2F4(playerHUD[arg0].speedometerX, playerHUD[arg0].speedometerY, 0U, 1.0f,
|
||||
// RGBA
|
||||
CM_GetProps()->Minimap.Colour.r, CM_GetProps()->Minimap.Colour.g, CM_GetProps()->Minimap.Colour.b, 0xFF,
|
||||
LOAD_ASSET(common_texture_speedometer), LOAD_ASSET(D_0D0064B0), 64, 96, 64, 48);
|
||||
CM_GetProps()->Minimap.Colour.r, CM_GetProps()->Minimap.Colour.g, CM_GetProps()->Minimap.Colour.b,
|
||||
0xFF, LOAD_ASSET(common_texture_speedometer), LOAD_ASSET(D_0D0064B0), 64, 96, 64, 48);
|
||||
func_8004A258(D_8018CFEC, D_8018CFF4, D_8016579E, 1.0f, common_texture_speedometer_needle, D_0D005FF0, 0x40, 0x20,
|
||||
0x40, 0x20);
|
||||
}
|
||||
|
|
@ -2708,14 +2716,14 @@ void func_8004EE54(s32 playerId) {
|
|||
if (gIsMirrorMode != 0) {
|
||||
func_8004D4E8(CM_GetProps()->Minimap.Pos[playerId].X, CM_GetProps()->Minimap.Pos[playerId].Y, (u8*) D_8018D240,
|
||||
// RGBA
|
||||
CM_GetProps()->Minimap.Colour.r, CM_GetProps()->Minimap.Colour.g, CM_GetProps()->Minimap.Colour.b, 0xFF,
|
||||
CM_GetProps()->Minimap.Width, CM_GetProps()->Minimap.Height, CM_GetProps()->Minimap.Width,
|
||||
CM_GetProps()->Minimap.Colour.r, CM_GetProps()->Minimap.Colour.g, CM_GetProps()->Minimap.Colour.b,
|
||||
0xFF, CM_GetProps()->Minimap.Width, CM_GetProps()->Minimap.Height, CM_GetProps()->Minimap.Width,
|
||||
CM_GetProps()->Minimap.Height);
|
||||
} else {
|
||||
func_8004D37C(CM_GetProps()->Minimap.Pos[playerId].X, CM_GetProps()->Minimap.Pos[playerId].Y, (u8*) D_8018D240,
|
||||
// RGBA
|
||||
CM_GetProps()->Minimap.Colour.r, CM_GetProps()->Minimap.Colour.g, CM_GetProps()->Minimap.Colour.b, 0xFF,
|
||||
CM_GetProps()->Minimap.Width, CM_GetProps()->Minimap.Height, CM_GetProps()->Minimap.Width,
|
||||
CM_GetProps()->Minimap.Colour.r, CM_GetProps()->Minimap.Colour.g, CM_GetProps()->Minimap.Colour.b,
|
||||
0xFF, CM_GetProps()->Minimap.Width, CM_GetProps()->Minimap.Height, CM_GetProps()->Minimap.Width,
|
||||
CM_GetProps()->Minimap.Height);
|
||||
}
|
||||
}
|
||||
|
|
@ -2745,8 +2753,10 @@ void set_minimap_finishline_position(s32 playerId) {
|
|||
}
|
||||
|
||||
// minimap center pos - minimap left edge + offset
|
||||
var_f2 = (center - (CM_GetProps()->Minimap.Width / 2)) + CM_GetProps()->Minimap.PlayerX; // (center - (gMinimapWidth / 2)) + gMinimapPlayerX;
|
||||
var_f0 = (CM_GetProps()->Minimap.Pos[playerId].Y - (CM_GetProps()->Minimap.Height / 2)) + CM_GetProps()->Minimap.PlayerY; // (gMinimapY[arg0] - (gMinimapHeight / 2)) + gMinimapPlayerY
|
||||
var_f2 = (center - (CM_GetProps()->Minimap.Width / 2)) +
|
||||
CM_GetProps()->Minimap.PlayerX; // (center - (gMinimapWidth / 2)) + gMinimapPlayerX;
|
||||
var_f0 = (CM_GetProps()->Minimap.Pos[playerId].Y - (CM_GetProps()->Minimap.Height / 2)) +
|
||||
CM_GetProps()->Minimap.PlayerY; // (gMinimapY[arg0] - (gMinimapHeight / 2)) + gMinimapPlayerY
|
||||
|
||||
var_f2 += CM_GetProps()->Minimap.FinishlineX;
|
||||
var_f0 += CM_GetProps()->Minimap.FinishlineY;
|
||||
|
|
@ -2780,7 +2790,8 @@ void func_8004F168(s32 arg0, s32 playerId, s32 characterId) {
|
|||
}
|
||||
|
||||
temp_a0 = (center - (CM_GetProps()->Minimap.Width / 2)) + CM_GetProps()->Minimap.PlayerX + (s16) (thing0);
|
||||
temp_a1 = (CM_GetProps()->Minimap.Pos[arg0].Y - (CM_GetProps()->Minimap.Height / 2)) + CM_GetProps()->Minimap.PlayerY + (s16) (thing1);
|
||||
temp_a1 = (CM_GetProps()->Minimap.Pos[arg0].Y - (CM_GetProps()->Minimap.Height / 2)) +
|
||||
CM_GetProps()->Minimap.PlayerY + (s16) (thing1);
|
||||
if (characterId != 8) {
|
||||
if ((gGPCurrentRaceRankByPlayerId[playerId] == 0) && (gModeSelection != 3) && (gModeSelection != 1)) {
|
||||
#if EXPLICIT_AND == 1
|
||||
|
|
@ -3002,7 +3013,7 @@ void draw_lap_count(s16 lapX, s16 lapY, s8 lap) {
|
|||
}
|
||||
|
||||
void func_8004FDB4(f32 arg0, f32 arg1, s16 arg2, s16 arg3, s16 characterId, s32 arg5, s32 arg6, s32 arg7, s32 arg8) {
|
||||
if ((GetCourse() == GetYoshiValley()) && (arg3 < 3) && (arg8 == 0)) {
|
||||
if ((IsYoshiValley()) && (arg3 < 3) && (arg8 == 0)) {
|
||||
func_80042330((s32) arg0, (s32) arg1, 0U, 1.0f);
|
||||
gSPDisplayList(gDisplayListHead++, D_0D007DB8);
|
||||
func_8004B35C(0x000000FF, 0x000000FF, 0x000000FF, D_8018D3E0);
|
||||
|
|
@ -3044,47 +3055,57 @@ void func_8004FDB4(f32 arg0, f32 arg1, s16 arg2, s16 arg3, s16 characterId, s32
|
|||
void func_80050320(void) {
|
||||
s16 temp_v0;
|
||||
s16 characterId;
|
||||
s32 var_s0;
|
||||
s32 i;
|
||||
s32 lapCount;
|
||||
s32 var_a0;
|
||||
|
||||
if (D_801657E2 == 0) {
|
||||
for (var_s0 = 0; var_s0 < 4; var_s0++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
var_a0 = 0;
|
||||
if (D_8018D050[var_s0] >= 0.0f) {
|
||||
if (D_8018D078[var_s0] < 0.0) {
|
||||
if (D_8018D050[i] >= 0.0f) {
|
||||
if (D_8018D078[i] < 0.0) {
|
||||
var_a0 = 1;
|
||||
}
|
||||
temp_v0 = gGPCurrentRacePlayerIdByRank[var_s0];
|
||||
characterId = gGPCurrentRaceCharacterIdByRank[var_s0];
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("ranking portraits", i | var_a0 << 16);
|
||||
|
||||
temp_v0 = gGPCurrentRacePlayerIdByRank[i];
|
||||
characterId = gGPCurrentRaceCharacterIdByRank[i];
|
||||
lapCount = gLapCountByPlayerId[temp_v0];
|
||||
if (characterId == gPlayerOne->characterId) {
|
||||
func_8004FDB4(D_8018D028[var_s0], D_8018D050[var_s0], var_s0, lapCount, characterId, 0x000000FF, 1,
|
||||
var_a0, 0);
|
||||
func_8004FDB4(D_8018D028[i], D_8018D050[i], i, lapCount, characterId, 0x000000FF, 1, var_a0, 0);
|
||||
} else {
|
||||
func_8004FDB4(D_8018D028[var_s0], D_8018D050[var_s0], var_s0, lapCount, characterId, D_8018D3E0, 0,
|
||||
var_a0, 0);
|
||||
func_8004FDB4(D_8018D028[i], D_8018D050[i], i, lapCount, characterId, D_8018D3E0, 0, var_a0, 0);
|
||||
}
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (var_s0 = 0; var_s0 < 8; var_s0++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
var_a0 = 0;
|
||||
if (D_8018D050[var_s0] >= 0.0f) {
|
||||
if (D_8018D078[var_s0] <= 0.0) {
|
||||
if (D_8018D050[i] >= 0.0f) {
|
||||
if (D_8018D078[i] <= 0.0) {
|
||||
var_a0 = 1;
|
||||
}
|
||||
temp_v0 = gGPCurrentRacePlayerIdByRank[var_s0];
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("ranking portraits 2", i | var_a0 << 16);
|
||||
|
||||
temp_v0 = gGPCurrentRacePlayerIdByRank[i];
|
||||
// ????
|
||||
characterId = (gPlayerOne + temp_v0)->characterId;
|
||||
lapCount = gLapCountByPlayerId[temp_v0];
|
||||
if (temp_v0 == 0) {
|
||||
func_8004FDB4(D_8018D028[var_s0], D_8018D050[var_s0], var_s0, lapCount, characterId, 0x000000FF, 1,
|
||||
var_a0, 1);
|
||||
func_8004FDB4(D_8018D028[i], D_8018D050[i], i, lapCount, characterId, 0x000000FF, 1, var_a0, 1);
|
||||
} else {
|
||||
func_8004FDB4(D_8018D028[var_s0], D_8018D050[var_s0], var_s0, lapCount, characterId, 0x000000FF, 0,
|
||||
var_a0, 1);
|
||||
func_8004FDB4(D_8018D028[i], D_8018D050[i], i, lapCount, characterId, 0x000000FF, 0, var_a0, 1);
|
||||
}
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3299,7 +3320,7 @@ void func_80050E34(s32 playerId, s32 arg1) {
|
|||
spB8 = 0;
|
||||
}
|
||||
|
||||
if ((GetCourse() == GetYoshiValley()) && (lapCount < 3)) {
|
||||
if ((IsYoshiValley()) && (lapCount < 3)) {
|
||||
gSPDisplayList(gDisplayListHead++, D_0D007DB8);
|
||||
gDPLoadTLUT_pal256(gDisplayListHead++, common_tlut_portrait_bomb_kart_and_question_mark);
|
||||
rsp_load_texture(common_texture_portrait_question_mark, 0x00000020, 0x00000020);
|
||||
|
|
@ -3380,15 +3401,19 @@ void func_800514BC(void) {
|
|||
}
|
||||
|
||||
void render_object_leaf_particle(UNUSED s32 cameraId) {
|
||||
s32 someIndex;
|
||||
size_t i;
|
||||
s32 leafIndex;
|
||||
Object* object;
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, D_0D0079C8);
|
||||
gSPClearGeometryMode(gDisplayListHead++, G_CULL_BOTH);
|
||||
load_texture_block_rgba16_mirror((u8*) common_texture_particle_leaf, 0x00000020, 0x00000010);
|
||||
for (someIndex = 0; someIndex < gLeafParticle_SIZE; someIndex++) {
|
||||
leafIndex = gLeafParticle[someIndex];
|
||||
for (i = 0; i < gLeafParticle_SIZE; i++) {
|
||||
leafIndex = gLeafParticle[i];
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Leaves", leafIndex);
|
||||
|
||||
if (leafIndex != -1) {
|
||||
object = &gObjectList[leafIndex];
|
||||
if ((object->state >= 2) && (object->unk_0D5 == 7) && (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) {
|
||||
|
|
@ -3396,40 +3421,83 @@ void render_object_leaf_particle(UNUSED s32 cameraId) {
|
|||
gSPDisplayList(gDisplayListHead++, D_0D0069C8);
|
||||
}
|
||||
}
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK);
|
||||
gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
|
||||
}
|
||||
|
||||
void render_object_snowflakes_particles(void) {
|
||||
s32 someIndex;
|
||||
size_t i;
|
||||
s32 snowflakeIndex;
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, D_0D007AE0);
|
||||
gDPSetCombineLERP(gDisplayListHead++, 1, 0, SHADE, 0, 0, 0, 0, TEXEL0, 1, 0, SHADE, 0, 0, 0, 0, TEXEL0);
|
||||
func_80044F34(D_0D0293D8, 0x10, 0x10);
|
||||
for (someIndex = 0; someIndex < NUM_SNOWFLAKES; someIndex++) {
|
||||
snowflakeIndex = gObjectParticle1[someIndex];
|
||||
for (i = 0; i < NUM_SNOWFLAKES; i++) {
|
||||
snowflakeIndex = gObjectParticle1[i];
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("SnowFlakes", snowflakeIndex);
|
||||
|
||||
if (gObjectList[snowflakeIndex].state >= 2) {
|
||||
rsp_set_matrix_gObjectList(snowflakeIndex);
|
||||
gSPDisplayList(gDisplayListHead++, D_0D006980);
|
||||
}
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
|
||||
}
|
||||
|
||||
void func_800518F8(s32 objectIndex, s16 arg1, s16 arg2) {
|
||||
UNUSED s32 pad[1];
|
||||
struct ObjectInterpData {
|
||||
s32 objectIndex;
|
||||
s16 x, y;
|
||||
};
|
||||
|
||||
struct ObjectInterpData prevObject[OBJECT_LIST_SIZE] = { 0 };
|
||||
|
||||
void func_800518F8(s32 objectIndex, s16 x, s16 y) {
|
||||
|
||||
// Search all recorded objects for the one we're drawing
|
||||
for (int i = 0; i < OBJECT_LIST_SIZE; i++) {
|
||||
if (objectIndex == prevObject[i].objectIndex) {
|
||||
// Coincidence!
|
||||
// Skip drawing the object this frame if it warped to the other side of the screen
|
||||
if ((fabs(x - prevObject[i].x) > SCREEN_WIDTH / 2) || (fabs(y - prevObject[i].y) > SCREEN_HEIGHT / 2)) {
|
||||
prevObject[objectIndex].x = x;
|
||||
prevObject[objectIndex].y = y;
|
||||
prevObject[objectIndex].objectIndex = objectIndex;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gObjectList[objectIndex].status & 0x10) {
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("func_800518F8", (uintptr_t) &gObjectList[objectIndex]);
|
||||
|
||||
if (D_8018D228 != gObjectList[objectIndex].unk_0D5) {
|
||||
D_8018D228 = gObjectList[objectIndex].unk_0D5;
|
||||
func_80044DA0(gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].textureWidth,
|
||||
gObjectList[objectIndex].textureHeight);
|
||||
}
|
||||
func_80042330_unchanged(arg1, arg2, 0U, gObjectList[objectIndex].sizeScaling);
|
||||
func_80042330_unchanged(x, y, 0, gObjectList[objectIndex].sizeScaling);
|
||||
gSPVertex(gDisplayListHead++, gObjectList[objectIndex].vertex, 4, 0);
|
||||
gSPDisplayList(gDisplayListHead++, common_rectangle_display);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
// Save current cloud index and x position
|
||||
prevObject[objectIndex].x = x;
|
||||
prevObject[objectIndex].y = y;
|
||||
prevObject[objectIndex].objectIndex = objectIndex;
|
||||
}
|
||||
|
||||
void func_800519D4(s32 objectIndex, s16 arg1, s16 arg2) {
|
||||
|
|
@ -3446,6 +3514,7 @@ void func_800519D4(s32 objectIndex, s16 arg1, s16 arg2) {
|
|||
}
|
||||
}
|
||||
|
||||
// Render clouds
|
||||
void func_80051ABC(s16 arg0, s32 arg1) {
|
||||
s32 var_s0;
|
||||
s32 objectIndex;
|
||||
|
|
@ -3465,7 +3534,14 @@ void func_80051ABC(s16 arg0, s32 arg1) {
|
|||
for (var_s0 = 0; var_s0 < D_8018D1F0; var_s0++) {
|
||||
objectIndex = D_8018CC80[arg1 + var_s0];
|
||||
object = &gObjectList[objectIndex];
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("func_80051ABC", TAG_OBJECT(object));
|
||||
|
||||
func_800518F8(objectIndex, object->unk_09C, arg0 - object->unk_09E);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3477,16 +3553,16 @@ void func_80051C60(s16 arg0, s32 arg1) {
|
|||
Object* object;
|
||||
|
||||
if (D_801658FE == 0) {
|
||||
if (GetCourse() == GetKoopaTroopaBeach()) {
|
||||
if (IsKoopaTroopaBeach()) {
|
||||
var_s5 = arg0;
|
||||
} else if (GetCourse() == GetMooMooFarm()) {
|
||||
} else if (IsMooMooFarm()) {
|
||||
var_s5 = arg0 - 16;
|
||||
} else if (GetCourse() == GetYoshiValley()) {
|
||||
} else if (IsYoshiValley()) {
|
||||
var_s5 = arg0 - 16;
|
||||
} else {
|
||||
var_s5 = arg0 + 16;
|
||||
}
|
||||
} else if (GetCourse() == GetKoopaTroopaBeach()) {
|
||||
} else if (IsKoopaTroopaBeach()) {
|
||||
var_s5 = arg0 * 2;
|
||||
} else {
|
||||
var_s5 = arg0 + 32;
|
||||
|
|
@ -3520,11 +3596,11 @@ void func_80051EF8(void) {
|
|||
s16 temp_a0;
|
||||
|
||||
temp_a0 = 0xF0 - D_800DC5EC->cameraHeight;
|
||||
if (GetCourse() == GetKoopaTroopaBeach()) {
|
||||
if (IsKoopaTroopaBeach()) {
|
||||
temp_a0 = temp_a0 - 0x30;
|
||||
} else if (GetCourse() == GetMooMooFarm()) {
|
||||
} else if (IsMooMooFarm()) {
|
||||
temp_a0 = temp_a0 - 0x40;
|
||||
} else if (GetCourse() == GetYoshiValley()) {
|
||||
} else if (IsYoshiValley()) {
|
||||
temp_a0 = temp_a0 - 0x40;
|
||||
} else {
|
||||
temp_a0 = temp_a0 - 0x30;
|
||||
|
|
@ -3536,11 +3612,11 @@ void func_80051F9C(void) {
|
|||
s16 temp_a0;
|
||||
|
||||
temp_a0 = 0xF0 - D_800DC5F0->cameraHeight;
|
||||
if (GetCourse() == GetKoopaTroopaBeach()) {
|
||||
if (IsKoopaTroopaBeach()) {
|
||||
temp_a0 = temp_a0 - 0x30;
|
||||
} else if (GetCourse() == GetMooMooFarm()) {
|
||||
} else if (IsMooMooFarm()) {
|
||||
temp_a0 = temp_a0 - 0x40;
|
||||
} else if (GetCourse() == GetYoshiValley()) {
|
||||
} else if (IsYoshiValley()) {
|
||||
temp_a0 = temp_a0 - 0x40;
|
||||
} else {
|
||||
temp_a0 = temp_a0 - 0x30;
|
||||
|
|
@ -3796,6 +3872,9 @@ void render_object_bowser_flame_particle(s32 objectIndex, s32 cameraId) {
|
|||
camera = &camera1[cameraId];
|
||||
if (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX) {
|
||||
object = &gObjectList[objectIndex];
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Bowser Statue Flame", TAG_ITEM_ADDR(object));
|
||||
if (object->unk_0D5 == 9) {
|
||||
func_8004B72C(0xFF, (s32) object->type, 0, (s32) object->unk_0A2, 0, 0, (s32) object->primAlpha);
|
||||
} else {
|
||||
|
|
@ -3803,6 +3882,9 @@ void render_object_bowser_flame_particle(s32 objectIndex, s32 cameraId) {
|
|||
}
|
||||
D_80183E80[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos);
|
||||
func_800431B0(object->pos, D_80183E80, object->sizeScaling, D_0D005AE0);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3849,20 +3931,23 @@ void func_8005477C(s32 objectIndex, u8 arg1, Vec3f arg2) {
|
|||
void render_object_smoke_particles(s32 cameraId) {
|
||||
UNUSED s32 stackPadding[2];
|
||||
Camera* sp54;
|
||||
s32 var_s0;
|
||||
s32 i;
|
||||
s32 objectIndex;
|
||||
Object* object;
|
||||
|
||||
sp54 = &camera1[cameraId];
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, D_0D007AE0);
|
||||
load_texture_block_i8_nomirror(common_texture_particle_smoke[D_80165598], 32, 32);
|
||||
func_8004B72C(255, 255, 255, 255, 255, 255, 255);
|
||||
D_80183E80[0] = 0;
|
||||
D_80183E80[2] = 0x8000;
|
||||
for (var_s0 = 0; var_s0 < gObjectParticle4_SIZE; var_s0++) {
|
||||
objectIndex = gObjectParticle4[var_s0];
|
||||
for (i = 0; i < gObjectParticle4_SIZE; i++) {
|
||||
objectIndex = gObjectParticle4[i];
|
||||
if (objectIndex != NULL_OBJECT_ID) {
|
||||
object = &gObjectList[objectIndex];
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("SmokeParticles", (uintptr_t) object);
|
||||
if (object->state >= 2) {
|
||||
if (object->unk_0D8 == 3) {
|
||||
func_8008A364(objectIndex, cameraId, 0x4000U, 0x00000514);
|
||||
|
|
@ -3873,6 +3958,8 @@ void render_object_smoke_particles(s32 cameraId) {
|
|||
func_8005477C(objectIndex, object->unk_0D8, sp54->pos);
|
||||
}
|
||||
}
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3885,6 +3972,9 @@ void func_800557B4(s32 objectIndex, u32 arg1, u32 arg2) {
|
|||
Object* object;
|
||||
|
||||
object = &gObjectList[objectIndex];
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Penguin", (uintptr_t) object);
|
||||
if (object->state >= 2) {
|
||||
if (is_obj_flag_status_active(objectIndex, 0x00000020) != 0) {
|
||||
if (func_80072320(objectIndex, 4) != 0) {
|
||||
|
|
@ -3907,6 +3997,9 @@ void func_800557B4(s32 objectIndex, u32 arg1, u32 arg2) {
|
|||
render_animated_model((Armature*) object->model, (Animation**) object->vertex, (s16) object->unk_0D8,
|
||||
(s16) object->textureListIndex);
|
||||
}
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
void func_80055EF4(s32 objectIndex, UNUSED s32 arg1) {
|
||||
|
|
@ -3920,15 +4013,15 @@ void func_80055EF4(s32 objectIndex, UNUSED s32 arg1) {
|
|||
|
||||
void render_object_neon(s32 cameraId) {
|
||||
Camera* camera;
|
||||
s32 var_s2;
|
||||
s32 objectIndex;
|
||||
Object* object;
|
||||
|
||||
camera = &camera1[cameraId];
|
||||
for (var_s2 = 0; var_s2 < 10; var_s2++) {
|
||||
objectIndex = indexObjectList1[var_s2];
|
||||
for (size_t i = 0; i < 10; i++) {
|
||||
objectIndex = indexObjectList1[i];
|
||||
if (D_8018E838[cameraId] == 0) {
|
||||
object = &gObjectList[objectIndex];
|
||||
FrameInterpolation_RecordOpenChild(object, TAG_OBJECT((objectIndex << 8) + i));
|
||||
if ((object->state >= 2) && (is_obj_index_flag_status_inactive(objectIndex, 0x00080000) != 0) &&
|
||||
(is_object_visible_on_camera(objectIndex, camera, 0x2AABU) != 0)) {
|
||||
Vtx* vtx = (Vtx*) LOAD_ASSET(common_vtx_hedgehog);
|
||||
|
|
@ -3936,6 +4029,7 @@ void render_object_neon(s32 cameraId) {
|
|||
draw_2d_texture_at(object->pos, object->orientation, object->sizeScaling, (u8*) object->activeTLUT,
|
||||
object->activeTexture, vtx, 0x00000040, 0x00000040, 0x00000040, 0x00000020);
|
||||
}
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4019,8 +4113,8 @@ void func_8005669C(s32 objectIndex, UNUSED s32 arg1, s32 arg2) {
|
|||
gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
|
||||
}
|
||||
|
||||
Mat4 mtx;
|
||||
void func_800568A0(s32 objectIndex, s32 playerId) {
|
||||
Mat4 mtx;
|
||||
Player* player;
|
||||
|
||||
player = &gPlayerOne[playerId];
|
||||
|
|
@ -4040,13 +4134,12 @@ void func_800569F4(s32 playerIndex) {
|
|||
CM_DisplayBattleBombKart(playerIndex, 0);
|
||||
}
|
||||
|
||||
|
||||
void func_80056A40(s32 playerIndex, s32 arg1) {
|
||||
CM_DisplayBattleBombKart(playerIndex, arg1);
|
||||
}
|
||||
|
||||
void func_80056A94(s32 playerIndex) {
|
||||
//func_80072428(gIndexObjectBombKart[playerIndex]);
|
||||
// func_80072428(gIndexObjectBombKart[playerIndex]);
|
||||
CM_DisplayBattleBombKart(playerIndex, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <assets/donkeykong_kart.h>
|
||||
#include "port/Game.h"
|
||||
#include "engine/Matrix.h"
|
||||
#include "port/interpolation/FrameInterpolation.h"
|
||||
|
||||
s8 gRenderingFramebufferByPlayer[] = { 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02 };
|
||||
|
||||
|
|
@ -47,7 +48,6 @@ s16 gMatrixEffectCount;
|
|||
s32 D_80164AF4[3];
|
||||
struct_D_802F1F80* gPlayerPalette;
|
||||
static const char* sKartUpperTexture;
|
||||
static const char* sKartLowerTexture;
|
||||
u16 gPlayerRedEffect[8];
|
||||
u16 gPlayerGreenEffect[8];
|
||||
u16 gPlayerBlueEffect[8];
|
||||
|
|
@ -722,7 +722,7 @@ const char** wheelPtr[] = {
|
|||
donkeykong_kart_wheels, wario_kart_wheels, peach_kart_wheels, bowser_kart_wheels,
|
||||
};
|
||||
|
||||
s32 D_800DDE74[] = { 96, 128, 192, 256, 288, 384, 512, 544, 576, 0, 0};
|
||||
s32 D_800DDE74[] = { 96, 128, 192, 256, 288, 384, 512, 544, 576, 0, 0 };
|
||||
|
||||
void render_players_on_screen_two(void) {
|
||||
gPlayersToRenderCount = 0;
|
||||
|
|
@ -902,6 +902,8 @@ void mtxf_translate_rotate(Mat4 dest, Vec3f pos, Vec3s orientation) {
|
|||
f32 sinZ = sins(orientation[2]);
|
||||
f32 cosZ = coss(orientation[2]);
|
||||
|
||||
FrameInterpolation_RecordTranslateRotate(dest, pos, orientation);
|
||||
|
||||
dest[0][0] = (cosY * cosZ) + ((sinX * sinY) * sinZ);
|
||||
dest[1][0] = (-cosY * sinZ) + ((sinX * sinY) * cosZ);
|
||||
dest[2][0] = cosX * sinY;
|
||||
|
|
@ -926,18 +928,6 @@ UNUSED void func_80021F50(Mat4 arg0, Vec3f arg1) {
|
|||
arg0[3][2] += arg1[2];
|
||||
}
|
||||
|
||||
void mtxf_scale2(Mat4 arg0, f32 scale) {
|
||||
arg0[0][0] *= scale;
|
||||
arg0[1][0] *= scale;
|
||||
arg0[2][0] *= scale;
|
||||
arg0[0][1] *= scale;
|
||||
arg0[1][1] *= scale;
|
||||
arg0[2][1] *= scale;
|
||||
arg0[0][2] *= scale;
|
||||
arg0[1][2] *= scale;
|
||||
arg0[2][2] *= scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function writes a fixed-point value to each Mtx entry. This is not how the Mtx struct works.
|
||||
* The first half of Mtx only holds s16 whole numbers and the second half holds the s16 decimal (fractional) parts.
|
||||
|
|
@ -1287,7 +1277,7 @@ void change_player_color_effect_cmy(UNUSED Player* player, s8 arg1, s32 arg2, f3
|
|||
* Sort of an atmospheric effect.
|
||||
*/
|
||||
bool is_player_under_light_luigi_raceway(Player* player, s8 arg1) {
|
||||
if (GetCourse() == GetLuigiRaceway()) {
|
||||
if (IsLuigiRaceway()) {
|
||||
if (((gNearestWaypointByPlayerId[arg1] >= 0x14F) && (gNearestWaypointByPlayerId[arg1] < 0x158)) ||
|
||||
((gNearestWaypointByPlayerId[arg1] >= 0x15E) && (gNearestWaypointByPlayerId[arg1] < 0x164)) ||
|
||||
((gNearestWaypointByPlayerId[arg1] >= 0x169) && (gNearestWaypointByPlayerId[arg1] < 0x170)) ||
|
||||
|
|
@ -1305,7 +1295,7 @@ bool is_player_under_light_luigi_raceway(Player* player, s8 arg1) {
|
|||
}
|
||||
|
||||
void render_light_environment_on_player(Player* player, s8 arg1) {
|
||||
if (GetCourse() == GetBowsersCastle()) {
|
||||
if (IsBowsersCastle()) {
|
||||
if (((gNearestWaypointByPlayerId[arg1] >= 0x15) && (gNearestWaypointByPlayerId[arg1] < 0x2A)) ||
|
||||
((gNearestWaypointByPlayerId[arg1] >= 0x14D) && (gNearestWaypointByPlayerId[arg1] < 0x15C)) ||
|
||||
((gNearestWaypointByPlayerId[arg1] >= 0x1D1) && (gNearestWaypointByPlayerId[arg1] < 0x1E4)) ||
|
||||
|
|
@ -1328,7 +1318,7 @@ void render_light_environment_on_player(Player* player, s8 arg1) {
|
|||
change_player_color_effect_cmy(player, arg1, 0, 0.3f);
|
||||
D_80164B80[arg1] = 0;
|
||||
}
|
||||
} else if (GetCourse() == GetBansheeBoardwalk()) {
|
||||
} else if (IsBansheeBoardwalk()) {
|
||||
if (((gNearestWaypointByPlayerId[arg1] >= 0xD) && (gNearestWaypointByPlayerId[arg1] < 0x15)) ||
|
||||
((gNearestWaypointByPlayerId[arg1] >= 0x29) && (gNearestWaypointByPlayerId[arg1] < 0x39)) ||
|
||||
((gNearestWaypointByPlayerId[arg1] >= 0x46) && (gNearestWaypointByPlayerId[arg1] < 0x4E)) ||
|
||||
|
|
@ -1483,6 +1473,8 @@ void render_player_shadow(Player* player, s8 playerId, s8 screenId) {
|
|||
UNUSED Vec3f pad2;
|
||||
f32 var_f2;
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Kart Shadow", TAG_ITEM_ADDR(player));
|
||||
temp_t9 = (u16) (player->unk_048[screenId] + player->rotation[1] + player->unk_0C0) / 128; // << 7) & 0xFFFF;
|
||||
spC0 = -player->rotation[1] - player->unk_0C0;
|
||||
|
||||
|
|
@ -1520,7 +1512,7 @@ void render_player_shadow(Player* player, s8 playerId, s8 screenId) {
|
|||
spCC[1] = player->unk_074 + 1.0f;
|
||||
spCC[2] = player->pos[2] + ((spB0 * coss(spC0)) - (spAC * sins(spC0)));
|
||||
mtxf_translate_rotate(mtx, spCC, spC4);
|
||||
mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size);
|
||||
mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size);
|
||||
}
|
||||
// convert_to_fixed_point_matrix(&gGfxPool->mtxShadow[playerId + (screenId * 8)], mtx);
|
||||
|
||||
|
|
@ -1546,6 +1538,9 @@ void render_player_shadow(Player* player, s8 playerId, s8 screenId) {
|
|||
|
||||
gSPDisplayList(gDisplayListHead++, common_square_plain_render);
|
||||
gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
void render_player_shadow_credits(Player* player, s8 playerId, s8 arg2) {
|
||||
|
|
@ -1576,7 +1571,7 @@ void render_player_shadow_credits(Player* player, s8 playerId, s8 arg2) {
|
|||
spCC[1] = gObjectList[indexObjectList1[playerId]].pos[1] + sp94[playerId];
|
||||
|
||||
mtxf_translate_rotate(mtx, spCC, spC4);
|
||||
mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size);
|
||||
mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size);
|
||||
// convert_to_fixed_point_matrix(&gGfxPool->mtxShadow[playerId + (arg2 * 8)], mtx);
|
||||
|
||||
// gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxShadow[playerId + (arg2 * 8)]),
|
||||
|
|
@ -1604,6 +1599,19 @@ void render_player_shadow_credits(Player* player, s8 playerId, s8 arg2) {
|
|||
gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
|
||||
}
|
||||
|
||||
Vtx player_vtx[] = {
|
||||
{ { { 9, 18, -6 }, 0, { 4032, 0 }, { 0xFF, 0xFF, 0xFF, 0xFF } } },
|
||||
{ { { 9, 0, -6 }, 0, { 4032, 4032 }, { 0xFF, 0xFF, 0xFF, 0xFF } } },
|
||||
{ { { -9, 18, -6 }, 0, { 0, 0 }, { 0xFF, 0xFF, 0xFF, 0xFF } } },
|
||||
{ { { -9, 0, -6 }, 0, { 0, 4032 }, { 0xFF, 0xFF, 0xFF, 0xFF } } },
|
||||
};
|
||||
Vtx player_vtx_flip[] = {
|
||||
{ { { 9, 18, -6 }, 0, { 0, 0 }, { 0xFF, 0xFF, 0xFF, 0xFF } } },
|
||||
{ { { 9, 0, -6 }, 0, { 0, 4032 }, { 0xFF, 0xFF, 0xFF, 0xFF } } },
|
||||
{ { { -9, 18, -6 }, 0, { 4032, 0 }, { 0xFF, 0xFF, 0xFF, 0xFF } } },
|
||||
{ { { -9, 0, -6 }, 0, { 4032, 4032 }, { 0xFF, 0xFF, 0xFF, 0xFF } } },
|
||||
};
|
||||
|
||||
void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) {
|
||||
UNUSED s32 pad;
|
||||
Mat4 mtx;
|
||||
|
|
@ -1616,6 +1624,7 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) {
|
|||
s16 temp_v1;
|
||||
s16 thing;
|
||||
|
||||
FrameInterpolation_RecordOpenChild("player_kart", playerId | screenId << 8);
|
||||
if (player->unk_044 & 0x2000) {
|
||||
sp14C[0] = 0;
|
||||
sp14C[1] = player->unk_048[screenId];
|
||||
|
|
@ -1668,9 +1677,11 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) {
|
|||
#endif
|
||||
}
|
||||
mtxf_translate_rotate(mtx, sp154, sp14C);
|
||||
mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size);
|
||||
mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size);
|
||||
// convert_to_fixed_point_matrix(&gGfxPool->mtxKart[playerId + (screenId * 8)], mtx);
|
||||
|
||||
// @port: Tag the transform.
|
||||
|
||||
if ((player->effects & BOO_EFFECT) == BOO_EFFECT) {
|
||||
if (screenId == playerId) {
|
||||
AddKartMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
|
@ -1728,21 +1739,20 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) {
|
|||
}
|
||||
|
||||
// Render heads
|
||||
gDPLoadTextureBlock(gDisplayListHead++, sKartUpperTexture, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0,
|
||||
gDPLoadTextureBlock(gDisplayListHead++, sKartUpperTexture, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 64, 0,
|
||||
G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
||||
G_TX_NOLOD);
|
||||
gSPVertex(gDisplayListHead++, &D_800DDBB4[playerId][arg3], 4, 0);
|
||||
gSPDisplayList(gDisplayListHead++, common_square_plain_render);
|
||||
|
||||
// Render karts
|
||||
u8* test = (u8*) LOAD_ASSET(sKartUpperTexture);
|
||||
gDPLoadTextureBlock(gDisplayListHead++, test + 0x7C0, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0,
|
||||
G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
||||
G_TX_NOLOD);
|
||||
gSPVertex(gDisplayListHead++, &D_800DDBB4[playerId][arg3 + 4], 4, 0);
|
||||
gSPDisplayList(gDisplayListHead++, common_square_plain_render);
|
||||
if (arg3 == 0) {
|
||||
gSPVertex(gDisplayListHead++, player_vtx, 4, 0);
|
||||
} else {
|
||||
gSPVertex(gDisplayListHead++, player_vtx_flip, 4, 0);
|
||||
}
|
||||
gSP2Triangles(gDisplayListHead++, 0, 1, 2, 0, 1, 3, 2, 0);
|
||||
gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
|
||||
gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
void render_ghost(Player* player, s8 playerId, s8 screenId, s8 arg3) {
|
||||
|
|
@ -1789,7 +1799,7 @@ void render_ghost(Player* player, s8 playerId, s8 screenId, s8 arg3) {
|
|||
}
|
||||
|
||||
mtxf_translate_rotate(mtx, spDC, spD4);
|
||||
mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size);
|
||||
mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size);
|
||||
// convert_to_fixed_point_matrix(&gGfxPool->mtxKart[playerId + (screenId * 8)], mtx);
|
||||
|
||||
// gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxKart[playerId + (screenId * 8)]),
|
||||
|
|
@ -1834,8 +1844,11 @@ void func_80025DE8(Player* player, s8 playerId, s8 screenId, s8 arg3) {
|
|||
sp94[1] = player->unk_048[screenId];
|
||||
sp94[2] = player->unk_050[screenId];
|
||||
|
||||
FrameInterpolation_RecordOpenChild("player_boost", playerId | screenId << 8);
|
||||
|
||||
|
||||
mtxf_translate_rotate(mtx, sp9C, sp94);
|
||||
mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size);
|
||||
mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size);
|
||||
// convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx);
|
||||
|
||||
// gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]),
|
||||
|
|
@ -1865,6 +1878,8 @@ void func_80025DE8(Player* player, s8 playerId, s8 screenId, s8 arg3) {
|
|||
gSPDisplayList(gDisplayListHead++, common_square_plain_render);
|
||||
gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
|
||||
gMatrixEffectCount += 1;
|
||||
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 arg3) {
|
||||
|
|
@ -1884,8 +1899,11 @@ void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 a
|
|||
arg3 = 0;
|
||||
}
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("PlayerReflection", playerId | screenId << 8);
|
||||
|
||||
mtxf_translate_rotate(mtx, sp9C, sp94);
|
||||
mtxf_scale2(mtx, gCharacterSize[player->characterId] * player->size);
|
||||
mtxf_scale(mtx, gCharacterSize[player->characterId] * player->size);
|
||||
// convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx);
|
||||
|
||||
// gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxEffect[gMatrixEffectCount]),
|
||||
|
|
@ -1911,6 +1929,9 @@ void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 a
|
|||
gSPDisplayList(gDisplayListHead++, common_square_plain_render);
|
||||
gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
|
||||
gMatrixEffectCount += 1;
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
void render_player(Player* player, s8 playerId, s8 screenId) {
|
||||
|
|
@ -1951,7 +1972,7 @@ void render_player(Player* player, s8 playerId, s8 screenId) {
|
|||
func_80025DE8(player, playerId, screenId, var_v1);
|
||||
}
|
||||
// Allows wheels to spin
|
||||
gSPInvalidateTexCache(gDisplayListHead++, sKartLowerTexture);
|
||||
gSPInvalidateTexCache(gDisplayListHead++, sKartUpperTexture);
|
||||
}
|
||||
|
||||
void func_80026A48(Player* player, s8 arg1) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef CODE_8001F980_H
|
||||
#define CODE_8001F980_H
|
||||
#ifndef RENDER_PLAYER_H
|
||||
#define RENDER_PLAYER_H
|
||||
|
||||
#include <common_structs.h>
|
||||
#include "buffers.h"
|
||||
|
|
@ -29,7 +29,6 @@ void func_80021D40(void);
|
|||
void func_80021DA8(void);
|
||||
void mtxf_translate_rotate(Mat4, Vec3f, Vec3s);
|
||||
void func_80021F50(Mat4, Vec3f);
|
||||
void mtxf_scale2(Mat4, f32);
|
||||
void failed_fixed_point_matrix_conversion(Mtx*, Mat4);
|
||||
void convert_to_fixed_point_matrix(Mtx*, Mat4);
|
||||
bool adjust_angle(s16*, s16, s16);
|
||||
|
|
@ -279,4 +278,4 @@ extern s16 D_80165150[4][8];
|
|||
extern s16 D_80165190[4][8];
|
||||
extern s16 D_801651D0[4][8];
|
||||
|
||||
#endif
|
||||
#endif // RENDER_PLAYER_H
|
||||
|
|
|
|||
|
|
@ -729,7 +729,7 @@ void spawn_players_versus_two_player(f32* arg0, f32* arg1, f32 arg2) {
|
|||
}
|
||||
|
||||
void spawn_players_2p_battle(f32* arg0, f32* arg1, f32 arg2) {
|
||||
if (GetCourse() == GetBigDonut()) {
|
||||
if (IsBigDonut()) {
|
||||
spawn_player(gPlayerOne, 0, arg0[0], arg1[0], arg2, -16384.0f, gCharacterSelections[0],
|
||||
PLAYER_EXISTS | PLAYER_START_SEQUENCE | PLAYER_HUMAN);
|
||||
spawn_player(gPlayerTwo, 1, arg0[1], arg1[1], arg2, 16384.0f, gCharacterSelections[1],
|
||||
|
|
@ -778,7 +778,7 @@ void func_8003B318(f32* arg0, f32* arg1, f32 arg2) {
|
|||
}
|
||||
|
||||
void spawn_players_3p_battle(f32* arg0, f32* arg1, f32 arg2) {
|
||||
if (GetCourse() == GetBigDonut()) {
|
||||
if (IsBigDonut()) {
|
||||
spawn_player(gPlayerOne, 0, arg0[0], arg1[0], arg2, -16384.0f, gCharacterSelections[0],
|
||||
PLAYER_EXISTS | PLAYER_START_SEQUENCE | PLAYER_HUMAN);
|
||||
spawn_player(gPlayerTwo, 1, arg0[1], arg1[1], arg2, 16384.0f, gCharacterSelections[1],
|
||||
|
|
@ -830,7 +830,7 @@ void func_8003B870(f32* arg0, f32* arg1, f32 arg2) {
|
|||
}
|
||||
|
||||
void spawn_players_4p_battle(f32* arg0, f32* arg1, f32 arg2) {
|
||||
if (GetCourse() == GetBigDonut()) {
|
||||
if (IsBigDonut()) {
|
||||
spawn_player(gPlayerOne, 0, arg0[0], arg1[0], arg2, -16384.0f, gCharacterSelections[0],
|
||||
PLAYER_EXISTS | PLAYER_START_SEQUENCE | PLAYER_HUMAN);
|
||||
spawn_player(gPlayerTwo, 1, arg0[1], arg1[1], arg2, 16384.0f, gCharacterSelections[1],
|
||||
|
|
@ -888,17 +888,17 @@ void func_8003C0F0(void) {
|
|||
|
||||
if (gModeSelection == BATTLE) {
|
||||
func_8000EEDC();
|
||||
} else if (GetCourse() != GetPodiumCeremony()) {
|
||||
} else if (!IsPodiumCeremony()) {
|
||||
func_8000F2DC();
|
||||
sp5E = (f32) D_80164550[0][0].posX;
|
||||
sp5C = (f32) D_80164550[0][0].posZ;
|
||||
sp5A = (f32) D_80164550[0][0].posY;
|
||||
if (GetCourse() == GetToadsTurnpike()) {
|
||||
if (IsToadsTurnpike()) {
|
||||
sp5E = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((gModeSelection != BATTLE) && (GetCourse() != GetPodiumCeremony())) {
|
||||
if ((gModeSelection != BATTLE) && (!IsPodiumCeremony())) {
|
||||
switch (gActiveScreenMode) {
|
||||
case SCREEN_MODE_1P:
|
||||
switch (gModeSelection) {
|
||||
|
|
@ -993,7 +993,7 @@ void func_8003C0F0(void) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
} else if (GetCourse() == GetBlockFort()) {
|
||||
} else if (IsBlockFort()) {
|
||||
switch (gActiveScreenMode) {
|
||||
case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL:
|
||||
case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL:
|
||||
|
|
@ -1023,7 +1023,7 @@ void func_8003C0F0(void) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
} else if (GetCourse() == GetSkyscraper()) {
|
||||
} else if (IsSkyscraper()) {
|
||||
switch (gActiveScreenMode) {
|
||||
case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL:
|
||||
case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL:
|
||||
|
|
@ -1053,7 +1053,7 @@ void func_8003C0F0(void) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
} else if (GetCourse() == GetDoubleDeck()) {
|
||||
} else if (IsDoubleDeck()) {
|
||||
switch (gActiveScreenMode) {
|
||||
case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL:
|
||||
case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL:
|
||||
|
|
@ -1083,7 +1083,7 @@ void func_8003C0F0(void) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
} else if (GetCourse() == GetBigDonut()) {
|
||||
} else if (IsBigDonut()) {
|
||||
switch (gActiveScreenMode) {
|
||||
case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL:
|
||||
case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL:
|
||||
|
|
@ -1194,12 +1194,13 @@ void func_8003D080(void) {
|
|||
} else {
|
||||
func_8003C0F0();
|
||||
}
|
||||
|
||||
if (!gDemoMode) {
|
||||
switch (gActiveScreenMode) {
|
||||
case SCREEN_MODE_1P:
|
||||
switch (gModeSelection) {
|
||||
case GRAND_PRIX:
|
||||
if (GetCourse() == GetToadsTurnpike()) {
|
||||
if (IsToadsTurnpike()) {
|
||||
camera_init(0.0f, player->pos[1], D_80165230[7], player->rotation[1], 8, 0);
|
||||
} else {
|
||||
camera_init((D_80165210[7] + D_80165210[6]) / 2, player->pos[1], D_80165230[7],
|
||||
|
|
@ -1289,6 +1290,9 @@ void func_8003D080(void) {
|
|||
}
|
||||
}
|
||||
|
||||
// Init freecam
|
||||
//freecam_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 4);
|
||||
|
||||
switch (gActiveScreenMode) {
|
||||
case SCREEN_MODE_1P:
|
||||
func_8003CD98(gPlayerOneCopy, camera1, 0, 0); // sic
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ u32* D_80162DB4;
|
|||
s16 D_80162DB8;
|
||||
u32* D_80162DBC;
|
||||
|
||||
u16 D_80162DC0;
|
||||
uintptr_t staff_ghost_track_ptr;
|
||||
StaffGhost* D_80162DC4;
|
||||
s32 D_80162DC8;
|
||||
s32 D_80162DCC;
|
||||
|
|
@ -164,11 +164,11 @@ void func_80005310(void) {
|
|||
|
||||
set_staff_ghost();
|
||||
|
||||
if (D_80162DC0 != gCurrentCourseId) {
|
||||
if (staff_ghost_track_ptr != (uintptr_t)GetCourse()) {
|
||||
D_80162DD4 = 1;
|
||||
}
|
||||
|
||||
D_80162DC0 = (u16) gCurrentCourseId;
|
||||
staff_ghost_track_ptr = (uintptr_t)GetCourse();
|
||||
D_80162DF0 = 0;
|
||||
D_80162DEC = 0;
|
||||
D_80162DF8 = 0;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@
|
|||
#include <assets/boo_frames.h>
|
||||
#include "port/Game.h"
|
||||
|
||||
float OTRGetAspectRatio(void);
|
||||
|
||||
//! @todo unused?
|
||||
f32 D_800E43B0[] = { 65536.0, 0.0, 1.0, 0.0, 0.0, 65536.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
|
||||
|
|
@ -2088,8 +2090,6 @@ void init_smoke_particles(s32 arg0) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void init_object_leaf_particle(s32 objectIndex, Vec3f arg1, s32 num) {
|
||||
UNUSED s32 stackPadding1;
|
||||
UNUSED u16 stackPadding0;
|
||||
|
|
@ -2104,19 +2104,19 @@ void init_object_leaf_particle(s32 objectIndex, Vec3f arg1, s32 num) {
|
|||
gObjectList[objectIndex].sizeScaling = 0.1f;
|
||||
gObjectList[objectIndex].surfaceHeight = arg1[1];
|
||||
|
||||
if (GetCourse() == GetMarioRaceway()) {
|
||||
if (IsMarioRaceway()) {
|
||||
object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 25.0, arg1[2], 0x14, 0x1E, 0x14);
|
||||
gObjectList[objectIndex].unk_034 = 1.5f;
|
||||
gObjectList[objectIndex].velocity[1] = 1.5f;
|
||||
} else if (GetCourse() == GetYoshiValley()) {
|
||||
} else if (IsYoshiValley()) {
|
||||
object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 25.0, arg1[2], 0x14, 0x1E, 0x14);
|
||||
gObjectList[objectIndex].unk_034 = 2.0f;
|
||||
gObjectList[objectIndex].velocity[1] = 2.0f;
|
||||
} else if (GetCourse() == GetRoyalRaceway()) {
|
||||
} else if (IsRoyalRaceway()) {
|
||||
object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 30.0, arg1[2], 0x10, 0x28, 0x10);
|
||||
gObjectList[objectIndex].unk_034 = 2.0f;
|
||||
gObjectList[objectIndex].velocity[1] = 2.0f;
|
||||
} else if (GetCourse() == GetLuigiRaceway()) {
|
||||
} else if (IsLuigiRaceway()) {
|
||||
object_origin_pos_randomize_around_xyz(objectIndex, arg1[0], arg1[1] + 25.0, arg1[2], 0x14, 0x1E, 0x14);
|
||||
gObjectList[objectIndex].unk_034 = 1.5f;
|
||||
gObjectList[objectIndex].velocity[1] = 1.0f;
|
||||
|
|
@ -2454,21 +2454,30 @@ void update_snowflakes(void) {
|
|||
}
|
||||
}
|
||||
|
||||
// This function adjusted to place clouds in the sky correctly
|
||||
void func_800788F8(s32 objectIndex, u16 rot, Camera* camera) {
|
||||
s16 temp_v0;
|
||||
s16 cameraRot;
|
||||
// Adjustable culling factor
|
||||
const float cullingFactor = OTRGetAspectRatio();
|
||||
|
||||
temp_v0 = camera->rot[1] + rot;
|
||||
if ((temp_v0 >= D_8018D210) && (D_8018D208 >= temp_v0)) {
|
||||
gObjectList[objectIndex].unk_09C = (D_8018D218 + (D_8018D1E8 * temp_v0));
|
||||
set_object_flag(objectIndex, 0x00000010);
|
||||
return;
|
||||
// Calculate the cloud's rotation relative to the camera
|
||||
cameraRot = camera->rot[1] + rot;
|
||||
|
||||
// Adjust bounds based on the culling factor
|
||||
s16 adjustedLowerBound = (s16) (D_8018D210 * cullingFactor);
|
||||
s16 adjustedUpperBound = (s16) (D_8018D208 * cullingFactor);
|
||||
|
||||
// Check if the object is within the adjusted bounds
|
||||
if ((cameraRot >= adjustedLowerBound) && (adjustedUpperBound >= cameraRot)) {
|
||||
// Calculate and update the object's position
|
||||
gObjectList[objectIndex].unk_09C = (D_8018D218 + (D_8018D1E8 * cameraRot));
|
||||
|
||||
// Mark the object as visible
|
||||
set_object_flag(objectIndex, 0x10);
|
||||
} else {
|
||||
// If outside the bounds, mark the object as not visible
|
||||
set_object_flag(objectIndex, 0x10);
|
||||
}
|
||||
if (CVarGetInteger("gNoCulling", 0) == 1) {
|
||||
gObjectList[objectIndex].unk_09C = (D_8018D218 + (D_8018D1E8 * temp_v0));
|
||||
set_object_flag(objectIndex, 0x00000010);
|
||||
return;
|
||||
}
|
||||
clear_object_flag(objectIndex, 0x00000010);
|
||||
}
|
||||
|
||||
void update_clouds(s32 arg0, Camera* arg1, CloudData* cloudList) {
|
||||
|
|
@ -2601,7 +2610,6 @@ void func_80078C70(s32 arg0) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void func_8007ABFC(s32 playerId, bool arg1) {
|
||||
s32 itemWindow;
|
||||
|
||||
|
|
@ -3448,7 +3456,7 @@ void func_8007BB9C(s32 arg0) {
|
|||
}
|
||||
|
||||
void wrapper_update_boos(void) {
|
||||
//update_boos();
|
||||
// update_boos();
|
||||
}
|
||||
|
||||
// Updates the display status on an object based on its relative direction to the camera
|
||||
|
|
@ -3476,7 +3484,6 @@ void func_8007C420(s32 objectIndex, Player* player, Camera* camera) {
|
|||
func_8007C360(objectIndex, camera);
|
||||
}
|
||||
|
||||
|
||||
void func_8007CE0C(s32 objectIndex) {
|
||||
Object* object;
|
||||
|
||||
|
|
@ -3873,8 +3880,6 @@ void func_800842C8(void) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void func_80085BB4(s32 objectIndex) {
|
||||
gObjectList[objectIndex].sizeScaling = 8.0f;
|
||||
set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f);
|
||||
|
|
|
|||
2
torch
2
torch
|
|
@ -1 +1 @@
|
|||
Subproject commit 8e56ea0294973b7c9f8f077a131b40fce13b8489
|
||||
Subproject commit f75facb20883570ed091e8ae733ec0539f606e57
|
||||
Loading…
Reference in New Issue