mirror of
https://github.com/BanjoRecomp/BanjoRecomp
synced 2026-07-07 20:11:58 -04:00
Fix demos, SNS, and Bottles Bonus timings and desyncs (#29)
* Fix speed of demos by using recorded deltatime to control frame divisor * Adjust frustum culling in demos to make them play back correctly * Adjust deltatime used for hourglass decrement in Bottles' Bonus to have slowdown like original hardware * Limit framerate in Mumbo SNS cutscene for some maps to let all dialog finish
This commit is contained in:
+180
-1
@@ -1,16 +1,105 @@
|
||||
#include "patches.h"
|
||||
#include "core1/ml.h"
|
||||
#include "core1/mlmtx.h"
|
||||
#include "core1/core1.h"
|
||||
#include "core1/vimgr.h"
|
||||
#include "functions.h"
|
||||
|
||||
extern f32 sViewportPosition[3];
|
||||
extern f32 sViewportFrustumPlanes[4][4];
|
||||
void animMtxList_setBoned(AnimMtxList **this_ptr, BKAnimationList *anim_list, BoneTransformList *arg2);
|
||||
|
||||
extern s32 cur_model_would_have_been_culled_in_demo;
|
||||
bool recomp_in_demo_playback_game_mode();
|
||||
|
||||
int frustum_checks_enabled = TRUE;
|
||||
void set_frustum_checks_enabled(int enabled) {
|
||||
frustum_checks_enabled = enabled;
|
||||
}
|
||||
|
||||
RECOMP_PATCH bool viewport_isBoundingBoxInFrustum(f32 arg0[3], f32 arg1[3]) {
|
||||
// Unpatched copy of viewport_isBoundingBoxInFrustum, used to check if a cube would have been culled originally.
|
||||
bool viewport_isBoundingBoxInFrustumCopy(f32 min[3], f32 max[3]) {
|
||||
if (((sViewportFrustumPlanes[0][0] * min[0] + sViewportFrustumPlanes[0][1] * min[1] + sViewportFrustumPlanes[0][2] * min[2] + sViewportFrustumPlanes[0][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[0][0] * min[0] + sViewportFrustumPlanes[0][1] * min[1] + sViewportFrustumPlanes[0][2] * max[2] + sViewportFrustumPlanes[0][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[0][0] * min[0] + sViewportFrustumPlanes[0][1] * max[1] + sViewportFrustumPlanes[0][2] * min[2] + sViewportFrustumPlanes[0][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[0][0] * min[0] + sViewportFrustumPlanes[0][1] * max[1] + sViewportFrustumPlanes[0][2] * max[2] + sViewportFrustumPlanes[0][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[0][0] * max[0] + sViewportFrustumPlanes[0][1] * min[1] + sViewportFrustumPlanes[0][2] * min[2] + sViewportFrustumPlanes[0][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[0][0] * max[0] + sViewportFrustumPlanes[0][1] * min[1] + sViewportFrustumPlanes[0][2] * max[2] + sViewportFrustumPlanes[0][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[0][0] * max[0] + sViewportFrustumPlanes[0][1] * max[1] + sViewportFrustumPlanes[0][2] * min[2] + sViewportFrustumPlanes[0][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[0][0] * max[0] + sViewportFrustumPlanes[0][1] * max[1] + sViewportFrustumPlanes[0][2] * max[2] + sViewportFrustumPlanes[0][3]) >= 0.0f))
|
||||
return FALSE;
|
||||
|
||||
if (((sViewportFrustumPlanes[1][0] * min[0] + sViewportFrustumPlanes[1][1] * min[1] + sViewportFrustumPlanes[1][2] * min[2] + sViewportFrustumPlanes[1][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[1][0] * min[0] + sViewportFrustumPlanes[1][1] * min[1] + sViewportFrustumPlanes[1][2] * max[2] + sViewportFrustumPlanes[1][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[1][0] * min[0] + sViewportFrustumPlanes[1][1] * max[1] + sViewportFrustumPlanes[1][2] * min[2] + sViewportFrustumPlanes[1][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[1][0] * min[0] + sViewportFrustumPlanes[1][1] * max[1] + sViewportFrustumPlanes[1][2] * max[2] + sViewportFrustumPlanes[1][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[1][0] * max[0] + sViewportFrustumPlanes[1][1] * min[1] + sViewportFrustumPlanes[1][2] * min[2] + sViewportFrustumPlanes[1][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[1][0] * max[0] + sViewportFrustumPlanes[1][1] * min[1] + sViewportFrustumPlanes[1][2] * max[2] + sViewportFrustumPlanes[1][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[1][0] * max[0] + sViewportFrustumPlanes[1][1] * max[1] + sViewportFrustumPlanes[1][2] * min[2] + sViewportFrustumPlanes[1][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[1][0] * max[0] + sViewportFrustumPlanes[1][1] * max[1] + sViewportFrustumPlanes[1][2] * max[2] + sViewportFrustumPlanes[1][3]) >= 0.0f))
|
||||
return FALSE;
|
||||
|
||||
if (((sViewportFrustumPlanes[2][0] * min[0] + sViewportFrustumPlanes[2][1] * min[1] + sViewportFrustumPlanes[2][2] * min[2] + sViewportFrustumPlanes[2][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[2][0] * min[0] + sViewportFrustumPlanes[2][1] * min[1] + sViewportFrustumPlanes[2][2] * max[2] + sViewportFrustumPlanes[2][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[2][0] * min[0] + sViewportFrustumPlanes[2][1] * max[1] + sViewportFrustumPlanes[2][2] * min[2] + sViewportFrustumPlanes[2][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[2][0] * min[0] + sViewportFrustumPlanes[2][1] * max[1] + sViewportFrustumPlanes[2][2] * max[2] + sViewportFrustumPlanes[2][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[2][0] * max[0] + sViewportFrustumPlanes[2][1] * min[1] + sViewportFrustumPlanes[2][2] * min[2] + sViewportFrustumPlanes[2][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[2][0] * max[0] + sViewportFrustumPlanes[2][1] * min[1] + sViewportFrustumPlanes[2][2] * max[2] + sViewportFrustumPlanes[2][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[2][0] * max[0] + sViewportFrustumPlanes[2][1] * max[1] + sViewportFrustumPlanes[2][2] * min[2] + sViewportFrustumPlanes[2][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[2][0] * max[0] + sViewportFrustumPlanes[2][1] * max[1] + sViewportFrustumPlanes[2][2] * max[2] + sViewportFrustumPlanes[2][3]) >= 0.0f))
|
||||
return FALSE;
|
||||
|
||||
if (((sViewportFrustumPlanes[3][0] * min[0] + sViewportFrustumPlanes[3][1] * min[1] + sViewportFrustumPlanes[3][2] * min[2] + sViewportFrustumPlanes[3][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[3][0] * min[0] + sViewportFrustumPlanes[3][1] * min[1] + sViewportFrustumPlanes[3][2] * max[2] + sViewportFrustumPlanes[3][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[3][0] * min[0] + sViewportFrustumPlanes[3][1] * max[1] + sViewportFrustumPlanes[3][2] * min[2] + sViewportFrustumPlanes[3][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[3][0] * min[0] + sViewportFrustumPlanes[3][1] * max[1] + sViewportFrustumPlanes[3][2] * max[2] + sViewportFrustumPlanes[3][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[3][0] * max[0] + sViewportFrustumPlanes[3][1] * min[1] + sViewportFrustumPlanes[3][2] * min[2] + sViewportFrustumPlanes[3][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[3][0] * max[0] + sViewportFrustumPlanes[3][1] * min[1] + sViewportFrustumPlanes[3][2] * max[2] + sViewportFrustumPlanes[3][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[3][0] * max[0] + sViewportFrustumPlanes[3][1] * max[1] + sViewportFrustumPlanes[3][2] * min[2] + sViewportFrustumPlanes[3][3]) >= 0.0f) &&
|
||||
((sViewportFrustumPlanes[3][0] * max[0] + sViewportFrustumPlanes[3][1] * max[1] + sViewportFrustumPlanes[3][2] * max[2] + sViewportFrustumPlanes[3][3]) >= 0.0f))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
s32 cmd_0;
|
||||
s32 size_4;
|
||||
s16 unk8[3];
|
||||
s16 unkE[3];
|
||||
s16 unk14;
|
||||
}GeoCmdD;
|
||||
|
||||
void func_80339124(Gfx **, Mtx **, BKGeoList *);
|
||||
|
||||
// @recomp Patched to disable culling in model rendering.
|
||||
RECOMP_PATCH void func_80338DCC(Gfx ** gfx, Mtx ** mtx, void *arg2){
|
||||
f32 sp2C[3];
|
||||
f32 sp20[3];
|
||||
GeoCmdD * cmd = (GeoCmdD *)arg2;
|
||||
if(cmd->unk14){
|
||||
// @recomp Always run the child command.
|
||||
// sp2C[0] = (f32)cmd->unk8[0] * modelRenderScale;
|
||||
// sp2C[1] = (f32)cmd->unk8[1] * modelRenderScale;
|
||||
// sp2C[2] = (f32)cmd->unk8[2] * modelRenderScale;
|
||||
|
||||
// sp20[0] = (f32)cmd->unkE[0] * modelRenderScale;
|
||||
// sp20[1] = (f32)cmd->unkE[1] * modelRenderScale;
|
||||
// sp20[2] = (f32)cmd->unkE[2] * modelRenderScale;
|
||||
if(TRUE){//viewport_isBoundingBoxInFrustum(sp2C, sp20)){
|
||||
func_80339124(gfx, mtx, (BKGeoList*)((s32)cmd + cmd->unk14));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @recomp Patched to disable frustum culling.
|
||||
RECOMP_PATCH bool viewport_isBoundingBoxInFrustum(f32 min[3], f32 max[3]) {
|
||||
// @recomp Disable frustum culling for cubes outside of demos. Demos need to maintain the original
|
||||
// culling for cubes to prevent them from behaving differently than the original game.
|
||||
if (recomp_in_demo_playback_game_mode()) {
|
||||
return viewport_isBoundingBoxInFrustumCopy(min, max);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -35,3 +124,93 @@ RECOMP_PATCH bool viewport_func_8024DB50(f32 pos[3], f32 distance) {
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// @recomp Patched to use the frustum culling result to set the marker's field.
|
||||
// This is only enabled during demos, and is needed so that demos play back correctly.
|
||||
RECOMP_PATCH void actor_postdrawMethod(ActorMarker *marker){
|
||||
if (!cur_model_would_have_been_culled_in_demo) {
|
||||
marker->unk14_21 = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
extern struct5Bs *D_8036E568;
|
||||
bool func_80330534(Actor *actor);
|
||||
bool func_8033056C(Actor *actor);
|
||||
void anim_802897D4(AnimMtxList *this, BKAnimationList *arg0, Animation *dst);
|
||||
void modelRender_setBoneTransformList(s32);
|
||||
void modelRender_setAnimatedTexturesCacheId(s32 arg0);
|
||||
s32 actor_getAnimatedTexturesCacheId(Actor *actor);
|
||||
|
||||
// @recomp Patched to not call the actor's callback if the actor's model would have been culled.
|
||||
// This is only enabled during demos, and is needed so that demos play back correctly.
|
||||
RECOMP_PATCH void actor_predrawMethod(Actor *this){
|
||||
s32 pad4C;
|
||||
BKModelBin *sp48;
|
||||
bool sp44;
|
||||
BKVertexList *sp40;
|
||||
f32 sp34[3];
|
||||
|
||||
sp48 = marker_loadModelBin(this->marker);
|
||||
func_80330534(this);
|
||||
if(this->anctrl != NULL){
|
||||
anctrl_drawSetup(this->anctrl, this->position, 1);
|
||||
}
|
||||
|
||||
if(this->marker->unk20 != NULL){
|
||||
sp44 = FALSE;
|
||||
if(this->unk148 != NULL){
|
||||
animMtxList_setBoned(&this->marker->unk20, model_getAnimationList(sp48), skeletalAnim_getBoneTransformList(this->unk148));
|
||||
sp44 = TRUE;
|
||||
}//L8032542C
|
||||
else if(this->anctrl != NULL && model_getAnimationList(sp48)){
|
||||
anim_802897D4(&this->marker->unk20, model_getAnimationList(sp48), anctrl_getAnimPtr(this->anctrl));
|
||||
sp44 = TRUE;
|
||||
}//L80325474
|
||||
|
||||
if(sp44){
|
||||
func_8033A444((AnimMtxList*)this->marker->unk20);
|
||||
}
|
||||
}//L8032548C
|
||||
|
||||
if(this->alpha_124_19 < 0xFF){
|
||||
modelRender_setAlpha(this->alpha_124_19);
|
||||
}
|
||||
|
||||
modelRender_setDepthMode(this->depth_mode);
|
||||
if(this->marker->unk44 != 0){
|
||||
if((s32)this->marker->unk44 == 1){
|
||||
func_8033A450(D_8036E568);
|
||||
}
|
||||
else{
|
||||
func_8033A450(this->marker->unk44);
|
||||
}
|
||||
}
|
||||
|
||||
if(this->unkF4_30){
|
||||
sp40 = func_80330C74(this);
|
||||
if(this->unk138_29){
|
||||
sp34[0] = this->pitch;
|
||||
sp34[1] = this->yaw;
|
||||
sp34[2] = this->roll;
|
||||
codeAC520_func_80333D48(sp40, this->position, sp34, this->scale, 0, model_getVtxList(sp48));
|
||||
}//L80325560
|
||||
modelRender_setVertexList(sp40);
|
||||
this->unkF4_29 = NOT(this->unkF4_29);
|
||||
}//L80325594
|
||||
|
||||
// @recomp Only call the actor's callback if the model wouldn't have been frustum culled.
|
||||
// This only has an effect during demos, as the in frustum flag always set to true outside of demos.
|
||||
if (!cur_model_would_have_been_culled_in_demo) {
|
||||
if(this->unk130){
|
||||
this->unk130(this);
|
||||
}
|
||||
}
|
||||
|
||||
if(this->unk148 && !this->marker->unk20){
|
||||
modelRender_setBoneTransformList((s32)skeletalAnim_getBoneTransformList(this->unk148));
|
||||
}
|
||||
|
||||
func_8033056C(this);
|
||||
modelRender_setAnimatedTexturesCacheId(actor_getAnimatedTexturesCacheId(this));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
#include "patches.h"
|
||||
#include "prop.h"
|
||||
|
||||
typedef struct demo_input{
|
||||
u8 unk0;
|
||||
u8 unk1;
|
||||
u16 unk2;
|
||||
u8 unk4;
|
||||
u8 unk5;
|
||||
}DemoInput;
|
||||
|
||||
typedef struct demo_file_header{
|
||||
u8 pad0[0x4];
|
||||
DemoInput inputs[];
|
||||
} DemoFileHeader;
|
||||
|
||||
extern DemoInput *D_803860D0; //demo_input_ptr
|
||||
extern DemoFileHeader * D_803860D4; //demo_file_ptr
|
||||
extern s32 D_803860D8;//current_input
|
||||
extern s32 D_803860DC;//total_inputs
|
||||
|
||||
extern DemoInput D_80371EF0;
|
||||
|
||||
enum extra_actors_e {
|
||||
ACTOR_19_FRAMERATE_60 = 0x19,
|
||||
ACTOR_1A_FRAMERATE_30,
|
||||
ACTOR_1B_FRAMERATE_20,
|
||||
ACTOR_1C_FRAMERATE_15,
|
||||
ACTOR_1D_FRAMERATE_12,
|
||||
};
|
||||
|
||||
typedef struct struct_core2_9B180_s{
|
||||
s16 unk0;
|
||||
// u8 pad2[0x2];
|
||||
NodeProp *unk4;
|
||||
void (*unk8)(struct struct_core2_9B180_s *);
|
||||
void (*unkC)(struct struct_core2_9B180_s *);
|
||||
void (*unk10)(struct struct_core2_9B180_s *);
|
||||
}Struct_core2_9B180_0;
|
||||
|
||||
extern Struct_core2_9B180_0 D_8036DE00[6];
|
||||
|
||||
extern volatile s32 D_802808D8;
|
||||
extern s32 D_802808DC;
|
||||
extern s32 D_80280E90;
|
||||
|
||||
void func_80244A98(s32 arg0);
|
||||
NodeProp *cubeList_findNodePropByActorIdAndPosition_s32(enum actor_e actor_id, s32 arg1[3]);
|
||||
void func_8032236C(s32 arg0, s32 arg1, s32 *arg2);
|
||||
void viMgr_func_8024BF94(s32 arg0);
|
||||
void viMgr_func_8024BFD8(s32 arg0);
|
||||
void dummy_func_8025AFB8(void);
|
||||
s32 getGameMode(void);
|
||||
f32 time_getDelta(void);
|
||||
s32 item_adjustByDiffWithHud(enum item_e item, s32 diff);
|
||||
void func_802FACA4(enum item_e item_id);
|
||||
bool func_802FAFE8(enum item_e item_id);
|
||||
enum map_e map_get(void);
|
||||
|
||||
s32 demo_frame_divisor = -1;
|
||||
|
||||
// @recomp Patched to set a variable to use as the frame divisor when processing demo inputs.
|
||||
RECOMP_PATCH int demo_readInput(OSContPad* arg0, s32* arg1){
|
||||
DemoInput *input_ptr = &D_803860D0[D_803860D8++];
|
||||
int not_eof = D_803860D8 < D_803860DC;
|
||||
|
||||
if(!not_eof)
|
||||
input_ptr = &D_80371EF0;
|
||||
|
||||
arg0->stick_x = input_ptr->unk0;
|
||||
arg0->stick_y = input_ptr->unk1;
|
||||
arg0->button = input_ptr->unk2;
|
||||
*arg1 = input_ptr->unk4;
|
||||
|
||||
// @recomp Track the frame divisor for later.
|
||||
demo_frame_divisor = input_ptr->unk4;
|
||||
|
||||
// @recomp Lock the frame divisor to 3 (20 FPS) in Bottles' Bonus.
|
||||
// The game generally runs at 20 FPS during Bottles' Bonus on original hardware, which means the minigame timer should last a similar amount of time.
|
||||
// Return 2 (30 FPS) into arg1 so that the game doesn't compensate by making the timer run faster.
|
||||
s32 game_mode = getGameMode();
|
||||
if (game_mode == GAME_MODE_8_BOTTLES_BONUS) {
|
||||
// *arg1 = 2;
|
||||
demo_frame_divisor = 3;
|
||||
}
|
||||
// @recomp Lock the frame divisor in the Mumbo SNS pictures based on the loaded map.
|
||||
// This makes sure that the dialog doesn't get cut off because the scene runs too quickly.
|
||||
if (game_mode == GAME_MODE_A_SNS_PICTURE) {
|
||||
s32 cur_map = map_get();
|
||||
|
||||
switch (cur_map) {
|
||||
// 20 FPS maps.
|
||||
case MAP_7F_FP_WOZZAS_CAVE:
|
||||
case MAP_92_GV_SNS_CHAMBER:
|
||||
demo_frame_divisor = 3;
|
||||
break;
|
||||
// Remaining maps run at 30 FPS.
|
||||
default:
|
||||
demo_frame_divisor = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return not_eof;
|
||||
}
|
||||
|
||||
// @recomp Patched to override the VI frame divisor when the demo frame divisor has been set.
|
||||
RECOMP_PATCH s32 viMgr_func_8024BFA0() {
|
||||
if (demo_frame_divisor != -1) {
|
||||
return demo_frame_divisor;
|
||||
}
|
||||
return D_802808DC;
|
||||
}
|
||||
|
||||
// @recomp Patched to clear the demo frame divisor after viMgr_func_8024BFD8.
|
||||
RECOMP_PATCH void viMgr_func_8024C1B4(void){
|
||||
viMgr_func_8024BFD8(0);
|
||||
// @recomp Clear the demo frame divisor.
|
||||
demo_frame_divisor = -1;
|
||||
dummy_func_8025AFB8();
|
||||
}
|
||||
|
||||
// @recomp Patched to clear the demo frame divisor after viMgr_func_8024BFD8.
|
||||
RECOMP_PATCH void viMgr_func_8024C1DC(void){
|
||||
viMgr_func_8024BFD8(1);
|
||||
// @recomp Clear the demo frame divisor.
|
||||
demo_frame_divisor = -1;
|
||||
}
|
||||
|
||||
// @recomp Patched to use a fixed time delta of 30 FPS when decrementing the hourglass timer during Bottles' Bonus.
|
||||
// Because the game is running at 20 FPS, this will result in the timer running slightly slower, which is accurate
|
||||
// to how fast it runs on original hardware.
|
||||
RECOMP_PATCH void func_80345EB0(enum item_e item){
|
||||
if(func_802FAFE8(item)){
|
||||
// @recomp Get the time delta and override it if this is the hourglass timer and the gamemode is Bottles' Bonus.
|
||||
f32 time_delta = time_getDelta();
|
||||
if (item == ITEM_0_HOURGLASS_TIMER && getGameMode() == GAME_MODE_8_BOTTLES_BONUS) {
|
||||
time_delta = 1.0f / 30.0f;
|
||||
}
|
||||
item_adjustByDiffWithHud(item, (s32)(-time_delta*60.0f * 1.1));
|
||||
}else{
|
||||
func_802FACA4(item);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "core1/mlmtx.h"
|
||||
#include "functions.h"
|
||||
|
||||
extern bool recomp_in_demo_playback_game_mode();
|
||||
|
||||
bool skip_all_interpolation = FALSE;
|
||||
bool has_additional_model_scale = FALSE;
|
||||
f32 additional_model_scale_x;
|
||||
@@ -32,6 +34,7 @@ s32 cur_drawn_model_transform_id = 0;
|
||||
s32 cur_drawn_model_transform_id_skip_interpolation = FALSE;
|
||||
s32 cur_model_transform_id_offset = 0;
|
||||
s32 cur_model_uses_bones = FALSE;
|
||||
s32 cur_model_would_have_been_culled_in_demo = FALSE;
|
||||
|
||||
Mtx identity_fixed_mtx = {{
|
||||
{
|
||||
@@ -598,16 +601,20 @@ RECOMP_PATCH BKModelBin *modelRender_draw(Gfx **gfx, Mtx **mtx, f32 position[3],
|
||||
return 0;
|
||||
}
|
||||
|
||||
// @recomp Disable frustum checks.
|
||||
set_frustum_checks_enabled(FALSE);
|
||||
|
||||
D_80370990 = (D_80383704) ? viewport_func_8024DB50(object_position, spD0*scale) : 1;
|
||||
|
||||
// @recomp Re-enable frustum checks.
|
||||
set_frustum_checks_enabled(TRUE);
|
||||
// @recomp Record the frustum check result, but ignore it during this function to disable frustum culling.
|
||||
// It will get set before this function returns.
|
||||
cur_model_would_have_been_culled_in_demo = !((D_80383704) ? viewport_func_8024DB50(object_position, spD0*scale) : 1);
|
||||
D_80370990 = TRUE;
|
||||
|
||||
// @recomp Force the frustum check to be true if the game isn't in demo playback mode.
|
||||
if (!recomp_in_demo_playback_game_mode()) {
|
||||
cur_model_would_have_been_culled_in_demo = FALSE;
|
||||
}
|
||||
|
||||
if(D_80370990 == 0){
|
||||
modelRender_reset();
|
||||
// @recomp Clear the flag indicating that the model would have been culled before returning.
|
||||
cur_model_would_have_been_culled_in_demo = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -841,5 +848,10 @@ RECOMP_PATCH BKModelBin *modelRender_draw(Gfx **gfx, Mtx **mtx, f32 position[3],
|
||||
}
|
||||
|
||||
modelRender_reset();
|
||||
|
||||
// @recomp Save the actual frustum culling result before returning.
|
||||
D_80370990 = !cur_model_would_have_been_culled_in_demo;
|
||||
// @recomp Clear the flag indicating that the model would have been culled before returning.
|
||||
cur_model_would_have_been_culled_in_demo = FALSE;
|
||||
return model_bin;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user