From 9a29b187cd5a2492960819df789d9bc923c4d018 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Sun, 12 Jan 2025 15:53:31 +0000 Subject: [PATCH] Implemented support for maintaining aspect ratio for movies (#73) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * video_patches: aspect ratio support for CPlayMovieWrapper * config: remove movie scale mode option * 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> * api: upload Inspire research * api: move Vertex struct --------- 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.h | 4 ++ .../api/SWA/Inspire/InspireMovieOverlay.h | 17 ++++++ .../api/SWA/Inspire/InspireMovieOverlayInfo.h | 17 ++++++ .../api/SWA/Inspire/InspireTextureOverlay.h | 18 ++++++ .../SWA/Inspire/InspireTextureOverlayInfo.h | 15 +++++ .../Utility/SequencePlayMovieWrapper.h | 25 ++++---- UnleashedRecomp/gpu/shader/movie_ps.hlsl | 4 ++ UnleashedRecomp/locale/config_locale.cpp | 17 ------ UnleashedRecomp/patches/video_patches.cpp | 57 +++++++++++++++---- UnleashedRecomp/ui/options_menu.cpp | 1 - .../ui/options_menu_thumbnails.cpp | 1 - UnleashedRecomp/user/config.h | 15 ----- UnleashedRecompLib/config/SWA.toml | 10 ++-- 13 files changed, 139 insertions(+), 62 deletions(-) create mode 100644 UnleashedRecomp/api/SWA/Inspire/InspireMovieOverlay.h create mode 100644 UnleashedRecomp/api/SWA/Inspire/InspireMovieOverlayInfo.h create mode 100644 UnleashedRecomp/api/SWA/Inspire/InspireTextureOverlay.h create mode 100644 UnleashedRecomp/api/SWA/Inspire/InspireTextureOverlayInfo.h diff --git a/UnleashedRecomp/api/SWA.h b/UnleashedRecomp/api/SWA.h index bc40f81..35155ef 100644 --- a/UnleashedRecomp/api/SWA.h +++ b/UnleashedRecomp/api/SWA.h @@ -60,6 +60,10 @@ #include "SWA/HUD/Pause/HudPause.h" #include "SWA/HUD/SaveIcon/SaveIcon.h" #include "SWA/HUD/Sonic/HudSonicStage.h" +#include "SWA/Inspire/InspireMovieOverlay.h" +#include "SWA/Inspire/InspireMovieOverlayInfo.h" +#include "SWA/Inspire/InspireTextureOverlay.h" +#include "SWA/Inspire/InspireTextureOverlayInfo.h" #include "SWA/Movie/MovieDisplayer.h" #include "SWA/Movie/MovieManager.h" #include "SWA/Player/Character/EvilSonic/EvilSonic.h" diff --git a/UnleashedRecomp/api/SWA/Inspire/InspireMovieOverlay.h b/UnleashedRecomp/api/SWA/Inspire/InspireMovieOverlay.h new file mode 100644 index 0000000..1753668 --- /dev/null +++ b/UnleashedRecomp/api/SWA/Inspire/InspireMovieOverlay.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +namespace SWA::Inspire +{ + class CScene; + + class CMovieOverlay + { + public: + boost::shared_ptr m_spInfo; + xpointer m_pScene; + xpointer m_pTextureData; + }; +} diff --git a/UnleashedRecomp/api/SWA/Inspire/InspireMovieOverlayInfo.h b/UnleashedRecomp/api/SWA/Inspire/InspireMovieOverlayInfo.h new file mode 100644 index 0000000..3443d63 --- /dev/null +++ b/UnleashedRecomp/api/SWA/Inspire/InspireMovieOverlayInfo.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +namespace SWA::Inspire +{ + class CMovieOverlayInfo + { + public: + Hedgehog::Base::CSharedString m_MovieName; + be m_StartTime; + be m_FadeInStartTime; + be m_FadeInEndTime; + be m_FadeOutStartTime; + be m_FadeOutEndTime; + }; +} diff --git a/UnleashedRecomp/api/SWA/Inspire/InspireTextureOverlay.h b/UnleashedRecomp/api/SWA/Inspire/InspireTextureOverlay.h new file mode 100644 index 0000000..b6e1986 --- /dev/null +++ b/UnleashedRecomp/api/SWA/Inspire/InspireTextureOverlay.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +namespace SWA::Inspire +{ + class CScene; + + class CTextureOverlay + { + public: + xpointer m_pVftable; + boost::shared_ptr m_spInfo; + xpointer m_pScene; + boost::shared_ptr m_spTextureData; + }; +} diff --git a/UnleashedRecomp/api/SWA/Inspire/InspireTextureOverlayInfo.h b/UnleashedRecomp/api/SWA/Inspire/InspireTextureOverlayInfo.h new file mode 100644 index 0000000..3befa01 --- /dev/null +++ b/UnleashedRecomp/api/SWA/Inspire/InspireTextureOverlayInfo.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace SWA::Inspire +{ + class CInspireTextureOverlayInfo + { + public: + Hedgehog::Base::CSharedString m_CameraName; + be m_Unk1; + be m_Unk2; + be m_Unk3; + }; +} diff --git a/UnleashedRecomp/api/SWA/Sequence/Utility/SequencePlayMovieWrapper.h b/UnleashedRecomp/api/SWA/Sequence/Utility/SequencePlayMovieWrapper.h index a73c7ad..a10d6f6 100644 --- a/UnleashedRecomp/api/SWA/Sequence/Utility/SequencePlayMovieWrapper.h +++ b/UnleashedRecomp/api/SWA/Sequence/Utility/SequencePlayMovieWrapper.h @@ -11,23 +11,24 @@ namespace SWA::Sequence::Utility class CRender : public Hedgehog::Mirage::CRenderable { public: + struct SVertexData + { + be X; + be Y; + be Z; + be U; + be V; + }; + be m_ScreenWidth; be m_ScreenHeight; 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); + SVertexData m_TopLeft; + SVertexData m_TopRight; + SVertexData m_BottomRight; + SVertexData 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 f60e5fe..ec441a1 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/locale/config_locale.cpp b/UnleashedRecomp/locale/config_locale.cpp index ed330b4..d617929 100644 --- a/UnleashedRecomp/locale/config_locale.cpp +++ b/UnleashedRecomp/locale/config_locale.cpp @@ -275,23 +275,6 @@ CONFIG_DEFINE_LOCALE(XboxColorCorrection) { ELanguage::English, { "Xbox Color Correction", "Use the warm tint from the Xbox version of the game." } } }; -CONFIG_DEFINE_LOCALE(MovieScaleMode) -{ - { ELanguage::English, { "Movie Scale Mode", "Change how the movie player scales to the display." } } -}; - -CONFIG_DEFINE_ENUM_LOCALE(EMovieScaleMode) -{ - { - ELanguage::English, - { - { EMovieScaleMode::Stretch, { "STRETCH", "Stretch: the movie will stretch to the display." } }, - { EMovieScaleMode::Fit, { "FIT", "Fit: the movie will maintain its aspect ratio and fit to the display." } }, - { EMovieScaleMode::Fill, { "FILL", "Fill: the movie will scale past the bounds of the display if it doesn't match the aspect ratio." } }, - } - } -}; - CONFIG_DEFINE_LOCALE(UIScaleMode) { { ELanguage::English, { "UI Scale Mode", "Change how the UI scales to the display." } } diff --git a/UnleashedRecomp/patches/video_patches.cpp b/UnleashedRecomp/patches/video_patches.cpp index cbe4ce5..04fde68 100644 --- a/UnleashedRecomp/patches/video_patches.cpp +++ b/UnleashedRecomp/patches/video_patches.cpp @@ -2,27 +2,62 @@ #include #include -// TODO: to be removed. -constexpr float m_baseAspectRatio = 16.0f / 9.0f; +using SVertexData = SWA::Sequence::Utility::CPlayMovieWrapper::CRender::SVertexData; -// 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 = (SVertexData*)g_memory.Translate(ctx.r4.u32 + 0x6C); + auto pTopRight = (SVertexData*)g_memory.Translate(ctx.r4.u32 + 0x6C + sizeof(SVertexData)); + auto pBottomRight = (SVertexData*)g_memory.Translate(ctx.r4.u32 + 0x6C + sizeof(SVertexData) * 2); + auto pBottomLeft = (SVertexData*)g_memory.Translate(ctx.r4.u32 + 0x6C + sizeof(SVertexData) * 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; diff --git a/UnleashedRecomp/ui/options_menu.cpp b/UnleashedRecomp/ui/options_menu.cpp index bb67687..0e27b99 100644 --- a/UnleashedRecomp/ui/options_menu.cpp +++ b/UnleashedRecomp/ui/options_menu.cpp @@ -910,7 +910,6 @@ static void DrawConfigOptions() DrawConfigOption(rowCount++, yOffset, &Config::GITextureFiltering, true); DrawConfigOption(rowCount++, yOffset, &Config::MotionBlur, true); DrawConfigOption(rowCount++, yOffset, &Config::XboxColorCorrection, true); - DrawConfigOption(rowCount++, yOffset, &Config::MovieScaleMode, true); DrawConfigOption(rowCount++, yOffset, &Config::UIScaleMode, true); break; diff --git a/UnleashedRecomp/ui/options_menu_thumbnails.cpp b/UnleashedRecomp/ui/options_menu_thumbnails.cpp index dc1701e..40f238e 100644 --- a/UnleashedRecomp/ui/options_menu_thumbnails.cpp +++ b/UnleashedRecomp/ui/options_menu_thumbnails.cpp @@ -117,7 +117,6 @@ void LoadThumbnails() g_xboxColorCorrectionThumbnails[false] = LOAD_ZSTD_TEXTURE(g_xbox_color_correction_false); g_xboxColorCorrectionThumbnails[true] = LOAD_ZSTD_TEXTURE(g_xbox_color_correction_true); - g_configThumbnails[&Config::MovieScaleMode] = LOAD_ZSTD_TEXTURE(g_movie_scale_mode); g_configThumbnails[&Config::UIScaleMode] = LOAD_ZSTD_TEXTURE(g_ui_scale_mode); } diff --git a/UnleashedRecomp/user/config.h b/UnleashedRecomp/user/config.h index 0f335fb..157f3f0 100644 --- a/UnleashedRecomp/user/config.h +++ b/UnleashedRecomp/user/config.h @@ -252,20 +252,6 @@ CONFIG_DEFINE_ENUM_TEMPLATE(EMotionBlur) { "Enhanced", EMotionBlur::Enhanced } }; -enum class EMovieScaleMode : uint32_t -{ - Stretch, - Fit, - Fill -}; - -CONFIG_DEFINE_ENUM_TEMPLATE(EMovieScaleMode) -{ - { "Stretch", EMovieScaleMode::Stretch }, - { "Fit", EMovieScaleMode::Fit }, - { "Fill", EMovieScaleMode::Fill } -}; - enum class EUIScaleMode : uint32_t { Stretch, @@ -662,7 +648,6 @@ public: CONFIG_DEFINE_ENUM("Video", EDepthOfFieldQuality, DepthOfFieldQuality, EDepthOfFieldQuality::Auto); CONFIG_DEFINE_ENUM_LOCALISED("Video", EMotionBlur, MotionBlur, EMotionBlur::Original); CONFIG_DEFINE_LOCALISED("Video", bool, XboxColorCorrection, false); - CONFIG_DEFINE_ENUM_LOCALISED("Video", EMovieScaleMode, MovieScaleMode, EMovieScaleMode::Fit); CONFIG_DEFINE_ENUM_LOCALISED("Video", EUIScaleMode, UIScaleMode, EUIScaleMode::Edge); // TODO: remove these once the exports are implemented. diff --git a/UnleashedRecompLib/config/SWA.toml b/UnleashedRecompLib/config/SWA.toml index 91084cc..9ece1ab 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