diff --git a/include/recomp_ui.h b/include/recomp_ui.h index f4d99c4..715574a 100644 --- a/include/recomp_ui.h +++ b/include/recomp_ui.h @@ -55,6 +55,7 @@ namespace recomp { void destroy_ui(); void apply_color_hack(); + void get_window_size(int& width, int& height); } #endif diff --git a/patches/graphics.h b/patches/graphics.h new file mode 100644 index 0000000..82d8f86 --- /dev/null +++ b/patches/graphics.h @@ -0,0 +1,8 @@ +#ifndef __PATCH_GRAPHICS_H__ +#define __PATCH_GRAPHICS_H__ + +#include "patch_helpers.h" + +DECLARE_FUNC(float, recomp_get_aspect_ratio); + +#endif diff --git a/patches/syms.ld b/patches/syms.ld index b964e73..97eeecc 100644 --- a/patches/syms.ld +++ b/patches/syms.ld @@ -8,3 +8,4 @@ recomp_handle_quicksave_actions_main = 0x8100000C; osRecvMesg_recomp = 0x81000010; osSendMesg_recomp = 0x81000014; recomp_get_gyro_deltas = 0x81000018; +recomp_get_aspect_ratio = 0x8100001C; diff --git a/patches/widescreen_effect_fixes.c b/patches/widescreen_effect_fixes.c new file mode 100644 index 0000000..5cff1e6 --- /dev/null +++ b/patches/widescreen_effect_fixes.c @@ -0,0 +1,43 @@ +#include "patches.h" +#include "graphics.h" + +extern TransitionOverlay gTransitionOverlayTable[]; +extern Gfx sTransWipe3DL[]; + +#define THIS ((TransitionWipe3*)thisx) +// @recomp patched to scale the transition based on aspect ratio +void TransitionWipe3_Draw(void* thisx, Gfx** gfxP) { + Gfx* gfx = *gfxP; + Mtx* modelView = &THIS->modelView[THIS->frame]; + f32 scale = 14.8f; + Gfx* texScroll; + + // @recomp Modify the scale based on the aspect ratio to make sure the transition circle covers the whole screen + scale *= (recomp_get_aspect_ratio() / (4.0f / 3.0f)); + + THIS->frame ^= 1; + gDPPipeSync(gfx++); + texScroll = Gfx_BranchTexScroll(&gfx, THIS->scrollX, THIS->scrollY, 16, 64); + gSPSegment(gfx++, 0x09, texScroll); + gSPSegment(gfx++, 0x08, THIS->curTexture); + gDPSetColor(gfx++, G_SETPRIMCOLOR, THIS->color.rgba); + gDPSetColor(gfx++, G_SETENVCOLOR, THIS->color.rgba); + gSPMatrix(gfx++, &THIS->projection, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + gSPPerspNormalize(gfx++, THIS->normal); + gSPMatrix(gfx++, &THIS->lookAt, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION); + + if (scale != 1.0f) { + guScale(modelView, scale, scale, 1.0f); + gSPMatrix(gfx++, modelView, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + } + // sTransWipe3DL is an overlay symbol, so its addresses need to be offset to get the actual loaded vram address. + // TODO remove this once the recompiler is able to handle overlay symbols automatically for patch functions. + ptrdiff_t reloc_offset; + TransitionOverlay* overlay_entry = &gTransitionOverlayTable[FBDEMO_WIPE3]; + reloc_offset = (uintptr_t)Lib_PhysicalToVirtual(overlay_entry->loadInfo.addr) - (uintptr_t)overlay_entry->vramStart; + gSPDisplayList(gfx++, (Gfx*)((u8*)sTransWipe3DL + reloc_offset)); + gDPPipeSync(gfx++); + *gfxP = gfx; +} + +#undef THIS \ No newline at end of file diff --git a/src/game/controls.cpp b/src/game/controls.cpp index 4bc0b99..c9ff3a4 100644 --- a/src/game/controls.cpp +++ b/src/game/controls.cpp @@ -4,6 +4,7 @@ #include "recomp_input.h" #include "../ultramodern/ultramodern.hpp" #include "../patches/input.h" +#include "../patches/graphics.h" // Arrays that hold the mappings for every input for keyboard and controller respectively. using input_mapping = std::array; @@ -127,3 +128,11 @@ extern "C" void recomp_get_gyro_deltas(uint8_t* rdram, recomp_context* ctx) { recomp::get_gyro_deltas(x_out, y_out); } + +#include "recomp_ui.h" +extern "C" void recomp_get_aspect_ratio(uint8_t* rdram, recomp_context* ctx) { + int width, height; + recomp::get_window_size(width, height); + + _return(ctx, static_cast(width) / height); +} diff --git a/src/ui/ui_renderer.cpp b/src/ui/ui_renderer.cpp index 222e8b4..b0c2ec7 100644 --- a/src/ui/ui_renderer.cpp +++ b/src/ui/ui_renderer.cpp @@ -877,6 +877,10 @@ struct { // TODO make this not be global extern SDL_Window* window; +void recomp::get_window_size(int& width, int& height) { + SDL_GetWindowSizeInPixels(window, &width, &height); +} + void init_hook(RT64::RenderInterface* interface, RT64::RenderDevice* device) { printf("RT64 hook init\n");