Fix interpolation crashes due to unclosed records (#263)

* Fix interpolation crashes due to unclosed records

* rework en_mnk drawface to avoid return in open/close disps pair [still matching]

* fix placement of close_disps in en_osn draw

* replace returns with goto to follow other decomp patterns
This commit is contained in:
Archez
2024-05-22 09:05:02 -05:00
committed by Garrett Cox
parent 8f2d856519
commit bbb0e2a4e0
7 changed files with 39 additions and 23 deletions
+25 -15
View File
@@ -261,24 +261,34 @@ extern Gfx gEmptyDL[];
#define OVERLAY_DISP __gfxCtx->overlay.p
#define DEBUG_DISP __gfxCtx->debug.p
// #region 2S2H [Port] Logic to perform in DISPS methods for debug information and frame interpolation support
#define OPEN_DISPS_PORT_HELPERS(gfxCtx) \
void FrameInterpolation_RecordOpenChild(const void* a, int b); \
FrameInterpolation_RecordOpenChild(__FILE__, __LINE__); \
Gfx* __dispRefs[3]; \
Gfx __dispVals[3]; \
Graph_OpenDisps(__dispRefs, __dispVals, gfxCtx, __FILE__, __LINE__)
#define CLOSE_DISPS_PORT_HELPERS(gfxCtx) \
void FrameInterpolation_RecordCloseChild(void); \
FrameInterpolation_RecordCloseChild(); \
Graph_CloseDisps(__dispRefs, __dispVals, gfxCtx, __FILE__, __LINE__)
// #endregion
// __gfxCtx shouldn't be used directly.
// Use the DISP macros defined above when writing to display buffers.
// 2S2H [Port] Augmented to provide debug information and support interpolation
#define OPEN_DISPS(gfxCtx) \
{ \
void FrameInterpolation_RecordOpenChild(const void* a, int b); \
FrameInterpolation_RecordOpenChild(__FILE__, __LINE__); \
GraphicsContext* __gfxCtx = gfxCtx; \
Gfx* __dispRefs[3]; \
Gfx __dispVals[3]; \
Graph_OpenDisps(__dispRefs, __dispVals, gfxCtx, __FILE__, __LINE__)
// 2S2H [Port] Augmented to use our disps helpers
#define OPEN_DISPS(gfxCtx) \
{ \
GraphicsContext* __gfxCtx = gfxCtx; \
s32 __dispPad; \
OPEN_DISPS_PORT_HELPERS(gfxCtx)
#define CLOSE_DISPS(gfxCtx) \
(void)0; \
void FrameInterpolation_RecordCloseChild(void); \
FrameInterpolation_RecordCloseChild(); \
Graph_CloseDisps(__dispRefs, __dispVals, gfxCtx, __FILE__, __LINE__); \
} \
#define CLOSE_DISPS(gfxCtx) \
(void)0; \
CLOSE_DISPS_PORT_HELPERS(gfxCtx); \
} \
(void)0
#define GRAPH_ALLOC(gfxCtx, size) ((void*)((gfxCtx)->polyOpa.d = (Gfx*)((u8*)(gfxCtx)->polyOpa.d - ALIGN16(size))))
+2
View File
@@ -115,6 +115,8 @@ void SpeedMeter_DrawTimeEntries(SpeedMeter* this, GraphicsContext* gfxCtx) {
/*! @bug if gIrqMgrRetraceTime is 0, CLOSE_DISPS will never be reached */
if (gIrqMgrRetraceTime == 0) {
// 2S2H [Port] We need our close disps helpers called to prevent interpolation crashes
CLOSE_DISPS_PORT_HELPERS(gfxCtx);
return;
}
+3 -2
View File
@@ -652,7 +652,7 @@ void EffectBlure_DrawSmooth(EffectBlure* this2, GraphicsContext* gfxCtx) {
FrameInterpolation_RecordOpenChild(this, interpolationEpoch);
if (this->numElements < 2) {
return;
goto close_disps;
}
this->elements[0].flags &= ~3;
@@ -672,7 +672,7 @@ void EffectBlure_DrawSmooth(EffectBlure* this2, GraphicsContext* gfxCtx) {
mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &sp5C);
if (mtx == NULL) {
return;
goto close_disps;
}
gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
@@ -691,6 +691,7 @@ void EffectBlure_DrawSmooth(EffectBlure* this2, GraphicsContext* gfxCtx) {
}
}
close_disps:
FrameInterpolation_RecordCloseChild();
CLOSE_DISPS(gfxCtx);
}
+2
View File
@@ -2818,6 +2818,8 @@ void func_80126BD0(PlayState* play, Player* player, s32 arg2) {
D_801C05F0[1].unk_2 = D_801C05F0[0].unk_2;
} else {
//! @bug Skips CLOSE_DISPS
// 2S2H [Port] We need our close disps helpers called to prevent interpolation crashes
CLOSE_DISPS_PORT_HELPERS(play->state.gfxCtx);
return;
}
+3 -4
View File
@@ -2203,17 +2203,16 @@ void EnMnk_Monkey_DrawFace(EnMnk* this, PlayState* play) {
} else {
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sMonkeyFaceTextures[this->blinkFrame]));
}
return;
break;
case 2:
case 3:
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sMonkeyFaceTextures[this->unk_3E0]));
return;
break;
default:
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sMonkeyFaceTextures[this->blinkFrame]));
break;
}
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sMonkeyFaceTextures[this->blinkFrame]));
CLOSE_DISPS(play->state.gfxCtx);
}
+2 -2
View File
@@ -1064,7 +1064,7 @@ void EnOsn_Draw(Actor* thisx, PlayState* play) {
POLY_XLU_DISP =
SkelAnime_DrawFlex(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
EnOsn_OverrideLimbDraw, EnOsn_PostLimbDraw, &this->actor, POLY_XLU_DISP);
CLOSE_DISPS(play->state.gfxCtx);
}
CLOSE_DISPS(play->state.gfxCtx);
}
@@ -1965,6 +1965,8 @@ void ObjUm_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
}
} else {
//! @bug skips CLOSE_DISPS
// 2S2H [Port] We need our close disps helpers called to prevent interpolation crashes
CLOSE_DISPS_PORT_HELPERS(gfxCtx);
return;
}
}