Implemented camera aspect ratio hooks

This commit is contained in:
Hyper 2024-10-17 19:15:36 +01:00
parent 02c9484c9c
commit 3c1c13e4ce
17 changed files with 307 additions and 7 deletions

View file

@ -0,0 +1,8 @@
#pragma once
#include "SWA/Camera/Camera.h"
#include "SWA/Player/Character/EvilSonic/EvilSonicContext.h"
#include "SWA/System/ApplicationDocument.h"
#include "SWA/System/GameDocument.h"
#include "SWA/System/InputState.h"
#include "SWA/System/PadState.h"

View file

@ -0,0 +1,9 @@
#pragma once
#include <cpu/guest_code.h>
#define SWA__CONCAT2(x, y) x##y
#define SWA_CONCAT2(x, y) _CONCAT(x, y)
#define SWA_INSERT_PADDING(length) \
uint8_t SWA_CONCAT2(pad, __LINE__)[length]

View file

@ -0,0 +1,19 @@
#pragma once
#include "SWA.inl"
namespace SWA
{
class CCamera // : public CGameObject, public Hedgehog::Universe::TStateMachine<CCamera>
{
public:
SWA_INSERT_PADDING(0x184);
be<float> m_VertAspectRatio;
SWA_INSERT_PADDING(0x48);
be<float> m_HorzAspectRatio;
SWA_INSERT_PADDING(0x178);
be<float> m_FieldOfView;
be<float> m_VertFieldOfView;
be<float> m_HorzFieldOfView;
};
}

View file

@ -0,0 +1,15 @@
#pragma once
#include "SWA.inl"
namespace SWA::Player
{
class CEvilSonicContext // : public CPlayerContext
{
public:
SWA_INSERT_PADDING(0x688);
be<float> m_DarkGaiaEnergy;
SWA_INSERT_PADDING(0x138);
be<uint32_t> m_AnimationID;
};
}

View file

@ -0,0 +1,19 @@
#pragma once
namespace SWA
{
class CApplicationDocument // : public Hedgehog::Base::CSynchronizedObject
{
public:
// TODO: Hedgehog::Base::TSynchronizedPtr<CApplicationDocument>*
inline static xpointer<CApplicationDocument>* ms_pInstance = (xpointer<CApplicationDocument>*)g_memory.Translate(0x833678A0);
// TODO: Hedgehog::Base::TSynchronizedPtr<CApplicationDocument>
static CApplicationDocument* GetInstance();
SWA_INSERT_PADDING(0x18);
be<uint32_t> m_Region;
};
}
#include "ApplicationDocument.inl"

View file

@ -0,0 +1,8 @@
namespace SWA
{
// TODO: Hedgehog::Base::TSynchronizedPtr<CApplicationDocument>
inline CApplicationDocument* CApplicationDocument::GetInstance()
{
return *ms_pInstance;
}
}

View file

@ -0,0 +1,26 @@
#pragma once
namespace SWA
{
class CGameDocument // : public Hedgehog::Base::CSynchronizedObject
{
public:
class CMember
{
public:
SWA_INSERT_PADDING(0x20C);
be<uint32_t> m_Score;
};
// TODO: Hedgehog::Base::TSynchronizedPtr<CGameDocument>*
inline static xpointer<CGameDocument>* ms_pInstance = (xpointer<CGameDocument>*)g_memory.Translate(0x83367900);
// TODO: Hedgehog::Base::TSynchronizedPtr<CGameDocument>
static CGameDocument* GetInstance();
SWA_INSERT_PADDING(0x08);
xpointer<CMember> m_pMember;
};
}
#include "GameDocument.inl"

View file

@ -0,0 +1,8 @@
namespace SWA
{
// TODO: Hedgehog::Base::TSynchronizedPtr<CGameDocument>
inline CGameDocument* CGameDocument::GetInstance()
{
return *ms_pInstance;
}
}

View file

@ -0,0 +1,26 @@
#pragma once
#include "SWA.inl"
#include "PadState.h"
namespace SWA
{
class CInputState // : public Hedgehog::Base::CSynchronizedObject
{
public:
// TODO: Hedgehog::Base::TSynchronizedPtr<CInputState>*
inline static xpointer<CInputState>* ms_pInstance = (xpointer<CInputState>*)g_memory.Translate(0x833671EC);
// TODO: Hedgehog::Base::TSynchronizedPtr<CInputState>
static CInputState* GetInstance();
SPadState m_PadStates[40];
SWA_INSERT_PADDING(0x50);
be<uint32_t> m_CurrentPadStateIndex;
SWA_INSERT_PADDING(0x04);
const SPadState& GetPadState() const;
};
}
#include "InputState.inl"

View file

@ -0,0 +1,13 @@
namespace SWA
{
// TODO: Hedgehog::Base::TSynchronizedPtr<CInputState>
inline CInputState* CInputState::GetInstance()
{
return *ms_pInstance;
}
inline const SPadState& CInputState::GetPadState() const
{
return m_PadStates[m_CurrentPadStateIndex];
}
}

View file

@ -0,0 +1,77 @@
#pragma once
#include "SWA.inl"
namespace SWA
{
enum EKeyState : uint32_t
{
eKeyState_None = 0x0,
eKeyState_A = 0x1,
eKeyState_B = 0x2,
eKeyState_X = 0x8,
eKeyState_Y = 0x10,
eKeyState_DpadUp = 0x40,
eKeyState_DpadDown = 0x80,
eKeyState_DpadLeft = 0x100,
eKeyState_DpadRight = 0x200,
eKeyState_Start = 0x400,
eKeyState_Select = 0x800,
eKeyState_LeftBumper = 0x1000,
eKeyState_RightBumper = 0x2000,
eKeyState_LeftTrigger = 0x4000,
eKeyState_RightTrigger = 0x8000,
eKeyState_LeftStick = 0x10000,
eKeyState_RightStick = 0x20000,
eKeyState_LeftStickUp = 0x40000,
eKeyState_LeftStickDown = 0x80000,
eKeyState_LeftStickLeft = 0x100000,
eKeyState_LeftStickRight = 0x200000,
eKeyState_RightStickUp = 0x400000,
eKeyState_RightStickDown = 0x800000,
eKeyState_RightStickLeft = 0x1000000,
eKeyState_RightStickRight = 0x2000000
};
struct SPadState
{
SWA_INSERT_PADDING(0x20);
be<uint32_t> DownState;
be<uint32_t> UpState;
be<uint32_t> TappedState;
be<uint32_t> ReleasedState;
SWA_INSERT_PADDING(0x04);
be<float> LeftStickHorizontal;
be<float> LeftStickVertical;
SWA_INSERT_PADDING(0x04);
be<float> RightStickHorizontal;
be<float> RightStickVertical;
SWA_INSERT_PADDING(0x04);
be<float> LeftTrigger;
be<float> RightTrigger;
SWA_INSERT_PADDING(0x20);
bool IsDown(const EKeyState in_Keys) const;
bool IsUp(const EKeyState in_Keys) const;
bool IsTapped(const EKeyState in_Keys) const;
bool IsReleased(const EKeyState in_Keys) const;
};
}
#include "PadState.inl"

View file

@ -0,0 +1,22 @@
namespace SWA
{
inline bool SPadState::IsDown(const EKeyState in_Keys) const
{
return (DownState & in_Keys) == in_Keys;
}
inline bool SPadState::IsUp(const EKeyState in_Keys) const
{
return (UpState & in_Keys) == in_Keys;
}
inline bool SPadState::IsTapped(const EKeyState in_Keys) const
{
return (TappedState & in_Keys) == in_Keys;
}
inline bool SPadState::IsReleased(const EKeyState in_Keys) const
{
return (ReleasedState & in_Keys) == in_Keys;
}
}

View file

@ -1,5 +1,10 @@
#include <cpu/guest_code.h>
#include "api/SWA.h"
#include "ui/window.h"
#include "game.h"
constexpr float m_baseAspectRatio = 16.0f / 9.0f;
void Game::Exit()
{
s_isSignalExit = true;
@ -10,3 +15,31 @@ bool GracefulLoopExitMidAsmHook()
// TODO (Sajid): investigate XAM handle closing causing assertion failure here.
return Game::s_isSignalExit;
}
bool CameraAspectRatioMidAsmHook(PPCRegister& r31)
{
auto pCamera = (SWA::CCamera*)g_memory.Translate(r31.u32);
auto newAspectRatio = (float)Window::s_width / (float)Window::s_height;
// Dynamically adjust aspect ratio to window dimensions.
pCamera->m_HorzAspectRatio = newAspectRatio;
// Jump to 4:3 code for VERT+ adjustments if using a narrow aspect ratio.
return newAspectRatio < m_baseAspectRatio;
}
void CameraBoostAspectRatioMidAsmHook(PPCRegister& r31, PPCRegister& f0)
{
auto pCamera = (SWA::CCamera*)g_memory.Translate(r31.u32);
if (Window::s_width < Window::s_height)
{
// Use horizontal FOV for narrow aspect ratios.
f0.f32 = pCamera->m_HorzFieldOfView;
}
else
{
// Use vertical FOV for normal aspect ratios.
f0.f32 = pCamera->m_VertFieldOfView;
}
}

View file

@ -1,6 +1,7 @@
#pragma once
#define NOMINMAX
#include <windows.h>
#include <mutex>
#include <vector>
@ -14,5 +15,5 @@
#include <toml++/toml.hpp>
#include "framework.h"
#include "Mutex.h"
#include "Config.h"
#include "mutex.h"
#include "config.h"

View file

@ -87,7 +87,7 @@ void Window::Init()
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
SDL_AddEventWatch(Window_OnSDLEvent, s_window);
s_window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_RESIZABLE);
s_window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Window::s_width, Window::s_height, SDL_WINDOW_RESIZABLE);
if (auto icon = GetIconSurface())
{
@ -95,6 +95,7 @@ void Window::Init()
SDL_FreeSurface(icon);
}
SetWindowDimensions();
SetFullscreen(Config::Fullscreen);
SDL_SysWMinfo info;

View file

@ -13,8 +13,8 @@ public:
inline static bool s_isFocused;
inline static int s_width;
inline static int s_height;
inline static int s_width = 1280;
inline static int s_height = 720;
static SDL_Surface* GetIconSurface(void* pIconBmp = nullptr, size_t iconSize = 0)
{
@ -81,7 +81,7 @@ public:
}
}
static void SetWindowDimensions(int w, int h)
static void SetWindowDimensions(int w = -1, int h = -1)
{
auto width = w <= 0 ? Config::Width : w;
auto height = h <= 0 ? Config::Height : h;
@ -97,6 +97,9 @@ public:
SDL_SetWindowMinimumSize(s_window, 640, 480);
SDL_SetWindowPosition(s_window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
s_width = width;
s_height = height;
if (!isPendingMaximise)
return;

View file

@ -107,4 +107,16 @@ registers = ["f13"]
[[midasm_hook]]
name = "GracefulLoopExitMidAsmHook"
address = 0x822C1018
return_on_true = true
return_on_true = true
[[midasm_hook]]
name = "CameraAspectRatioMidAsmHook"
address = 0x82468E84
registers = ["r31"]
jump_address_on_true = 0x82468E88
jump_address_on_false = 0x82468EE0
[[midasm_hook]]
name = "CameraBoostAspectRatioMidAsmHook"
address = 0x8246BDA8
registers = ["r31", "f0"]