video_patches: improve movie aspect ratio correction, support intro logos

Co-Authored-By: Darío <538504+DarioSamo@users.noreply.github.com>
Co-Authored-By: Skyth (Asilkan) <19259897+blueskythlikesclouds@users.noreply.github.com>
This commit is contained in:
Hyper 2025-01-10 16:30:21 +00:00
parent 33b5be28d1
commit f2b89a9736
5 changed files with 67 additions and 94 deletions

View file

@ -19,3 +19,12 @@
GuestToHostFunction<returnType>(*(be<uint32_t>*)(g_memory.Translate(*(be<uint32_t>*)(this) + (4 * virtualIndex))), __VA_ARGS__)
struct swa_null_ctor {};
struct Vertex
{
be<float> X;
be<float> Y;
be<float> Z;
be<float> U;
be<float> V;
};

View file

@ -16,18 +16,10 @@ namespace SWA::Sequence::Utility
be<float> m_MovieWidth;
be<float> m_MovieHeight;
SWA_INSERT_PADDING(0x74);
be<float> m_TopLeftX;
be<float> m_TopLeftY;
SWA_INSERT_PADDING(0x0C);
be<float> m_TopRightX;
be<float> m_TopRightY;
SWA_INSERT_PADDING(0x0C);
be<float> m_BottomRightX;
be<float> m_BottomRightY;
SWA_INSERT_PADDING(0x0C);
be<float> m_BottomLeftX;
be<float> 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<float> m_TimeElapsed;

View file

@ -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;
}

View file

@ -2,93 +2,61 @@
#include <api/SWA.h>
#include <ui/game_window.h>
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<float>*)g_memory.Translate(ctx.r4.u32 - 0x10);
auto movieHeight = *(be<float>*)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;
}

View file

@ -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