2024-02-05 05:12:34 +01:00
# include "patches.h"
# include "transform_ids.h"
2024-04-01 09:40:54 +02:00
# include "overlays/actors/ovl_Dm_Opstage/z_dm_opstage.h"
2024-05-06 01:09:11 +02:00
# include "overlays/actors/ovl_Dm_Char01/z_dm_char01.h"
2024-02-05 05:12:34 +01:00
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 ) {
2024-03-29 01:36:16 +01:00
gEXMatrixGroupInterpolateOnlyTiles ( POLY_OPA_DISP + + , G_EX_PUSH , G_MTX_MODELVIEW , G_EX_EDIT_ALLOW ) ;
2024-02-05 05:12:34 +01:00
}
if ( flags & ROOM_DRAW_XLU ) {
2024-03-29 01:36:16 +01:00
gEXMatrixGroupInterpolateOnlyTiles ( POLY_XLU_DISP + + , G_EX_PUSH , G_MTX_MODELVIEW , G_EX_EDIT_ALLOW ) ;
2024-02-05 05:12:34 +01:00
}
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 ) {
2024-03-29 01:36:16 +01:00
gEXPopMatrixGroup ( POLY_OPA_DISP + + , G_MTX_MODELVIEW ) ;
2024-02-05 05:12:34 +01:00
}
if ( flags & ROOM_DRAW_XLU ) {
2024-03-29 01:36:16 +01:00
gEXPopMatrixGroup ( POLY_XLU_DISP + + , G_MTX_MODELVIEW ) ;
2024-02-05 05:12:34 +01:00
}
CLOSE_DISPS ( play - > state . gfxCtx ) ;
}
return ;
}
2024-04-01 09:40:54 +02:00
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 ;
}
}
2024-05-06 01:09:11 +02:00
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 ;
}
}