mirror of
https://github.com/Mr-Wiseguy/Zelda64Recomp.git
synced 2024-09-19 10:19:47 +02:00
300 lines
13 KiB
C
300 lines
13 KiB
C
#include "patches.h"
|
|
#include "transform_ids.h"
|
|
#include "overlays/actors/ovl_Dm_Opstage/z_dm_opstage.h"
|
|
#include "overlays/actors/ovl_Dm_Char01/z_dm_char01.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;
|
|
}
|
|
}
|
|
|
|
extern AnimatedMaterial gWoodfallSceneryPoisonWaterTexAnim[];
|
|
extern AnimatedMaterial gWoodfallSceneryPurifiedWaterTexAnim[];
|
|
extern AnimatedMaterial gWoodfallSceneryDynamicPoisonWaterTexAnim[];
|
|
extern AnimatedMaterial gWoodfallSceneryPoisonWallsTexAnim[];
|
|
extern AnimatedMaterial gWoodfallSceneryPurifiedWallsTexAnim[];
|
|
extern AnimatedMaterial gWoodfallSceneryTempleTexAnim[];
|
|
extern AnimatedMaterial gWoodfallSceneryWaterFlowingOverTempleTexAnim[];
|
|
extern Gfx gWoodfallSceneryPoisonWaterDL[];
|
|
extern Gfx gWoodfallSceneryFloorDL[];
|
|
extern Gfx gWoodfallSceneryPurifiedWaterDL[];
|
|
extern Gfx gWoodfallSceneryPurifiedWallsDL[];
|
|
extern Gfx gWoodfallSceneryDynamicPoisonWaterDL[];
|
|
extern Gfx gWoodfallSceneryPoisonWallsDL[];
|
|
extern Gfx gWoodfallSceneryTempleDL[];
|
|
extern Gfx gWoodfallSceneryWaterFlowingOverTempleDL[];
|
|
extern Gfx gWoodfallSceneryTempleEntrancesDL[];
|
|
extern Gfx gWoodfallSceneryTempleRampAndPlatformDL[];
|
|
extern Vtx gWoodfallSceneryDynamicPoisonWaterVtx[];
|
|
|
|
extern s16 D_80AAAE20;
|
|
extern s16 D_80AAAE22;
|
|
extern s16 D_80AAAE24;
|
|
|
|
// @recomp Patched to enable vertex interpolation for the dynamic water as Woodfall temple rises from below the water.
|
|
void DmChar01_Draw(Actor* thisx, PlayState* play) {
|
|
static f32 D_80AAAAB8 = 0.0f;
|
|
static f32 D_80AAAABC = 0.0f;
|
|
static s16 D_80AAAAC0 = 0;
|
|
static s16 D_80AAAAC4 = 0;
|
|
static s16 D_80AAAAC8 = 0;
|
|
static s16 D_80AAAACC = 0;
|
|
DmChar01* this = (DmChar01*)thisx;
|
|
f32 temp_f12;
|
|
f32 spBC;
|
|
s32 i;
|
|
u8 spB7 = false;
|
|
|
|
switch (DMCHAR01_GET(thisx)) {
|
|
case DMCHAR01_0:
|
|
switch (this->unk_34C) {
|
|
case 0:
|
|
AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryPoisonWaterTexAnim));
|
|
Gfx_DrawDListOpa(play, gWoodfallSceneryPoisonWaterDL);
|
|
break;
|
|
|
|
case 1:
|
|
if (gSaveContext.sceneLayer == 1) {
|
|
AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryPurifiedWaterTexAnim));
|
|
Gfx_DrawDListOpa(play, gWoodfallSceneryFloorDL);
|
|
Gfx_DrawDListXlu(play, gWoodfallSceneryPurifiedWaterDL);
|
|
Matrix_Translate(0.0f, 10.0f, 0.0f, MTXMODE_APPLY);
|
|
}
|
|
AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryDynamicPoisonWaterTexAnim));
|
|
|
|
OPEN_DISPS(play->state.gfxCtx);
|
|
|
|
if ((u8)this->unk_348 == 255) {
|
|
Gfx_SetupDL25_Opa(play->state.gfxCtx);
|
|
|
|
gDPSetRenderMode(POLY_OPA_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2);
|
|
gDPPipeSync(POLY_OPA_DISP++);
|
|
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
|
|
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x96, 255, 255, 255, 255);
|
|
// @recomp Manual relocation, TODO remove when automated.
|
|
gSPSegment(POLY_OPA_DISP++, 0x0B, actor_relocate(thisx, gWoodfallSceneryDynamicPoisonWaterVtx));
|
|
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx),
|
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
// @recomp Tag the matrix to enable vertex interpolation.
|
|
gEXMatrixGroupDecomposedVerts(POLY_OPA_DISP++, actor_transform_id(thisx), G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
|
|
gSPDisplayList(POLY_OPA_DISP++, gWoodfallSceneryDynamicPoisonWaterDL);
|
|
// @recomp Tag the matrix to enable vertex interpolation.
|
|
gEXPopMatrixGroup(POLY_OPA_DISP++, G_MTX_MODELVIEW);
|
|
} else {
|
|
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
|
|
|
|
gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2);
|
|
gDPPipeSync(POLY_XLU_DISP++);
|
|
gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, (u8)this->unk_348);
|
|
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x96, 255, 255, 255, (u8)this->unk_348);
|
|
// @recomp Manual relocation, TODO remove when automated.
|
|
gSPSegment(POLY_XLU_DISP++, 0x0B, actor_relocate(thisx, gWoodfallSceneryDynamicPoisonWaterVtx));
|
|
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx),
|
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
// @recomp Tag the matrix to enable vertex interpolation.
|
|
gEXMatrixGroupDecomposedVerts(POLY_XLU_DISP++, actor_transform_id(thisx), G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
|
|
gSPDisplayList(POLY_XLU_DISP++, gWoodfallSceneryDynamicPoisonWaterDL);
|
|
// @recomp Tag the matrix to enable vertex interpolation.
|
|
gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW);
|
|
}
|
|
|
|
CLOSE_DISPS(play->state.gfxCtx);
|
|
break;
|
|
|
|
case 2:
|
|
AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryPurifiedWaterTexAnim));
|
|
Gfx_DrawDListOpa(play, gWoodfallSceneryFloorDL);
|
|
Gfx_DrawDListXlu(play, gWoodfallSceneryPurifiedWaterDL);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case DMCHAR01_1:
|
|
switch (this->unk_34C) {
|
|
case 0:
|
|
AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryPoisonWallsTexAnim));
|
|
Gfx_DrawDListOpa(play, gWoodfallSceneryPoisonWallsDL);
|
|
break;
|
|
|
|
case 1:
|
|
AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryPurifiedWallsTexAnim));
|
|
Gfx_DrawDListOpa(play, gWoodfallSceneryPurifiedWallsDL);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case DMCHAR01_2:
|
|
AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryTempleTexAnim));
|
|
Gfx_DrawDListOpa(play, gWoodfallSceneryTempleDL);
|
|
|
|
if ((this->unk_34C != 0) && ((u8)this->unk_348 != 0)) {
|
|
AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gWoodfallSceneryWaterFlowingOverTempleTexAnim));
|
|
|
|
OPEN_DISPS(play->state.gfxCtx);
|
|
|
|
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
|
|
|
|
gDPPipeSync(POLY_XLU_DISP++);
|
|
gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, (u8)this->unk_348);
|
|
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, (u8)this->unk_348);
|
|
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx),
|
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gSPDisplayList(POLY_XLU_DISP++, gWoodfallSceneryWaterFlowingOverTempleDL);
|
|
|
|
CLOSE_DISPS(play->state.gfxCtx);
|
|
}
|
|
|
|
// @recomp Manual relocations, TODO remove when automated.
|
|
s16 D_80AAAE20_val = *(s16*)actor_relocate(thisx, &D_80AAAE20);
|
|
s16 D_80AAAE22_val = *(s16*)actor_relocate(thisx, &D_80AAAE22);
|
|
s16 D_80AAAE24_val = *(s16*)actor_relocate(thisx, &D_80AAAE24);
|
|
|
|
if (D_80AAAE24_val != 0) {
|
|
if ((D_80AAAE22_val > -1800) && (D_80AAAE22_val < 3000)) {
|
|
temp_f12 = D_80AAAE22_val - 640.0f;
|
|
if ((D_80AAAE20_val == 380) && (D_80AAAE22_val > 640)) {
|
|
D_80AAAAC0 = 2;
|
|
D_80AAAAC4 = 0;
|
|
D_80AAAAC8 = 900;
|
|
D_80AAAACC = 700;
|
|
spB7 = true;
|
|
if (D_80AAAE22_val < 1350) {
|
|
f32 temp_f0 = temp_f12 / 2000.0f;
|
|
|
|
D_80AAAAB8 = 420.0f - (420.0f * temp_f0);
|
|
D_80AAAABC = (200.0f * temp_f0) + 200.0f;
|
|
} else {
|
|
f32 temp_f0 = temp_f12 / 2000.0f;
|
|
|
|
D_80AAAAB8 = 420.0f - (420.0f * temp_f0);
|
|
D_80AAAABC = 400.0f;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (spB7) {
|
|
for (i = 0; i < D_80AAAAC0 * 2; i++) {
|
|
Vec3f sp44;
|
|
f32 phi_f2 = D_80AAAABC;
|
|
s16 temp;
|
|
|
|
spBC = Rand_ZeroOne() * D_80AAAAC8;
|
|
if ((play->state.frames % 2) != 0) {
|
|
sp44.x = (Rand_ZeroOne() - 0.5f) * (2.0f * phi_f2);
|
|
sp44.y = D_80AAAAB8;
|
|
sp44.z = (Rand_ZeroOne() * D_80AAAAC4) + phi_f2;
|
|
temp = (s16)spBC + D_80AAAACC;
|
|
EffectSsGSplash_Spawn(play, &sp44, NULL, NULL, 0, temp);
|
|
} else {
|
|
sp44.x = -phi_f2 - (Rand_ZeroOne() * D_80AAAAC4);
|
|
sp44.y = D_80AAAAB8;
|
|
sp44.z = (Rand_ZeroOne() - 0.5f) * (2.0f * phi_f2);
|
|
temp = (s16)spBC + D_80AAAACC;
|
|
EffectSsGSplash_Spawn(play, &sp44, NULL, NULL, 0, temp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Gfx_DrawDListXlu(play, gWoodfallSceneryTempleEntrancesDL);
|
|
break;
|
|
|
|
case DMCHAR01_3:
|
|
if (thisx->world.pos.y > -120.0f) {
|
|
Gfx_DrawDListOpa(play, gWoodfallSceneryTempleRampAndPlatformDL);
|
|
}
|
|
break;
|
|
}
|
|
}
|