diff --git a/include/regs.h b/include/regs.h index fbbd3bbf9c..41a3af177b 100644 --- a/include/regs.h +++ b/include/regs.h @@ -51,6 +51,7 @@ #define R_ROOM_IMAGE_NODRAW_FLAGS SREG(25) #define R_ROOM_BG2D_FORCE_SCALEBG SREG(26) #define R_UPDATE_RATE SREG(30) +#define R_GRAPH_TASKSET00_FLAGS SREG(33) #define R_ENABLE_AUDIO_DBG SREG(36) #define R_VI_MODE_EDIT_STATE SREG(48) #define R_VI_MODE_EDIT_WIDTH SREG(49) @@ -64,7 +65,7 @@ #define R_FB_FILTER_A SREG(84) #define R_FB_FILTER_ENV_COLOR(c) SREG(85 + (c)) #define R_ENABLE_FB_FILTER SREG(88) -#define R_PAUSE_MENU_MODE SREG(94) +#define R_PAUSE_BG_PRERENDER_STATE SREG(94) // `PauseBgPreRenderState` #define R_CAM_XZ_OFFSET_UPDATE_RATE OREG(2) #define R_CAM_Y_OFFSET_UPDATE_RATE OREG(3) #define R_CAM_FOV_UPDATE_RATE OREG(4) diff --git a/include/z64.h b/include/z64.h index 289641a522..8e8ca43613 100644 --- a/include/z64.h +++ b/include/z64.h @@ -659,6 +659,14 @@ typedef struct { } restrictions; } InterfaceContext; // size = 0x270 +typedef enum { + /* 0 */ PAUSE_BG_PRERENDER_OFF, // Inactive, do nothing. + /* 1 */ PAUSE_BG_PRERENDER_SETUP, // The current frame is only drawn for the purpose of serving as the pause background. + /* 2 */ PAUSE_BG_PRERENDER_PROCESS, // The previous frame was PAUSE_BG_PRERENDER_SETUP, now apply prerender filters. + /* 3 */ PAUSE_BG_PRERENDER_DONE, // The pause background is ready to be used. + /* 4 */ PAUSE_BG_PRERENDER_MAX +} PauseBgPreRenderState; + typedef struct { /* 0x00 */ void* loadedRamAddr; /* 0x04 */ uintptr_t vromStart; diff --git a/src/code/game.c b/src/code/game.c index ae22e6ab36..9f3bc91bcc 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -319,7 +319,7 @@ void GameState_Update(GameState* gameState) { } } - if (R_PAUSE_MENU_MODE != 2u) { + if (R_PAUSE_BG_PRERENDER_STATE != (u32)PAUSE_BG_PRERENDER_PROCESS) { GameState_Draw(gameState, gfxCtx); func_800C49F4(gfxCtx); } diff --git a/src/code/graph.c b/src/code/graph.c index 1c9093dc96..e5309966c7 100644 --- a/src/code/graph.c +++ b/src/code/graph.c @@ -242,8 +242,8 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx) { scTask->next = NULL; scTask->flags = OS_SC_NEEDS_RSP | OS_SC_NEEDS_RDP | OS_SC_SWAPBUFFER | OS_SC_LAST_TASK; - if (SREG(33) & 1) { - SREG(33) &= ~1; + if (R_GRAPH_TASKSET00_FLAGS & 1) { + R_GRAPH_TASKSET00_FLAGS &= ~1; scTask->flags &= ~OS_SC_SWAPBUFFER; gfxCtx->fbIdx--; } diff --git a/src/code/z_kaleido_scope_call.c b/src/code/z_kaleido_scope_call.c index b9c116ff16..ced5b5203e 100644 --- a/src/code/z_kaleido_scope_call.c +++ b/src/code/z_kaleido_scope_call.c @@ -61,7 +61,7 @@ void KaleidoScopeCall_Update(PlayState* play) { if (Letterbox_GetSize() == 0) { R_HREG_MODE = HREG_MODE_UCODE_DISAS; R_UCODE_DISAS_LOG_MODE = 3; - R_PAUSE_MENU_MODE = 1; + R_PAUSE_BG_PRERENDER_STATE = PAUSE_BG_PRERENDER_SETUP; pauseCtx->unk_1E4 = 0; pauseCtx->unk_1EC = 0; pauseCtx->state = (pauseCtx->state & 0xFFFF) + 1; @@ -69,14 +69,14 @@ void KaleidoScopeCall_Update(PlayState* play) { } else if (pauseCtx->state == 8) { R_HREG_MODE = HREG_MODE_UCODE_DISAS; R_UCODE_DISAS_LOG_MODE = 3; - R_PAUSE_MENU_MODE = 1; + R_PAUSE_BG_PRERENDER_STATE = PAUSE_BG_PRERENDER_SETUP; pauseCtx->unk_1E4 = 0; pauseCtx->unk_1EC = 0; pauseCtx->state = (pauseCtx->state & 0xFFFF) + 1; } else if ((pauseCtx->state == 2) || (pauseCtx->state == 9)) { - osSyncPrintf("PR_KAREIDOSCOPE_MODE=%d\n", R_PAUSE_MENU_MODE); + osSyncPrintf("PR_KAREIDOSCOPE_MODE=%d\n", R_PAUSE_BG_PRERENDER_STATE); - if (R_PAUSE_MENU_MODE >= 3) { + if (R_PAUSE_BG_PRERENDER_STATE >= PAUSE_BG_PRERENDER_DONE) { pauseCtx->state++; } } else if (pauseCtx->state != 0) { @@ -118,7 +118,7 @@ void KaleidoScopeCall_Update(PlayState* play) { void KaleidoScopeCall_Draw(PlayState* play) { KaleidoMgrOverlay* kaleidoScopeOvl = &gKaleidoMgrOverlayTable[KALEIDO_OVL_KALEIDO_SCOPE]; - if (R_PAUSE_MENU_MODE >= 3) { + if (R_PAUSE_BG_PRERENDER_STATE >= PAUSE_BG_PRERENDER_DONE) { if (((play->pauseCtx.state >= 4) && (play->pauseCtx.state <= 7)) || ((play->pauseCtx.state >= 11) && (play->pauseCtx.state <= 18))) { if (gKaleidoMgrCurOvl == kaleidoScopeOvl) { diff --git a/src/code/z_parameter.c b/src/code/z_parameter.c index b63702ec35..b8e7a0a8dc 100644 --- a/src/code/z_parameter.c +++ b/src/code/z_parameter.c @@ -3238,7 +3238,8 @@ void Interface_Draw(PlayState* play) { Magic_DrawMeter(play); Minimap_Draw(play); - if ((R_PAUSE_MENU_MODE != 2) && (R_PAUSE_MENU_MODE != 3)) { + if ((R_PAUSE_BG_PRERENDER_STATE != PAUSE_BG_PRERENDER_PROCESS) && + (R_PAUSE_BG_PRERENDER_STATE != PAUSE_BG_PRERENDER_DONE)) { func_8002C124(&play->actorCtx.targetCtx, play); // Draw Z-Target } diff --git a/src/code/z_play.c b/src/code/z_play.c index 4f8284cfdf..9a3fb32046 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -179,7 +179,7 @@ void Play_Destroy(GameState* thisx) { this->state.gfxCtx->callbackParam = NULL; SREG(91) = 0; - R_PAUSE_MENU_MODE = 0; + R_PAUSE_BG_PRERENDER_STATE = PAUSE_BG_PRERENDER_OFF; PreRender_Destroy(&this->pauseBgPreRender); Effect_DeleteAll(this); @@ -357,7 +357,7 @@ void Play_Init(GameState* thisx) { } SREG(91) = -1; - R_PAUSE_MENU_MODE = 0; + R_PAUSE_BG_PRERENDER_STATE = PAUSE_BG_PRERENDER_OFF; PreRender_Init(&this->pauseBgPreRender); PreRender_SetValuesSave(&this->pauseBgPreRender, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, NULL); PreRender_SetValues(&this->pauseBgPreRender, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL); @@ -1115,19 +1115,25 @@ void Play_Draw(PlayState* this) { } else { PreRender_SetValues(&this->pauseBgPreRender, SCREEN_WIDTH, SCREEN_HEIGHT, gfxCtx->curFrameBuffer, gZBuffer); - if (R_PAUSE_MENU_MODE == 2) { + if (R_PAUSE_BG_PRERENDER_STATE == PAUSE_BG_PRERENDER_PROCESS) { + // Wait for the previous frame's display list to be processed, + // so that `pauseBgPreRender.fbufSave` and `pauseBgPreRender.cvgSave` are filled with the appropriate + // content and can be used by `PreRender_ApplyFilters` below. Sched_FlushTaskQueue(); + PreRender_ApplyFilters(&this->pauseBgPreRender); - R_PAUSE_MENU_MODE = 3; - } else if (R_PAUSE_MENU_MODE >= 4) { - R_PAUSE_MENU_MODE = 0; + + R_PAUSE_BG_PRERENDER_STATE = PAUSE_BG_PRERENDER_DONE; + } else if (R_PAUSE_BG_PRERENDER_STATE >= PAUSE_BG_PRERENDER_MAX) { + R_PAUSE_BG_PRERENDER_STATE = PAUSE_BG_PRERENDER_OFF; } - if (R_PAUSE_MENU_MODE == 3) { - Gfx* sp84 = POLY_OPA_DISP; + if (R_PAUSE_BG_PRERENDER_STATE == PAUSE_BG_PRERENDER_DONE) { + Gfx* gfxP = POLY_OPA_DISP; + + PreRender_RestoreFramebuffer(&this->pauseBgPreRender, &gfxP); + POLY_OPA_DISP = gfxP; - PreRender_RestoreFramebuffer(&this->pauseBgPreRender, &sp84); - POLY_OPA_DISP = sp84; goto Play_Draw_DrawOverlayElements; } else { s32 roomDrawFlags; @@ -1238,22 +1244,25 @@ void Play_Draw(PlayState* this) { DebugDisplay_DrawObjects(this); } - if ((R_PAUSE_MENU_MODE == 1) || (gTrnsnUnkState == 1)) { - Gfx* sp70 = OVERLAY_DISP; + if ((R_PAUSE_BG_PRERENDER_STATE == PAUSE_BG_PRERENDER_SETUP) || (gTrnsnUnkState == 1)) { + Gfx* gfxP = OVERLAY_DISP; + // Copy the frame buffer contents at this point in the display list to the zbuffer + // The zbuffer must then stay untouched until unpausing this->pauseBgPreRender.fbuf = gfxCtx->curFrameBuffer; this->pauseBgPreRender.fbufSave = (u16*)gZBuffer; - PreRender_SaveFramebuffer(&this->pauseBgPreRender, &sp70); - if (R_PAUSE_MENU_MODE == 1) { + PreRender_SaveFramebuffer(&this->pauseBgPreRender, &gfxP); + if (R_PAUSE_BG_PRERENDER_STATE == PAUSE_BG_PRERENDER_SETUP) { this->pauseBgPreRender.cvgSave = (u8*)gfxCtx->curFrameBuffer; - PreRender_DrawCoverage(&this->pauseBgPreRender, &sp70); - R_PAUSE_MENU_MODE = 2; + PreRender_DrawCoverage(&this->pauseBgPreRender, &gfxP); + + R_PAUSE_BG_PRERENDER_STATE = PAUSE_BG_PRERENDER_PROCESS; } else { gTrnsnUnkState = 2; } - OVERLAY_DISP = sp70; + OVERLAY_DISP = gfxP; this->unk_121C7 = 2; - SREG(33) |= 1; + R_GRAPH_TASKSET00_FLAGS |= 1; } else { Play_Draw_DrawOverlayElements: if ((R_HREG_MODE != HREG_MODE_PLAY) || R_PLAY_DRAW_OVERLAY_ELEMENTS) { diff --git a/src/code/z_rcp.c b/src/code/z_rcp.c index 8b8c6d9be2..7b93284593 100644 --- a/src/code/z_rcp.c +++ b/src/code/z_rcp.c @@ -1469,7 +1469,7 @@ void Gfx_SetupFrame(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b) { gDPSetDepthImage(POLY_XLU_DISP++, gZBuffer); gDPSetDepthImage(OVERLAY_DISP++, gZBuffer); - if ((R_PAUSE_MENU_MODE < 2) && (gTrnsnUnkState < 2)) { + if ((R_PAUSE_BG_PRERENDER_STATE <= PAUSE_BG_PRERENDER_SETUP) && (gTrnsnUnkState < 2)) { s32 letterboxSize = Letterbox_GetSize(); if (R_HREG_MODE == HREG_MODE_SETUP_FRAME) { diff --git a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index 3d10978b18..95b16ae33d 100644 --- a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -251,7 +251,7 @@ void KaleidoScope_SetupPlayerPreRender(PlayState* play) { Graph_BranchDlist(gfxRef, gfx); POLY_OPA_DISP = gfx; - SREG(33) |= 1; + R_GRAPH_TASKSET00_FLAGS |= 1; CLOSE_DISPS(play->state.gfxCtx, "../z_kaleido_scope_PAL.c", 509); } @@ -2500,8 +2500,9 @@ void KaleidoScope_Update(PlayState* play) { s16 stepA; s32 pad; - if ((R_PAUSE_MENU_MODE >= 3) && (((pauseCtx->state >= 4) && (pauseCtx->state <= 7)) || - ((pauseCtx->state >= 0xA) && (pauseCtx->state <= 0x12)))) { + if ((R_PAUSE_BG_PRERENDER_STATE >= PAUSE_BG_PRERENDER_DONE) && + (((pauseCtx->state >= 4) && (pauseCtx->state <= 7)) || + ((pauseCtx->state >= 0xA) && (pauseCtx->state <= 0x12)))) { if ((!pauseCtx->unk_1E4 || (pauseCtx->unk_1E4 == 8)) && (pauseCtx->state == 6)) { pauseCtx->stickAdjX = input->rel.stick_x; @@ -3416,7 +3417,7 @@ void KaleidoScope_Update(PlayState* play) { interfaceCtx->unk_244 = 255; pauseCtx->state = 0; R_UPDATE_RATE = 3; - R_PAUSE_MENU_MODE = 0; + R_PAUSE_BG_PRERENDER_STATE = PAUSE_BG_PRERENDER_OFF; func_800981B8(&play->objectCtx); func_800418D0(&play->colCtx, play); if (pauseCtx->promptChoice == 0) { @@ -3475,7 +3476,7 @@ void KaleidoScope_Update(PlayState* play) { case 0x13: pauseCtx->state = 0; R_UPDATE_RATE = 3; - R_PAUSE_MENU_MODE = 0; + R_PAUSE_BG_PRERENDER_STATE = PAUSE_BG_PRERENDER_OFF; func_800981B8(&play->objectCtx); func_800418D0(&play->colCtx, play);