From f4aec1ed0a228e62543ccd8bc9b667eaeea1c6ec Mon Sep 17 00:00:00 2001 From: Archez Date: Tue, 27 Feb 2024 08:04:35 -0500 Subject: [PATCH] Implement VisMono with custom framebuffer effects (#136) --- mm/2s2h/framebuffer_effects.c | 8 +++++--- mm/2s2h/framebuffer_effects.h | 2 +- mm/src/code/z_play.c | 9 +++++++-- mm/src/code/z_visfbuf.c | 4 ++-- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/mm/2s2h/framebuffer_effects.c b/mm/2s2h/framebuffer_effects.c index 7cfe2c95b..7bebb34e9 100644 --- a/mm/2s2h/framebuffer_effects.c +++ b/mm/2s2h/framebuffer_effects.c @@ -5,7 +5,9 @@ int gfx_create_framebuffer(uint32_t width, uint32_t height); s32 gPauseFrameBuffer = -1; s32 gBlurFrameBuffer = -1; -s32 gShrinkFrameBuffer = -1; +// A framebuffer that should only be used for drawing in the same frame that it is copied too +// i.e. the VisMono and VisFbuf effects +s32 gReusableFrameBuffer = -1; void FB_CreateFramebuffers(void) { if (gPauseFrameBuffer == -1) { @@ -16,8 +18,8 @@ void FB_CreateFramebuffers(void) { gBlurFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT); } - if (gShrinkFrameBuffer == -1) { - gShrinkFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT); + if (gReusableFrameBuffer == -1) { + gReusableFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT); } } diff --git a/mm/2s2h/framebuffer_effects.h b/mm/2s2h/framebuffer_effects.h index 808af2203..e8bd9aba4 100644 --- a/mm/2s2h/framebuffer_effects.h +++ b/mm/2s2h/framebuffer_effects.h @@ -5,7 +5,7 @@ extern s32 gPauseFrameBuffer; extern s32 gBlurFrameBuffer; -extern s32 gShrinkFrameBuffer; +extern s32 gReusableFrameBuffer; 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_play.c b/mm/src/code/z_play.c index 51baee7c4..305e1f687 100644 --- a/mm/src/code/z_play.c +++ b/mm/src/code/z_play.c @@ -1276,8 +1276,13 @@ void Play_DrawMain(PlayState* this) { TransitionFade_Draw(&this->unk_18E48, &sp218); if (gVisMonoColor.a != 0) { - sPlayVisMono.primColor.rgba = gVisMonoColor.rgba; - VisMono_Draw(&sPlayVisMono, &sp218); + // 2S2H [Port] Implement VisMono by performing a framebuffer copy and redraw with an active + // grayscale command to set the mono color + FB_CopyToFramebuffer(&sp218, 0, gReusableFrameBuffer, false, NULL); + gDPSetGrayscaleColor(sp218++, gVisMonoColor.r, gVisMonoColor.g, gVisMonoColor.b, gVisMonoColor.a); + gSPGrayscale(sp218++, true); + FB_DrawFromFramebuffer(&sp218, gReusableFrameBuffer, 255); + gSPGrayscale(sp218++, false); } gSPEndDisplayList(sp218++); diff --git a/mm/src/code/z_visfbuf.c b/mm/src/code/z_visfbuf.c index bf777d986..b1d3fa4e1 100644 --- a/mm/src/code/z_visfbuf.c +++ b/mm/src/code/z_visfbuf.c @@ -170,7 +170,7 @@ void VisFbuf_ApplyEffects(VisFbuf* this, Gfx** gfxP, void* source, void* img, s3 G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_COPY | G_PM_NPRIMITIVE, G_AC_NONE | G_ZS_PIXEL | G_RM_NOOP | G_RM_NOOP2); - FB_CopyToFramebuffer(&gfx, 0, gShrinkFrameBuffer, false, NULL); + FB_CopyToFramebuffer(&gfx, 0, gReusableFrameBuffer, false, NULL); gDPPipeSync(gfx++); // fill framebuffer with primColor @@ -224,7 +224,7 @@ void VisFbuf_ApplyEffects(VisFbuf* this, Gfx** gfxP, void* source, void* img, s3 // 2S2H [Port][Widescreen] // Draw shrunk window using an adjusted horizontal scale accounting for different aspect ratios - FB_DrawFromFramebufferScaled(&gfx, gShrinkFrameBuffer, 255, + FB_DrawFromFramebufferScaled(&gfx, gReusableFrameBuffer, 255, (1.0f - scale) * (OTRGetAspectRatio() / ((float)SCREEN_WIDTH / SCREEN_HEIGHT)), (1.0f - scale)); }