Update RT64 to fix Granny's story, tagged some more matrices to help with matching performance

This commit is contained in:
Mr-Wiseguy 2024-04-15 20:05:31 -04:00
parent 38f813ae04
commit a293673a32
6 changed files with 447 additions and 70 deletions

@ -1 +1 @@
Subproject commit cbab135a3133313085cf515d2067f7b037a88a52
Subproject commit 00aecb38ac2f4563e81980445399e1c84c64e5bc

View File

@ -1,78 +1,9 @@
#include "patches.h"
#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
#define gSoaringWarpCsWindCapsuleTexAnim gameplay_keep_Matanimheader_0815D0
#define gSoaringWarpCsWindCapsuleDL gameplay_keep_DL_080FC8
#define EnTest7_DrawFeathers func_80AF14FC
void EnTest7_DrawFeathers(PlayState* play2, OwlWarpFeather* feathers);
s32 func_80AF31D0(PlayState* play, SkeletonInfo* skeletonInfo, s32 limbIndex, Gfx** dList, u8* flags, Actor* thisx,
Vec3f* scale, Vec3s* rot, Vec3f* pos);
extern AnimatedMaterial gSoaringWarpCsWindCapsuleTexAnim;
extern Gfx gSoaringWarpCsWindCapsuleDL[];
void EnTest7_Draw(Actor* thisx, PlayState* play) {
s32 pad[2];
EnTest7* this = (EnTest7*)thisx;
s32 sp40;
OPEN_DISPS(play->state.gfxCtx);
// Draw wings
if (this->flags & OWL_WARP_FLAGS_DRAW_WINGS) {
Mtx* mtx = GRAPH_ALLOC(play->state.gfxCtx, this->skeletonInfo.unk_18->unk_1 * sizeof(Mtx));
if (mtx == NULL) {
return;
}
// func_80AF31D0 is an overlay symbol, so its addresses need to be offset to get the actual loaded vram address.
// TODO remove this once the recompiler is able to handle overlay symbols automatically for patch functions.
OverrideKeyframeDrawScaled func_80AF31D0_relocated = (OverrideKeyframeDrawScaled)actor_relocate(thisx, func_80AF31D0);
// @recomp Push the matrix group for the song of soaring's wings.
gEXMatrixGroupDecomposedNormal(POLY_OPA_DISP++, SOARING_WINGS_TRANSFORM_ID, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
func_8018450C(play, &this->skeletonInfo, mtx, func_80AF31D0_relocated, NULL, &this->actor);
// @recomp Pop the wings matrix group.
gEXPopMatrixGroup(POLY_OPA_DISP++, G_MTX_MODELVIEW);
}
// Draw windCapsule encasing that surrounds player after wings
if (this->flags & OWL_WARP_FLAGS_DRAW_WIND_CAPSULE) {
// @recomp Push the matrix group for the song of soaring's capsule.
gEXMatrixGroupDecomposedNormal(POLY_XLU_DISP++, SOARING_CAPSULE_TRANSFORM_ID, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
Matrix_Push();
Matrix_Translate(0.0f, 4000.0f, 0.0f, MTXMODE_APPLY);
Matrix_RotateZYX(0, this->windCapsule.yaw, 0, MTXMODE_APPLY);
Matrix_Scale(this->windCapsule.xzScale * 100.0f, this->windCapsule.yScale * 100.0f,
this->windCapsule.xzScale * 100.0f, MTXMODE_APPLY);
sp40 = this->windCapsule.unk_00;
AnimatedMat_DrawStep(play, Lib_SegmentedToVirtual(&gSoaringWarpCsWindCapsuleTexAnim), sp40);
Gfx_DrawDListXlu(play, gSoaringWarpCsWindCapsuleDL);
// @recomp Pop the capsule matrix group.
gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW);
Matrix_Pop();
}
EnTest7_DrawFeathers(play, this->feathers);
if (this->flags & OWL_WARP_FLAGS_DRAW_LENS_FLARE) {
Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, this->actor.world.pos, 70.0f,
5.0f, 0, false);
}
CLOSE_DISPS(play->state.gfxCtx);
}
extern f32 D_808DE5B0;
extern Gfx gEffDust5Tex[];
extern Gfx gEffDustDL[];

View File

@ -2,6 +2,7 @@
#include "transform_ids.h"
#include "overlays/actors/ovl_En_Hanabi/z_en_hanabi.h"
#include "overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.h"
#include "overlays/actors/ovl_En_Water_Effect/z_en_water_effect.h"
extern EffectSsInfo sEffectSsInfo;
@ -382,3 +383,149 @@ void DemoKankyo_DrawMoonAndGiant(Actor* thisx, PlayState* play2) {
CLOSE_DISPS(gfxCtx);
}
}
static Vec3f D_80A5AFB0 = { 0.0f, 0.0f, 0.0f };
static Vec3f D_80A5AFBC = { 0.0f, -1.0f, 0.0f };
// The byte after unk_01 in EnWaterEffectStruct is unused, so we'll use it as a respawn flag.
#define WATER_EFFECT_RESPAWNED(ptr) (&(ptr)->unk_01)[1]
// @recomp Mark respawned water effect particles so they can be skipped for the first frame.
void func_80A599E8(EnWaterEffect* this, Vec3f* arg1, u8 arg2) {
s16 i;
EnWaterEffectStruct* ptr = &this->unk_144[0];
for (i = 0; i < ARRAY_COUNT(this->unk_144); i++, ptr++) {
if (ptr->unk_00 == 0) {
ptr->unk_00 = 4;
// @recomp Use an unused byte to mark that this particle was respawned.
WATER_EFFECT_RESPAWNED(ptr) = true;
ptr->unk_04 = *arg1;
ptr->unk_1C = D_80A5AFB0;
ptr->unk_10 = D_80A5AFB0;
if ((arg2 == 0) || (arg2 == 2)) {
ptr->unk_1C.y = -1.0f;
}
if (arg2 >= 2) {
if (arg2 == 2) {
ptr->unk_10.x = Rand_CenteredFloat(10.0f);
ptr->unk_10.y = Rand_ZeroFloat(3.0f) + 5.0f;
ptr->unk_10.z = Rand_CenteredFloat(10.0f);
}
ptr->unk_2C.z = 0.0017f;
ptr->unk_2C.x = 0.003f;
ptr->unk_2C.y = 0.0018f;
} else {
ptr->unk_2C.z = 0.003f;
ptr->unk_2C.x = 0.003f;
ptr->unk_2C.y = 0.003f;
}
ptr->unk_38 = 255.0f;
ptr->unk_28 = Rand_ZeroFloat(0x10000);
ptr->unk_3C = 255;
ptr->unk_01 = Rand_ZeroFloat(200.0f);
ptr->unk_2A = arg2;
break;
}
}
}
extern Gfx object_water_effect_DL_004340[];
extern Gfx object_water_effect_DL_0043E8[];
extern Gfx gameplay_keep_DL_06AB30[];
// @recomp Tag the transforms for falling fire rocks.
void func_80A5A184(Actor* thisx, PlayState* play2) {
PlayState* play = play2;
EnWaterEffect* this = (EnWaterEffect*)thisx;
GraphicsContext* gfxCtx = play->state.gfxCtx;
EnWaterEffectStruct* ptr = &this->unk_144[0];
u8 flag = false;
s16 i;
OPEN_DISPS(gfxCtx);
Gfx_SetupDL25_Opa(play->state.gfxCtx);
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
for (i = 0; i < ARRAY_COUNT(this->unk_144); i++, ptr++) {
if (ptr->unk_00 == 4) {
if (!flag) {
gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004340);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 10, 0, 0);
POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 500, 3600);
flag++;
}
gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, (u8)ptr->unk_38, 0, 0, (u8)ptr->unk_3C);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, (ptr->unk_01 * -20) & 0x1FF,
0x20, 0x80));
Matrix_Translate(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW);
if (ptr->unk_2A >= 2) {
Matrix_ReplaceRotation(&play->billboardMtxF);
} else {
Matrix_RotateYS(Camera_GetInputDirYaw(GET_ACTIVE_CAM(play)), MTXMODE_APPLY);
}
Matrix_Scale(ptr->unk_2C.x, ptr->unk_2C.y, 1.0f, MTXMODE_APPLY);
if ((i & 1) != 0) {
Matrix_RotateYF(M_PI, MTXMODE_APPLY);
}
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
// @recomp Tag the matrix group. Skip all interpolation if this particle just respawned. Otherwise,
// skip rotation interpolation if there was a camera cut since this is a billboard.
if (WATER_EFFECT_RESPAWNED(ptr)) {
gEXMatrixGroupDecomposedSkipAll(POLY_XLU_DISP++, actor_transform_id(thisx) + (i * 2) + 0, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
else if (camera_was_skipped()) {
gEXMatrixGroupDecomposedSkipRot(POLY_XLU_DISP++, actor_transform_id(thisx) + (i * 2) + 0, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
else {
gEXMatrixGroupDecomposedNormal(POLY_XLU_DISP++, actor_transform_id(thisx) + (i * 2) + 0, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0043E8);
// @recomp Pop the matrix group.
gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW);
if ((ptr->unk_2A & 1) == 0) {
Matrix_Translate(ptr->unk_04.x, ptr->unk_04.y + 5.0f, ptr->unk_04.z, MTXMODE_NEW);
Matrix_RotateXS(ptr->unk_28, MTXMODE_APPLY);
Matrix_Scale(ptr->unk_2C.z, ptr->unk_2C.z, ptr->unk_2C.z, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
// @recomp Tag the matrix group. Skip all interpolation if the base particle just respawned.
if (WATER_EFFECT_RESPAWNED(ptr)) {
gEXMatrixGroupDecomposedSkipAll(POLY_OPA_DISP++, actor_transform_id(thisx) + (i * 2) + 1, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
}
else {
gEXMatrixGroupDecomposedNormal(POLY_OPA_DISP++, actor_transform_id(thisx) + (i * 2) + 1, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
}
gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_06AB30);
// @recomp Pop the matrix group.
gEXPopMatrixGroup(POLY_OPA_DISP++, G_MTX_MODELVIEW);
}
// @recomp Clear the respawned state of this particle.
WATER_EFFECT_RESPAWNED(ptr) = false;
}
}
POLY_OPA_DISP = Play_SetFog(play, POLY_OPA_DISP);
CLOSE_DISPS(gfxCtx);
}

View File

@ -16,6 +16,9 @@
#include "global.h"
#include "rt64_extended_gbi.h"
#define gEXMatrixGroupNoInterpolation(cmd, push, proj, edit) \
gEXMatrixGroup(cmd, G_EX_ID_IGNORE, G_EX_INTERPOLATE_SIMPLE, 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_SKIP, G_EX_ORDER_LINEAR, edit)
#define gEXMatrixGroupInterpolateOnlyTiles(cmd, push, proj, edit) \
gEXMatrixGroup(cmd, G_EX_ID_IGNORE, G_EX_INTERPOLATE_SIMPLE, 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)

View File

@ -0,0 +1,184 @@
#include "patches.h"
#include "transform_ids.h"
#include "overlays/actors/ovl_En_Test6/z_en_test6.h"
#include "overlays/actors/ovl_En_Test7/z_en_test7.h"
// Decomp renames, TODO update decomp and remove these
#define gSoaringWarpCsWindCapsuleTexAnim gameplay_keep_Matanimheader_0815D0
#define gSoaringWarpCsWindCapsuleDL gameplay_keep_DL_080FC8
#define EnTest7_DrawFeathers func_80AF14FC
void EnTest7_DrawFeathers(PlayState* play2, OwlWarpFeather* feathers);
s32 func_80AF31D0(PlayState* play, SkeletonInfo* skeletonInfo, s32 limbIndex, Gfx** dList, u8* flags, Actor* thisx,
Vec3f* scale, Vec3s* rot, Vec3f* pos);
extern AnimatedMaterial gSoaringWarpCsWindCapsuleTexAnim;
extern Gfx gSoaringWarpCsWindCapsuleDL[];
void EnTest7_Draw(Actor* thisx, PlayState* play) {
s32 pad[2];
EnTest7* this = (EnTest7*)thisx;
s32 sp40;
OPEN_DISPS(play->state.gfxCtx);
// Draw wings
if (this->flags & OWL_WARP_FLAGS_DRAW_WINGS) {
Mtx* mtx = GRAPH_ALLOC(play->state.gfxCtx, this->skeletonInfo.unk_18->unk_1 * sizeof(Mtx));
if (mtx == NULL) {
return;
}
// func_80AF31D0 is an overlay symbol, so its addresses need to be offset to get the actual loaded vram address.
// TODO remove this once the recompiler is able to handle overlay symbols automatically for patch functions.
OverrideKeyframeDrawScaled func_80AF31D0_relocated = (OverrideKeyframeDrawScaled)actor_relocate(thisx, func_80AF31D0);
// @recomp Push the matrix group for the song of soaring's wings.
gEXMatrixGroupDecomposedNormal(POLY_OPA_DISP++, SOARING_WINGS_TRANSFORM_ID, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
func_8018450C(play, &this->skeletonInfo, mtx, func_80AF31D0_relocated, NULL, &this->actor);
// @recomp Pop the wings matrix group.
gEXPopMatrixGroup(POLY_OPA_DISP++, G_MTX_MODELVIEW);
}
// Draw windCapsule encasing that surrounds player after wings
if (this->flags & OWL_WARP_FLAGS_DRAW_WIND_CAPSULE) {
// @recomp Push the matrix group for the song of soaring's capsule.
gEXMatrixGroupDecomposedNormal(POLY_XLU_DISP++, SOARING_CAPSULE_TRANSFORM_ID, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
Matrix_Push();
Matrix_Translate(0.0f, 4000.0f, 0.0f, MTXMODE_APPLY);
Matrix_RotateZYX(0, this->windCapsule.yaw, 0, MTXMODE_APPLY);
Matrix_Scale(this->windCapsule.xzScale * 100.0f, this->windCapsule.yScale * 100.0f,
this->windCapsule.xzScale * 100.0f, MTXMODE_APPLY);
sp40 = this->windCapsule.unk_00;
AnimatedMat_DrawStep(play, Lib_SegmentedToVirtual(&gSoaringWarpCsWindCapsuleTexAnim), sp40);
Gfx_DrawDListXlu(play, gSoaringWarpCsWindCapsuleDL);
// @recomp Pop the capsule matrix group.
gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW);
Matrix_Pop();
}
EnTest7_DrawFeathers(play, this->feathers);
if (this->flags & OWL_WARP_FLAGS_DRAW_LENS_FLARE) {
Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, this->actor.world.pos, 70.0f,
5.0f, 0, false);
}
CLOSE_DISPS(play->state.gfxCtx);
}
extern Gfx gSongOfTimeClockDL[];
struct SoTCsAmmoDrops;
typedef void (*SoTCsAmmoDropDrawFunc)(EnTest6*, PlayState*, struct SoTCsAmmoDrops*);
typedef enum SoTCsAmmoDropType {
/* 0 */ SOTCS_AMMO_DROP_NONE,
/* 1 */ SOTCS_AMMO_DROP_ARROWS,
/* 2 */ SOTCS_AMMO_DROP_BOMB,
/* 3 */ SOTCS_AMMO_DROP_DEKU_NUT,
/* 4 */ SOTCS_AMMO_DROP_DEKU_STICK,
/* 5 */ SOTCS_AMMO_DROP_RUPEE_GREEN,
/* 6 */ SOTCS_AMMO_DROP_RUPEE_BLUE
} SoTCsAmmoDropType;
typedef struct SoTCsAmmoDrops {
/* 0x00 */ SoTCsAmmoDropType type;
/* 0x04 */ f32 scale;
/* 0x08 */ Vec3f pos;
/* 0x14 */ SoTCsAmmoDropDrawFunc draw;
} SoTCsAmmoDrops; // size = 0x18
extern SoTCsAmmoDrops sSoTCsAmmoDrops[12];
/**
* Draws clocks in a double spiral above and below player
*/
void EnTest6_DrawThreeDayResetSoTCutscene(EnTest6* this, PlayState* play) {
s16 clock1Yaw;
s16 clock2Yaw;
s16 angle;
s32 i;
Vec3f clockPos;
OPEN_DISPS(play->state.gfxCtx);
this->gfx = POLY_OPA_DISP;
clockPos.y = 0.0f;
clock1Yaw = this->clockAngle;
clock2Yaw = clock1Yaw + 0x4E20 + (s32)(0x2EE0 * Math_SinS(play->state.frames));
// The `& 0x3C` ensures the angle only updates once every 4 frames
angle = (play->state.frames & 0x3C) * 1024;
angle *= this->clockSpeed / 200.0f;
this->clockAngle += (s16)this->clockSpeed;
this->clockRingRotZ = (s16)((this->clockSpeed / 200.0f) * 256.0f);
// Draw 2 clocks per loop
for (i = 0; i < (SOTCS_RESET_NUM_CLOCKS / 2); i++) {
// Clock 1
clock1Yaw += 0x1000;
clockPos.x = Math_CosS(clock1Yaw) * this->clockDist;
clockPos.z = Math_SinS(clock1Yaw) * this->clockDist;
Matrix_Translate(clockPos.x, clockPos.y, clockPos.z, MTXMODE_NEW);
Matrix_RotateXS(0x4000, MTXMODE_APPLY);
Matrix_Scale(0.8f, 0.8f, 0.8f, MTXMODE_APPLY);
Matrix_RotateZS(angle, MTXMODE_APPLY);
gSPMatrix(this->gfx++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPSetPrimColor(this->gfx++, 0, 0xFF, 28, 28, 28, 255);
gDPSetEnvColor(this->gfx++, 255, 255, 255, 255);
gDPSetRenderMode(this->gfx++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2);
// @recomp Tag the clock's matrix.
gEXMatrixGroupDecomposedSkipRot(this->gfx++, actor_transform_id(&this->actor) + (2 * i) + 0, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
gSPDisplayList(this->gfx++, gSongOfTimeClockDL);
// @recomp Pop the clock's matrix group.
gEXPopMatrixGroup(this->gfx++, G_MTX_MODELVIEW);
// Clock 2
clock2Yaw += 0x1000;
clockPos.x = Math_CosS(clock2Yaw) * this->clockDist;
clockPos.z = Math_SinS(clock2Yaw) * this->clockDist;
Matrix_Translate(clockPos.x, clockPos.y, clockPos.z, MTXMODE_NEW);
Matrix_RotateXS(0x4000, MTXMODE_APPLY);
Matrix_Scale(0.8f, 0.8f, 0.8f, MTXMODE_APPLY);
Matrix_RotateZS(-angle, MTXMODE_APPLY);
gSPMatrix(this->gfx++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPSetPrimColor(this->gfx++, 0, 0xFF, 28, 28, 28, 255);
gDPSetEnvColor(this->gfx++, 255, 255, 255, 255);
gDPSetRenderMode(this->gfx++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2);
// @recomp Tag the clock's matrix.
gEXMatrixGroupDecomposedSkipRot(this->gfx++, actor_transform_id(&this->actor) + (2 * i) + 1, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
gSPDisplayList(this->gfx++, gSongOfTimeClockDL);
// @recomp Pop the clock's matrix group.
gEXPopMatrixGroup(this->gfx++, G_MTX_MODELVIEW);
clockPos.y -= this->speed;
angle += this->clockRingRotZ;
}
POLY_OPA_DISP = this->gfx;
// @recomp Manual relocation, TODO remove when automated.
SoTCsAmmoDrops* sSoTCsAmmoDrops_reloc = (SoTCsAmmoDrops*)actor_relocate(&this->actor, sSoTCsAmmoDrops);
for (i = 0; i < ARRAY_COUNT(sSoTCsAmmoDrops); i++) {
if (sSoTCsAmmoDrops_reloc[i].scale > 0.0f) {
sSoTCsAmmoDrops_reloc[i].draw(this, play, &sSoTCsAmmoDrops_reloc[i]);
}
}
CLOSE_DISPS(play->state.gfxCtx);
}

View File

@ -7,6 +7,7 @@
#include "overlays/actors/ovl_En_Water_Effect/z_en_water_effect.h"
#include "overlays/actors/ovl_En_Osn/z_en_osn.h"
#include "overlays/actors/ovl_En_Fall2/z_en_fall2.h"
#include "overlays/actors/ovl_Obj_Entotu/z_obj_entotu.h"
extern EnTanron2* D_80BB8458[82];
extern Boss04* D_80BB8450;
@ -956,3 +957,114 @@ void func_800A6A40(EnItem00* this, PlayState* play) {
actor_set_custom_flag_1(&this->actor);
}
}
extern Vtx ovl_Obj_Entotu_Vtx_000D10[7];
extern Gfx object_f53_obj_DL_001C00[];
// @recomp Skip rotation interpolation for the Clock Town chimney's smoke when the camera skips interolation.
void func_80A34B28(ObjEntotu* this, PlayState* play) {
u8 sp57;
u8 sp56;
s32 i;
this->unk_1B8.y += 1.8f;
this->unk_1B8.z += 0.6f;
sp57 = 0x7F - (u8)this->unk_1B8.y;
sp56 = 0x7F - (u8)this->unk_1B8.z;
this->unk_1B8.x = CLAMP(this->unk_1B8.x, 0.0f, 1.0f);
// @recomp Manual relocation, TODO remove when automated.
Vtx* verts = (Vtx*)actor_relocate(&this->actor, ovl_Obj_Entotu_Vtx_000D10);
for (i = 0; i < ARRAY_COUNT(ovl_Obj_Entotu_Vtx_000D10); i++) {
this->unk_148[i].v.cn[3] = verts[i].v.cn[3] * this->unk_1B8.x;
}
if (this->unk_1B8.x > 0.0f) {
Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW);
this->actor.shape.rot.y = BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)));
Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY);
Matrix_Scale(0.1f, 0.1f, 0.0f, MTXMODE_APPLY);
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL25_Opa(play->state.gfxCtx);
// @recomp Tag the matrix, skipping rotation if the camera skipped interpolation this frame.
if (camera_was_skipped()) {
gEXMatrixGroupDecomposedSkipRot(POLY_XLU_DISP++, actor_transform_id(&this->actor), G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
else {
gEXMatrixGroupDecomposedNormal(POLY_XLU_DISP++, actor_transform_id(&this->actor), G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, sp57, 0x20, 0x20, 1, 0, sp56, 0x20, 0x20));
gSPSegment(POLY_XLU_DISP++, 0x09, Lib_SegmentedToVirtual(this->unk_148));
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, object_f53_obj_DL_001C00);
// @recomp Pop the matrix group.
gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW);
CLOSE_DISPS(play->state.gfxCtx);
}
}
extern Gfx object_f53_obj_DL_000158[];
// @recomp Skip rotation interpolation for the Clock Town chimney when the camera skips interolation.
void func_80A34A44(ObjEntotu* this, PlayState* play) {
Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW);
this->actor.shape.rot.y = BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)));
Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY);
Matrix_Scale(0.1f, 0.1f, 0.0f, MTXMODE_APPLY);
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL25_Opa(play->state.gfxCtx);
// @recomp Tag the matrix, skipping rotation if the camera skipped interpolation this frame.
if (camera_was_skipped()) {
gEXMatrixGroupDecomposedSkipRot(POLY_OPA_DISP++, actor_transform_id(&this->actor) + 1, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
else {
gEXMatrixGroupDecomposedNormal(POLY_OPA_DISP++, actor_transform_id(&this->actor) + 1, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
}
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, object_f53_obj_DL_000158);
// @recomp Pop the matrix group.
gEXPopMatrixGroup(POLY_OPA_DISP++, G_MTX_MODELVIEW);
CLOSE_DISPS(play->state.gfxCtx);
}
void Environment_DrawRainImpl(PlayState* play, View* view, GraphicsContext* gfxCtx);
// @recomp Skip interpolation for the splashes that raindrops make.
void Environment_DrawRain(PlayState* play, View* view, GraphicsContext* gfxCtx) {
if (!(GET_ACTIVE_CAM(play)->stateFlags & CAM_STATE_UNDERWATER) &&
(play->envCtx.precipitation[PRECIP_SNOW_CUR] == 0)) {
// @recomp Open the displaylists and skip interpolation for rain.
OPEN_DISPS(gfxCtx);
gEXMatrixGroupNoInterpolation(POLY_XLU_DISP++, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
if (play->envCtx.precipitation[PRECIP_SOS_MAX] != 0) {
if (play->envCtx.precipitation[PRECIP_SNOW_CUR] == 0) {
Environment_DrawRainImpl(play, view, gfxCtx);
}
} else if (!(GET_ACTIVE_CAM(play)->stateFlags & CAM_STATE_UNDERWATER)) {
if ((Environment_GetStormState(play) != STORM_STATE_OFF) &&
(play->envCtx.precipitation[PRECIP_SNOW_CUR] == 0)) {
Environment_DrawRainImpl(play, view, gfxCtx);
}
}
// @recomp Pop the matrix group and close the displaylists.
gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW);
CLOSE_DISPS(gfxCtx);
}
}