Port pause menu framebuffer handling from 2Ship (#4346)
* bring over framebuffer effects methods * Implement framebuffer capture and drawing for pause menu * revert hookshot and title cards to draw using original buffers * remove old game over crash fix * Adjust mirror mode handling for kaleido * Avoid flashing the hud when pausing
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include <overlays/misc/ovl_kaleido_scope/z_kaleido_scope.h>
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/framebuffer_effects.h"
|
||||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
@@ -1341,6 +1342,24 @@ void Play_Draw(PlayState* play) {
|
||||
Lights* sp228;
|
||||
Vec3f sp21C;
|
||||
|
||||
// #region SOH [Port] Frame buffer effects for pause menu
|
||||
// Track render size when paused and that a copy was performed
|
||||
static u32 lastPauseWidth;
|
||||
static u32 lastPauseHeight;
|
||||
static u8 hasCapturedPauseBuffer;
|
||||
u8 recapturePauseBuffer = false;
|
||||
|
||||
// If the size has changed or dropped frames leading to the buffer not being copied,
|
||||
// set the prerender state back to setup to copy a new frame.
|
||||
// This requires not rendering kaleido during this copy to avoid kaleido being copied
|
||||
if ((R_PAUSE_MENU_MODE == 2 || R_PAUSE_MENU_MODE == 3) &&
|
||||
(lastPauseWidth != OTRGetGameRenderWidth() || lastPauseHeight != OTRGetGameRenderHeight() ||
|
||||
!hasCapturedPauseBuffer)) {
|
||||
R_PAUSE_MENU_MODE = 1;
|
||||
recapturePauseBuffer = true;
|
||||
}
|
||||
// #endregion
|
||||
|
||||
OPEN_DISPS(gfxCtx);
|
||||
|
||||
gSegments[4] = VIRTUAL_TO_PHYSICAL(play->objectCtx.status[play->objectCtx.mainKeepIndex].segment);
|
||||
@@ -1374,8 +1393,8 @@ void Play_Draw(PlayState* play) {
|
||||
func_800AAA50(&play->view, 15);
|
||||
|
||||
// Flip the projections and invert culling for the OPA and XLU display buffers
|
||||
// These manage the world and effects
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) {
|
||||
// These manage the world and effects when we are not drawing kaleido
|
||||
if (R_PAUSE_MENU_MODE <= 1 && CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) {
|
||||
gSPSetExtraGeometryMode(POLY_OPA_DISP++, G_EX_INVERT_CULLING);
|
||||
gSPSetExtraGeometryMode(POLY_XLU_DISP++, G_EX_INVERT_CULLING);
|
||||
gSPMatrix(POLY_OPA_DISP++, play->view.projectionFlippedPtr, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
@@ -1455,13 +1474,13 @@ void Play_Draw(PlayState* play) {
|
||||
if (R_PAUSE_MENU_MODE == 3) {
|
||||
Gfx* sp84 = POLY_OPA_DISP;
|
||||
|
||||
// SOH [Port] Draw game framebuffer using our custom handling
|
||||
//func_800C24BC(&play->pauseBgPreRender, &sp84);
|
||||
FB_DrawFromFramebuffer(&sp84, gPauseFrameBuffer, 255);
|
||||
POLY_OPA_DISP = sp84;
|
||||
|
||||
//goto Play_Draw_DrawOverlayElements;
|
||||
}
|
||||
//else
|
||||
{
|
||||
goto Play_Draw_DrawOverlayElements;
|
||||
} else {
|
||||
s32 sp80;
|
||||
|
||||
if ((HREG(80) != 10) || (HREG(83) != 0)) {
|
||||
@@ -1535,10 +1554,6 @@ void Play_Draw(PlayState* play) {
|
||||
Environment_FillScreen(gfxCtx, 0, 0, 0, play->unk_11E18, FILL_SCREEN_OPA);
|
||||
}
|
||||
|
||||
if ((play->pauseCtx.state != 0) && (HREG(80) != 10) || (HREG(89) != 0)) {
|
||||
Play_DrawOverlayElements(play);
|
||||
}
|
||||
|
||||
if ((HREG(80) != 10) || (HREG(85) != 0)) {
|
||||
func_800315AC(play, &play->actorCtx);
|
||||
}
|
||||
@@ -1586,17 +1601,36 @@ void Play_Draw(PlayState* play) {
|
||||
|
||||
play->pauseBgPreRender.fbuf = gfxCtx->curFrameBuffer;
|
||||
play->pauseBgPreRender.fbufSave = (u16*)gZBuffer;
|
||||
func_800C1F20(&play->pauseBgPreRender, &sp70);
|
||||
// SOH [Port] Use our custom copy method instead of the prerender system
|
||||
// func_800C1F20(&play->pauseBgPreRender, &sp70);
|
||||
if (R_PAUSE_MENU_MODE == 1) {
|
||||
play->pauseBgPreRender.cvgSave = (u8*)gfxCtx->curFrameBuffer;
|
||||
func_800C20B4(&play->pauseBgPreRender, &sp70);
|
||||
// func_800C20B4(&play->pauseBgPreRender, &sp70);
|
||||
R_PAUSE_MENU_MODE = 2;
|
||||
|
||||
// #region SOH [Port] Custom handling for pause prerender background capture
|
||||
lastPauseWidth = OTRGetGameRenderWidth();
|
||||
lastPauseHeight = OTRGetGameRenderHeight();
|
||||
hasCapturedPauseBuffer = false;
|
||||
|
||||
FB_CopyToFramebuffer(&sp70, 0, gPauseFrameBuffer, false, &hasCapturedPauseBuffer);
|
||||
|
||||
// Set the state back to ready after the recapture is done
|
||||
if (recapturePauseBuffer) {
|
||||
R_PAUSE_MENU_MODE = 3;
|
||||
}
|
||||
// #endregion
|
||||
} else {
|
||||
gTrnsnUnkState = 2;
|
||||
}
|
||||
OVERLAY_DISP = sp70;
|
||||
play->unk_121C7 = 2;
|
||||
SREG(33) |= 1;
|
||||
|
||||
// 2S2H [Port] Continue to render the post world for pausing to avoid flashing the HUD
|
||||
if (!(gTrnsnUnkState == 1)) {
|
||||
goto Play_Draw_DrawOverlayElements;
|
||||
}
|
||||
} else if (R_PAUSE_MENU_MODE != 3) {
|
||||
Play_Draw_DrawOverlayElements:
|
||||
if ((HREG(80) != 10) || (HREG(89) != 0)) {
|
||||
@@ -1627,15 +1661,6 @@ void Play_Draw(PlayState* play) {
|
||||
|
||||
Camera_Finish(GET_ACTIVE_CAM(play));
|
||||
|
||||
{
|
||||
Gfx* prevDisplayList = POLY_OPA_DISP;
|
||||
Gfx* gfxP = Graph_GfxPlusOne(POLY_OPA_DISP);
|
||||
gSPDisplayList(OVERLAY_DISP++, gfxP);
|
||||
gSPEndDisplayList(gfxP++);
|
||||
Graph_BranchDlist(prevDisplayList, gfxP);
|
||||
POLY_OPA_DISP = gfxP;
|
||||
}
|
||||
|
||||
CLOSE_DISPS(gfxCtx);
|
||||
|
||||
Interface_DrawTotalGameplayTimer(play);
|
||||
|
||||
Reference in New Issue
Block a user