summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArchez <Archez@users.noreply.github.com>2024-04-13 16:54:20 -0400
committerGarrett Cox <garrettjcox@gmail.com>2024-05-22 09:05:01 -0500
commitb4c7a8bd22ffb2868c0b3e5caeafefb20236918a (patch)
tree28eeeb565731797cea0c40ff1bdacd343c7511a8
parent18d88ec374a5f907f4c4cdb49a9a76ab551fa208 (diff)
Implement picto box frame buffer and reading logic (#189)
m---------libultraship0
-rw-r--r--mm/2s2h/framebuffer_effects.c16
-rw-r--r--mm/2s2h/framebuffer_effects.h1
-rw-r--r--mm/src/code/z_parameter.c6
-rw-r--r--mm/src/code/z_play.c67
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: