From 19c3c3f5c18105bf079f628db9c01154a03034dc Mon Sep 17 00:00:00 2001 From: Archez Date: Thu, 11 Apr 2024 19:08:44 -0400 Subject: [PATCH] Implement HIRES support and fix Bombers notebook (#181) * Implement HIRES support and fix Bombers notebook * bump lus --- libultraship | 2 +- mm/2s2h/BenPort.cpp | 5 +++-- mm/2s2h/framebuffer_effects.c | 8 ++++---- mm/src/code/sys_cfb.c | 7 +++++++ mm/src/code/z_play.c | 16 ++++++++++++++-- mm/src/code/z_play_hireso.c | 17 ++++++++++++++--- 6 files changed, 43 insertions(+), 12 deletions(-) diff --git a/libultraship b/libultraship index 86bdd4654..682fbb9ed 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 86bdd465478dae2c929a65ca48ca3ac54eceef43 +Subproject commit 682fbb9ed6fbbb4b514fcbe6c8bfc2ed97b5d8b5 diff --git a/mm/2s2h/BenPort.cpp b/mm/2s2h/BenPort.cpp index 49e9a86f8..3b9f0359c 100644 --- a/mm/2s2h/BenPort.cpp +++ b/mm/2s2h/BenPort.cpp @@ -1397,11 +1397,12 @@ extern "C" float OTRGetAspectRatio() { } extern "C" float OTRGetDimensionFromLeftEdge(float v) { - return (SCREEN_WIDTH / 2 - SCREEN_HEIGHT / 2 * OTRGetAspectRatio() + (v)); + return (gfx_native_dimensions.width / 2 - gfx_native_dimensions.height / 2 * OTRGetAspectRatio() + (v)); } extern "C" float OTRGetDimensionFromRightEdge(float v) { - return (SCREEN_WIDTH / 2 + SCREEN_HEIGHT / 2 * OTRGetAspectRatio() - (SCREEN_WIDTH - v)); + return (gfx_native_dimensions.width / 2 + gfx_native_dimensions.height / 2 * OTRGetAspectRatio() - + (gfx_native_dimensions.width - v)); } // Gets the width of the current render target area diff --git a/mm/2s2h/framebuffer_effects.c b/mm/2s2h/framebuffer_effects.c index ec6043ae9..2c8bca0b4 100644 --- a/mm/2s2h/framebuffer_effects.c +++ b/mm/2s2h/framebuffer_effects.c @@ -1,7 +1,7 @@ #include "framebuffer_effects.h" #include "global.h" -int gfx_create_framebuffer(uint32_t width, uint32_t height); +int gfx_create_framebuffer(uint32_t width, uint32_t height, uint32_t native_width, uint32_t native_height); s32 gPauseFrameBuffer = -1; s32 gBlurFrameBuffer = -1; @@ -11,15 +11,15 @@ s32 gReusableFrameBuffer = -1; void FB_CreateFramebuffers(void) { if (gPauseFrameBuffer == -1) { - gPauseFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT); + gPauseFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT); } if (gBlurFrameBuffer == -1) { - gBlurFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT); + gBlurFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT); } if (gReusableFrameBuffer == -1) { - gReusableFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT); + gReusableFrameBuffer = gfx_create_framebuffer(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT); } } diff --git a/mm/src/code/sys_cfb.c b/mm/src/code/sys_cfb.c index 14cd50b3a..c8565759b 100644 --- a/mm/src/code/sys_cfb.c +++ b/mm/src/code/sys_cfb.c @@ -3,6 +3,7 @@ #include "functions.h" #include "macros.h" #include "2s2h/framebuffer_effects.h" +#include // Variables are put before most headers as a hacky way to bypass bss reordering OSViMode sNotebookViMode; // placeholder name @@ -59,6 +60,9 @@ void SysCfb_SetLoResMode(void) { gScreenWidth = gCfbWidth; gScreenHeight = gCfbHeight; //gActiveViMode = &osViModeNtscLan1; + + // 2S2H [Port] Inform LUS on resolution changes + GfxSetNativeDimensions((uint32_t)gScreenWidth, (uint32_t)gScreenHeight); } void SysCfb_SetHiResMode(void) { @@ -90,6 +94,9 @@ void SysCfb_SetHiResMode(void) { gActiveViMode = &sNotebookViMode; } gSysCfbHiResEnabled = true; + + // 2S2H [Port] Inform LUS on resolution changes + GfxSetNativeDimensions((uint32_t)gScreenWidth, (uint32_t)gScreenHeight); } void SysCfb_Init(void) { diff --git a/mm/src/code/z_play.c b/mm/src/code/z_play.c index 305e1f687..2a123904e 100644 --- a/mm/src/code/z_play.c +++ b/mm/src/code/z_play.c @@ -45,6 +45,9 @@ u8 D_801D0D54 = false; PlayState* gPlayState; // #endregion +// Track when the notebook is closed so we can refresh our framebuffer captures +u8 sJustClosedBomberNotebook = false; + typedef enum { /* 0 */ MOTION_BLUR_OFF, /* 1 */ MOTION_BLUR_SETUP, @@ -94,7 +97,8 @@ void Play_DrawMotionBlur(PlayState* this) { // 2S2H [Port] When the render size changes, we need to skip the blur for one frame to // avoid rendering and copying a blank framebuffer if (sMotionBlurStatus == MOTION_BLUR_PROCESS && - (lastBlurWidth != OTRGetGameRenderWidth() || lastBlurHeight != OTRGetGameRenderHeight())) { + (lastBlurWidth != OTRGetGameRenderWidth() || lastBlurHeight != OTRGetGameRenderHeight() || + sJustClosedBomberNotebook)) { sMotionBlurStatus = MOTION_BLUR_SETUP; } @@ -405,6 +409,8 @@ void Play_Destroy(GameState* thisx) { gfxCtx->yScale = gViConfigYScale; gfxCtx->updateViMode = true; sBombersNotebookOpen = false; + + sJustClosedBomberNotebook = false; } BombersNotebook_Destroy(&sBombersNotebook); @@ -1091,6 +1097,8 @@ void Play_Update(PlayState* this) { sBombersNotebookOpen = true; sBombersNotebook.loadState = BOMBERS_NOTEBOOK_LOAD_STATE_NONE; } + + sJustClosedBomberNotebook = false; } else if (CHECK_BTN_ALL(CONTROLLER1(&this->state)->press.button, BTN_L) || CHECK_BTN_ALL(CONTROLLER1(&this->state)->press.button, BTN_B) || CHECK_BTN_ALL(CONTROLLER1(&this->state)->press.button, BTN_START) || (gIrqMgrResetStatus != 0)) { @@ -1102,6 +1110,8 @@ void Play_Update(PlayState* this) { this->msgCtx.currentTextId = 0; this->msgCtx.stateTimer = 0; Audio_PlaySfx(NA_SE_SY_CANCEL); + + sJustClosedBomberNotebook = true; } if (sBombersNotebookOpen) { BombersNotebook_Update(this, &sBombersNotebook, this->state.input); @@ -1173,7 +1183,7 @@ void Play_DrawMain(PlayState* this) { if ((R_PAUSE_BG_PRERENDER_STATE == PAUSE_BG_PRERENDER_PROCESS || R_PAUSE_BG_PRERENDER_STATE == PAUSE_BG_PRERENDER_READY) && (lastPauseWidth != OTRGetGameRenderWidth() || lastPauseHeight != OTRGetGameRenderHeight() || - !hasCapturedPauseBuffer)) { + !hasCapturedPauseBuffer || sJustClosedBomberNotebook)) { R_PAUSE_BG_PRERENDER_STATE = PAUSE_BG_PRERENDER_SETUP; recapturePauseBuffer = true; } @@ -2422,4 +2432,6 @@ void Play_Init(GameState* thisx) { gSaveContext.respawnFlag = 0; sBombersNotebookOpen = false; BombersNotebook_Init(&sBombersNotebook); + + sJustClosedBomberNotebook = false; } diff --git a/mm/src/code/z_play_hireso.c b/mm/src/code/z_play_hireso.c index 59df18458..3166b1e05 100644 --- a/mm/src/code/z_play_hireso.c +++ b/mm/src/code/z_play_hireso.c @@ -497,6 +497,11 @@ void BombersNotebook_DrawEntries(Gfx** gfxP, s32 row, u32 rectTop) { yOffset -= 6; } } + + // 2S2H [Port] We need to set the render mode to XLU_SURF for alpha logic to be used in Fast3D + // If Fast3D changes how it decides alpha in the future, we may be able to remove this line + gDPSetRenderMode(gfx++, G_RM_XLU_SURF, G_RM_XLU_SURF2); + gDPLoadTextureBlock(gfx++, sBombersNotebookEventIconTextures[eventIcon], G_IM_FMT_IA, G_IM_SIZ_8b, sBombersNotebookEventIconWidths[eventIcon], sBombersNotebookEventIconHeights[eventIcon], 0, G_TX_MIRROR | G_TX_WRAP, G_TX_MIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, @@ -841,7 +846,11 @@ void BombersNotebook_DrawTimeOfDay(Gfx** gfxP) { gDPSetPrimColor(gfx++, 0, 0, 242, 0, 14, 255); gDPLoadTextureBlock(gfx++, gBombersNotebookLineTex, G_IM_FMT_I, G_IM_SIZ_8b, 8, 1, 0, G_TX_MIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); - BombersNotebook_DrawScisTexRect(&gfx, lineRectLeft * 4, 74 * 4, (lineRectLeft + 32) * 4, 490 * 4, 0, 0, 0, 1 << 10, + + // 2S2H [Cosmetic] The vertical red line texture is only 8 pixels wide, but the rectangle draw 32 pixels wide. + // Because the texture is mirrored and wrap along the S axis, this caused there to be 3 lines + // Setting it to 8 replicates the effect from console + BombersNotebook_DrawScisTexRect(&gfx, lineRectLeft * 4, 74 * 4, (lineRectLeft + 8) * 4, 490 * 4, 0, 0, 0, 1 << 10, 1 << 10); gDPPipeSync(gfx++); @@ -1070,8 +1079,10 @@ void BombersNotebook_Draw(BombersNotebook* this, GraphicsContext* gfxCtx) { gDPLoadTextureBlock(gfx++, gBombersNotebookBackgroundTex, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD); - BombersNotebook_DrawScisTexRect(&gfx, 0 * 4, 0 * 4, SCREEN_WIDTH_HIRES * 4, SCREEN_HEIGHT_HIRES * 4, 0, 0, 0, - 0x200, 0x200); + // 2S2H [Cosmetic][Widescreen] Extend the background tiling for widescreens + gSPWideTextureRectangle(gfx++, OTRGetRectDimensionFromLeftEdge(0) * 4, 0 * 4, + OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH_HIRES) * 4, SCREEN_HEIGHT_HIRES * 4, 0, 0, + 0, 0x200, 0x200); gDPPipeSync(gfx++); gDPSetCombineMode(gfx++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);