diff --git a/mm/include/functions.h b/mm/include/functions.h index a7f79fa38..6b37938dd 100644 --- a/mm/include/functions.h +++ b/mm/include/functions.h @@ -1324,6 +1324,8 @@ void PadMgr_ThreadEntry(); void Heaps_Alloc(void); // #endregion // #region 2S2H [Port] New methods added for porting +void Graph_OpenDisps(Gfx** dispRefs, Gfx* dispVals, GraphicsContext* gfxCtx, const char* file, s32 line); +void Graph_CloseDisps(Gfx** dispRefs, Gfx* dispVals, GraphicsContext* gfxCtx, const char* file, s32 line); void Lights_GlowCheckPrepare(PlayState* play); // #endregion // #region 2S2H [Port] Stubbed methods diff --git a/mm/include/gfx.h b/mm/include/gfx.h index 13ab495f2..cf61b2482 100644 --- a/mm/include/gfx.h +++ b/mm/include/gfx.h @@ -263,23 +263,22 @@ extern Gfx gEmptyDL[]; // __gfxCtx shouldn't be used directly. // Use the DISP macros defined above when writing to display buffers. -#define OPEN_DISPS(gfxCtx) \ - { \ - void FrameInterpolation_RecordOpenChild(const void* a, int b); \ - FrameInterpolation_RecordOpenChild(__FILE__, __LINE__); \ - GraphicsContext* __gfxCtx = gfxCtx; \ - gDPNoOpOpenDisp(gfxCtx->polyOpa.p++, __FILE__, __LINE__); \ - gDPNoOpOpenDisp(gfxCtx->polyXlu.p++, __FILE__, __LINE__); \ - gDPNoOpOpenDisp(gfxCtx->overlay.p++, __FILE__, __LINE__); +// 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__) -#define CLOSE_DISPS(gfxCtx) \ - (void)0; \ - void FrameInterpolation_RecordCloseChild(void); \ - FrameInterpolation_RecordCloseChild(); \ - gDPNoOpCloseDisp(gfxCtx->polyOpa.p++, __FILE__, __LINE__); \ - gDPNoOpCloseDisp(gfxCtx->polyXlu.p++, __FILE__, __LINE__); \ - gDPNoOpCloseDisp(gfxCtx->overlay.p++, __FILE__, __LINE__); \ - } \ +#define CLOSE_DISPS(gfxCtx) \ + (void)0; \ + void FrameInterpolation_RecordCloseChild(void); \ + FrameInterpolation_RecordCloseChild(); \ + Graph_CloseDisps(__dispRefs, __dispVals, gfxCtx, __FILE__, __LINE__); \ + } \ (void)0 #define GRAPH_ALLOC(gfxCtx, size) ((void*)((gfxCtx)->polyOpa.d = (Gfx*)((u8*)(gfxCtx)->polyOpa.d - ALIGN16(size)))) diff --git a/mm/src/code/graph.c b/mm/src/code/graph.c index dda350749..ab77211d6 100644 --- a/mm/src/code/graph.c +++ b/mm/src/code/graph.c @@ -435,3 +435,46 @@ void RunFrame() { void Graph_ThreadEntry(void* arg0) { Graph_ProcessFrame(RunFrame); } + +// #region 2S2H [Debugging] Debugging methods for viewing file/line info in the renderer. +// Particularly useful with the Gfx Debugger window +// Modeled after OOT-debug decomp +void Graph_OpenDisps(Gfx** dispRefs, Gfx* dispVals, GraphicsContext* gfxCtx, const char* file, s32 line) { + // Copy pointers and values for restoration in CloseDisps + dispRefs[0] = gfxCtx->polyOpa.p; + dispVals[0] = gfxCtx->polyOpa.p[0]; + dispRefs[1] = gfxCtx->polyXlu.p; + dispVals[1] = gfxCtx->polyXlu.p[0]; + dispRefs[2] = gfxCtx->overlay.p; + dispVals[2] = gfxCtx->overlay.p[0]; + + gDPNoOpOpenDisp(gfxCtx->polyOpa.p++, file, line); + gDPNoOpOpenDisp(gfxCtx->polyXlu.p++, file, line); + gDPNoOpOpenDisp(gfxCtx->overlay.p++, file, line); +} + +void Graph_CloseDisps(Gfx** dispRefs, Gfx* dispVals, GraphicsContext* gfxCtx, const char* file, s32 line) { + // If no instructions were added for a buffer since the OpenDisp, + // restore the buffer pointer and original value (essentially removing the noop open) + if (dispRefs[0] + 1 == gfxCtx->polyOpa.p) { + gfxCtx->polyOpa.p = dispRefs[0]; + gfxCtx->polyOpa.p[0] = dispVals[0]; + } else { + gDPNoOpCloseDisp(gfxCtx->polyOpa.p++, file, line); + } + + if (dispRefs[1] + 1 == gfxCtx->polyXlu.p) { + gfxCtx->polyXlu.p = dispRefs[1]; + gfxCtx->polyXlu.p[0] = dispVals[1]; + } else { + gDPNoOpCloseDisp(gfxCtx->polyXlu.p++, file, line); + } + + if (dispRefs[2] + 1 == gfxCtx->overlay.p) { + gfxCtx->overlay.p = dispRefs[2]; + gfxCtx->overlay.p[0] = dispVals[2]; + } else { + gDPNoOpCloseDisp(gfxCtx->overlay.p++, file, line); + } +} +// #endregion diff --git a/mm/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c b/mm/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c index 1e3890b74..c4c543122 100644 --- a/mm/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c +++ b/mm/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c @@ -2105,16 +2105,12 @@ void DmStk_Draw(Actor* thisx, PlayState* play) { if (this->alpha < 255) { Gfx_SetupDL25_Xlu(play->state.gfxCtx); Scene_SetRenderModeXlu(play, 1, 2); - // BENTODO - // #region 2S2H [TODO] This should be XLU, but it crashes because for some reason the limbs are attempting to - // render before the DrawFlex matrix is added to the segment (or something, not really certain) - gDPPipeSync(POLY_OPA_DISP++); - gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, this->alpha); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->alpha); - POLY_OPA_DISP = + POLY_XLU_DISP = SkelAnime_DrawFlex(play, this->skelAnime.skeleton, this->skelAnime.jointTable, - this->skelAnime.dListCount, NULL, DmStk_PostLimbDraw2, &this->actor, POLY_OPA_DISP); - // #endregion + this->skelAnime.dListCount, NULL, DmStk_PostLimbDraw2, &this->actor, POLY_XLU_DISP); } else { Scene_SetRenderModeXlu(play, 0, 1); diff --git a/mm/src/overlays/actors/ovl_En_Mkk/z_en_mkk.c b/mm/src/overlays/actors/ovl_En_Mkk/z_en_mkk.c index d4cea0be1..4de590ffc 100644 --- a/mm/src/overlays/actors/ovl_En_Mkk/z_en_mkk.c +++ b/mm/src/overlays/actors/ovl_En_Mkk/z_en_mkk.c @@ -562,8 +562,9 @@ void EnMkk_Draw(Actor* thisx, PlayState* play) { gSPDisplayList(&gfx[5], dLists->unk8); POLY_XLU_DISP = &gfx[6]; } + + CLOSE_DISPS(play->state.gfxCtx); } - CLOSE_DISPS(play->state.gfxCtx); } void func_80A4F4C8(Actor* thisx, PlayState* play) {