Implemented system for detecting billboards and disabling rotation interpolation for them during camera cuts, update RT64

This commit is contained in:
Mr-Wiseguy 2024-03-31 23:12:22 -04:00
parent 30e66ab12b
commit 81fca5bf96
11 changed files with 1105 additions and 15 deletions

@ -1 +1 @@
Subproject commit 7e2479d6b63ab4447635fadbb16ce3cf416afb00
Subproject commit bdd9ee86c0b058f8313493b25193ea610f481b90

View File

@ -84,7 +84,7 @@ Gfx* push_limb_matrix_group(Gfx* dlist, Actor* actor, u32 limb_index) {
if (actor != NULL) {
u32 cur_transform_id = actor_transform_id(actor);
if (actor_get_interpolation_skipped(actor)) {
gEXMatrixGroupDecomposedSkip(dlist++, cur_transform_id + limb_index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
gEXMatrixGroupDecomposedSkipAll(dlist++, cur_transform_id + limb_index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
} else {
gEXMatrixGroupDecomposedNormal(dlist++, cur_transform_id + limb_index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
}
@ -97,7 +97,7 @@ Gfx* push_post_limb_matrix_group(Gfx* dlist, Actor* actor, u32 limb_index) {
if (actor != NULL) {
u32 cur_transform_id = actor_transform_id(actor);
if (actor_get_interpolation_skipped(actor)) {
gEXMatrixGroupDecomposedSkip(dlist++, cur_transform_id + limb_index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
gEXMatrixGroupDecomposedSkipAll(dlist++, cur_transform_id + limb_index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
} else {
gEXMatrixGroupDecomposedNormal(dlist++, cur_transform_id + limb_index + ACTOR_TRANSFORM_LIMB_COUNT, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
}
@ -110,7 +110,7 @@ Gfx* push_skin_limb_matrix_group(Gfx* dlist, Actor* actor, u32 limb_index) {
if (actor != NULL) {
u32 cur_transform_id = actor_transform_id(actor);
if (actor_get_interpolation_skipped(actor)) {
gEXMatrixGroupDecomposedSkip(dlist++, cur_transform_id + limb_index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
gEXMatrixGroupDecomposedSkipAll(dlist++, cur_transform_id + limb_index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
} else {
gEXMatrixGroupDecomposedVerts(dlist++, cur_transform_id + limb_index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
}

1024
patches/billboard_tagging.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@
#include "transform_ids.h"
#include "overlays/actors/ovl_En_Test7/z_en_test7.h"
#include "overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h"
#include "overlays/actors/ovl_Eff_Stk/z_eff_stk.h"
#include "z64effect.h"
// Decomp renames, TODO update decomp and remove these
@ -304,7 +305,7 @@ void func_808DD3C8(Actor* thisx, PlayState* play2) {
// @recomp Check if the particle's interpolation should be skipped this frame.
if (particle_skipped(this->unk_14C[i])) {
// @recomp Tag the particle's transform to skip interpolation.
gEXMatrixGroupDecomposedSkip(POLY_XLU_DISP++, actor_transform_id(thisx) + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
gEXMatrixGroupDecomposedSkipPosRot(POLY_XLU_DISP++, actor_transform_id(thisx) + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
else {
// @recomp Tag the particle's matrix to interpolate normally.
@ -458,3 +459,49 @@ void Effect_DrawAll(GraphicsContext* gfxCtx) {
pop_effect_tag(gfxCtx);
}
}
extern Gfx object_stk2_DL_008920[];
extern Gfx object_stk2_DL_008A38[];
extern AnimatedMaterial object_stk2_Matanimheader_009F60[];
void EffStk_Draw(Actor* thisx, PlayState* play) {
EffStk* this = (EffStk*)thisx;
s32 pad;
Camera* activeCam = GET_ACTIVE_CAM(play);
Vec3f eye = activeCam->eye;
Vec3f quakeOffset;
quakeOffset = Camera_GetQuakeOffset(activeCam);
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
Matrix_Translate(eye.x + quakeOffset.x, eye.y + quakeOffset.y, eye.z + quakeOffset.z, MTXMODE_NEW);
Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_Translate(0.0f, 0.0f, this->unk148, MTXMODE_APPLY);
Mtx* mtx = Matrix_NewMtx(play->state.gfxCtx);
recomp_printf("EffStk_Draw matrix: %08X\n", (u32)mtx);
// @recomp Tag the transform. Do not allow edits as this will get edited by the billboard detection and we'll want to skip position during a camera cut too.
if (camera_was_skipped()) {
gEXMatrixGroupDecomposedSkipPosRot(POLY_XLU_DISP++, actor_transform_id(thisx), G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
recomp_printf(" Skipped EffStk_Draw matrix\n");
}
else {
gEXMatrixGroupDecomposedNormal(POLY_XLU_DISP++, actor_transform_id(thisx), G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
AnimatedMat_DrawAlphaStep(play, Lib_SegmentedToVirtual(object_stk2_Matanimheader_009F60), 1.0f, this->unk144);
gDPSetColorDither(POLY_XLU_DISP++, G_CD_NOISE);
gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_NOISE);
gSPDisplayList(POLY_XLU_DISP++, object_stk2_DL_008920);
gSPDisplayList(POLY_XLU_DISP++, object_stk2_DL_008A38);
// @recomp Tag the transform.
gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW);
CLOSE_DISPS(play->state.gfxCtx);
}

View File

@ -71,8 +71,8 @@ void EffectSS_DrawParticle(PlayState* play, s32 index) {
// @recomp If this particle was just reset then skip interpolation.
if (particle_reset_list[index]) {
gEXMatrixGroupDecomposedSkip(POLY_OPA_DISP++, PARTICLE_TRANSFORM_ID_START + index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
gEXMatrixGroupDecomposedSkip(POLY_XLU_DISP++, PARTICLE_TRANSFORM_ID_START + index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
gEXMatrixGroupDecomposedSkipAll(POLY_OPA_DISP++, PARTICLE_TRANSFORM_ID_START + index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
gEXMatrixGroupDecomposedSkipAll(POLY_XLU_DISP++, PARTICLE_TRANSFORM_ID_START + index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
else {
gEXMatrixGroupDecomposedNormal(POLY_OPA_DISP++, PARTICLE_TRANSFORM_ID_START + index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);

View File

@ -17,7 +17,10 @@
#define gEXMatrixGroupDecomposedNormal(cmd, id, push, proj, edit) \
gEXMatrixGroupDecomposed(cmd, id, push, proj, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR, edit)
#define gEXMatrixGroupDecomposedSkip(cmd, id, push, proj, edit) \
#define gEXMatrixGroupDecomposedSkipPosRot(cmd, id, push, proj, edit) \
gEXMatrixGroupDecomposed(cmd, id, push, proj, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR, edit)
#define gEXMatrixGroupDecomposedSkipAll(cmd, id, push, proj, edit) \
gEXMatrixGroupDecomposed(cmd, id, push, proj, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR, edit)
#define gEXMatrixGroupDecomposedVerts(cmd, id, push, proj, edit) \
@ -59,6 +62,7 @@ void View_ApplyInterpolate(View* view, s32 mask, bool reset_interpolation_state)
void set_camera_skipped(bool skipped);
void clear_camera_skipped();
void edit_billboard_groups(PlayState* play);
bool camera_was_skipped();
void room_load_hook(PlayState* play, Room* room);

View File

@ -16,6 +16,7 @@ void Play_Main(GameState* thisx) {
// @recomp
debug_play_update(this);
controls_play_update(this);
matrix_play_update(this);
// @recomp avoid unused variable warning
(void)prevInput;

View File

@ -6,5 +6,6 @@
void debug_play_update(PlayState* play);
void camera_pre_play_update(PlayState* play);
void camera_post_play_update(PlayState* play);
void matrix_play_update(PlayState* play);
#endif

View File

@ -32,7 +32,7 @@ void Skybox_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId
// @recomp Tag the skybox's matrix, skipping interpolation if the camera's interpolation was also skipped.
if (camera_was_skipped()) {
gEXMatrixGroupDecomposedSkip(POLY_OPA_DISP++, SKYBOX_TRANSFORM_ID_START, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
gEXMatrixGroupDecomposedSkipAll(POLY_OPA_DISP++, SKYBOX_TRANSFORM_ID_START, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
else {
gEXMatrixGroupDecomposedNormal(POLY_OPA_DISP++, SKYBOX_TRANSFORM_ID_START, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
@ -247,9 +247,16 @@ void Environment_DrawSkyboxStarsImpl(PlayState* play, Gfx** gfxP) {
viewProjectionMtxF = play->viewProjectionMtxF.mf;
if (imgWidth >= 2) {
// @recomp Tag the star.
gEXMatrixGroupSimple(gfx++, STAR_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW,
G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR, G_EX_EDIT_NONE);
if (camera_was_skipped()) {
gEXMatrixGroupSimple(gfx++, STAR_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW,
G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_ORDER_LINEAR, G_EX_EDIT_NONE);
}
else {
gEXMatrixGroupSimple(gfx++, STAR_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW,
G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR, G_EX_EDIT_NONE);
}
// @recomp Draw the star in 3D with a billboarded matrix.
Environment_DrawSkyboxStarBillboard(play->state.gfxCtx, &billboard_mtx, &gfx, pos.x, pos.y, pos.z, imgWidth, imgWidth);

View File

@ -291,7 +291,7 @@ void Boss03_DrawEffects(PlayState* play) {
// @recomp Tag this effect and clear its reset state.
if (special_effect_reset_states[i]) {
gEXMatrixGroupDecomposedSkip(POLY_OPA_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
gEXMatrixGroupDecomposedSkipAll(POLY_OPA_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
else {
gEXMatrixGroupDecomposedNormal(POLY_OPA_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
@ -340,7 +340,7 @@ void Boss03_DrawEffects(PlayState* play) {
// @recomp Tag this effect and clear its reset state.
if (special_effect_reset_states[i]) {
gEXMatrixGroupDecomposedSkip(POLY_XLU_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
gEXMatrixGroupDecomposedSkipAll(POLY_XLU_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
else {
gEXMatrixGroupDecomposedNormal(POLY_XLU_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
@ -381,7 +381,7 @@ void Boss03_DrawEffects(PlayState* play) {
// @recomp Tag this effect and clear its reset state.
if (special_effect_reset_states[i]) {
gEXMatrixGroupDecomposedSkip(POLY_XLU_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
gEXMatrixGroupDecomposedSkipAll(POLY_XLU_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
else {
gEXMatrixGroupDecomposedNormal(POLY_XLU_DISP++, SPECIAL_EFFECTS_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);

View File

@ -97,6 +97,12 @@ void Graph_ExecuteAndDraw(GraphicsContext* gfxCtx, GameState* gameState) {
// @recomp Send the current framerate to RT64, including any extra VI interrupt periods.
gEXSetRefreshRate(POLY_OPA_DISP++, 60 / (gameState->framerateDivisor + extra_vis));
// @recomp Edit billboard groups to skip interpolation if the camera also skipped.
if (gameState->destroy == Play_Destroy) {
PlayState* play = (PlayState*)gameState;
edit_billboard_groups(play);
}
// @recomp Clear the camera skip state.
clear_camera_skipped();