mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-28 05:11:37 +00:00
Ultrawide patch for HUD 3D items.
This commit is contained in:
parent
f67895253e
commit
c6e2dbcce0
4 changed files with 91 additions and 13 deletions
|
|
@ -1,6 +1,7 @@
|
|||
#include <api/SWA.h>
|
||||
#include <ui/game_window.h>
|
||||
#include <user/config.h>
|
||||
#include "camera_patches.h"
|
||||
|
||||
static constexpr float ORIGINAL_ASPECT_RATIO = 4.0f / 3.0f;
|
||||
static constexpr float ORIGINAL_WIDESCREEN_ASPECT_RATIO = 16.0f / 9.0f;
|
||||
|
|
@ -15,23 +16,27 @@ void CameraAspectRatioMidAsmHook(PPCRegister& r30, PPCRegister& r31)
|
|||
camera->m_HorzAspectRatio = float(GameWindow::s_width) / float(GameWindow::s_height);
|
||||
}
|
||||
|
||||
float AdjustFieldOfView(float fieldOfView, float aspectRatio)
|
||||
{
|
||||
if (Config::AspectRatio == EAspectRatio::OriginalNarrow)
|
||||
{
|
||||
// Replicate the original incorrect field of view formula if requested.
|
||||
fieldOfView *= ORIGINAL_ASPECT_RATIO;
|
||||
}
|
||||
else if (aspectRatio < ORIGINAL_WIDESCREEN_ASPECT_RATIO)
|
||||
{
|
||||
// Use proper VERT+ otherwise for narrow aspect ratios.
|
||||
fieldOfView = 2.0 * atan(tan(0.5 * fieldOfView) / aspectRatio * ORIGINAL_WIDESCREEN_ASPECT_RATIO);
|
||||
}
|
||||
|
||||
return fieldOfView;
|
||||
}
|
||||
|
||||
void CameraFieldOfViewMidAsmHook(PPCRegister& r31, PPCRegister& f31)
|
||||
{
|
||||
auto camera = (SWA::CCamera*)g_memory.Translate(r31.u32);
|
||||
|
||||
// Replicate the original incorrect field of view formula if requested.
|
||||
if (Config::AspectRatio == EAspectRatio::OriginalNarrow)
|
||||
{
|
||||
if (abs(camera->m_HorzAspectRatio - ORIGINAL_ASPECT_RATIO) < 0.001f)
|
||||
{
|
||||
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);
|
||||
}
|
||||
f31.f64 = AdjustFieldOfView(f31.f64, camera->m_HorzAspectRatio);
|
||||
}
|
||||
|
||||
PPC_FUNC_IMPL(__imp__sub_824697B0);
|
||||
|
|
|
|||
3
UnleashedRecomp/patches/camera_patches.h
Normal file
3
UnleashedRecomp/patches/camera_patches.h
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
extern float AdjustFieldOfView(float fieldOfView, float aspectRatio);
|
||||
|
|
@ -5,6 +5,8 @@
|
|||
#include <ui/sdl_listener.h>
|
||||
#include <gpu/video.h>
|
||||
|
||||
#include "camera_patches.h"
|
||||
|
||||
// These are here for now to not recompile basically all of the project.
|
||||
namespace Chao::CSD
|
||||
{
|
||||
|
|
@ -876,3 +878,66 @@ PPC_FUNC(sub_830D1EF0)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Objects are pushed forward by 1m, so the coordinates need to compensate for it.
|
||||
static const double OBJ_GET_ITEM_TANGENT = tan(M_PI / 8.0);
|
||||
|
||||
// Coordinates are in [-1, 1] range. Automatically fit and centered.
|
||||
// The tangent is calculated incorrectly in game, causing distortion.
|
||||
// This hook makes them move to the correct position regardless of FOV.
|
||||
void ObjGetItemFieldOfViewMidAsmHook(PPCRegister& r1, PPCRegister& f1)
|
||||
{
|
||||
*reinterpret_cast<be<float>*>(g_memory.base + r1.u32 + 0x58) = tan(AdjustFieldOfView(f1.f64, g_aspectRatio) / 2.0) / OBJ_GET_ITEM_TANGENT;
|
||||
}
|
||||
|
||||
// SWA::CObjGetItem::GetX
|
||||
PPC_FUNC(sub_82690660)
|
||||
{
|
||||
uint32_t type = PPC_LOAD_U32(ctx.r3.u32 + 0xE8);
|
||||
if (type >= 47) // Ring, Moon Medal, Sun Medal
|
||||
{
|
||||
double x;
|
||||
|
||||
if (type == 47) // Ring
|
||||
x = 142.0;
|
||||
else // Medal
|
||||
x = 0.0; // TODO
|
||||
|
||||
x *= g_scale;
|
||||
|
||||
if (type != 47)
|
||||
x += g_offsetX * 2.0 + (1280.0 * (1.0 - g_scale));
|
||||
|
||||
auto backBuffer = Video::GetBackBuffer();
|
||||
ctx.f1.f64 = (x - (0.5 * backBuffer->width)) / (0.5 * backBuffer->height) * OBJ_GET_ITEM_TANGENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.f1.f64 = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// SWA::CObjGetItem::GetY
|
||||
PPC_FUNC(sub_826906A8)
|
||||
{
|
||||
uint32_t type = PPC_LOAD_U32(ctx.r3.u32 + 0xE8);
|
||||
if (type >= 47) // Ring, Moon Medal, Sun Medal
|
||||
{
|
||||
double y;
|
||||
|
||||
if (type == 47) // Ring
|
||||
y = 642.0;
|
||||
else // Medal
|
||||
y = 0.0; // TODO
|
||||
|
||||
y *= g_scale;
|
||||
y += g_offsetY * 2.0 + 720.0 * (1.0 - g_scale);
|
||||
|
||||
auto backBuffer = Video::GetBackBuffer();
|
||||
ctx.f1.f64 = ((0.5 * backBuffer->height) - y) / (0.5 * backBuffer->height) * OBJ_GET_ITEM_TANGENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.f1.f64 = 0.25;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -623,3 +623,8 @@ registers = ["r4"]
|
|||
name = "AddPrimitive2DMidAsmHook"
|
||||
address = 0x824DB3E4
|
||||
registers = ["r3"]
|
||||
|
||||
[[midasm_hook]]
|
||||
name = "ObjGetItemFieldOfViewMidAsmHook"
|
||||
address = 0x82692934
|
||||
registers = ["r1", "f1"]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue