diff options
| author | Archez <Archez@users.noreply.github.com> | 2024-04-13 16:54:20 -0400 |
|---|---|---|
| committer | Garrett Cox <garrettjcox@gmail.com> | 2024-05-22 09:05:01 -0500 |
| commit | b4c7a8bd22ffb2868c0b3e5caeafefb20236918a (patch) | |
| tree | 28eeeb565731797cea0c40ff1bdacd343c7511a8 | |
| parent | 18d88ec374a5f907f4c4cdb49a9a76ab551fa208 (diff) | |
Implement picto box frame buffer and reading logic (#189)
| m--------- | libultraship | 0 | ||||
| -rw-r--r-- | mm/2s2h/framebuffer_effects.c | 16 | ||||
| -rw-r--r-- | mm/2s2h/framebuffer_effects.h | 1 | ||||
| -rw-r--r-- | mm/src/code/z_parameter.c | 6 | ||||
| -rw-r--r-- | mm/src/code/z_play.c | 67 |
5 files changed, 72 insertions, 18 deletions
diff --git a/libultraship b/libultraship -Subproject 682fbb9ed6fbbb4b514fcbe6c8bfc2ed97b5d8b +Subproject 96684915df17ebd1c9b0030907887691fcf2feb diff --git a/mm/2s2h/framebuffer_effects.c b/mm/2s2h/framebuffer_effects.c index 2c8bca0b4..c2109263f 100644 --- a/mm/2s2h/framebuffer_effects.c +++ b/mm/2s2h/framebuffer_effects.c @@ -1,7 +1,8 @@ #include "framebuffer_effects.h" #include "global.h" -int gfx_create_framebuffer(uint32_t width, uint32_t height, uint32_t native_width, uint32_t native_height); +int gfx_create_framebuffer(uint32_t width, uint32_t height, uint32_t native_width, uint32_t native_height, + uint8_t resize); s32 gPauseFrameBuffer = -1; s32 gBlurFrameBuffer = -1; @@ -9,17 +10,24 @@ s32 gBlurFrameBuffer = -1; // i.e. the VisMono and VisFbuf effects s32 gReusableFrameBuffer = -1; +// Picto box buffer is unscaled at 320x240 +s32 gPictoBoxFrameBuffer = -1; + void FB_CreateFramebuffers(void) { if (gPauseFrameBuffer == -1) { - gPauseFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT); + gPauseFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, true); } if (gBlurFrameBuffer == -1) { - gBlurFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT); + gBlurFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, true); } if (gReusableFrameBuffer == -1) { - gReusableFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT); + gReusableFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, true); + } + + if (gPictoBoxFrameBuffer == -1) { + gPictoBoxFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, false); } } diff --git a/mm/2s2h/framebuffer_effects.h b/mm/2s2h/framebuffer_effects.h index e8bd9aba4..5ee8bb99e 100644 --- a/mm/2s2h/framebuffer_effects.h +++ b/mm/2s2h/framebuffer_effects.h @@ -6,6 +6,7 @@ extern s32 gPauseFrameBuffer; extern s32 gBlurFrameBuffer; extern s32 gReusableFrameBuffer; +extern s32 gPictoBoxFrameBuffer; void FB_CreateFramebuffers(void); void FB_CopyToFramebuffer(Gfx** gfxp, s32 fb_src, s32 fb_dest, u8 oncePerFrame, u8* hasCopied); diff --git a/mm/src/code/z_parameter.c b/mm/src/code/z_parameter.c index 4d538ba56..e1f4db8b7 100644 --- a/mm/src/code/z_parameter.c +++ b/mm/src/code/z_parameter.c @@ -2480,7 +2480,7 @@ void Interface_UpdateButtonsPart1(PlayState* play) { if (!CHECK_EVENTINF(EVENTINF_41) || (CHECK_EVENTINF(EVENTINF_41) && (CutsceneManager_GetCurrentCsId() == CS_ID_NONE))) { Audio_PlaySfx(NA_SE_SY_CAMERA_SHUTTER); - SREG(89) = 1; + R_PICTO_PHOTO_STATE = PICTO_PHOTO_STATE_SETUP; play->haltAllActors = true; sPictoState = PICTO_BOX_STATE_SETUP_PHOTO; sPictoPhotoBeingTaken = true; @@ -7128,6 +7128,10 @@ void Interface_Draw(PlayState* play) { pictoRectTop = PICTO_PHOTO_TOPLEFT_Y - 33; for (sp2CC = 0; sp2CC < (PICTO_PHOTO_HEIGHT / 8); sp2CC++, pictoRectTop += 8) { pictoRectLeft = PICTO_PHOTO_TOPLEFT_X; + // 2S2H [Port] Invalidate each section. This could probably be optimized to only be done once each pic + gSPInvalidateTexCache(OVERLAY_DISP++, + (u8*)((play->pictoPhotoI8 != NULL) ? play->pictoPhotoI8 : gWorkBuffer) + + (0x500 * sp2CC)); gDPLoadTextureBlock(OVERLAY_DISP++, (u8*)((play->pictoPhotoI8 != NULL) ? play->pictoPhotoI8 : gWorkBuffer) + (0x500 * sp2CC), diff --git a/mm/src/code/z_play.c b/mm/src/code/z_play.c index 2a123904e..22cefb632 100644 --- a/mm/src/code/z_play.c +++ b/mm/src/code/z_play.c @@ -1451,21 +1451,65 @@ void Play_DrawMain(PlayState* this) { R_PAUSE_BG_PRERENDER_STATE = PAUSE_BG_PRERENDER_PROCESS; this->pauseBgPreRender.fbufSave = gfxCtx->zbuffer; this->pauseBgPreRender.cvgSave = this->unk_18E58; + + // #region 2S2H [Port] Custom handling for pause prerender background capture + lastPauseWidth = OTRGetGameRenderWidth(); + lastPauseHeight = OTRGetGameRenderHeight(); + hasCapturedPauseBuffer = false; + + FB_CopyToFramebuffer(&sp74, 0, gPauseFrameBuffer, false, &hasCapturedPauseBuffer); + + // Set the state back to ready after the recapture is done + if (recapturePauseBuffer) { + R_PAUSE_BG_PRERENDER_STATE = PAUSE_BG_PRERENDER_READY; + } + // #endregion } else if (R_PICTO_PHOTO_STATE == PICTO_PHOTO_STATE_SETUP) { R_PICTO_PHOTO_STATE = PICTO_PHOTO_STATE_PROCESS; this->pauseBgPreRender.fbufSave = gfxCtx->zbuffer; - this->pauseBgPreRender.cvgSave = this->unk_18E58; + // BENTODO: Add this back when coverage is figured out - for the anti aliasing filter + // this->pauseBgPreRender.cvgSave = this->unk_18E58; + this->pauseBgPreRender.cvgSave = NULL; + + // #region 2S2H [Port] Custom handling for picto box capture + // Copy to our reusable buffer first + FB_CopyToFramebuffer(&sp74, 0, gReusableFrameBuffer, false, NULL); + + // Set the picto framebuffer as the draw target (320x240) + gsSPSetFB(sp74++, gPictoBoxFrameBuffer); + + int16_t s0 = 0, t0 = 0; + int16_t s1 = OTRGetGameRenderWidth(); + int16_t t1 = OTRGetGameRenderHeight(); + + float aspectRatio = OTRGetAspectRatio(); + float fourByThree = 4.0f / 3.0f; + + // Adjsut the texture coordinates so that only a 4:3 region from the center is drawn + // to the picto buffer. Currently ratios smaller than 4:3 will just stretch to fill. + if (aspectRatio > fourByThree) { + int16_t adjustedWidth = OTRGetGameRenderWidth() / (aspectRatio / fourByThree); + s0 = (OTRGetCurrentWidth() - adjustedWidth) / 2; + s1 -= s0; + } + + gDPSetTextureImageFB(sp74++, 0, 0, 0, gReusableFrameBuffer); + gDPImageRectangle(sp74++, 0 << 2, 0 << 2, s0, t0, SCREEN_WIDTH << 2, SCREEN_HEIGHT << 2, s1, t1, + G_TX_RENDERTILE, OTRGetGameRenderWidth(), OTRGetGameRenderHeight()); + + // Read the picto box framebuffer back as a rgba16 buffer + gDPReadFB(sp74++, gPictoBoxFrameBuffer, this->pauseBgPreRender.fbufSave, 0, 0, SCREEN_WIDTH, + SCREEN_HEIGHT); + + gsSPResetFB(sp74++); + // #endregion } else { gTransitionTileState = TRANS_TILE_PROCESS; this->pauseBgPreRender.fbufSave = gfxCtx->zbuffer; this->pauseBgPreRender.cvgSave = NULL; - } - - lastPauseWidth = OTRGetGameRenderWidth(); - lastPauseHeight = OTRGetGameRenderHeight(); - hasCapturedPauseBuffer = false; - FB_CopyToFramebuffer(&sp74, 0, gPauseFrameBuffer, false, &hasCapturedPauseBuffer); + // BENTODO: Figure out what the transition does with framebuffers + } gSPEndDisplayList(sp74++); Graph_BranchDlist(sp70, sp74); @@ -1473,13 +1517,10 @@ void Play_DrawMain(PlayState* this) { this->unk_18B49 = 2; SREG(33) |= 1; - // 2S2H [Port] Set the state back to ready after the recapture is done - if (recapturePauseBuffer) { - R_PAUSE_BG_PRERENDER_STATE = PAUSE_BG_PRERENDER_READY; + // 2S2H [Port] Continue to render the post world for pausing to avoid flashing the HUD + if (gTransitionTileState == TRANS_TILE_PROCESS || R_PICTO_PHOTO_STATE == PICTO_PHOTO_STATE_PROCESS) { + goto SkipPostWorldDraw; } - - // 2S2H [Port] Continue to render the post world to avoid flashing the HUD - // goto SkipPostWorldDraw; } PostWorldDraw: |
