mirror of
https://github.com/izzy2lost/2ship2harkinian-Android.git
synced 2026-06-19 01:20:08 -07:00
Implement picto box frame buffer and reading logic (#189)
This commit is contained in:
+1
-1
Submodule libultraship updated: 682fbb9ed6...96684915df
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
|
||||
+54
-13
@@ -1451,35 +1451,76 @@ 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;
|
||||
|
||||
// BENTODO: Figure out what the transition does with framebuffers
|
||||
}
|
||||
|
||||
lastPauseWidth = OTRGetGameRenderWidth();
|
||||
lastPauseHeight = OTRGetGameRenderHeight();
|
||||
hasCapturedPauseBuffer = false;
|
||||
|
||||
FB_CopyToFramebuffer(&sp74, 0, gPauseFrameBuffer, false, &hasCapturedPauseBuffer);
|
||||
|
||||
gSPEndDisplayList(sp74++);
|
||||
Graph_BranchDlist(sp70, sp74);
|
||||
POLY_OPA_DISP = sp74;
|
||||
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:
|
||||
|
||||
Reference in New Issue
Block a user