Zelda64Recomp/patches/terrain_transform_tagging.c

100 lines
3.7 KiB
C

#include "patches.h"
#include "transform_ids.h"
#include "overlays/actors/ovl_Dm_Opstage/z_dm_opstage.h"
static Vec3f sZeroVec = { 0.0f, 0.0f, 0.0f };
extern RoomDrawHandler sRoomDrawHandlers[];
void Room_Draw(PlayState* play, Room* room, u32 flags) {
if (room->segment != NULL) {
gSegments[3] = OS_K0_TO_PHYSICAL(room->segment);
OPEN_DISPS(play->state.gfxCtx);
// @recomp Tag the room's matrices if applicable.
// Tag terrain as being ignored for interpolation, which prevents interpolation glitches where some pieces of terrain swap places when one comes into view.
if (flags & ROOM_DRAW_OPA) {
gEXMatrixGroupInterpolateOnlyTiles(POLY_OPA_DISP++, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
}
if (flags & ROOM_DRAW_XLU) {
gEXMatrixGroupInterpolateOnlyTiles(POLY_XLU_DISP++, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
}
CLOSE_DISPS(play->state.gfxCtx);
sRoomDrawHandlers[room->roomShape->base.type](play, room, flags);
OPEN_DISPS(play->state.gfxCtx);
// @recomp Pop the room's matrix tags if applicable.
if (flags & ROOM_DRAW_OPA) {
gEXPopMatrixGroup(POLY_OPA_DISP++, G_MTX_MODELVIEW);
}
if (flags & ROOM_DRAW_XLU) {
gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW);
}
CLOSE_DISPS(play->state.gfxCtx);
}
return;
}
extern Gfx gKeikokuDemoFloorDL[];
extern Gfx gKeikokuDemoFloorEmptyDL[];
extern Gfx gKeikokuDemoTallTreeWithRootBaseDL[];
extern Gfx gKeikokuDemoTallTreeWithRootBaseEmptyDL[];
extern Gfx gKeikokuDemoTallTreeCutDL[];
extern Gfx gKeikokuDemoTallTreeCutEmptyDL[];
extern Gfx gKeikokuDemoTallTreeStraightDL[];
extern Gfx gKeikokuDemoTallTreeStraightEmptyDL[];
// @recomp Tag the ground in the intro cutscene to not interpolate rotation.
void DmOpstage_Draw(Actor* thisx, PlayState* play) {
DmOpstage* this = (DmOpstage*)thisx;
if (DMOPSTAGE_GET_TYPE(&this->dyna.actor) > DMOPSTAGE_TYPE_GROUND) {
// Assumption: worldPos is being manipulated by cutscene
Matrix_Translate(this->dyna.actor.world.pos.x + this->drawOffset.x,
this->dyna.actor.world.pos.y + this->drawOffset.y,
this->dyna.actor.world.pos.z + this->drawOffset.z, MTXMODE_NEW);
Matrix_RotateYS(this->dyna.actor.world.rot.y, MTXMODE_APPLY);
Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY);
}
switch (DMOPSTAGE_GET_TYPE(&this->dyna.actor)) {
case DMOPSTAGE_TYPE_GROUND:
OPEN_DISPS(play->state.gfxCtx);
// @recomp Tag the ground to skip rotation.
gEXMatrixGroupDecomposedSkipRot(POLY_OPA_DISP++, actor_transform_id(thisx) + 0, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
Gfx_DrawDListOpa(play, gKeikokuDemoFloorDL);
Gfx_DrawDListXlu(play, gKeikokuDemoFloorEmptyDL);
// @recomp Pop the tag.
gEXPopMatrixGroup(POLY_OPA_DISP++, G_MTX_MODELVIEW);
CLOSE_DISPS(play->state.gfxCtx);
break;
case DMOPSTAGE_TYPE_ROOT_TREE:
Gfx_DrawDListOpa(play, gKeikokuDemoTallTreeWithRootBaseDL);
Gfx_DrawDListXlu(play, gKeikokuDemoTallTreeWithRootBaseEmptyDL);
break;
case DMOPSTAGE_TYPE_CUT_TREE:
Gfx_DrawDListOpa(play, gKeikokuDemoTallTreeCutDL);
Gfx_DrawDListXlu(play, gKeikokuDemoTallTreeCutEmptyDL);
break;
case DMOPSTAGE_TYPE_STRAIGHT_TREE:
Gfx_DrawDListOpa(play, gKeikokuDemoTallTreeStraightDL);
Gfx_DrawDListXlu(play, gKeikokuDemoTallTreeStraightEmptyDL);
break;
default:
break;
}
}