From f2b89a97367d4a5402cfe6c871dbbee542f80f59 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:30:21 +0000 Subject: [PATCH] video_patches: improve movie aspect ratio correction, support intro logos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: DarĂ­o <538504+DarioSamo@users.noreply.github.com> Co-Authored-By: Skyth (Asilkan) <19259897+blueskythlikesclouds@users.noreply.github.com> --- UnleashedRecomp/api/SWA.inl | 9 ++ .../Utility/SequencePlayMovieWrapper.h | 16 +-- UnleashedRecomp/gpu/shader/movie_ps.hlsl | 4 + UnleashedRecomp/patches/video_patches.cpp | 122 +++++++----------- UnleashedRecompLib/config/SWA.toml | 10 +- 5 files changed, 67 insertions(+), 94 deletions(-) diff --git a/UnleashedRecomp/api/SWA.inl b/UnleashedRecomp/api/SWA.inl index acffd8fc..757f45bd 100644 --- a/UnleashedRecomp/api/SWA.inl +++ b/UnleashedRecomp/api/SWA.inl @@ -19,3 +19,12 @@ GuestToHostFunction(*(be*)(g_memory.Translate(*(be*)(this) + (4 * virtualIndex))), __VA_ARGS__) struct swa_null_ctor {}; + +struct Vertex +{ + be X; + be Y; + be Z; + be U; + be V; +}; diff --git a/UnleashedRecomp/api/SWA/Sequence/Utility/SequencePlayMovieWrapper.h b/UnleashedRecomp/api/SWA/Sequence/Utility/SequencePlayMovieWrapper.h index a73c7add..b4a69830 100644 --- a/UnleashedRecomp/api/SWA/Sequence/Utility/SequencePlayMovieWrapper.h +++ b/UnleashedRecomp/api/SWA/Sequence/Utility/SequencePlayMovieWrapper.h @@ -16,18 +16,10 @@ namespace SWA::Sequence::Utility be m_MovieWidth; be m_MovieHeight; SWA_INSERT_PADDING(0x74); - be m_TopLeftX; - be m_TopLeftY; - SWA_INSERT_PADDING(0x0C); - be m_TopRightX; - be m_TopRightY; - SWA_INSERT_PADDING(0x0C); - be m_BottomRightX; - be m_BottomRightY; - SWA_INSERT_PADDING(0x0C); - be m_BottomLeftX; - be m_BottomLeftY; - SWA_INSERT_PADDING(0xD4); + Vertex m_TopLeft; + Vertex m_TopRight; + Vertex m_BottomRight; + Vertex m_BottomLeft; bool m_MaintainAspectRatio; SWA_INSERT_PADDING(0x18); be m_TimeElapsed; diff --git a/UnleashedRecomp/gpu/shader/movie_ps.hlsl b/UnleashedRecomp/gpu/shader/movie_ps.hlsl index f60e5fe9..ec441a1d 100644 --- a/UnleashedRecomp/gpu/shader/movie_ps.hlsl +++ b/UnleashedRecomp/gpu/shader/movie_ps.hlsl @@ -92,6 +92,10 @@ PixelShaderOutput main(in Interpolators In) Out.Color.b = ValY + ValU * 2.017; } Out.Color.a = ValA; + + if (any(In.UV < 0.0) || any(In.UV > 1.0)) + Out.Color.rgb = 0.0; + Out.Depth = ValD; return Out; } diff --git a/UnleashedRecomp/patches/video_patches.cpp b/UnleashedRecomp/patches/video_patches.cpp index 520205ef..849d31f6 100644 --- a/UnleashedRecomp/patches/video_patches.cpp +++ b/UnleashedRecomp/patches/video_patches.cpp @@ -2,93 +2,61 @@ #include #include -SWA::Sequence::Utility::CPlayMovieWrapper::CRender* g_pPlayMovieWrapperRender; - -// TODO: to be removed. -constexpr float m_baseAspectRatio = 16.0f / 9.0f; - -// TODO: to be removed. -void CSDAspectRatioMidAsmHook(PPCRegister& f1, PPCRegister& f2) +// Update movie player aspect ratio. +PPC_FUNC_IMPL(__imp__sub_82AE30D8); +PPC_FUNC(sub_82AE30D8) { - if (Config::UIScaleMode == EUIScaleMode::Stretch) - return; + auto movieWidth = *(be*)g_memory.Translate(ctx.r4.u32 - 0x10); + auto movieHeight = *(be*)g_memory.Translate(ctx.r4.u32 - 0x0C); + auto movieAspectRatio = movieWidth / movieHeight; + auto windowAspectRatio = (float)GameWindow::s_width / (float)GameWindow::s_height; - auto newAspectRatio = (float)GameWindow::s_width / (float)GameWindow::s_height; + auto pTopLeft = (Vertex*)g_memory.Translate(ctx.r4.u32 + 0x6C); + auto pTopRight = (Vertex*)g_memory.Translate(ctx.r4.u32 + 0x6C + sizeof(Vertex)); + auto pBottomRight = (Vertex*)g_memory.Translate(ctx.r4.u32 + 0x6C + sizeof(Vertex) * 2); + auto pBottomLeft = (Vertex*)g_memory.Translate(ctx.r4.u32 + 0x6C + sizeof(Vertex) * 3); - if (newAspectRatio > m_baseAspectRatio) + auto a = -1.00078f; + auto b = 1.00139f; + auto scaleU = 1.0f; + auto scaleV = 1.0f; + auto centreV = (pTopLeft->V + pBottomRight->V) / 2.0f; + + if (windowAspectRatio > movieAspectRatio) { - f1.f64 = 1280.0f / ((newAspectRatio * 720.0f) / 1280.0f); + scaleU = movieAspectRatio / windowAspectRatio; } - else if (newAspectRatio < m_baseAspectRatio) + else { - f2.f64 = 720.0f / ((1280.0f / newAspectRatio) / 720.0f); + scaleV = windowAspectRatio / movieAspectRatio; } + + pTopLeft->X = a; + pTopLeft->Y = b; + pTopLeft->U = (pTopLeft->U - centreV) / scaleU + centreV; + pTopLeft->V = (pTopLeft->V - centreV) / scaleV + centreV; + + pTopRight->X = b; + pTopRight->Y = b; + pTopRight->U = (pTopRight->U - centreV) / scaleU + centreV; + pTopRight->V = (pTopRight->V - centreV) / scaleV + centreV; + + pBottomLeft->X = a; + pBottomLeft->Y = a; + pBottomLeft->U = (pBottomLeft->U - centreV) / scaleU + centreV; + pBottomLeft->V = (pBottomLeft->V - centreV) / scaleV + centreV; + + pBottomRight->X = b; + pBottomRight->Y = a; + pBottomRight->U = (pBottomRight->U - centreV) / scaleU + centreV; + pBottomRight->V = (pBottomRight->V - centreV) / scaleV + centreV; + + __imp__sub_82AE30D8(ctx, base); } +void RemoveMoviePlayerLetterboxMidAsmHook() {} + bool MotionBlurMidAsmHook() { return Config::MotionBlur != EMotionBlur::Off; } - -// SWA::Sequence::Utility::CPlayMovieWrapper::CRender -PPC_FUNC_IMPL(__imp__sub_82B732F8); -PPC_FUNC(sub_82B732F8) -{ - g_pPlayMovieWrapperRender = (SWA::Sequence::Utility::CPlayMovieWrapper::CRender*)g_memory.Translate(ctx.r3.u32); - - __imp__sub_82B732F8(ctx, base); -} - -// SWA::Sequence::Utility::CPlayMovieWrapper::~CRender -PPC_FUNC_IMPL(__imp__sub_82B71FB0); -PPC_FUNC(sub_82B71FB0) -{ - g_pPlayMovieWrapperRender = nullptr; - - __imp__sub_82B71FB0(ctx, base); -} - -// Update movie player dimensions. -PPC_FUNC_IMPL(__imp__sub_82AE2F08); -PPC_FUNC(sub_82AE2F08) -{ - __imp__sub_82AE2F08(ctx, base); - - if (!g_pPlayMovieWrapperRender) - return; - - // Disable aspect ratio changes so we can do our own. - g_pPlayMovieWrapperRender->m_MaintainAspectRatio = false; - - auto videoAspectRatio = g_pPlayMovieWrapperRender->m_MovieWidth / g_pPlayMovieWrapperRender->m_MovieHeight; - auto windowAspectRatio = (float)GameWindow::s_width / (float)GameWindow::s_height; - - float sx, sy, x, y; - - if (windowAspectRatio > videoAspectRatio) - { - // Pillarbox. - sy = 1.0f; - sx = sy * videoAspectRatio / windowAspectRatio; - x = (1.0f - sx) / 2.0f; - y = 0.0f; - } - else - { - // Letterbox. - sx = 1.0f; - sy = sx * windowAspectRatio / videoAspectRatio; - x = 0.0f; - y = (1.0f - sy) / 2.0f; - } - - // TODO: use ImGui element to draw letter/pillarbox over screen edges. - g_pPlayMovieWrapperRender->m_TopLeftX = -1.0f + x * 2.0f; - g_pPlayMovieWrapperRender->m_TopLeftY = 1.0f - y * 2.0f; - g_pPlayMovieWrapperRender->m_TopRightX = -1.0f + (x + sx) * 2.0f; - g_pPlayMovieWrapperRender->m_TopRightY = 1.0f - y * 2.0f; - g_pPlayMovieWrapperRender->m_BottomLeftX = -1.0f + x * 2.0f; - g_pPlayMovieWrapperRender->m_BottomLeftY = 1.0f - (y + sy) * 2.0f; - g_pPlayMovieWrapperRender->m_BottomRightX = -1.0f + (x + sx) * 2.0f; - g_pPlayMovieWrapperRender->m_BottomRightY = 1.0f - (y + sy) * 2.0f; -} diff --git a/UnleashedRecompLib/config/SWA.toml b/UnleashedRecompLib/config/SWA.toml index 91084cc8..9ece1abe 100644 --- a/UnleashedRecompLib/config/SWA.toml +++ b/UnleashedRecompLib/config/SWA.toml @@ -102,11 +102,6 @@ address = 0x8246BDA0 registers = ["r31", "f0", "f10", "f12"] jump_address_on_true = 0x8246BDAC -[[midasm_hook]] -name = "CSDAspectRatioMidAsmHook" -address = 0x830C0A28 -registers = ["f1", "f2"] - [[midasm_hook]] name = "ResetScoreOnRestartMidAsmHook" address = 0x82304374 @@ -590,3 +585,8 @@ address = 0x825360C8 registers = ["r31"] jump_address_on_true = 0x825360C8 jump_address_on_false = 0x82536140 + +[[midasm_hook]] +name = "RemoveMoviePlayerLetterboxMidAsmHook" +address = 0x82B723A8 +jump_address = 0x82B723BC