Fix interpolation camera bug

This commit is contained in:
MegaMech
2025-05-19 16:42:11 -06:00
parent c12225592a
commit 1eba8ebc17
15 changed files with 281 additions and 66 deletions
+144 -2
View File
@@ -25,11 +25,12 @@
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];
@@ -194,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;
@@ -994,7 +1135,8 @@ void func_8001EE98(Player* player, Camera* camera, s8 index) {
func_8001E8E8(camera, player, index);
break;
}
freecam(camera, player, index); // Runs func_8001E45C when freecam is disabled
//freecam(camera, player, index); // Runs func_8001E45C when freecam is disabled
func_8001E45C(camera, player, index);
break;
case 8:
func_8001E0C4(camera, player, index);
+2
View File
@@ -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
+3 -1
View File
@@ -4967,9 +4967,10 @@ void func_800651F4(Player* player, UNUSED s8 arg1, UNUSED s8 arg2, s8 arg3) {
}
}
s32 D_func_800652D4_counter = 0;
void func_800652D4(Vec3f arg0, Vec3s arg1, f32 arg2) {
Mat4 mtx;
FrameInterpolation_RecordOpenChild("some_thing", D_func_800652D4_counter++ << 8);
mtxf_translate_rotate(mtx, arg0, arg1);
mtxf_scale(mtx, arg2);
// convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx);
@@ -4977,6 +4978,7 @@ void func_800652D4(Vec3f arg0, Vec3s arg1, f32 arg2) {
// G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
AddEffectMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
FrameInterpolation_RecordCloseChild();
}
void func_8006538C(Player* player, s8 arg1, s16 arg2, s8 arg3) {
+25 -16
View File
@@ -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>
@@ -85,7 +86,7 @@ void freecam(Camera* camera, Player* player, s8 index) {
if (enabled && (player == gPlayerOne)) {
freecam_loop(camera, player, index);
} else {
func_8001E45C(camera, player, index);
func_8001EE98(gPlayerOneCopy, camera, index);
}
}
@@ -104,7 +105,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 +389,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++);
}
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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;
+13 -7
View File
@@ -758,15 +758,18 @@ void process_game_tick(void) {
func_800382DC();
}
// Editor requires this for camera movement.
func_8001EE98(gPlayerOneCopy, camera1, 0);
if (gIsEditorPaused == true) {
return;
}
switch(gActiveScreenMode) {
case SCREEN_MODE_1P:
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;
}
func_80028F70();
break;
case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL:
@@ -930,6 +933,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 +971,7 @@ void game_state_handler(void) {
credits_loop();
break;
}
FrameInterpolation_StopRecord();
}
void interrupt_gfx_sptask(void) {
+1
View File
@@ -76,4 +76,5 @@ 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);
guMtxF2L(mf, m);
FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mf, m);
}
+1
View File
@@ -37,4 +37,5 @@ void guPerspective(Mtx* m, u16* perspNorm, float fovy, float aspect, float near,
float mat[4][4];
guPerspectiveF(mat, perspNorm, fovy, aspect, near, far, scale);
guMtxF2L(mat, m);
FrameInterpolation_RecordMatrixMtxFToMtx((MtxF*)mat, m);
}
@@ -550,7 +550,7 @@ unordered_map<Mtx*, MtxF> FrameInterpolation_Interpolate(float step) {
bool camera_interpolation = true;
void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate) {
// camera_interpolation = shouldInterpolate;
camera_interpolation = shouldInterpolate;
is_recording = shouldInterpolate;
}
@@ -559,12 +559,12 @@ void FrameInterpolation_StartRecord(void) {
current_recording = {};
current_path.clear();
current_path.push_back(&current_recording.root_path);
// if (!camera_interpolation) {
// // default to interpolating
// camera_interpolation = true;
// is_recording = false;
// return;
// }
if (!camera_interpolation) {
// default to interpolating
camera_interpolation = true;
is_recording = false;
return;
}
if (GameEngine::GetInterpolationFPS() != 20) {
is_recording = true;
}
+7
View File
@@ -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"
@@ -240,9 +241,15 @@ 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);
//FrameInterpolation_RecordCloseChild();
CM_DrawWater(arg0, pathCounter, cameraRot, playerDirection);
FrameInterpolation_RecordCloseChild();
// switch (gCurrentCourseId) {
// case COURSE_BOWSER_CASTLE:
// if (gActiveScreenMode != SCREEN_MODE_1P) {
+60 -25
View File
@@ -755,17 +755,45 @@ void func_802A5760(void) {
}
}
void render_screens(s32 mode, s32 cameraId, s32 playerId) {
UNUSED s32 pad[4];
void setup_camera(Camera* camera, s32 playerId, s32 cameraId, struct UnkStruct_800DC5EC* screen) {
Mat4 matrix;
u16 perspNorm;
UNUSED s32 pad2[2];
UNUSED s32 pad3;
if (CVarGetInteger("gFreecam", 0) == true) {
freecam_render_setup(gFreecamCamera);
return;
}
FrameInterpolation_RecordOpenChild("camerapersp", FrameInterpolation_GetCameraEpoch());
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);
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);
}
FrameInterpolation_RecordCloseChild();
}
extern s32 D_func_800652D4_counter;
void render_screens(s32 mode, s32 cameraId, s32 playerId) {
Mat4 matrix;
s32 screenId = 0;
s32 screenMode = SCREEN_MODE_1P;
FrameInterpolation_StartRecord();
D_func_800652D4_counter = 0;
switch (mode) {
case RENDER_SCREEN_MODE_1P_PLAYER_ONE:
@@ -824,7 +852,14 @@ void render_screens(s32 mode, s32 cameraId, s32 playerId) {
}
struct UnkStruct_800DC5EC* screen = &D_8015F480[screenId];
Camera* camera = &cameras[cameraId];
Camera* 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);
@@ -834,27 +869,28 @@ void render_screens(s32 mode, s32 cameraId, s32 playerId) {
func_802A3730(screen);
gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH);
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
//FrameInterpolation_RecordOpenChild("SCREENCAMERA", (playerId | cameraId) << 8);
setup_camera(camera, playerId, cameraId, screen); // Setup camera perspective and lookAt
// render_course(screen);
//FrameInterpolation_RecordOpenChild("track", 0);
//Mat4 trackMtx;
//mtxf_identity(trackMtx);
//AddObjectMatrix(trackMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
render_course(screen);
//FrameInterpolation_RecordCloseChild();
//Mat4 projectionF;
//Matrix_MtxToMtxF(&gGfxPool->mtxLookAt[cameraId], &projectionF);
// SkinMatrix_MtxFMtxFMult(&projectionF, &flipF, &projectionF);
// FrameInterpolation_RecordCloseChild();
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);
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);
}
render_course(screen);
if (D_800DC5C8 == 1) {
//PushLookAtMtx(gGfxPool->mtxLookAt[cameraId], G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxLookAt[cameraId]),
G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
mtxf_identity(matrix);
@@ -910,7 +946,6 @@ void render_screens(s32 mode, s32 cameraId, s32 playerId) {
gNumScreens += 1;
}
FrameInterpolation_StopRecord();
}
void func_802A74BC(void) {
+4 -3
View File
@@ -3934,15 +3934,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);
@@ -3950,6 +3950,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();
}
}
}
+7 -2
View File
@@ -1611,8 +1611,8 @@ void render_kart(Player* player, s8 playerId, s8 screenId, s8 arg3) {
f32 sp140;
s16 temp_v1;
s16 thing;
FrameInterpolation_RecordOpenChild("Player", playerId | screenId << 8);
FrameInterpolation_RecordOpenChild("player_kart", playerId | screenId << 8);
if (player->unk_044 & 0x2000) {
sp14C[0] = 0;
sp14C[1] = player->unk_048[screenId];
@@ -1836,6 +1836,9 @@ 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_scale(mtx, gCharacterSize[player->characterId] * player->size);
// convert_to_fixed_point_matrix(&gGfxPool->mtxEffect[gMatrixEffectCount], mtx);
@@ -1867,6 +1870,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) {
+4
View File
@@ -1194,6 +1194,10 @@ void func_8003D080(void) {
} else {
func_8003C0F0();
}
// Init free cam
freecam_init(player->pos[0], player->pos[1], player->pos[2], player->rotation[1], 1, 4);
if (!gDemoMode) {
switch (gActiveScreenMode) {
case SCREEN_MODE_1P: