diff --git a/UnleashedRecomp/patches/camera_patches.cpp b/UnleashedRecomp/patches/camera_patches.cpp index cea316e1..2351fe66 100644 --- a/UnleashedRecomp/patches/camera_patches.cpp +++ b/UnleashedRecomp/patches/camera_patches.cpp @@ -19,20 +19,19 @@ void CameraFieldOfViewMidAsmHook(PPCRegister& r31, PPCRegister& f31) { auto camera = (SWA::CCamera*)g_memory.Translate(r31.u32); - // Interpolate to the original 4:3 field of view for narrow aspect ratios. - if (camera->m_HorzAspectRatio < ORIGINAL_WIDESCREEN_ASPECT_RATIO) + // Replicate the original incorrect field of view formula if requested. + if (Config::AspectRatio == EAspectRatio::OriginalSquare) { - float factor = std::clamp((camera->m_HorzAspectRatio - ORIGINAL_ASPECT_RATIO) / (ORIGINAL_WIDESCREEN_ASPECT_RATIO - ORIGINAL_ASPECT_RATIO), 0.0f, 1.0f); - factor = ORIGINAL_ASPECT_RATIO + (1.0f - ORIGINAL_ASPECT_RATIO) * factor; - - f31.f64 *= factor; - - // For tall aspect ratios, use proper VERT+. - if (camera->m_HorzAspectRatio < ORIGINAL_ASPECT_RATIO) + if (abs(camera->m_HorzAspectRatio - ORIGINAL_ASPECT_RATIO) < 0.001f) { - f31.f64 = 2.0 * atan(tan(0.5 * f31.f64) / camera->m_HorzAspectRatio * ORIGINAL_ASPECT_RATIO); + f31.f64 *= ORIGINAL_ASPECT_RATIO; } } + // Use proper VERT+ otherwise for narrow aspect ratios. + else if (camera->m_HorzAspectRatio < ORIGINAL_WIDESCREEN_ASPECT_RATIO) + { + f31.f64 = 2.0 * atan(tan(0.5 * f31.f64) / camera->m_HorzAspectRatio * ORIGINAL_WIDESCREEN_ASPECT_RATIO); + } } PPC_FUNC_IMPL(__imp__sub_824697B0); diff --git a/UnleashedRecomp/patches/csd_patches.cpp b/UnleashedRecomp/patches/csd_patches.cpp index 3ed0de7a..dc15b584 100644 --- a/UnleashedRecomp/patches/csd_patches.cpp +++ b/UnleashedRecomp/patches/csd_patches.cpp @@ -154,6 +154,9 @@ void MakeCsdProjectMidAsmHook(PPCRegister& r3, PPCRegister& r29) static constexpr float ORIGINAL_ASPECT_RATIO = 4.0f / 3.0f; static constexpr float ORIGINAL_WIDESCREEN_ASPECT_RATIO = 16.0f / 9.0f; +static constexpr float INV_WIDESCREEN_ASPECT_RATIO = 1.0f / ORIGINAL_WIDESCREEN_ASPECT_RATIO; +static constexpr float INV_WIDESCREEN_SCALE = 1280.0f / 960.0f; +static constexpr float SQUARE_SCALE = 960.0f / 1280.0f; static float g_offsetX; static float g_offsetY; @@ -164,19 +167,37 @@ static float g_worldMapOffset; static void ComputeOffsets(float width, float height) { float aspectRatio = width / height; + g_scale = 1.0f; + if (aspectRatio >= ORIGINAL_ASPECT_RATIO) { + // height is locked to 720 in this case g_offsetX = 0.5f * (aspectRatio * 720.0f - 1280.0f); g_offsetY = 0.0f; + + // narrow resolutions will zoom the UI in, but we + // want the gameplay UI to retain the same scale + if (aspectRatio < ORIGINAL_WIDESCREEN_ASPECT_RATIO) + g_scale = aspectRatio / ORIGINAL_WIDESCREEN_ASPECT_RATIO; } else { - g_offsetX = 0.5f * (960.0f - 1280.0f); // width is locked to 960 in video.cpp + // width is locked to 960 in this case to have 4:3 crop + g_offsetX = 0.5f * (960.0f - 1280.0f); g_offsetY = 0.5f * (960.0f / aspectRatio - 720.0f); + + // scale to 16:9 as the aspect ratio becomes 9:16 + float factor = std::clamp((aspectRatio - INV_WIDESCREEN_ASPECT_RATIO) / (ORIGINAL_ASPECT_RATIO - INV_WIDESCREEN_ASPECT_RATIO), 0.0f, 1.0f); + g_scale = INV_WIDESCREEN_SCALE + factor * (SQUARE_SCALE - INV_WIDESCREEN_SCALE); + } + + // use original 4:3 scaling if requested + if (Config::AspectRatio == EAspectRatio::OriginalSquare) + { + aspectRatio = std::clamp(aspectRatio, ORIGINAL_ASPECT_RATIO, ORIGINAL_WIDESCREEN_ASPECT_RATIO); + g_scale = ((aspectRatio * 720.0f) / 1280.0f) / sqrt((aspectRatio * 720.0f) / 1280.0f); } - aspectRatio = std::clamp(aspectRatio, ORIGINAL_ASPECT_RATIO, ORIGINAL_WIDESCREEN_ASPECT_RATIO); - g_scale = ((aspectRatio * 720.0f) / 1280.0f) / sqrt((aspectRatio * 720.0f) / 1280.0f); g_worldMapOffset = std::clamp((aspectRatio - ORIGINAL_ASPECT_RATIO) / (ORIGINAL_WIDESCREEN_ASPECT_RATIO - ORIGINAL_ASPECT_RATIO), 0.0f, 1.0f); } diff --git a/UnleashedRecomp/user/config.h b/UnleashedRecomp/user/config.h index 852ef2ba..f3785112 100644 --- a/UnleashedRecomp/user/config.h +++ b/UnleashedRecomp/user/config.h @@ -148,15 +148,17 @@ CONFIG_DEFINE_ENUM_TEMPLATE(EWindowState) enum class EAspectRatio : uint32_t { Auto, + Widescreen, Square, - Widescreen + OriginalSquare }; CONFIG_DEFINE_ENUM_TEMPLATE(EAspectRatio) { { "Auto", EAspectRatio::Auto }, + { "16:9", EAspectRatio::Widescreen }, { "4:3", EAspectRatio::Square }, - { "16:9", EAspectRatio::Widescreen } + { "Original 4:3", EAspectRatio::OriginalSquare }, }; enum class ETripleBuffering : uint32_t