From 8f525b571be08c0ebba83c3266e57ce936e7a251 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Mon, 25 Nov 2024 10:50:10 +0000 Subject: [PATCH] Implemented guest-to-host function pointers (#7) * Implemented guest-to-host function pointers (WIP) Co-Authored-By: Skyth (Asilkan) <19259897+blueskythlikesclouds@users.noreply.github.com> * function: support more types for function pointers * api: ported BlueBlur headers and misc. research * Move over function-pointers changes from options-menu branch. --------- Co-authored-by: Skyth (Asilkan) <19259897+blueskythlikesclouds@users.noreply.github.com> --- UnleashedRecomp/api/CSD/Manager/csdmBase.h | 6 + .../api/CSD/Manager/csdmMotionPattern.h | 8 + UnleashedRecomp/api/CSD/Manager/csdmNode.h | 33 ++ UnleashedRecomp/api/CSD/Manager/csdmNode.inl | 51 ++ .../api/CSD/Manager/csdmNodeObserver.h | 10 + .../api/CSD/Manager/csdmObserverBase.h | 23 + .../api/CSD/Manager/csdmObserverBase.inl | 8 + UnleashedRecomp/api/CSD/Manager/csdmProject.h | 31 ++ .../api/CSD/Manager/csdmProject.inl | 40 ++ .../api/CSD/Manager/csdmRCObject.h | 28 ++ .../api/CSD/Manager/csdmRCObject.inl | 35 ++ .../api/CSD/Manager/csdmRCObjectImp.h | 9 + .../api/CSD/Manager/csdmRCObjectImp.inl | 14 + UnleashedRecomp/api/CSD/Manager/csdmRCPtr.h | 32 ++ UnleashedRecomp/api/CSD/Manager/csdmRCPtr.inl | 45 ++ .../api/CSD/Manager/csdmRCPtrAbs.h | 42 ++ .../api/CSD/Manager/csdmRCPtrAbs.inl | 58 +++ .../api/CSD/Manager/csdmResourceBase.h | 26 + .../api/CSD/Manager/csdmResourceBase.inl | 15 + UnleashedRecomp/api/CSD/Manager/csdmScene.h | 53 +++ UnleashedRecomp/api/CSD/Manager/csdmScene.inl | 53 +++ .../api/CSD/Manager/csdmSceneObserver.h | 10 + .../api/CSD/Manager/csdmSubjectBase.h | 25 + .../api/CSD/Manager/csdmSubjectBase.inl | 14 + UnleashedRecomp/api/CSD/Platform/csdTexList.h | 23 + .../api/CSD/Platform/csdTexList.inl | 7 + .../api/Hedgehog/Base/System/hhAllocator.h | 36 ++ .../api/Hedgehog/Base/Thread/hhHolder.h | 20 + .../api/Hedgehog/Base/Thread/hhHolderBase.h | 28 ++ .../Base/Thread/hhSynchronizedObject.h | 12 + .../Hedgehog/Base/Thread/hhSynchronizedPtr.h | 27 ++ .../Base/Type/detail/hhStringHolder.h | 44 ++ .../Base/Type/detail/hhStringHolder.inl | 134 ++++++ .../api/Hedgehog/Base/Type/hhSharedString.h | 88 ++++ .../api/Hedgehog/Base/Type/hhSharedString.inl | 444 ++++++++++++++++++ UnleashedRecomp/api/Hedgehog/Base/hhObject.h | 23 + .../Hedgehog/Database/System/hhDatabaseData.h | 39 ++ .../Database/System/hhDatabaseData.inl | 36 ++ UnleashedRecomp/api/Hedgehog/Math/Vector2.h | 13 + .../MirageCore/Renderable/hhRenderable.h | 14 + .../Hedgehog/Universe/Engine/hhMessageActor.h | 14 + .../Universe/Engine/hhMessageProcess.h | 14 + .../Hedgehog/Universe/Engine/hhUpdateInfo.h | 13 + .../Hedgehog/Universe/Engine/hhUpdateUnit.h | 25 + .../Hedgehog/Universe/Thread/hhParallelJob.h | 21 + UnleashedRecomp/api/SWA.h | 58 +++ UnleashedRecomp/api/SWA.inl | 7 + .../api/SWA/CSD/CsdDatabaseWrapper.h | 25 + .../api/SWA/CSD/CsdDatabaseWrapper.inl | 9 + UnleashedRecomp/api/SWA/CSD/CsdProject.h | 18 + .../api/SWA/CSD/CsdTexListMirage.h | 18 + UnleashedRecomp/api/SWA/CSD/GameObjectCSD.h | 20 + UnleashedRecomp/api/SWA/Camera/Camera.h | 11 +- .../api/SWA/HUD/GeneralWindow/GeneralWindow.h | 18 + UnleashedRecomp/api/SWA/HUD/Loading/Loading.h | 30 ++ UnleashedRecomp/api/SWA/HUD/Pause/HudPause.h | 67 +++ .../api/SWA/HUD/Sonic/HudSonicStage.h | 22 + .../api/SWA/Movie/MovieDisplayer.h | 14 + UnleashedRecomp/api/SWA/Movie/MovieManager.h | 17 + .../api/SWA/Movie/MovieManager.inl | 7 + .../Player/Character/EvilSonic/EvilSonic.h | 2 +- .../Character/EvilSonic/Hud/EvilHudGuide.h | 7 +- .../api/SWA/Sequence/Unit/SequenceUnitBase.h | 13 + .../SWA/Sequence/Unit/SequenceUnitPlayMovie.h | 8 + .../Utility/SequencePlayMovieWrapper.h | 39 ++ UnleashedRecomp/api/SWA/Sound/Sound.h | 56 +++ .../api/SWA/Sound/SoundBGMActSonic.h | 21 + UnleashedRecomp/api/SWA/Sound/SoundBGMBase.h | 15 + UnleashedRecomp/api/SWA/System/Application.h | 21 + .../api/SWA/System/ApplicationD3D9.h | 8 + .../api/SWA/System/ApplicationDocument.h | 42 +- .../api/SWA/System/ApplicationXenon.h | 12 + UnleashedRecomp/api/SWA/System/Game.h | 10 + UnleashedRecomp/api/SWA/System/GameDocument.h | 15 +- .../api/SWA/System/GameMode/GameMode.h | 13 + .../api/SWA/System/GameMode/GameModeStage.h | 13 + .../SWA/System/GameMode/GameModeStageMovie.h | 20 + .../api/SWA/System/GameMode/Title/TitleMenu.h | 13 + .../System/GameMode/Title/TitleStateBase.h | 22 + UnleashedRecomp/api/SWA/System/GameObject.h | 27 ++ UnleashedRecomp/api/SWA/System/InputState.h | 6 +- UnleashedRecomp/api/SWA/System/InputState.inl | 2 +- UnleashedRecomp/api/SWA/System/PadState.h | 6 +- UnleashedRecomp/api/SWA/System/World.h | 20 + .../api/boost/smart_ptr/make_shared_object.h | 12 + .../api/boost/smart_ptr/shared_ptr.h | 164 +++++++ UnleashedRecomp/cpu/guest_stack_var.h | 123 +++++ UnleashedRecomp/gpu/video.cpp | 40 +- UnleashedRecomp/kernel/function.h | 174 ++++++- UnleashedRecomp/kernel/heap.h | 1 - UnleashedRecomp/kernel/memory.h | 6 + UnleashedRecomp/stdafx.h | 1 + thirdparty/PowerRecomp | 2 +- 93 files changed, 2957 insertions(+), 62 deletions(-) create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmBase.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmMotionPattern.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmNode.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmNode.inl create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmNodeObserver.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmObserverBase.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmObserverBase.inl create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmProject.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmProject.inl create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmRCObject.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmRCObject.inl create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmRCObjectImp.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmRCObjectImp.inl create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmRCPtr.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmRCPtr.inl create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmRCPtrAbs.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmRCPtrAbs.inl create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmResourceBase.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmResourceBase.inl create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmScene.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmScene.inl create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmSceneObserver.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmSubjectBase.h create mode 100644 UnleashedRecomp/api/CSD/Manager/csdmSubjectBase.inl create mode 100644 UnleashedRecomp/api/CSD/Platform/csdTexList.h create mode 100644 UnleashedRecomp/api/CSD/Platform/csdTexList.inl create mode 100644 UnleashedRecomp/api/Hedgehog/Base/System/hhAllocator.h create mode 100644 UnleashedRecomp/api/Hedgehog/Base/Thread/hhHolder.h create mode 100644 UnleashedRecomp/api/Hedgehog/Base/Thread/hhHolderBase.h create mode 100644 UnleashedRecomp/api/Hedgehog/Base/Thread/hhSynchronizedObject.h create mode 100644 UnleashedRecomp/api/Hedgehog/Base/Thread/hhSynchronizedPtr.h create mode 100644 UnleashedRecomp/api/Hedgehog/Base/Type/detail/hhStringHolder.h create mode 100644 UnleashedRecomp/api/Hedgehog/Base/Type/detail/hhStringHolder.inl create mode 100644 UnleashedRecomp/api/Hedgehog/Base/Type/hhSharedString.h create mode 100644 UnleashedRecomp/api/Hedgehog/Base/Type/hhSharedString.inl create mode 100644 UnleashedRecomp/api/Hedgehog/Base/hhObject.h create mode 100644 UnleashedRecomp/api/Hedgehog/Database/System/hhDatabaseData.h create mode 100644 UnleashedRecomp/api/Hedgehog/Database/System/hhDatabaseData.inl create mode 100644 UnleashedRecomp/api/Hedgehog/Math/Vector2.h create mode 100644 UnleashedRecomp/api/Hedgehog/MirageCore/Renderable/hhRenderable.h create mode 100644 UnleashedRecomp/api/Hedgehog/Universe/Engine/hhMessageActor.h create mode 100644 UnleashedRecomp/api/Hedgehog/Universe/Engine/hhMessageProcess.h create mode 100644 UnleashedRecomp/api/Hedgehog/Universe/Engine/hhUpdateInfo.h create mode 100644 UnleashedRecomp/api/Hedgehog/Universe/Engine/hhUpdateUnit.h create mode 100644 UnleashedRecomp/api/Hedgehog/Universe/Thread/hhParallelJob.h create mode 100644 UnleashedRecomp/api/SWA/CSD/CsdDatabaseWrapper.h create mode 100644 UnleashedRecomp/api/SWA/CSD/CsdDatabaseWrapper.inl create mode 100644 UnleashedRecomp/api/SWA/CSD/CsdProject.h create mode 100644 UnleashedRecomp/api/SWA/CSD/CsdTexListMirage.h create mode 100644 UnleashedRecomp/api/SWA/CSD/GameObjectCSD.h create mode 100644 UnleashedRecomp/api/SWA/HUD/GeneralWindow/GeneralWindow.h create mode 100644 UnleashedRecomp/api/SWA/HUD/Loading/Loading.h create mode 100644 UnleashedRecomp/api/SWA/HUD/Pause/HudPause.h create mode 100644 UnleashedRecomp/api/SWA/HUD/Sonic/HudSonicStage.h create mode 100644 UnleashedRecomp/api/SWA/Movie/MovieDisplayer.h create mode 100644 UnleashedRecomp/api/SWA/Movie/MovieManager.h create mode 100644 UnleashedRecomp/api/SWA/Movie/MovieManager.inl create mode 100644 UnleashedRecomp/api/SWA/Sequence/Unit/SequenceUnitBase.h create mode 100644 UnleashedRecomp/api/SWA/Sequence/Unit/SequenceUnitPlayMovie.h create mode 100644 UnleashedRecomp/api/SWA/Sequence/Utility/SequencePlayMovieWrapper.h create mode 100644 UnleashedRecomp/api/SWA/Sound/Sound.h create mode 100644 UnleashedRecomp/api/SWA/Sound/SoundBGMActSonic.h create mode 100644 UnleashedRecomp/api/SWA/Sound/SoundBGMBase.h create mode 100644 UnleashedRecomp/api/SWA/System/Application.h create mode 100644 UnleashedRecomp/api/SWA/System/ApplicationD3D9.h create mode 100644 UnleashedRecomp/api/SWA/System/ApplicationXenon.h create mode 100644 UnleashedRecomp/api/SWA/System/Game.h create mode 100644 UnleashedRecomp/api/SWA/System/GameMode/GameMode.h create mode 100644 UnleashedRecomp/api/SWA/System/GameMode/GameModeStage.h create mode 100644 UnleashedRecomp/api/SWA/System/GameMode/GameModeStageMovie.h create mode 100644 UnleashedRecomp/api/SWA/System/GameMode/Title/TitleMenu.h create mode 100644 UnleashedRecomp/api/SWA/System/GameMode/Title/TitleStateBase.h create mode 100644 UnleashedRecomp/api/SWA/System/GameObject.h create mode 100644 UnleashedRecomp/api/SWA/System/World.h create mode 100644 UnleashedRecomp/api/boost/smart_ptr/make_shared_object.h create mode 100644 UnleashedRecomp/api/boost/smart_ptr/shared_ptr.h create mode 100644 UnleashedRecomp/cpu/guest_stack_var.h diff --git a/UnleashedRecomp/api/CSD/Manager/csdmBase.h b/UnleashedRecomp/api/CSD/Manager/csdmBase.h new file mode 100644 index 00000000..d2ffca59 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmBase.h @@ -0,0 +1,6 @@ +#pragma once + +namespace Chao::CSD +{ + class CBase {}; +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmMotionPattern.h b/UnleashedRecomp/api/CSD/Manager/csdmMotionPattern.h new file mode 100644 index 00000000..dd5df27b --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmMotionPattern.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace Chao::CSD +{ + class CMotionPattern : CBase {}; +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmNode.h b/UnleashedRecomp/api/CSD/Manager/csdmNode.h new file mode 100644 index 00000000..08942f7a --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmNode.h @@ -0,0 +1,33 @@ +#pragma once + +#include "SWA.inl" +#include "CSD/Manager/csdmBase.h" +#include "CSD/Manager/csdmResourceBase.h" +#include "CSD/Manager/csdmNodeObserver.h" +#include "CSD/Manager/csdmSubjectBase.h" + +namespace Chao::CSD +{ + struct Node; + + class CNode : public CResourceBase, SubjectBase, CBase + { + public: + SWA_INSERT_PADDING(0x34); + xpointer m_pMotionPattern; + SWA_INSERT_PADDING(0x18); + + ~CNode(); + + void SetText(const char* in_pText); + void SetText(const wchar_t* in_pText); + Hedgehog::Math::CVector2* GetPosition() const; + void SetPosition(float in_X, float in_Y); + void SetHideFlag(uint32_t in_HideFlag); + void SetRotation(float in_Rotation); + void SetScale(float in_X, float in_Y); + void SetPatternIndex(uint32_t in_PatternIndex); + }; +} + +#include "CSD/Manager/csdmNode.inl" diff --git a/UnleashedRecomp/api/CSD/Manager/csdmNode.inl b/UnleashedRecomp/api/CSD/Manager/csdmNode.inl new file mode 100644 index 00000000..92e64079 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmNode.inl @@ -0,0 +1,51 @@ +#include "SWA.inl" + +namespace Chao::CSD +{ + inline CNode::~CNode() + { + SWA_VIRTUAL_FUNCTION(void, 0, this); + } + + inline void CNode::SetText(const char* in_pText) + { + GuestToHostFunction(0x830BF640, this, in_pText); + } + + inline void CNode::SetText(const wchar_t* in_pText) + { + GuestToHostFunction(0x830BF640, this, in_pText); + } + + inline Hedgehog::Math::CVector2* CNode::GetPosition() const + { + guest_stack_var pos; + GuestToHostFunction(0x830BF008, pos.get(), this); + return pos.get(); + } + + inline void CNode::SetPosition(float in_X, float in_Y) + { + GuestToHostFunction(0x830BF078, this, in_X, in_Y); + } + + inline void CNode::SetHideFlag(uint32_t in_HideFlag) + { + GuestToHostFunction(0x830BF080, this, in_HideFlag); + } + + inline void CNode::SetRotation(float in_Rotation) + { + GuestToHostFunction(0x830BF088, this, in_Rotation); + } + + inline void CNode::SetScale(float in_X, float in_Y) + { + GuestToHostFunction(0x830BF090, this, in_X, in_Y); + } + + inline void CNode::SetPatternIndex(uint32_t in_PatternIndex) + { + GuestToHostFunction(0x830BF300, this, in_PatternIndex); + } +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmNodeObserver.h b/UnleashedRecomp/api/CSD/Manager/csdmNodeObserver.h new file mode 100644 index 00000000..abfba980 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmNodeObserver.h @@ -0,0 +1,10 @@ +#pragma once + +#include "CSD/Manager/csdmObserverBase.h" + +namespace Chao::CSD +{ + class CNode; + + class CNodeObserver : public CObserverBase {}; +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmObserverBase.h b/UnleashedRecomp/api/CSD/Manager/csdmObserverBase.h new file mode 100644 index 00000000..63daf398 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmObserverBase.h @@ -0,0 +1,23 @@ +#pragma once + +#include "SWA.inl" + +namespace Chao::CSD +{ + template + class CObserverBase + { + public: + struct Vftable + { + be m_fpDtor; + }; + + xpointer m_pVftable; + SWA_INSERT_PADDING(0x08); + + ~CObserverBase(); + }; +} + +#include "CSD/Manager/csdmObserverBase.inl" diff --git a/UnleashedRecomp/api/CSD/Manager/csdmObserverBase.inl b/UnleashedRecomp/api/CSD/Manager/csdmObserverBase.inl new file mode 100644 index 00000000..beeabb4f --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmObserverBase.inl @@ -0,0 +1,8 @@ +namespace Chao::CSD +{ + template + inline CObserverBase::~CObserverBase() + { + GuestToHostFunction(m_pVftable->m_fpDtor, this); + } +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmProject.h b/UnleashedRecomp/api/CSD/Manager/csdmProject.h new file mode 100644 index 00000000..ed01cd3b --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmProject.h @@ -0,0 +1,31 @@ +#pragma once + +#include "SWA.inl" +#include "CSD/Manager/csdmBase.h" +#include "CSD/Manager/csdmResourceBase.h" + +namespace Chao::CSD +{ + struct Project; + class CProject; + class CScene; + class CTexList; + + class CProject : public CResourceBase, CBase + { + public: + SWA_INSERT_PADDING(0x1C); + RCPtr m_rcTexList; + SWA_INSERT_PADDING(0x1C); + + RCPtr CreateScene(const char* in_pName) const; + RCPtr CreateScene(const char* in_pName, const char* in_pMotionName) const; + + void DestroyScene(CScene* in_pScene); + void DestroyScene(RCPtr& inout_rcScene); + + static void DestroyScene(CProject* in_pProject, RCPtr& inout_rcScene); + }; +} + +#include "CSD/Manager/csdmProject.inl" diff --git a/UnleashedRecomp/api/CSD/Manager/csdmProject.inl b/UnleashedRecomp/api/CSD/Manager/csdmProject.inl new file mode 100644 index 00000000..c579789e --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmProject.inl @@ -0,0 +1,40 @@ +#include "kernel/function.h" + +namespace Chao::CSD +{ + inline RCPtr CProject::CreateScene(const char* in_pName) const + { + RCPtr rcScene; + GuestToHostFunction(0x830BEE00, this, rcScene, in_pName, nullptr); + return rcScene; + } + + inline RCPtr CProject::CreateScene(const char* in_pName, const char* in_pMotionName) const + { + RCPtr rcScene; + GuestToHostFunction(0x830BECE0, this, rcScene, in_pName, in_pMotionName, nullptr); + return rcScene; + } + + inline void CProject::DestroyScene(CScene* in_pScene) + { + GuestToHostFunction(0x830BE298, this, in_pScene); + } + + inline void CProject::DestroyScene(RCPtr& inout_rcScene) + { + if (!inout_rcScene) + return; + + DestroyScene(inout_rcScene.Get()); + inout_rcScene = nullptr; + } + + inline void CProject::DestroyScene(CProject* in_pProject, RCPtr& inout_rcScene) + { + if (in_pProject) + in_pProject->DestroyScene(inout_rcScene); + else + inout_rcScene = nullptr; + } +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmRCObject.h b/UnleashedRecomp/api/CSD/Manager/csdmRCObject.h new file mode 100644 index 00000000..143dcb07 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmRCObject.h @@ -0,0 +1,28 @@ +#pragma once + +#include "CSD/Manager/csdmRCPtrAbs.h" + +namespace Chao::CSD +{ + class RCPtrAbs::RCObject + { + public: + struct Vftable + { + be m_fpDtor; + be m_fpDeallocate; + }; + + xpointer m_pVftable; + xpointer m_pMemory; + be m_RefCount; + xpointer m_pDealloctor; + be m_eDealloctor; + + ~RCObject(); + void Deallocate(void* in_pMemory); + void Release(); + }; +} + +#include "CSD/Manager/csdmRCObject.inl" diff --git a/UnleashedRecomp/api/CSD/Manager/csdmRCObject.inl b/UnleashedRecomp/api/CSD/Manager/csdmRCObject.inl new file mode 100644 index 00000000..60909972 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmRCObject.inl @@ -0,0 +1,35 @@ +namespace Chao::CSD +{ + inline RCPtrAbs::RCObject::~RCObject() + { + GuestToHostFunction(m_pVftable->m_fpDtor, this); + } + + inline RCPtrAbs::~RCPtrAbs() + { + RCPtrAbs::RCObject* pObj = m_pObject; + + m_pObject = nullptr; + + if (pObj) + pObj->Release(); + } + + inline void* RCPtrAbs::GetAbs() const + { + if (!m_pObject) + return nullptr; + + return m_pObject->m_pMemory; + } + + inline void RCPtrAbs::RCObject::Deallocate(void* in_pMemory) + { + GuestToHostFunction(m_pVftable->m_fpDeallocate, this, in_pMemory); + } + + inline void RCPtrAbs::RCObject::Release() + { + GuestToHostFunction(0x830BA068, this); + } +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmRCObjectImp.h b/UnleashedRecomp/api/CSD/Manager/csdmRCObjectImp.h new file mode 100644 index 00000000..aa814cfa --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmRCObjectImp.h @@ -0,0 +1,9 @@ +#pragma once + +#include "CSD/Manager/csdmRCPtr.h" + +namespace Chao::CSD +{ + template + class RCPtr::RCObjectImp : public RCObject {}; +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmRCObjectImp.inl b/UnleashedRecomp/api/CSD/Manager/csdmRCObjectImp.inl new file mode 100644 index 00000000..74465e61 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmRCObjectImp.inl @@ -0,0 +1,14 @@ +namespace Chao::CSD +{ + template + void RCPtr::RCObjectImp::Deallocate(void* in_pMemory) + { + // delete static_cast(in_pMemory); + } + + template + RCPtrAbs::RCObject* RCPtr::CreateRCObject() + { + return new RCObjectImp(); + } +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmRCPtr.h b/UnleashedRecomp/api/CSD/Manager/csdmRCPtr.h new file mode 100644 index 00000000..10878100 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmRCPtr.h @@ -0,0 +1,32 @@ +#pragma once + +#include "CSD/Manager/csdmRCPtrAbs.h" + +namespace Chao::CSD +{ + template + class RCPtr : RCPtrAbs + { + public: + class RCObjectImp; + + RCPtr() : RCPtrAbs() {} + RCPtr(T* in_pMemory) : RCPtrAbs(in_pMemory) {} + RCPtr(const RCPtr& in_rOther) : RCPtrAbs(in_rOther) {} + RCPtr(RCPtr&& in_rOther) : RCPtrAbs(std::move(in_rOther)) {} + + void Attach(T* in_pObject); + + T* Get() const; + void Set(const RCPtr& in_rOther); + + T* operator*() const; + T* operator->() const; + + RCPtr& operator=(const RCPtr& in_rOther); + + operator bool() const; + }; +} + +#include "CSD/Manager/csdmRCPtr.inl" diff --git a/UnleashedRecomp/api/CSD/Manager/csdmRCPtr.inl b/UnleashedRecomp/api/CSD/Manager/csdmRCPtr.inl new file mode 100644 index 00000000..01bcd6e1 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmRCPtr.inl @@ -0,0 +1,45 @@ +namespace Chao::CSD +{ + template + void RCPtr::Attach(T* in_pObject) + { + RCPtrAbs::AttachAbs(in_pObject); + } + + template + T* RCPtr::Get() const + { + return static_cast(RCPtrAbs::GetAbs()); + } + + template + void RCPtr::Set(const RCPtr& in_rOther) + { + RCPtrAbs::SetAbs(in_rOther); + } + + template + T* RCPtr::operator*() const + { + return Get(); + } + + template + T* RCPtr::operator->() const + { + return Get(); + } + + template + RCPtr& RCPtr::operator=(const RCPtr& in_rOther) + { + Set(in_rOther); + return *this; + } + + template + RCPtr::operator bool() const + { + return m_pObject != nullptr; + } +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmRCPtrAbs.h b/UnleashedRecomp/api/CSD/Manager/csdmRCPtrAbs.h new file mode 100644 index 00000000..e1e46be8 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmRCPtrAbs.h @@ -0,0 +1,42 @@ +#pragma once + +#include "SWA.inl" + +namespace Chao::CSD +{ + class RCPtrAbs + { + public: + class RCObject; + + struct Vftable + { + be m_fpDtor; + be m_fpCreateRCObject; + }; + + xpointer m_pVftable; + xpointer m_pObject; + + RCPtrAbs(); + RCPtrAbs(void* in_pMemory); + RCPtrAbs(const RCPtrAbs& in_rOther); + RCPtrAbs(RCPtrAbs&& in_rPtr); + + ~RCPtrAbs(); + RCObject* CreateRCObject(); + + void AttachAbs(void* in_pMemory); + void* GetAbs() const; + void SetAbs(const RCPtrAbs& in_rPtr); + + void* operator*() const; + void* operator->() const; + + RCPtrAbs& operator=(const RCPtrAbs& in_rPtr); + + operator bool() const; + }; +} + +#include "CSD/Manager/csdmRCPtrAbs.inl" diff --git a/UnleashedRecomp/api/CSD/Manager/csdmRCPtrAbs.inl b/UnleashedRecomp/api/CSD/Manager/csdmRCPtrAbs.inl new file mode 100644 index 00000000..2925fc54 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmRCPtrAbs.inl @@ -0,0 +1,58 @@ +namespace Chao::CSD +{ + inline RCPtrAbs::RCPtrAbs() + { + AttachAbs(nullptr); + } + + inline RCPtrAbs::RCPtrAbs(void* in_pMemory) + { + AttachAbs(in_pMemory); + } + + inline RCPtrAbs::RCPtrAbs(const RCPtrAbs& in_rOther) + { + SetAbs(in_rOther); + } + + inline RCPtrAbs::RCPtrAbs(RCPtrAbs&& in_rPtr) : m_pObject(in_rPtr.m_pObject) + { + in_rPtr.m_pObject = nullptr; + } + + inline RCPtrAbs::RCObject* RCPtrAbs::CreateRCObject() + { + return GuestToHostFunction(m_pVftable->m_fpCreateRCObject, this); + } + + inline void RCPtrAbs::AttachAbs(void* in_pMemory) + { + GuestToHostFunction(0x830BA298, this, in_pMemory); + } + + inline void RCPtrAbs::SetAbs(const RCPtrAbs& in_rPtr) + { + GuestToHostFunction(0x830BA328, this, in_rPtr); + } + + inline void* RCPtrAbs::operator*() const + { + return GetAbs(); + } + + inline void* RCPtrAbs::operator->() const + { + return GetAbs(); + } + + inline RCPtrAbs& RCPtrAbs::operator=(const RCPtrAbs& in_rPtr) + { + SetAbs(in_rPtr); + return *this; + } + + inline RCPtrAbs::operator bool() const + { + return m_pObject != nullptr; + } +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmResourceBase.h b/UnleashedRecomp/api/CSD/Manager/csdmResourceBase.h new file mode 100644 index 00000000..094ed06f --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmResourceBase.h @@ -0,0 +1,26 @@ +#pragma once + +#include "CSD/Manager/csdmRCPtr.h" + +namespace Chao::CSD +{ + template + class CResourceBase + { + public: + struct Vftable + { + be m_fpDtor; + be m_fpCopyResource; + }; + + xpointer m_pVftable; + RCPtr m_rcResourceHolder; + xpointer m_pResource; + + ~CResourceBase(); + void CopyResource(const CResourceBase& in_rOther); + }; +} + +#include "CSD/Manager/csdmResourceBase.h" diff --git a/UnleashedRecomp/api/CSD/Manager/csdmResourceBase.inl b/UnleashedRecomp/api/CSD/Manager/csdmResourceBase.inl new file mode 100644 index 00000000..d459e3c9 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmResourceBase.inl @@ -0,0 +1,15 @@ +namespace Chao::CSD +{ + template + inline CResourceBase::~CResourceBase() + { + GuestToHostFunction(m_pVftable->m_fpDtor, this); + } + + template + inline void CResourceBase::CopyResource(const CResourceBase& in_rOther) + { + m_rcResourceHolder = in_rOther.m_rcResourceHolder; + m_pResource = in_rOther.m_pResource; + } +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmScene.h b/UnleashedRecomp/api/CSD/Manager/csdmScene.h new file mode 100644 index 00000000..e26f2b91 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmScene.h @@ -0,0 +1,53 @@ +#pragma once + +#include "SWA.inl" +#include "CSD/Manager/csdmBase.h" +#include "CSD/Manager/csdmResourceBase.h" +#include "CSD/Manager/csdmSceneObserver.h" +#include "CSD/Manager/csdmSubjectBase.h" + +namespace Chao::CSD +{ + struct Scene; + class CScene; + class CNode; + + enum EMotionRepeatType : uint32_t + { + eMotionRepeatType_PlayOnce = 0, + eMotionRepeatType_Loop = 1, + eMotionRepeatType_PingPong = 2, + eMotionRepeatType_PlayThenDestroy = 3 + }; + + class CScene : public CResourceBase, SubjectBase, CBase + { + public: + SWA_INSERT_PADDING(0x60); + be m_PrevMotionFrame; + be m_MotionFrame; + be m_MotionSpeed; + be m_MotionStartFrame; + be m_MotionEndFrame; + SWA_INSERT_PADDING(0x0C); + be m_MotionDisableFlag; + SWA_INSERT_PADDING(0x10); + be m_MotionRepeatType; + SWA_INSERT_PADDING(0x2C); + + ~CScene(); + void Update(float in_DeltaTime = 0.0f); + void Render(void* in_pUnk); + + void GetNode(RCPtr& out_rResult, const char* in_pName); + + bool SetMotion(const char* in_pName); + void SetMotionFrame(float in_MotionFrame); + void SetPosition(float in_X, float in_Y); + void SetHideFlag(uint32_t in_HideFlag); + void SetRotation(float in_Angle); + void SetScale(float in_X, float in_Y); + }; +} + +#include "CSD/Manager/csdmScene.inl" diff --git a/UnleashedRecomp/api/CSD/Manager/csdmScene.inl b/UnleashedRecomp/api/CSD/Manager/csdmScene.inl new file mode 100644 index 00000000..a44a6cda --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmScene.inl @@ -0,0 +1,53 @@ +namespace Chao::CSD +{ + inline CScene::~CScene() + { + SWA_VIRTUAL_FUNCTION(void, 0, this); + } + + inline void CScene::Update(float in_DeltaTime) + { + SWA_VIRTUAL_FUNCTION(void, 2, this, in_DeltaTime); + } + + inline void CScene::Render(void* in_pUnk) + { + SWA_VIRTUAL_FUNCTION(void, 3, this, in_pUnk); + } + + inline void CScene::GetNode(RCPtr& out_rResult, const char* in_pName) + { + GuestToHostFunction(sub_830BCCA8, &out_rResult, this, in_pName); + } + + inline bool CScene::SetMotion(const char* in_pName) + { + return GuestToHostFunction(0x830BA760, this, in_pName); + } + + inline void CScene::SetMotionFrame(float in_MotionFrame) + { + m_PrevMotionFrame = in_MotionFrame; + m_MotionFrame = in_MotionFrame; + } + + inline void CScene::SetPosition(float in_X, float in_Y) + { + GuestToHostFunction(0x830BB550, this, in_X, in_Y); + } + + inline void CScene::SetHideFlag(uint32_t in_HideFlag) + { + GuestToHostFunction(0x830BB378, this, in_HideFlag); + } + + inline void CScene::SetRotation(float in_Angle) + { + GuestToHostFunction(0x830BB5F8, this, in_Angle); + } + + inline void CScene::SetScale(float in_X, float in_Y) + { + GuestToHostFunction(0x830BB650, this, in_X, in_Y); + } +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmSceneObserver.h b/UnleashedRecomp/api/CSD/Manager/csdmSceneObserver.h new file mode 100644 index 00000000..2e6abb2c --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmSceneObserver.h @@ -0,0 +1,10 @@ +#pragma once + +#include "CSD/Manager/csdmObserverBase.h" + +namespace Chao::CSD +{ + class CScene; + + class CSceneObserver : public CObserverBase {}; +} diff --git a/UnleashedRecomp/api/CSD/Manager/csdmSubjectBase.h b/UnleashedRecomp/api/CSD/Manager/csdmSubjectBase.h new file mode 100644 index 00000000..cb420c30 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmSubjectBase.h @@ -0,0 +1,25 @@ +#pragma once + +#include "SWA.inl" + +namespace Chao::CSD +{ + template + class SubjectBase + { + public: + struct Vftable + { + be m_fpDtor; + be m_fpGetObservee; + }; + + xpointer m_pVftable; + SWA_INSERT_PADDING(0x0C); + + ~SubjectBase(); + TObservee* GetObservee() const; + }; +} + +#include "CSD/Manager/csdmSubjectBase.inl" diff --git a/UnleashedRecomp/api/CSD/Manager/csdmSubjectBase.inl b/UnleashedRecomp/api/CSD/Manager/csdmSubjectBase.inl new file mode 100644 index 00000000..9c9b7f8f --- /dev/null +++ b/UnleashedRecomp/api/CSD/Manager/csdmSubjectBase.inl @@ -0,0 +1,14 @@ +namespace Chao::CSD +{ + template + inline SubjectBase::~SubjectBase() + { + GuestToHostFunction(m_pVftable->m_fpDtor, this); + } + + template + inline TObservee* SubjectBase::GetObservee() const + { + return nullptr; + } +} diff --git a/UnleashedRecomp/api/CSD/Platform/csdTexList.h b/UnleashedRecomp/api/CSD/Platform/csdTexList.h new file mode 100644 index 00000000..88fb7c81 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Platform/csdTexList.h @@ -0,0 +1,23 @@ +#pragma once + +#include "CSD/Manager/csdmBase.h" +#include "CSD/Manager/csdmRCPtr.h" + +namespace Chao::CSD +{ + class CTexList : public CBase + { + public: + struct Vftable + { + be m_fpDtor; + }; + + xpointer m_pVftable; + RCPtr m_rcData; + + ~CTexList(); + }; +} + +#include "CSD/Platform/csdTexList.inl" diff --git a/UnleashedRecomp/api/CSD/Platform/csdTexList.inl b/UnleashedRecomp/api/CSD/Platform/csdTexList.inl new file mode 100644 index 00000000..14835026 --- /dev/null +++ b/UnleashedRecomp/api/CSD/Platform/csdTexList.inl @@ -0,0 +1,7 @@ +namespace Chao::CSD +{ + inline CTexList::~CTexList() + { + GuestToHostFunction(m_pVftable->m_fpDtor, this); + } +} diff --git a/UnleashedRecomp/api/Hedgehog/Base/System/hhAllocator.h b/UnleashedRecomp/api/Hedgehog/Base/System/hhAllocator.h new file mode 100644 index 00000000..baa56d99 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Base/System/hhAllocator.h @@ -0,0 +1,36 @@ +#pragma once + +#include "SWA.inl" + +inline static void* __HH_ALLOC(const uint32_t in_Size) +{ + return GuestToHostFunction(0x82DFA0B0, in_Size, nullptr, 0, 0); +} + +inline static void __HH_FREE(const void* in_pData) +{ + GuestToHostFunction(0x82DF9E50, in_pData); +} + +namespace Hedgehog::Base +{ + template + class TAllocator + { + public: + using value_type = T; + + TAllocator() noexcept {} + template TAllocator(TAllocator const&) noexcept {} + + value_type* allocate(std::size_t n) + { + return reinterpret_cast(__HH_ALLOC(n * sizeof(value_type))); + } + + void deallocate(value_type* p, std::size_t) noexcept + { + __HH_FREE(p); + } + }; +} diff --git a/UnleashedRecomp/api/Hedgehog/Base/Thread/hhHolder.h b/UnleashedRecomp/api/Hedgehog/Base/Thread/hhHolder.h new file mode 100644 index 00000000..1e23c78c --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Base/Thread/hhHolder.h @@ -0,0 +1,20 @@ +#pragma once + +#include "Hedgehog/Base/Thread/hhHolderBase.h" + +#define HH_BASE_HOLDER(x) \ + Hedgehog::Base::THolder(x) + +namespace Hedgehog::Base +{ + template + class THolder : public CHolderBase + { + public: + THolder(T* in_pObject) : CHolderBase(in_pObject, ForceSync) {} + + T* get() const; + T* operator->() const; + T* operator*() const; + }; +} diff --git a/UnleashedRecomp/api/Hedgehog/Base/Thread/hhHolderBase.h b/UnleashedRecomp/api/Hedgehog/Base/Thread/hhHolderBase.h new file mode 100644 index 00000000..2d5d80a1 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Base/Thread/hhHolderBase.h @@ -0,0 +1,28 @@ +#pragma once + +#include "SWA.inl" + +namespace Hedgehog::Base +{ + class CSynchronizedObject; + + class CHolderBase + { + protected: + xpointer m_pSynchronizedObject; + bool m_Locked; + + public: + CHolderBase() : m_pSynchronizedObject(nullptr), m_Locked(false) {} + CHolderBase(CSynchronizedObject* in_pSynchronizedObject, bool in_ForceSync = false); + CHolderBase(CHolderBase&& io_rOther); + CHolderBase(const CHolderBase& in_rOther); + ~CHolderBase(); + + CSynchronizedObject* get() const; + CSynchronizedObject* operator->() const; + CSynchronizedObject* operator*() const; + + explicit operator bool() const; + }; +} diff --git a/UnleashedRecomp/api/Hedgehog/Base/Thread/hhSynchronizedObject.h b/UnleashedRecomp/api/Hedgehog/Base/Thread/hhSynchronizedObject.h new file mode 100644 index 00000000..d84df970 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Base/Thread/hhSynchronizedObject.h @@ -0,0 +1,12 @@ +#pragma once + +#include "SWA.inl" + +namespace Hedgehog::Base +{ + class CSynchronizedObject + { + public: + SWA_INSERT_PADDING(0x04); + }; +} diff --git a/UnleashedRecomp/api/Hedgehog/Base/Thread/hhSynchronizedPtr.h b/UnleashedRecomp/api/Hedgehog/Base/Thread/hhSynchronizedPtr.h new file mode 100644 index 00000000..53889dd1 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Base/Thread/hhSynchronizedPtr.h @@ -0,0 +1,27 @@ +#pragma once + +#include "SWA.inl" +#include "Hedgehog/Base/Thread/hhHolder.h" + +namespace Hedgehog::Base +{ + template + class TSynchronizedPtr + { + xpointer m_pObject; + + public: + TSynchronizedPtr(T* in_pObject); + TSynchronizedPtr(); + TSynchronizedPtr(const TSynchronizedPtr& in_rOther); + TSynchronizedPtr(TSynchronizedPtr&& io_rOther); + + TSynchronizedPtr& operator=(T* const in_pObject); + + THolder get() const; + THolder operator->() const; + THolder operator*() const; + + explicit operator bool() const; + }; +} diff --git a/UnleashedRecomp/api/Hedgehog/Base/Type/detail/hhStringHolder.h b/UnleashedRecomp/api/Hedgehog/Base/Type/detail/hhStringHolder.h new file mode 100644 index 00000000..087de601 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Base/Type/detail/hhStringHolder.h @@ -0,0 +1,44 @@ +#pragma once + +#include "SWA.inl" + +namespace Hedgehog::Base +{ + struct SStringHolder + { + union + { + struct + { + be Length; + be RefCount; + }; + + be RefCountAndLength; + }; + + char aStr[1u]; + + static SStringHolder* GetHolder(const char* in_pStr); + + static size_t GetMemorySize(const size_t in_Length); + static size_t GetMemorySizeAligned(const size_t in_Length); + + static SStringHolder* Make(const char* in_pStr, const size_t in_Length); + + static SStringHolder* Concat( + const char* in_pStrA, const size_t in_LengthA, + const char* in_pStrB, const size_t in_LengthB); + + void AddRef(); + void Release(); + + bool IsUnique() const; + + bool TryInplaceAssign(const char* in_pStr, const size_t in_Length); + bool TryInplaceAppend(const char* in_pStr, const size_t in_Length); + bool TryInplacePrepend(const char* in_pStr, const size_t in_Length); + }; +} + +#include "Hedgehog/Base/Type/detail/hhStringHolder.inl" diff --git a/UnleashedRecomp/api/Hedgehog/Base/Type/detail/hhStringHolder.inl b/UnleashedRecomp/api/Hedgehog/Base/Type/detail/hhStringHolder.inl new file mode 100644 index 00000000..5fede682 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Base/Type/detail/hhStringHolder.inl @@ -0,0 +1,134 @@ +namespace Hedgehog::Base +{ + inline SStringHolder* SStringHolder::GetHolder(const char* in_pStr) + { + return (SStringHolder*)((size_t)in_pStr - sizeof(RefCountAndLength)); + } + + inline size_t SStringHolder::GetMemorySize(const size_t in_Length) + { + return sizeof(RefCountAndLength) + in_Length; + } + + inline size_t SStringHolder::GetMemorySizeAligned(const size_t in_Length) + { + return (GetMemorySize(in_Length) + 0x10) & ~0x0F; + } + + inline SStringHolder* SStringHolder::Make(const char* in_pStr, const size_t in_Length) + { + const size_t memSize = GetMemorySize(in_Length); + const size_t memSizeAligned = GetMemorySizeAligned(in_Length); + + auto pHolder = (SStringHolder*)__HH_ALLOC(memSizeAligned); + pHolder->RefCount = 1; + pHolder->Length = (uint16_t)in_Length; + + if (in_pStr) + memcpy(pHolder->aStr, in_pStr, in_Length); + + memset(&pHolder->aStr[in_Length], 0, memSizeAligned - memSize); + + return pHolder; + } + + inline SStringHolder* SStringHolder::Concat(const char* in_pStrA, const size_t in_LengthA, const char* in_pStrB, const size_t in_LengthB) + { + SStringHolder* pHolder = Make(nullptr, in_LengthA + in_LengthB); + + memcpy(pHolder->aStr, in_pStrA, in_LengthA); + memcpy(&pHolder->aStr[in_LengthA], in_pStrB, in_LengthB); + + return pHolder; + } + + inline void SStringHolder::AddRef() + { + uint32_t originalValue, incrementedValue; + do + { + originalValue = RefCountAndLength.value; + incrementedValue = std::byteswap(std::byteswap(originalValue) + 1); + } while (InterlockedCompareExchange(reinterpret_cast(&RefCountAndLength), incrementedValue, originalValue) != originalValue); + } + + inline void SStringHolder::Release() + { + uint32_t originalValue, decrementedValue; + do + { + originalValue = RefCountAndLength.value; + decrementedValue = std::byteswap(std::byteswap(originalValue) - 1); + } while (InterlockedCompareExchange(reinterpret_cast(&RefCountAndLength), decrementedValue, originalValue) != originalValue); + + if (RefCountAndLength == 0) + __HH_FREE(this); + } + + inline bool SStringHolder::IsUnique() const + { + return RefCount == 1; + } + + inline bool SStringHolder::TryInplaceAssign(const char* in_pStr, const size_t in_Length) + { + if (!IsUnique()) + return false; + + const size_t memSizeAligned = GetMemorySizeAligned(in_Length); + + if (memSizeAligned > GetMemorySizeAligned(Length)) + return false; + + if (in_pStr) + memcpy(aStr, in_pStr, in_Length); + + memset(&aStr[in_Length], 0, memSizeAligned - GetMemorySize(in_Length)); + + Length = (uint16_t)in_Length; + + return true; + } + + inline bool SStringHolder::TryInplaceAppend(const char* in_pStr, const size_t in_Length) + { + if (!IsUnique()) + return false; + + const size_t memSizeAligned = GetMemorySizeAligned(Length + in_Length); + + if (memSizeAligned > GetMemorySizeAligned(Length)) + return false; + + if (in_pStr) + memcpy(&aStr[Length], in_pStr, in_Length); + + memset(&aStr[Length + in_Length], 0, memSizeAligned - GetMemorySize(Length + in_Length)); + + Length = (uint16_t)(Length + in_Length); + + return true; + } + + inline bool SStringHolder::TryInplacePrepend(const char* in_pStr, const size_t in_Length) + { + if (!IsUnique()) + return false; + + const size_t memSizeAligned = GetMemorySizeAligned(in_Length + Length); + + if (memSizeAligned > GetMemorySizeAligned(Length)) + return false; + + memmove(&aStr[in_Length], aStr, Length); + + if (in_pStr) + memcpy(aStr, in_pStr, in_Length); + + memset(&aStr[in_Length + Length], 0, memSizeAligned - GetMemorySize(in_Length + Length)); + + Length = (uint16_t)(in_Length + Length); + + return true; + } +} diff --git a/UnleashedRecomp/api/Hedgehog/Base/Type/hhSharedString.h b/UnleashedRecomp/api/Hedgehog/Base/Type/hhSharedString.h new file mode 100644 index 00000000..54a22e5b --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Base/Type/hhSharedString.h @@ -0,0 +1,88 @@ +#pragma once + +#include + +namespace Hedgehog::Base +{ + class CSharedString + { + private: + xpointer m_pStr; + + SStringHolder* GetHolder() const; + + CSharedString(SStringHolder* in_pHolder); + + public: + static constexpr size_t npos = ~0u; + + CSharedString(); + CSharedString(const char* in_pStr); + CSharedString(const CSharedString& in_rOther); + CSharedString(CSharedString&& io_rOther); + ~CSharedString(); + + const char* get() const; + const char* c_str() const; + const char* data() const; + + size_t size() const; + size_t length() const; + bool empty() const; + + const char* begin() const; + const char* end() const; + + CSharedString substr(size_t pos = 0, size_t len = npos) const; + + size_t find(char c, size_t pos = 0) const; + size_t find(const char* s, size_t pos = 0) const; + size_t rfind(char c, size_t pos = npos) const; + + size_t find_first_of(const char* s, size_t pos = 0) const; + size_t find_last_of(const char* s, size_t pos = npos) const; + size_t find_first_not_of(const char* s, size_t pos = 0) const; + size_t find_last_not_of(const char* s, size_t pos = npos) const; + + size_t find(const CSharedString& str, size_t pos = 0) const; + size_t rfind(const CSharedString& str, size_t pos = npos) const; + + size_t find_first_of(const CSharedString& str, size_t pos = 0) const; + size_t find_last_of(const CSharedString& str, size_t pos = npos) const; + size_t find_first_not_of(const CSharedString& str, size_t pos = 0) const; + size_t find_last_not_of(const CSharedString& str, size_t pos = npos) const; + + void assign(const CSharedString& in_rOther); + void assign(const char* in_pStr); + void assign(CSharedString&& io_rOther); + + void append(const CSharedString& in_rOther); + void append(const char* in_pStr); + + void prepend(const CSharedString& in_rOther); + void prepend(const char* in_pStr); + + int compare(const CSharedString& in_rOther) const; + + CSharedString& operator=(const CSharedString& in_rOther); + CSharedString& operator=(const char* in_pStr); + CSharedString& operator=(CSharedString&& io_rOther); + CSharedString& operator+=(const CSharedString& in_rOther); + CSharedString& operator+=(const char* in_pStr); + + friend CSharedString operator+(const CSharedString& in_rLeft, const CSharedString& in_rRight); + friend CSharedString operator+(const CSharedString& in_rLeft, const char* in_pRight); + friend CSharedString operator+(const char* in_pLeft, const CSharedString& in_pRight); + + bool operator>(const CSharedString& in_rOther) const; + bool operator>=(const CSharedString& in_rOther) const; + bool operator<(const CSharedString& in_rOther) const; + bool operator<=(const CSharedString& in_rOther) const; + bool operator==(const CSharedString& in_rOther) const; + bool operator!=(const CSharedString& in_rOther) const; + bool operator==(const char* in_pOther) const; + bool operator!=(const char* in_pOther) const; + }; +} + +#include diff --git a/UnleashedRecomp/api/Hedgehog/Base/Type/hhSharedString.inl b/UnleashedRecomp/api/Hedgehog/Base/Type/hhSharedString.inl new file mode 100644 index 00000000..67013585 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Base/Type/hhSharedString.inl @@ -0,0 +1,444 @@ +namespace Hedgehog::Base +{ + inline SStringHolder* CSharedString::GetHolder() const + { + return SStringHolder::GetHolder(m_pStr); + } + + inline CSharedString::CSharedString(SStringHolder* in_pHolder) : m_pStr(in_pHolder->aStr) + { + } + + inline CSharedString::CSharedString() : m_pStr(nullptr) + { + } + + inline CSharedString::CSharedString(const char* in_pStr) : m_pStr(nullptr) + { + size_t length; + + if (in_pStr && (length = strlen(in_pStr)) != 0) + m_pStr.ptr = g_memory.MapVirtual(SStringHolder::Make(in_pStr, length)->aStr); + } + + inline CSharedString::CSharedString(const CSharedString& in_rOther) : m_pStr(in_rOther.m_pStr) + { + GetHolder()->AddRef(); + } + + inline CSharedString::CSharedString(CSharedString&& io_rOther) : m_pStr(io_rOther.m_pStr) + { + io_rOther.m_pStr = nullptr; + } + + inline CSharedString::~CSharedString() + { + GetHolder()->Release(); + } + + inline const char* CSharedString::get() const + { + return m_pStr; + } + + inline const char* CSharedString::c_str() const + { + return get(); + } + + inline const char* CSharedString::data() const + { + return get(); + } + + inline size_t CSharedString::size() const + { + return GetHolder()->Length; + } + + inline size_t CSharedString::length() const + { + return size(); + } + + inline bool CSharedString::empty() const + { + return size() == 0; + } + + inline const char* CSharedString::begin() const + { + return get(); + } + + inline const char* CSharedString::end() const + { + return &m_pStr[GetHolder()->Length]; + } + + inline CSharedString CSharedString::substr(size_t pos, size_t len) const + { + if (len == 0) + return CSharedString(); + + if (len > (GetHolder()->Length - pos)) + len = GetHolder()->Length - pos; + + if (pos == 0 && len == GetHolder()->Length) + return *this; + + return SStringHolder::Make(&m_pStr[pos], len); + } + + inline size_t CSharedString::find(char c, size_t pos) const + { + for (size_t i = pos; i < GetHolder()->Length; i++) + { + if (m_pStr[i] == c) + return i; + } + + return npos; + } + + inline size_t CSharedString::find(const char* s, size_t pos) const + { + size_t len = strlen(s); + for (size_t i = pos; i < GetHolder()->Length - len + 1; i++) + { + if (strncmp(m_pStr + i, s, len) == 0) + return i; + } + + return npos; + } + + inline size_t CSharedString::rfind(char c, size_t pos) const + { + if (pos >= GetHolder()->Length) + pos = GetHolder()->Length - 1; + + for (size_t i = pos; i != static_cast(-1); i--) + { + if (m_pStr[i] == c) + return i; + } + + return npos; + } + + inline size_t CSharedString::find_first_of(const char* s, size_t pos) const + { + size_t len = strlen(s); + for (size_t i = pos; i < GetHolder()->Length; i++) + { + for (size_t j = 0; j < len; j++) + { + if (m_pStr[i] == s[j]) + return i; + } + } + + return npos; + } + + inline size_t CSharedString::find_last_of(const char* s, size_t pos) const + { + if (pos >= GetHolder()->Length) + pos = GetHolder()->Length - 1; + + size_t len = strlen(s); + for (size_t i = pos; i != static_cast(-1); i--) + { + for (size_t j = 0; j < len; j++) + { + if (m_pStr[i] == s[j]) + return i; + } + } + + return npos; + } + + inline size_t CSharedString::find_first_not_of(const char* s, size_t pos) const + { + size_t len = strlen(s); + for (size_t i = pos; i < GetHolder()->Length; i++) + { + bool found = false; + for (size_t j = 0; j < len; j++) + { + if (m_pStr[i] == s[j]) + { + found = true; + break; + } + } + + if (!found) + return i; + } + + return npos; + } + + inline size_t CSharedString::find_last_not_of(const char* s, size_t pos) const + { + if (pos >= GetHolder()->Length) + pos = GetHolder()->Length - 1; + + size_t len = strlen(s); + for (size_t i = pos; i != static_cast(-1); i--) + { + bool found = false; + for (size_t j = 0; j < len; j++) + { + if (m_pStr[i] == s[j]) + { + found = true; + break; + } + } + + if (!found) + return i; + } + + return npos; + } + + inline size_t CSharedString::find(const CSharedString& str, size_t pos) const + { + return find(str.c_str(), pos); + } + + inline size_t CSharedString::rfind(const CSharedString& str, size_t pos) const + { + return rfind(str.c_str(), pos); + } + + inline size_t CSharedString::find_first_of(const CSharedString& str, size_t pos) const + { + return find_first_of(str.c_str(), pos); + } + + inline size_t CSharedString::find_last_of(const CSharedString& str, size_t pos) const + { + return find_last_of(str.c_str(), pos); + } + + inline size_t CSharedString::find_first_not_of(const CSharedString& str, size_t pos) const + { + return find_first_not_of(str.c_str(), pos); + } + + inline size_t CSharedString::find_last_not_of(const CSharedString& str, size_t pos) const + { + return find_last_not_of(str.c_str(), pos); + } + + inline void CSharedString::assign(const CSharedString& in_rOther) + { + GetHolder()->Release(); + m_pStr = in_rOther.m_pStr; + GetHolder()->AddRef(); + } + + inline void CSharedString::assign(const char* in_pStr) + { + size_t length; + + if (in_pStr && (length = strlen(in_pStr)) != 0) + { + if (!GetHolder()->TryInplaceAssign(in_pStr, length)) + { + GetHolder()->Release(); + m_pStr = SStringHolder::Make(in_pStr, length)->aStr; + } + } + else + { + GetHolder()->Release(); + m_pStr = nullptr; + } + } + + inline void CSharedString::assign(CSharedString&& io_rOther) + { + m_pStr = io_rOther.m_pStr; + io_rOther.m_pStr = nullptr; + } + + inline void CSharedString::append(const CSharedString& in_rOther) + { + if (!GetHolder()->TryInplaceAppend(in_rOther.GetHolder()->aStr, in_rOther.GetHolder()->Length)) + { + SStringHolder* pHolder = SStringHolder::Concat( + GetHolder()->aStr, GetHolder()->Length, + in_rOther.GetHolder()->aStr, in_rOther.GetHolder()->Length); + + GetHolder()->Release(); + m_pStr = pHolder->aStr; + } + } + + inline void CSharedString::append(const char* in_pStr) + { + size_t length; + + if (in_pStr && (length = strlen(in_pStr)) != 0) + { + if (!GetHolder()->TryInplaceAppend(in_pStr, length)) + { + SStringHolder* pHolder = SStringHolder::Concat( + GetHolder()->aStr, GetHolder()->Length, in_pStr, length); + + GetHolder()->Release(); + m_pStr = pHolder->aStr; + } + } + } + + inline void CSharedString::prepend(const CSharedString& in_rOther) + { + if (!GetHolder()->TryInplacePrepend(in_rOther.GetHolder()->aStr, in_rOther.GetHolder()->Length)) + { + SStringHolder* pHolder = SStringHolder::Concat( + in_rOther.GetHolder()->aStr, in_rOther.GetHolder()->Length, + GetHolder()->aStr, GetHolder()->Length); + + GetHolder()->Release(); + m_pStr = pHolder->aStr; + } + } + + inline void CSharedString::prepend(const char* in_pStr) + { + size_t length; + + if (in_pStr && (length = strlen(in_pStr)) != 0) + { + if (!GetHolder()->TryInplacePrepend(in_pStr, length)) + { + SStringHolder* pHolder = SStringHolder::Concat( + in_pStr, length, GetHolder()->aStr, GetHolder()->Length); + + GetHolder()->Release(); + m_pStr = pHolder->aStr; + } + } + } + + inline int CSharedString::compare(const CSharedString& in_rOther) const + { + // TODO: DO NOT PASS BY REFERENCE. + return GuestToHostFunction(0x82DFB028, this, &in_rOther); + } + + inline CSharedString& CSharedString::operator=(const CSharedString& in_rOther) + { + assign(in_rOther); + return *this; + } + + inline CSharedString& CSharedString::operator=(const char* in_pStr) + { + assign(in_pStr); + return *this; + } + + inline CSharedString& CSharedString::operator=(CSharedString&& io_rOther) + { + assign(std::move(io_rOther)); + return *this; + } + + inline CSharedString& CSharedString::operator+=(const CSharedString& in_rOther) + { + append(in_rOther); + return *this; + } + + inline CSharedString& CSharedString::operator+=(const char* in_pStr) + { + append(in_pStr); + return *this; + } + + inline CSharedString operator+(const CSharedString& in_rLeft, const CSharedString& in_rRight) + { + return SStringHolder::Concat( + in_rLeft.GetHolder()->aStr, in_rLeft.GetHolder()->Length, + in_rRight.GetHolder()->aStr, in_rRight.GetHolder()->Length); + } + + inline CSharedString operator+(const CSharedString& in_rLeft, const char* in_pRight) + { + size_t length; + + if (in_pRight && (length = strlen(in_pRight)) != 0) + { + return SStringHolder::Concat( + in_rLeft.GetHolder()->aStr, in_rLeft.GetHolder()->Length, in_pRight, length); + } + else + { + return in_rLeft; + } + } + + inline CSharedString operator+(const char* in_pLeft, const CSharedString& in_pRight) + { + size_t length; + + if (in_pLeft && (length = strlen(in_pLeft)) != 0) + { + return SStringHolder::Concat( + in_pLeft, length, in_pRight.GetHolder()->aStr, in_pRight.GetHolder()->Length); + } + else + { + return in_pRight; + } + } + + inline bool CSharedString::operator>(const CSharedString& in_rOther) const + { + return compare(in_rOther) > 0; + } + + inline bool CSharedString::operator>=(const CSharedString& in_rOther) const + { + return compare(in_rOther) >= 0; + } + + inline bool CSharedString::operator<(const CSharedString& in_rOther) const + { + return compare(in_rOther) < 0; + } + + inline bool CSharedString::operator<=(const CSharedString& in_rOther) const + { + return compare(in_rOther) <= 0; + } + + inline bool CSharedString::operator==(const CSharedString& in_rOther) const + { + return compare(in_rOther) == 0; + } + + inline bool CSharedString::operator!=(const CSharedString& in_rOther) const + { + return !(*this == in_rOther); + } + + inline bool CSharedString::operator==(const char* in_pOther) const + { + return strcmp(c_str(), in_pOther) == 0; + } + + inline bool CSharedString::operator!=(const char* in_pOther) const + { + return !(*this == in_pOther); + } +} diff --git a/UnleashedRecomp/api/Hedgehog/Base/hhObject.h b/UnleashedRecomp/api/Hedgehog/Base/hhObject.h new file mode 100644 index 00000000..80723ee2 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Base/hhObject.h @@ -0,0 +1,23 @@ +#pragma once + +#include "SWA.inl" + +namespace Hedgehog::Base +{ + class CObject + { + public: + CObject(); + CObject(const swa_null_ctor&); + + void* operator new(const size_t in_Size); + void* operator new(const size_t in_Size, const size_t in_Align); + + void operator delete(void* in_pMem); + + void* operator new(const size_t in_Size, void* in_pObj); + void* operator new(const size_t in_Size, const size_t in_Align, void* in_pObj); + + void operator delete(void* in_pMem, void* in_pObj); + }; +} diff --git a/UnleashedRecomp/api/Hedgehog/Database/System/hhDatabaseData.h b/UnleashedRecomp/api/Hedgehog/Database/System/hhDatabaseData.h new file mode 100644 index 00000000..8552a514 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Database/System/hhDatabaseData.h @@ -0,0 +1,39 @@ +#pragma once + +#include "Hedgehog/Base/hhObject.h" + +namespace Hedgehog::Database +{ + enum EDatabaseDataFlags : uint8_t + { + eDatabaseDataFlags_IsMadeOne = 0x1, + eDatabaseDataFlags_IsMadeAll = 0x2, + eDatabaseDataFlags_CreatedFromArchive = 0x4, + eDatabaseDataFlags_IsMadeMakingOne = 0x8 + }; + + class CDatabaseData : public Base::CObject + { + public: + struct Vftable + { + be m_fpDtor; + be m_fpCheckMadeAll; + }; + + xpointer m_pVftable; + uint8_t m_Flags; + Base::CSharedString m_TypeAndName; + + ~CDatabaseData(); + bool CheckMadeAll(); + + bool IsMadeOne() const; + void SetMadeOne(); + + bool IsMadeAllInternal(); + bool IsMadeAll(); + }; +} + +#include "Hedgehog/Database/System/hhDatabaseData.inl" diff --git a/UnleashedRecomp/api/Hedgehog/Database/System/hhDatabaseData.inl b/UnleashedRecomp/api/Hedgehog/Database/System/hhDatabaseData.inl new file mode 100644 index 00000000..7e3e383f --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Database/System/hhDatabaseData.inl @@ -0,0 +1,36 @@ +namespace Hedgehog::Database +{ + inline CDatabaseData::~CDatabaseData() + { + GuestToHostFunction(m_pVftable->m_fpDtor, this); + } + + inline bool CDatabaseData::CheckMadeAll() + { + return true; + } + + inline bool CDatabaseData::IsMadeOne() const + { + return (m_Flags & eDatabaseDataFlags_IsMadeOne) != 0; + } + + inline void CDatabaseData::SetMadeOne() + { + m_Flags |= eDatabaseDataFlags_IsMadeOne; + } + + inline bool CDatabaseData::IsMadeAllInternal() + { + if ((m_Flags & eDatabaseDataFlags_IsMadeOne) == 0 || !CheckMadeAll()) + return false; + + m_Flags |= eDatabaseDataFlags_IsMadeAll; + return true; + } + + inline bool CDatabaseData::IsMadeAll() + { + return (m_Flags & eDatabaseDataFlags_IsMadeAll) != 0 || IsMadeAllInternal(); + } +} diff --git a/UnleashedRecomp/api/Hedgehog/Math/Vector2.h b/UnleashedRecomp/api/Hedgehog/Math/Vector2.h new file mode 100644 index 00000000..bc167197 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Math/Vector2.h @@ -0,0 +1,13 @@ +#pragma once + +#include "SWA.inl" + +namespace Hedgehog::Math +{ + class CVector2 + { + public: + be X; + be Y; + }; +} diff --git a/UnleashedRecomp/api/Hedgehog/MirageCore/Renderable/hhRenderable.h b/UnleashedRecomp/api/Hedgehog/MirageCore/Renderable/hhRenderable.h new file mode 100644 index 00000000..73fd409e --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/MirageCore/Renderable/hhRenderable.h @@ -0,0 +1,14 @@ +#pragma once + +#include "SWA.inl" +#include "Hedgehog/Base/hhObject.h" + +namespace Hedgehog::Mirage +{ + class CRenderable : public Base::CObject + { + public: + xpointer m_pVftable; + bool m_Enabled; + }; +} diff --git a/UnleashedRecomp/api/Hedgehog/Universe/Engine/hhMessageActor.h b/UnleashedRecomp/api/Hedgehog/Universe/Engine/hhMessageActor.h new file mode 100644 index 00000000..c7d55493 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Universe/Engine/hhMessageActor.h @@ -0,0 +1,14 @@ +#pragma once + +#include "SWA.inl" +#include "Hedgehog/Universe/Engine/hhMessageProcess.h" +#include "Hedgehog/Universe/Thread/hhParallelJob.h" + +namespace Hedgehog::Universe +{ + class CMessageActor : public IMessageProcess, public IParallelJob + { + public: + SWA_INSERT_PADDING(0x88); + }; +} diff --git a/UnleashedRecomp/api/Hedgehog/Universe/Engine/hhMessageProcess.h b/UnleashedRecomp/api/Hedgehog/Universe/Engine/hhMessageProcess.h new file mode 100644 index 00000000..b5b42d49 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Universe/Engine/hhMessageProcess.h @@ -0,0 +1,14 @@ +#pragma once + +#include "SWA.inl" +#include "Hedgehog/Base/hhObject.h" + +namespace Hedgehog::Universe +{ + class IMessageProcess : public Base::CObject + { + public: + IMessageProcess() {} + IMessageProcess(const swa_null_ctor& nil) : CObject(nil) {} + }; +} diff --git a/UnleashedRecomp/api/Hedgehog/Universe/Engine/hhUpdateInfo.h b/UnleashedRecomp/api/Hedgehog/Universe/Engine/hhUpdateInfo.h new file mode 100644 index 00000000..4369392e --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Universe/Engine/hhUpdateInfo.h @@ -0,0 +1,13 @@ +#pragma once + +#include "SWA.inl" + +namespace Hedgehog::Universe +{ + struct SUpdateInfo + { + be DeltaTime; + be Frame; + Base::CSharedString Category; + }; +} diff --git a/UnleashedRecomp/api/Hedgehog/Universe/Engine/hhUpdateUnit.h b/UnleashedRecomp/api/Hedgehog/Universe/Engine/hhUpdateUnit.h new file mode 100644 index 00000000..64513e66 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Universe/Engine/hhUpdateUnit.h @@ -0,0 +1,25 @@ +#pragma once + +#include "SWA.inl" +#include "Hedgehog/Universe/Thread/hhParallelJob.h" + +namespace Hedgehog::Universe +{ + class CUpdateUnit : public Base::CObject, public IParallelJob + { + public: + xpointer m_pVftable; + SWA_INSERT_PADDING(0x20); + + CUpdateUnit(const swa_null_ctor& nil) : CObject(nil), IParallelJob(nil) {} + CUpdateUnit(); + + // TODO: implement virtual functions. + // virtual ~CUpdateUnit(); + // + // virtual void ExecuteParallelJob(const SUpdateInfo& in_rUpdateInfo) override; + // + // virtual void UpdateParallel(const SUpdateInfo& in_rUpdateInfo) {} + // virtual void UpdateSerial(const SUpdateInfo& in_rUpdateInfo) {} + }; +} diff --git a/UnleashedRecomp/api/Hedgehog/Universe/Thread/hhParallelJob.h b/UnleashedRecomp/api/Hedgehog/Universe/Thread/hhParallelJob.h new file mode 100644 index 00000000..60b59be3 --- /dev/null +++ b/UnleashedRecomp/api/Hedgehog/Universe/Thread/hhParallelJob.h @@ -0,0 +1,21 @@ +#pragma once + +#include "SWA.inl" +#include "Hedgehog/Universe/Engine/hhUpdateInfo.h" + +namespace Hedgehog::Universe +{ + class IParallelJob + { + public: + xpointer m_pVftable; + + IParallelJob() {} + IParallelJob(const swa_null_ctor&) {} + + // TODO: implement virtual functions. + // virtual ~IParallelJob() = default; + // + // virtual void ExecuteParallelJob(const SUpdateInfo& in_rUpdateInfo) = 0; + }; +} diff --git a/UnleashedRecomp/api/SWA.h b/UnleashedRecomp/api/SWA.h index 7a93b527..305f36d4 100644 --- a/UnleashedRecomp/api/SWA.h +++ b/UnleashedRecomp/api/SWA.h @@ -1,10 +1,68 @@ #pragma once +#include "Hedgehog/Base/hhObject.h" +#include "Hedgehog/Base/System/hhAllocator.h" +#include "Hedgehog/Base/Thread/hhHolder.h" +#include "Hedgehog/Base/Thread/hhHolderBase.h" +#include "Hedgehog/Base/Thread/hhSynchronizedObject.h" +#include "Hedgehog/Base/Thread/hhSynchronizedPtr.h" +#include "Hedgehog/Base/Type/hhSharedString.h" +#include "Hedgehog/Database/System/hhDatabaseData.h" +#include "Hedgehog/Math/Vector2.h" +#include "Hedgehog/MirageCore/Renderable/hhRenderable.h" +#include "Hedgehog/Universe/Engine/hhMessageActor.h" +#include "Hedgehog/Universe/Engine/hhMessageProcess.h" +#include "Hedgehog/Universe/Engine/hhUpdateInfo.h" +#include "Hedgehog/Universe/Engine/hhUpdateUnit.h" +#include "Hedgehog/Universe/Thread/hhParallelJob.h" + +#include "CSD/Manager/csdmBase.h" +#include "CSD/Manager/csdmMotionPattern.h" +#include "CSD/Manager/csdmNode.h" +#include "CSD/Manager/csdmNodeObserver.h" +#include "CSD/Manager/csdmObserverBase.h" +#include "CSD/Manager/csdmProject.h" +#include "CSD/Manager/csdmRCObject.h" +#include "CSD/Manager/csdmRCObjectImp.h" +#include "CSD/Manager/csdmRCPtr.h" +#include "CSD/Manager/csdmRCPtrAbs.h" +#include "CSD/Manager/csdmResourceBase.h" +#include "CSD/Manager/csdmScene.h" +#include "CSD/Manager/csdmSceneObserver.h" +#include "CSD/Manager/csdmSubjectBase.h" +#include "CSD/Platform/csdTexList.h" + #include "SWA/Camera/Camera.h" +#include "SWA/CSD/CsdDatabaseWrapper.h" +#include "SWA/CSD/CsdProject.h" +#include "SWA/CSD/CsdTexListMirage.h" +#include "SWA/CSD/GameObjectCSD.h" +#include "SWA/HUD/GeneralWindow/GeneralWindow.h" +#include "SWA/HUD/Loading/Loading.h" +#include "SWA/HUD/Pause/HudPause.h" +#include "SWA/HUD/Sonic/HudSonicStage.h" +#include "SWA/Movie/MovieDisplayer.h" +#include "SWA/Movie/MovieManager.h" #include "SWA/Player/Character/EvilSonic/Hud/EvilHudGuide.h" #include "SWA/Player/Character/EvilSonic/EvilSonic.h" #include "SWA/Player/Character/EvilSonic/EvilSonicContext.h" +#include "SWA/Sequence/Unit/SequenceUnitBase.h" +#include "SWA/Sequence/Unit/SequenceUnitPlayMovie.h" +#include "SWA/Sequence/Utility/SequencePlayMovieWrapper.h" +#include "SWA/Sound/Sound.h" +#include "SWA/Sound/SoundBGMActSonic.h" +#include "SWA/Sound/SoundBGMBase.h" +#include "SWA/System/GameMode/Title/TitleMenu.h" +#include "SWA/System/GameMode/Title/TitleStateBase.h" +#include "SWA/System/GameMode/GameMode.h" +#include "SWA/System/GameMode/GameModeStage.h" +#include "SWA/System/GameMode/GameModeStageMovie.h" +#include "SWA/System/Application.h" +#include "SWA/System/ApplicationD3D9.h" +#include "SWA/System/ApplicationXenon.h" #include "SWA/System/ApplicationDocument.h" +#include "SWA/System/Game.h" #include "SWA/System/GameDocument.h" +#include "SWA/System/GameObject.h" #include "SWA/System/InputState.h" #include "SWA/System/PadState.h" diff --git a/UnleashedRecomp/api/SWA.inl b/UnleashedRecomp/api/SWA.inl index 005c0c83..3c6261f8 100644 --- a/UnleashedRecomp/api/SWA.inl +++ b/UnleashedRecomp/api/SWA.inl @@ -1,9 +1,16 @@ #pragma once #include +#include +#include #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] + +#define SWA_VIRTUAL_FUNCTION(returnType, virtualIndex, ...) \ + GuestToHostFunction(*(be*)(g_memory.Translate(*(be*)(this) + (4 * virtualIndex))), __VA_ARGS__) + +struct swa_null_ctor {}; diff --git a/UnleashedRecomp/api/SWA/CSD/CsdDatabaseWrapper.h b/UnleashedRecomp/api/SWA/CSD/CsdDatabaseWrapper.h new file mode 100644 index 00000000..94abf973 --- /dev/null +++ b/UnleashedRecomp/api/SWA/CSD/CsdDatabaseWrapper.h @@ -0,0 +1,25 @@ +#pragma once + +#include "boost/smart_ptr/shared_ptr.h" + +namespace Hedgehog::Database +{ + class CDatabase; +} + +namespace SWA +{ + class CCsdProject; + + class CCsdDatabaseWrapper + { + public: + Hedgehog::Database::CDatabase* m_pDatabase; + + CCsdDatabaseWrapper(Hedgehog::Database::CDatabase* in_pDatabase) : m_pDatabase(in_pDatabase) {} + + boost::shared_ptr GetCsdProject(const Hedgehog::Base::CSharedString& in_rName); + }; +} + +#include "SWA/CSD/CsdDatabaseWrapper.inl" diff --git a/UnleashedRecomp/api/SWA/CSD/CsdDatabaseWrapper.inl b/UnleashedRecomp/api/SWA/CSD/CsdDatabaseWrapper.inl new file mode 100644 index 00000000..414c6465 --- /dev/null +++ b/UnleashedRecomp/api/SWA/CSD/CsdDatabaseWrapper.inl @@ -0,0 +1,9 @@ +namespace SWA +{ + inline boost::shared_ptr CCsdDatabaseWrapper::GetCsdProject(const Hedgehog::Base::CSharedString& in_rName) + { + boost::shared_ptr spCsdProject; + GuestToHostFunction(0x825E2B40, &in_rName, this, &spCsdProject, 0); + return spCsdProject; + } +} diff --git a/UnleashedRecomp/api/SWA/CSD/CsdProject.h b/UnleashedRecomp/api/SWA/CSD/CsdProject.h new file mode 100644 index 00000000..0211933a --- /dev/null +++ b/UnleashedRecomp/api/SWA/CSD/CsdProject.h @@ -0,0 +1,18 @@ +#pragma once + +#include "CSD/Manager/csdmRCPtr.h" +#include "Hedgehog/Database/System/hhDatabaseData.h" + +namespace Chao::CSD +{ + class CProject; +} + +namespace SWA +{ + class CCsdProject : public Hedgehog::Database::CDatabaseData + { + public: + Chao::CSD::RCPtr m_rcProject; + }; +} diff --git a/UnleashedRecomp/api/SWA/CSD/CsdTexListMirage.h b/UnleashedRecomp/api/SWA/CSD/CsdTexListMirage.h new file mode 100644 index 00000000..ee0be919 --- /dev/null +++ b/UnleashedRecomp/api/SWA/CSD/CsdTexListMirage.h @@ -0,0 +1,18 @@ +#pragma once + +#include "CSD/Platform/csdTexList.h" + +namespace Hedgehog::Mirage +{ + class CTexsetData; +} + +namespace SWA +{ + class CCsdTexListMirage : public Chao::CSD::CTexList + { + public: + boost::shared_ptr m_spTexsetData; + SWA_INSERT_PADDING(0x04); + }; +} diff --git a/UnleashedRecomp/api/SWA/CSD/GameObjectCSD.h b/UnleashedRecomp/api/SWA/CSD/GameObjectCSD.h new file mode 100644 index 00000000..5049fdb0 --- /dev/null +++ b/UnleashedRecomp/api/SWA/CSD/GameObjectCSD.h @@ -0,0 +1,20 @@ +#pragma once + +#include "SWA.inl" +#include "CSD/Manager/csdmRCPtr.h" +#include "SWA/System/GameObject.h" + +namespace Chao::CSD +{ + class CProject; +} + +namespace SWA +{ + class CGameObjectCSD : public CGameObject + { + public: + xpointer m_pVftable; + Chao::CSD::RCPtr m_rcProject; + }; +} diff --git a/UnleashedRecomp/api/SWA/Camera/Camera.h b/UnleashedRecomp/api/SWA/Camera/Camera.h index 7737d9cb..1d3db6c6 100644 --- a/UnleashedRecomp/api/SWA/Camera/Camera.h +++ b/UnleashedRecomp/api/SWA/Camera/Camera.h @@ -1,13 +1,15 @@ #pragma once -#include "SWA.inl" +#include +#include namespace SWA { - class CCamera // : public CGameObject, public Hedgehog::Universe::TStateMachine + class CCamera : public CGameObject // , public Hedgehog::Universe::TStateMachine { public: - SWA_INSERT_PADDING(0x184); + xpointer m_pVftable; + SWA_INSERT_PADDING(0xC4); be m_VertAspectRatio; SWA_INSERT_PADDING(0x48); be m_HorzAspectRatio; @@ -15,5 +17,8 @@ namespace SWA be m_FieldOfView; be m_VertFieldOfView; be m_HorzFieldOfView; + SWA_INSERT_PADDING(0x18); + bool m_InvertY; + bool m_InvertX; }; } diff --git a/UnleashedRecomp/api/SWA/HUD/GeneralWindow/GeneralWindow.h b/UnleashedRecomp/api/SWA/HUD/GeneralWindow/GeneralWindow.h new file mode 100644 index 00000000..6728eba1 --- /dev/null +++ b/UnleashedRecomp/api/SWA/HUD/GeneralWindow/GeneralWindow.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace SWA +{ + class CGeneralWindow + { + public: + SWA_INSERT_PADDING(0xD0); + Chao::CSD::RCPtr m_rcGeneral; + Chao::CSD::RCPtr m_rcBg; + Chao::CSD::RCPtr m_rcWindow; + Chao::CSD::RCPtr m_rcWindow_2; + Chao::CSD::RCPtr m_rcWindowSelect; + Chao::CSD::RCPtr m_rcFooter; + }; +} diff --git a/UnleashedRecomp/api/SWA/HUD/Loading/Loading.h b/UnleashedRecomp/api/SWA/HUD/Loading/Loading.h new file mode 100644 index 00000000..a70dad0d --- /dev/null +++ b/UnleashedRecomp/api/SWA/HUD/Loading/Loading.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +namespace SWA +{ + enum ELoadingDisplayType + { + eLoadingDisplayType_MilesElectric, + eLoadingDisplayType_None, + eLoadingDisplayType_WerehogMovie, + eLoadingDisplayType_MilesElectricContext, + eLoadingDisplayType_Arrows, + eLoadingDisplayType_NowLoading, + eLoadingDisplayType_EventGallery, + eLoadingDisplayType_ChangeTimeOfDay, + eLoadingDisplayType_Blank + }; + + class CLoading + { + public: + SWA_INSERT_PADDING(0x128); + bool m_IsVisible; + SWA_INSERT_PADDING(0x0C); + be m_LoadingDisplayType; + SWA_INSERT_PADDING(0x65); + bool m_IsNightToDay; + }; +} diff --git a/UnleashedRecomp/api/SWA/HUD/Pause/HudPause.h b/UnleashedRecomp/api/SWA/HUD/Pause/HudPause.h new file mode 100644 index 00000000..f4e67093 --- /dev/null +++ b/UnleashedRecomp/api/SWA/HUD/Pause/HudPause.h @@ -0,0 +1,67 @@ +#pragma once + +#include + +using namespace Chao::CSD; + +namespace SWA +{ + enum EActionType : uint32_t + { + eActionType_Undefined, + eActionType_Status, + eActionType_Return, + eActionType_Inventory, + eActionType_Skills, + eActionType_Lab, + eActionType_Wait, + eActionType_Restart = 8, + eActionType_Continue + }; + + enum EMenuType : uint32_t + { + eMenuType_WorldMap, + eMenuType_Village, + eMenuType_Stage, + eMenuType_Hub, + eMenuType_Misc + }; + + enum EStatusType : uint32_t + { + eStatusType_Idle, + eStatusType_Accept, + eStatusType_Decline + }; + + enum ETransitionType : uint32_t + { + eTransitionType_Undefined, + eTransitionType_Quit = 2, + eTransitionType_Dialog = 5, + eTransitionType_Hide, + eTransitionType_Abort, + eTransitionType_SubMenu + }; + + class CHudPause : public CGameObject + { + public: + xpointer m_pVftable; + SWA_INSERT_PADDING(0x2C); + RCPtr m_rcPause; + RCPtr m_rcBg; + RCPtr m_rcBg1; + RCPtr m_rcBg1_2; + RCPtr m_rcBg1Select; + RCPtr m_rcBg1Select_2; + RCPtr m_rcStatusTitle; + RCPtr m_rcFooterA; + SWA_INSERT_PADDING(0x5C); + be m_Action; + be m_Menu; + be m_Status; + be m_Transition; + }; +} diff --git a/UnleashedRecomp/api/SWA/HUD/Sonic/HudSonicStage.h b/UnleashedRecomp/api/SWA/HUD/Sonic/HudSonicStage.h new file mode 100644 index 00000000..59e2d070 --- /dev/null +++ b/UnleashedRecomp/api/SWA/HUD/Sonic/HudSonicStage.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +namespace SWA +{ + class CHudSonicStage + { + public: + SWA_INSERT_PADDING(0xE0); + Chao::CSD::RCPtr m_rcPlayScreen; + Chao::CSD::RCPtr m_rcSpeedGauge; + Chao::CSD::RCPtr m_rcRingEnergyGauge; + Chao::CSD::RCPtr m_rcGaugeFrame; + SWA_INSERT_PADDING(0x28); + Chao::CSD::RCPtr m_rcScoreCount; + Chao::CSD::RCPtr m_rcTimeCount; + Chao::CSD::RCPtr m_rcTimeCount2; + Chao::CSD::RCPtr m_rcTimeCount3; + Chao::CSD::RCPtr m_rcPlayerCount; + }; +} diff --git a/UnleashedRecomp/api/SWA/Movie/MovieDisplayer.h b/UnleashedRecomp/api/SWA/Movie/MovieDisplayer.h new file mode 100644 index 00000000..64e13e34 --- /dev/null +++ b/UnleashedRecomp/api/SWA/Movie/MovieDisplayer.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +namespace SWA +{ + class CMovieDisplayer : public Hedgehog::Universe::CUpdateUnit, public Hedgehog::Mirage::CRenderable + { + public: + SWA_INSERT_PADDING(0x04); + be m_MovieWidth; + be m_MovieHeight; + }; +} diff --git a/UnleashedRecomp/api/SWA/Movie/MovieManager.h b/UnleashedRecomp/api/SWA/Movie/MovieManager.h new file mode 100644 index 00000000..4de3429e --- /dev/null +++ b/UnleashedRecomp/api/SWA/Movie/MovieManager.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +namespace SWA +{ + class CMovieManager // : Hedgehog::Base::TSingleton + { + public: + static CMovieManager* GetInstance(); + + xpointer m_pVftable; + SWA_INSERT_PADDING(0x330); + }; +} + +#include "SWA/Movie/MovieManager.inl" diff --git a/UnleashedRecomp/api/SWA/Movie/MovieManager.inl b/UnleashedRecomp/api/SWA/Movie/MovieManager.inl new file mode 100644 index 00000000..e9412070 --- /dev/null +++ b/UnleashedRecomp/api/SWA/Movie/MovieManager.inl @@ -0,0 +1,7 @@ +namespace SWA +{ + inline CMovieManager* CMovieManager::GetInstance() + { + return *(xpointer*)MmGetHostAddress(0x8336758C); + } +} diff --git a/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/EvilSonic.h b/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/EvilSonic.h index d6b510ea..bee25d07 100644 --- a/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/EvilSonic.h +++ b/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/EvilSonic.h @@ -5,7 +5,7 @@ namespace SWA::Player { - class CEvilSonic + class CEvilSonic // : public CPlayer { public: SWA_INSERT_PADDING(0xC4); diff --git a/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/Hud/EvilHudGuide.h b/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/Hud/EvilHudGuide.h index 090d5b09..d872fe48 100644 --- a/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/Hud/EvilHudGuide.h +++ b/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/Hud/EvilHudGuide.h @@ -18,12 +18,13 @@ namespace SWA::Player eGuideType_Y }; - class CEvilHudGuide + class CEvilHudGuide : public CGameObject { public: - SWA_INSERT_PADDING(0x14D); + xpointer m_pVftable; + SWA_INSERT_PADDING(0x8D); bool m_IsShown; bool m_IsVisible; - EGuideType m_GuideType; + be m_GuideType; }; } diff --git a/UnleashedRecomp/api/SWA/Sequence/Unit/SequenceUnitBase.h b/UnleashedRecomp/api/SWA/Sequence/Unit/SequenceUnitBase.h new file mode 100644 index 00000000..d45387f2 --- /dev/null +++ b/UnleashedRecomp/api/SWA/Sequence/Unit/SequenceUnitBase.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace SWA::Sequence::Unit +{ + class CUnitBase : public Hedgehog::Base::CObject + { + public: + xpointer m_pVftable; + SWA_INSERT_PADDING(0x14); + }; +} diff --git a/UnleashedRecomp/api/SWA/Sequence/Unit/SequenceUnitPlayMovie.h b/UnleashedRecomp/api/SWA/Sequence/Unit/SequenceUnitPlayMovie.h new file mode 100644 index 00000000..b7f64e36 --- /dev/null +++ b/UnleashedRecomp/api/SWA/Sequence/Unit/SequenceUnitPlayMovie.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace SWA::Sequence::Unit +{ + class CPlayMovieUnit : public CUnitBase {}; +} diff --git a/UnleashedRecomp/api/SWA/Sequence/Utility/SequencePlayMovieWrapper.h b/UnleashedRecomp/api/SWA/Sequence/Utility/SequencePlayMovieWrapper.h new file mode 100644 index 00000000..a73c7add --- /dev/null +++ b/UnleashedRecomp/api/SWA/Sequence/Utility/SequencePlayMovieWrapper.h @@ -0,0 +1,39 @@ +#pragma once + +#include "SWA.inl" +#include "Hedgehog/MirageCore/Renderable/hhRenderable.h" + +namespace SWA::Sequence::Utility +{ + class CPlayMovieWrapper + { + public: + class CRender : public Hedgehog::Mirage::CRenderable + { + public: + 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); + bool m_MaintainAspectRatio; + SWA_INSERT_PADDING(0x18); + be m_TimeElapsed; + }; + + SWA_INSERT_PADDING(0x18); + xpointer m_pRender; + }; +} diff --git a/UnleashedRecomp/api/SWA/Sound/Sound.h b/UnleashedRecomp/api/SWA/Sound/Sound.h new file mode 100644 index 00000000..d43c43a7 --- /dev/null +++ b/UnleashedRecomp/api/SWA/Sound/Sound.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include + +namespace SWA +{ + class CSoundAdministrator : public CGameObject + { + public: + class CSimplePlayer {}; + + class CBgm + { + public: + xpointer m_pThis; + boost::shared_ptr m_spSoundBGM; + be m_Volume1; + be m_Volume2; + be m_Volume3; + be m_Volume4; + SWA_INSERT_PADDING(0x10); + }; + + class CCommunicator + { + public: + class CCommunicatorDevice : Hedgehog::Base::CSynchronizedObject + { + public: + SWA_INSERT_PADDING(0x08); + Hedgehog::Base::CSharedString m_HostName; + SWA_INSERT_PADDING(0x04); + Hedgehog::Base::CSharedString m_Category; + Hedgehog::Base::CSharedString m_Command; + SWA_INSERT_PADDING(0x04); + }; + + xpointer m_pThis; + boost::shared_ptr m_spCommunicatorDevice; + }; + + class CMember + { + public: + boost::shared_ptr m_spSimplePlayer; + boost::shared_ptr m_spBgm; + boost::shared_ptr m_spCommunicator; + SWA_INSERT_PADDING(0x58); + }; + + xpointer m_pVftable; + SWA_INSERT_PADDING(0x04); + xpointer m_pMember; + }; +} diff --git a/UnleashedRecomp/api/SWA/Sound/SoundBGMActSonic.h b/UnleashedRecomp/api/SWA/Sound/SoundBGMActSonic.h new file mode 100644 index 00000000..5f3371ac --- /dev/null +++ b/UnleashedRecomp/api/SWA/Sound/SoundBGMActSonic.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +namespace SWA +{ + class CSoundBGMActSonic : public CSoundBGMBase + { + public: + class CMember + { + public: + SWA_INSERT_PADDING(0x58); + be m_Volume1; + be m_Volume2; + }; + + xpointer m_pMember; + }; +} diff --git a/UnleashedRecomp/api/SWA/Sound/SoundBGMBase.h b/UnleashedRecomp/api/SWA/Sound/SoundBGMBase.h new file mode 100644 index 00000000..3f8a7c2f --- /dev/null +++ b/UnleashedRecomp/api/SWA/Sound/SoundBGMBase.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace SWA +{ + class CSoundBGMBase : Hedgehog::Universe::CMessageActor + { + public: + SWA_INSERT_PADDING(0x04); // vftable ptr + SWA_INSERT_PADDING(0x04); + xpointer m_pGameDocument; + bool m_Unk; + }; +} diff --git a/UnleashedRecomp/api/SWA/System/Application.h b/UnleashedRecomp/api/SWA/System/Application.h new file mode 100644 index 00000000..5efd399a --- /dev/null +++ b/UnleashedRecomp/api/SWA/System/Application.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +namespace SWA +{ + class CApplication : public Hedgehog::Base::CObject + { + public: + class CMember + { + public: + xpointer m_pApplicationDocument; + }; + + xpointer m_pVftable; + xpointer m_pMember; + SWA_INSERT_PADDING(0x18); + }; +} diff --git a/UnleashedRecomp/api/SWA/System/ApplicationD3D9.h b/UnleashedRecomp/api/SWA/System/ApplicationD3D9.h new file mode 100644 index 00000000..ef88f297 --- /dev/null +++ b/UnleashedRecomp/api/SWA/System/ApplicationD3D9.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace SWA +{ + class CApplicationD3D9 : public CApplication {}; +} diff --git a/UnleashedRecomp/api/SWA/System/ApplicationDocument.h b/UnleashedRecomp/api/SWA/System/ApplicationDocument.h index 598c4715..6dfdc7da 100644 --- a/UnleashedRecomp/api/SWA/System/ApplicationDocument.h +++ b/UnleashedRecomp/api/SWA/System/ApplicationDocument.h @@ -1,24 +1,54 @@ #pragma once +#include +#include + namespace SWA { - class CApplicationDocument // : public Hedgehog::Base::CSynchronizedObject + enum ELanguage : uint32_t + { + eLanguage_English, + eLanguage_Japanese, + eLanguage_German, + eLanguage_French, + eLanguage_Italian, + eLanguage_Spanish + }; + + enum EVoiceLanguage : uint32_t + { + eVoiceLanguage_English, + eVoiceLanguage_Japanese + }; + + enum ERegion : uint32_t + { + eRegion_Japan, + eRegion_RestOfWorld + }; + + class CApplicationDocument : public Hedgehog::Base::CSynchronizedObject { public: class CMember { public: - SWA_INSERT_PADDING(0x138); - void* m_spGameParameter; + SWA_INSERT_PADDING(0x20); + boost::shared_ptr m_pGame; + SWA_INSERT_PADDING(0x114); + xpointer m_spGameParameter; }; // TODO: Hedgehog::Base::TSynchronizedPtr static CApplicationDocument* GetInstance(); - SWA_INSERT_PADDING(0x04); xpointer m_pMember; - SWA_INSERT_PADDING(0x14); - be m_Region; + be m_Language; + be m_VoiceLanguage; + SWA_INSERT_PADDING(0x08); + be m_Region; + bool m_InspireVoices; + bool m_InspireSubtitles; }; } diff --git a/UnleashedRecomp/api/SWA/System/ApplicationXenon.h b/UnleashedRecomp/api/SWA/System/ApplicationXenon.h new file mode 100644 index 00000000..ed5d6c1c --- /dev/null +++ b/UnleashedRecomp/api/SWA/System/ApplicationXenon.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +namespace SWA +{ + class CApplicationXenon : public CApplicationD3D9 + { + public: + SWA_INSERT_PADDING(0x1B4); + }; +} diff --git a/UnleashedRecomp/api/SWA/System/Game.h b/UnleashedRecomp/api/SWA/System/Game.h new file mode 100644 index 00000000..9e0101ae --- /dev/null +++ b/UnleashedRecomp/api/SWA/System/Game.h @@ -0,0 +1,10 @@ +#pragma once + +namespace SWA +{ + class CGame // : Hedgehog::Universe::TStateMachine + { + public: + SWA_INSERT_PADDING(0xFC); + }; +} diff --git a/UnleashedRecomp/api/SWA/System/GameDocument.h b/UnleashedRecomp/api/SWA/System/GameDocument.h index e13f6071..f07c3240 100644 --- a/UnleashedRecomp/api/SWA/System/GameDocument.h +++ b/UnleashedRecomp/api/SWA/System/GameDocument.h @@ -1,21 +1,30 @@ #pragma once +namespace Hedgehog::Database +{ + class CDatabase; +} + namespace SWA { - class CGameDocument // : public Hedgehog::Base::CSynchronizedObject + class CGameDocument : public Hedgehog::Base::CSynchronizedObject { public: class CMember { public: - SWA_INSERT_PADDING(0x20C); + SWA_INSERT_PADDING(0x1C); + boost::shared_ptr m_spDatabase; + SWA_INSERT_PADDING(0x8C); + xpointer m_pSoundAdministrator; + SWA_INSERT_PADDING(0x158); be m_Score; }; // TODO: Hedgehog::Base::TSynchronizedPtr static CGameDocument* GetInstance(); - SWA_INSERT_PADDING(0x08); + xpointer m_pVftable; xpointer m_pMember; }; } diff --git a/UnleashedRecomp/api/SWA/System/GameMode/GameMode.h b/UnleashedRecomp/api/SWA/System/GameMode/GameMode.h new file mode 100644 index 00000000..5b6c35dc --- /dev/null +++ b/UnleashedRecomp/api/SWA/System/GameMode/GameMode.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace SWA +{ + class CGameMode // : Hedgehog::Universe::TStateMachine::TState + { + public: + SWA_INSERT_PADDING(0x60); // base + SWA_INSERT_PADDING(0x08); + }; +} diff --git a/UnleashedRecomp/api/SWA/System/GameMode/GameModeStage.h b/UnleashedRecomp/api/SWA/System/GameMode/GameModeStage.h new file mode 100644 index 00000000..eeba70c5 --- /dev/null +++ b/UnleashedRecomp/api/SWA/System/GameMode/GameModeStage.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace SWA +{ + class CGameModeStage : public CGameMode + { + public: + xpointer m_pVftable; + SWA_INSERT_PADDING(0x1B4); + }; +} diff --git a/UnleashedRecomp/api/SWA/System/GameMode/GameModeStageMovie.h b/UnleashedRecomp/api/SWA/System/GameMode/GameModeStageMovie.h new file mode 100644 index 00000000..e1a95df4 --- /dev/null +++ b/UnleashedRecomp/api/SWA/System/GameMode/GameModeStageMovie.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +namespace SWA +{ + class CGameModeStageMovie : public CGameModeStage + { + public: + class CRender : public Hedgehog::Mirage::CRenderable + { + public: + xpointer m_pThis; + }; + + xpointer m_pVftable; + SWA_INSERT_PADDING(0x224); + xpointer m_pRender; + }; +} diff --git a/UnleashedRecomp/api/SWA/System/GameMode/Title/TitleMenu.h b/UnleashedRecomp/api/SWA/System/GameMode/Title/TitleMenu.h new file mode 100644 index 00000000..a533e260 --- /dev/null +++ b/UnleashedRecomp/api/SWA/System/GameMode/Title/TitleMenu.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace SWA +{ + class CTitleMenu + { + public: + SWA_INSERT_PADDING(0x44); + be m_CursorIndex; + }; +} diff --git a/UnleashedRecomp/api/SWA/System/GameMode/Title/TitleStateBase.h b/UnleashedRecomp/api/SWA/System/GameMode/Title/TitleStateBase.h new file mode 100644 index 00000000..6782f3b5 --- /dev/null +++ b/UnleashedRecomp/api/SWA/System/GameMode/Title/TitleStateBase.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +namespace SWA +{ + class CTitleStateBase // : Hedgehog::Universe::TStateMachine::TState + { + public: + class CMember + { + public: + SWA_INSERT_PADDING(0x1E8); + xpointer m_pTitleMenu; + }; + + SWA_INSERT_PADDING(0x08); + xpointer m_pMember; + SWA_INSERT_PADDING(0x5C); + be m_State; + }; +} diff --git a/UnleashedRecomp/api/SWA/System/GameObject.h b/UnleashedRecomp/api/SWA/System/GameObject.h new file mode 100644 index 00000000..dd4f7fd1 --- /dev/null +++ b/UnleashedRecomp/api/SWA/System/GameObject.h @@ -0,0 +1,27 @@ +#pragma once + +#include "SWA.inl" +#include "Hedgehog/Base/Thread/hhSynchronizedPtr.h" +#include "Hedgehog/Universe/Engine/hhMessageActor.h" +#include "Hedgehog/Universe/Engine/hhUpdateUnit.h" + +namespace SWA +{ + class CGameDocument; + class CWorld; + + class CGameObject : public Hedgehog::Universe::CUpdateUnit, public Hedgehog::Universe::CMessageActor + { + public: + class CMember + { + public: + Hedgehog::Base::TSynchronizedPtr m_pGameDocument; + Hedgehog::Base::TSynchronizedPtr m_pWorld; + SWA_INSERT_PADDING(0x70); + }; + + xpointer m_pVftable; + xpointer m_pMember; + }; +} diff --git a/UnleashedRecomp/api/SWA/System/InputState.h b/UnleashedRecomp/api/SWA/System/InputState.h index defe936e..b42c67eb 100644 --- a/UnleashedRecomp/api/SWA/System/InputState.h +++ b/UnleashedRecomp/api/SWA/System/InputState.h @@ -5,16 +5,14 @@ namespace SWA { - class CInputState // : public Hedgehog::Base::CSynchronizedObject + class CInputState : public Hedgehog::Base::CSynchronizedObject { public: // TODO: Hedgehog::Base::TSynchronizedPtr static CInputState* GetInstance(); - SPadState m_PadStates[40]; - SWA_INSERT_PADDING(0x50); + SPadState m_PadStates[8]; be m_CurrentPadStateIndex; - SWA_INSERT_PADDING(0x04); const SPadState& GetPadState() const; }; diff --git a/UnleashedRecomp/api/SWA/System/InputState.inl b/UnleashedRecomp/api/SWA/System/InputState.inl index 5eba9408..7b961c4d 100644 --- a/UnleashedRecomp/api/SWA/System/InputState.inl +++ b/UnleashedRecomp/api/SWA/System/InputState.inl @@ -3,7 +3,7 @@ namespace SWA // TODO: Hedgehog::Base::TSynchronizedPtr inline CInputState* CInputState::GetInstance() { - return *(xpointer*)MmGetHostAddress(0x833671EC); + return *(xpointer*)MmGetHostAddress(0x83361F5C); } inline const SPadState& CInputState::GetPadState() const diff --git a/UnleashedRecomp/api/SWA/System/PadState.h b/UnleashedRecomp/api/SWA/System/PadState.h index eca4a5a8..a27df47d 100644 --- a/UnleashedRecomp/api/SWA/System/PadState.h +++ b/UnleashedRecomp/api/SWA/System/PadState.h @@ -43,15 +43,11 @@ namespace SWA struct SPadState { - SWA_INSERT_PADDING(0x20); - be DownState; be UpState; be TappedState; be ReleasedState; - SWA_INSERT_PADDING(0x04); - be LeftStickHorizontal; be LeftStickVertical; @@ -65,7 +61,7 @@ namespace SWA be LeftTrigger; be RightTrigger; - SWA_INSERT_PADDING(0x20); + SWA_INSERT_PADDING(0x08); bool IsDown(const EKeyState in_Keys) const; bool IsUp(const EKeyState in_Keys) const; diff --git a/UnleashedRecomp/api/SWA/System/World.h b/UnleashedRecomp/api/SWA/System/World.h new file mode 100644 index 00000000..aafbcd2f --- /dev/null +++ b/UnleashedRecomp/api/SWA/System/World.h @@ -0,0 +1,20 @@ +#pragma once + +#include "SWA.inl" +#include "Hedgehog/Base/Thread/hhSynchronizedObject.h" +#include "Hedgehog/Universe/Engine/hhMessageActor.h" + +namespace SWA +{ + class CWorld : public Hedgehog::Base::CSynchronizedObject, public Hedgehog::Universe::CMessageActor + { + public: + class CMember + { + public: + SWA_INSERT_PADDING(0x80); + }; + + xpointer m_pMember; + }; +} diff --git a/UnleashedRecomp/api/boost/smart_ptr/make_shared_object.h b/UnleashedRecomp/api/boost/smart_ptr/make_shared_object.h new file mode 100644 index 00000000..9bba6b4b --- /dev/null +++ b/UnleashedRecomp/api/boost/smart_ptr/make_shared_object.h @@ -0,0 +1,12 @@ +#pragma once + +#include "boost/smart_ptr/shared_ptr.h" + +namespace boost +{ + template + shared_ptr make_shared(TArgs&&... args) + { + return shared_ptr(new T(std::forward(args)...)); + } +} diff --git a/UnleashedRecomp/api/boost/smart_ptr/shared_ptr.h b/UnleashedRecomp/api/boost/smart_ptr/shared_ptr.h new file mode 100644 index 00000000..ecea043a --- /dev/null +++ b/UnleashedRecomp/api/boost/smart_ptr/shared_ptr.h @@ -0,0 +1,164 @@ +#pragma once + +#include +#include + +namespace boost +{ + namespace detail + { + class sp_counted_base + { + protected: + struct vftable_t + { + be destructor; + be dispose; + be destroy; + be get_deleter; + }; + + xpointer vftable_; + be use_count_; + be weak_count_; + + public: + // TODO + sp_counted_base() = delete; + + void add_ref() + { + be original, incremented; + do + { + original = use_count_; + incremented = original + 1; + } while (InterlockedCompareExchange((unsigned long*)&use_count_, incremented.value, original.value) != original.value); + } + + void release() + { + be original, decremented; + do + { + original = use_count_; + decremented = original - 1; + } while (InterlockedCompareExchange((unsigned long*)&use_count_, decremented.value, original.value) != original.value); + + if (decremented == 0) + { + GuestToHostFunction(vftable_->dispose, this); + weak_release(); + } + } + + void weak_release() + { + be original, decremented; + do + { + original = weak_count_; + decremented = original - 1; + } while (InterlockedCompareExchange((unsigned long*)&weak_count_, decremented.value, original.value) != original.value); + + if (decremented == 0) + { + GuestToHostFunction(vftable_->destroy, this); + } + } + + uint32_t use_count() const + { + return use_count_; + } + }; + + template< class T > struct sp_dereference + { + typedef T& type; + }; + + template<> struct sp_dereference< void > + { + typedef void type; + }; + } + + template + class shared_ptr + { + private: + xpointer px; + xpointer pn; + + void add_ref() + { + if (pn) + pn->add_ref(); + } + + void release() + { + if (pn) + pn->release(); + } + + public: + shared_ptr() : px(nullptr), pn(nullptr) {} + + // TODO + explicit shared_ptr(T* p) = delete; + + shared_ptr(const shared_ptr& other) : px(other.px), pn(other.pn) + { + add_ref(); + } + + shared_ptr(shared_ptr&& other) noexcept : px(std::exchange(other.px, nullptr)), + pn(std::exchange(other.pn, nullptr)) {} + + ~shared_ptr() + { + release(); + } + + shared_ptr& operator=(const shared_ptr& other) + { + if (this != &other) + { + release(); + + px = other.px; + pn = other.pn; + + add_ref(); + } + + return *this; + } + + shared_ptr& operator=(shared_ptr&& other) noexcept + { + if (this != &other) + { + release(); + + px = std::exchange(other.px, nullptr); + pn = std::exchange(other.pn, nullptr); + } + + return *this; + } + + T* get() const { return px; } + + detail::sp_dereference operator*() const { assert(px); return *px; } + T* operator->() const { assert(px); return px; } + + explicit operator bool() const { return px != nullptr; } + + size_t use_count() const { return pn ? pn->use_count() : 0; } + }; + + using anonymous_shared_ptr = shared_ptr; +} diff --git a/UnleashedRecomp/cpu/guest_stack_var.h b/UnleashedRecomp/cpu/guest_stack_var.h new file mode 100644 index 00000000..e4e9406d --- /dev/null +++ b/UnleashedRecomp/cpu/guest_stack_var.h @@ -0,0 +1,123 @@ +#pragma once + +#include "ppc_context.h" +#include + +// DO NOT use this type as anything other than a local variable. +// This includes returning. It'll cause memory to leak in the guest stack! + +template +class guest_stack_var +{ +private: + uint32_t m_ptr = NULL; + uint32_t m_oldStackPtr = NULL; + + void AllocGuestStackMemory() + { + auto ctx = GetPPCContext(); + m_oldStackPtr = ctx->r1.u32; + m_ptr = (ctx->r1.u32 - sizeof(T)) & ~(std::max(alignof(T), 8) - 1); + ctx->r1.u32 = m_ptr; + } + +public: + T* get() + { + return reinterpret_cast(g_memory.Translate(m_ptr)); + } + + const T* get() const + { + return reinterpret_cast(g_memory.Translate(m_ptr)); + } + + template + guest_stack_var(Args&&... args) + { + AllocGuestStackMemory(); + + if (Init) + new (get()) T(std::forward(args)...); + } + + guest_stack_var(const guest_stack_var& other) + { + AllocGuestStackMemory(); + + if (Init) + new (get()) T(*other->get()); + } + + guest_stack_var(guest_stack_var&& other) + { + AllocGuestStackMemory(); + + if (Init) + new (get()) T(std::move(*other->get())); + } + + ~guest_stack_var() + { + get()->~T(); + + auto ctx = GetPPCContext(); + // This assert will fail if the type was used as anything other than a local variable. + assert(ctx->r1.u32 == m_ptr); + ctx->r1.u32 = m_oldStackPtr; + } + + void operator=(const guest_stack_var& other) + { + if (this != &other) + *get() = *other->get(); + } + + void operator=(guest_stack_var&& other) + { + if (this != &other) + *get() = std::move(*other->get()); + } + + void operator=(const T& other) + { + if (get() != &other) + *get() = *other; + } + + void operator=(T&& other) + { + if (get() != &other) + *get() = std::move(*other); + } + + operator const T* () const + { + return get(); + } + + operator T* () + { + return get(); + } + + const T* operator->() const + { + return get(); + } + + T* operator->() + { + return get(); + } + + const T& operator*() const + { + return *get(); + } + + T& operator*() + { + return *get(); + } +}; diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 5f27f32b..109468e0 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -935,23 +935,23 @@ static void ProcSetRenderState(const RenderCommand& cmd) static const std::pair g_setRenderStateFunctions[] = { - { D3DRS_ZENABLE, GuestFunction> }, - { D3DRS_ZWRITEENABLE, GuestFunction> }, - { D3DRS_ALPHATESTENABLE, GuestFunction> }, - { D3DRS_SRCBLEND, GuestFunction> }, - { D3DRS_DESTBLEND, GuestFunction> }, - { D3DRS_CULLMODE, GuestFunction> }, - { D3DRS_ZFUNC, GuestFunction> }, - { D3DRS_ALPHAREF, GuestFunction> }, - { D3DRS_ALPHABLENDENABLE, GuestFunction> }, - { D3DRS_BLENDOP, GuestFunction> }, - { D3DRS_SCISSORTESTENABLE, GuestFunction> }, - { D3DRS_SLOPESCALEDEPTHBIAS, GuestFunction> }, - { D3DRS_DEPTHBIAS, GuestFunction> }, - { D3DRS_SRCBLENDALPHA, GuestFunction> }, - { D3DRS_DESTBLENDALPHA, GuestFunction> }, - { D3DRS_BLENDOPALPHA, GuestFunction> }, - { D3DRS_COLORWRITEENABLE, GuestFunction> } + { D3DRS_ZENABLE, HostToGuestFunction> }, + { D3DRS_ZWRITEENABLE, HostToGuestFunction> }, + { D3DRS_ALPHATESTENABLE, HostToGuestFunction> }, + { D3DRS_SRCBLEND, HostToGuestFunction> }, + { D3DRS_DESTBLEND, HostToGuestFunction> }, + { D3DRS_CULLMODE, HostToGuestFunction> }, + { D3DRS_ZFUNC, HostToGuestFunction> }, + { D3DRS_ALPHAREF, HostToGuestFunction> }, + { D3DRS_ALPHABLENDENABLE, HostToGuestFunction> }, + { D3DRS_BLENDOP, HostToGuestFunction> }, + { D3DRS_SCISSORTESTENABLE, HostToGuestFunction> }, + { D3DRS_SLOPESCALEDEPTHBIAS, HostToGuestFunction> }, + { D3DRS_DEPTHBIAS, HostToGuestFunction> }, + { D3DRS_SRCBLENDALPHA, HostToGuestFunction> }, + { D3DRS_DESTBLENDALPHA, HostToGuestFunction> }, + { D3DRS_BLENDOPALPHA, HostToGuestFunction> }, + { D3DRS_COLORWRITEENABLE, HostToGuestFunction> } }; static std::unique_ptr g_resolveMsaaDepthPipelines[3]; @@ -1407,7 +1407,7 @@ static uint32_t CreateDevice(uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, memset(device, 0, sizeof(*device)); uint32_t functionOffset = 0x443344; // D3D - g_codeCache.Insert(functionOffset, reinterpret_cast(GuestFunction)); + g_codeCache.Insert(functionOffset, reinterpret_cast(HostToGuestFunction)); for (size_t i = 0; i < _countof(device->setRenderStateFunctions); i++) device->setRenderStateFunctions[i] = functionOffset; @@ -3831,8 +3831,8 @@ void SetShadowResolutionMidAsmHook(PPCRegister& r11) static void SetResolution(be* device) { - uint32_t width = uint32_t(g_swapChain->getWidth() * Config::ResolutionScale); - uint32_t height = uint32_t(g_swapChain->getHeight() * Config::ResolutionScale); + uint32_t width = uint32_t(round(g_swapChain->getWidth() * Config::ResolutionScale)); + uint32_t height = uint32_t(round(g_swapChain->getHeight() * Config::ResolutionScale)); device[46] = width == 0 ? 880 : width; device[47] = height == 0 ? 720 : height; } diff --git a/UnleashedRecomp/kernel/function.h b/UnleashedRecomp/kernel/function.h index 14eb09cc..14e88ea7 100644 --- a/UnleashedRecomp/kernel/function.h +++ b/UnleashedRecomp/kernel/function.h @@ -1,7 +1,9 @@ #pragma once + #include #include #include "xbox.h" +#include "memory.h" template constexpr std::tuple function_args(R(*)(T...)) noexcept @@ -78,10 +80,54 @@ struct ArgTranslator [[unlikely]] default: break; } - // how did you end up here + // TODO: get value from stack. return 0; } + FORCEINLINE constexpr static void SetIntegerArgumentValue(PPCContext& ctx, uint8_t* base, size_t arg, uint64_t value) noexcept + { + if (arg <= 7) + { + switch (arg) + { + case 0: ctx.r3.u64 = value; return; + case 1: ctx.r4.u64 = value; return; + case 2: ctx.r5.u64 = value; return; + case 3: ctx.r6.u64 = value; return; + case 4: ctx.r7.u64 = value; return; + case 5: ctx.r8.u64 = value; return; + case 6: ctx.r9.u64 = value; return; + case 7: ctx.r10.u64 = value; return; + [[unlikely]] default: break; + } + } + + assert(arg < 7 && "Pushing to stack memory is not yet supported."); + } + + FORCEINLINE static void SetPrecisionArgumentValue(PPCContext& ctx, uint8_t* base, size_t arg, double value) noexcept + { + switch (arg) + { + case 0: ctx.f1.f64 = value; return; + case 1: ctx.f2.f64 = value; return; + case 2: ctx.f3.f64 = value; return; + case 3: ctx.f4.f64 = value; return; + case 4: ctx.f5.f64 = value; return; + case 5: ctx.f6.f64 = value; return; + case 6: ctx.f7.f64 = value; return; + case 7: ctx.f8.f64 = value; return; + case 8: ctx.f9.f64 = value; return; + case 9: ctx.f10.f64 = value; return; + case 10: ctx.f11.f64 = value; return; + case 11: ctx.f12.f64 = value; return; + case 12: ctx.f13.f64 = value; return; + [[unlikely]] default: break; + } + + assert(arg < 12 && "Pushing to stack memory is not yet supported."); + } + template FORCEINLINE constexpr static std::enable_if_t, T> GetValue(PPCContext& ctx, uint8_t* base, size_t idx) noexcept { @@ -106,6 +152,39 @@ struct ArgTranslator return reinterpret_cast(base + static_cast(v)); } + + template + FORCEINLINE constexpr static std::enable_if_t, void> SetValue(PPCContext& ctx, uint8_t* base, size_t idx, T value) noexcept + { + if constexpr (is_precise_v) + { + SetPrecisionArgumentValue(ctx, base, idx, value); + } + else if constexpr (std::is_null_pointer_v) + { + SetIntegerArgumentValue(ctx, base, idx, 0); + } + else if constexpr (std::is_pointer_v) + { + SetIntegerArgumentValue(ctx, base, idx, g_memory.MapVirtual(value)); + } + else + { + SetIntegerArgumentValue(ctx, base, idx, value); + } + } + + template + FORCEINLINE constexpr static std::enable_if_t, void> SetValue(PPCContext& ctx, uint8_t* base, size_t idx, T value) noexcept + { + const auto v = g_memory.MapVirtual((void*)value); + if (!v) + { + return; + } + + SetValue(ctx, base, idx, v); + } }; struct Argument @@ -114,10 +193,10 @@ struct Argument int ordinal{}; }; -template -constexpr std::array::value> GatherFunctionArguments() +template +constexpr std::array> GatherFunctionArguments(const T1& tpl) { - std::array::value> args{}; + std::array> args{}; int floatOrdinal{}; size_t i{}; @@ -126,9 +205,9 @@ constexpr std::array::value> GatherFunctionArguments { std::apply([&](const auto& first, const auto&... rest) { - auto append = [&](const T & v) + auto append = [&](const T2& v) { - if constexpr (is_precise_v) + if constexpr (is_precise_v) { args[i] = { 1, floatOrdinal++ }; } @@ -142,12 +221,18 @@ constexpr std::array::value> GatherFunctionArguments append(first); (append(rest), ...); - }, function_args(Func)); + }, tpl); } return args; } +template +constexpr std::array::value> GatherFunctionArguments() +{ + return GatherFunctionArguments(function_args(Func)); +} + template struct arg_ordinal_t { @@ -155,27 +240,42 @@ struct arg_ordinal_t }; template -FORCEINLINE void _translate_args(PPCContext& ctx, uint8_t* base, std::tuple&) noexcept -requires (I >= sizeof...(TArgs)) +FORCEINLINE void _translate_args_to_host(PPCContext& ctx, uint8_t* base, std::tuple&) noexcept + requires (I >= sizeof...(TArgs)) { } template -FORCEINLINE std::enable_if_t<(I < sizeof...(TArgs)), void> _translate_args(PPCContext& ctx, uint8_t* base, std::tuple& tpl) noexcept +FORCEINLINE std::enable_if_t<(I < sizeof...(TArgs)), void> _translate_args_to_host(PPCContext& ctx, uint8_t* base, std::tuple& tpl) noexcept { using T = std::tuple_element_t>; std::get(tpl) = ArgTranslator::GetValue(ctx, base, arg_ordinal_t::value); - _translate_args(ctx, base, tpl); + _translate_args_to_host(ctx, base, tpl); +} + +template +FORCEINLINE void _translate_args_to_guest(PPCContext& ctx, uint8_t* base, std::tuple&) noexcept + requires (I >= sizeof...(TArgs)) +{ +} + +template +FORCEINLINE std::enable_if_t<(I < sizeof...(TArgs)), void> _translate_args_to_guest(PPCContext& ctx, uint8_t* base, std::tuple& tpl) noexcept +{ + using T = std::tuple_element_t>; + ArgTranslator::SetValue(ctx, base, GatherFunctionArguments(std::tuple{})[I].ordinal, std::get(tpl)); + + _translate_args_to_guest(ctx, base, tpl); } template -FORCEINLINE PPC_FUNC(GuestFunction) +FORCEINLINE PPC_FUNC(HostToGuestFunction) { using ret_t = decltype(std::apply(Func, function_args(Func))); auto args = function_args(Func); - _translate_args(ctx, base, args); + _translate_args_to_host(ctx, base, args); if constexpr (std::is_same_v) { @@ -207,8 +307,54 @@ FORCEINLINE PPC_FUNC(GuestFunction) } } +template +FORCEINLINE T GuestToHostFunction(const TFunction& func, TArgs&&... argv) +{ + auto args = std::make_tuple(std::forward(argv)...); + auto& currentCtx = *GetPPCContext(); + + PPCContext newCtx; // NOTE: No need for zero initialization, has lots of unnecessary code generation. + newCtx.fn = currentCtx.fn; + newCtx.r1 = currentCtx.r1; + newCtx.r13 = currentCtx.r13; + newCtx.fpscr = currentCtx.fpscr; + + _translate_args_to_guest(newCtx, (uint8_t*)g_memory.base, args); + + SetPPCContext(newCtx); + + if constexpr (std::is_function_v) + func(newCtx, (uint8_t*)g_memory.base); + else + (*(PPCFunc**)(newCtx.fn + uint64_t(func) * 2))(newCtx, (uint8_t*)g_memory.base); + + currentCtx.fpscr = newCtx.fpscr; + SetPPCContext(currentCtx); + + if constexpr (std::is_void_v) + { + return; + } + else if constexpr (std::is_pointer_v) + { + return reinterpret_cast((uint64_t)g_memory.Translate(newCtx.r3.u32)); + } + else if constexpr (is_precise_v) + { + return static_cast(newCtx.f1.f64); + } + else if constexpr (std::is_integral_v) + { + return static_cast(newCtx.r3.u64); + } + else + { + static_assert(false, "Unsupported return type."); + } +} + #define GUEST_FUNCTION_HOOK(subroutine, function) \ - PPC_FUNC(subroutine) { GuestFunction(ctx, base); } + PPC_FUNC(subroutine) { HostToGuestFunction(ctx, base); } #define GUEST_FUNCTION_STUB(subroutine) \ PPC_FUNC(subroutine) { } diff --git a/UnleashedRecomp/kernel/heap.h b/UnleashedRecomp/kernel/heap.h index 90da8e64..4e583be5 100644 --- a/UnleashedRecomp/kernel/heap.h +++ b/UnleashedRecomp/kernel/heap.h @@ -1,7 +1,6 @@ #pragma once #include "mutex.h" -#include struct Heap { diff --git a/UnleashedRecomp/kernel/memory.h b/UnleashedRecomp/kernel/memory.h index 8cea4c4f..0a1eba22 100644 --- a/UnleashedRecomp/kernel/memory.h +++ b/UnleashedRecomp/kernel/memory.h @@ -16,11 +16,17 @@ public: void* Translate(size_t offset) const noexcept { + if (offset) + assert(offset < 0x100000000ull); + return base + offset; } uint32_t MapVirtual(void* host) const noexcept { + if (host) + assert(host >= base && host < (base + size)); + return static_cast(static_cast(host) - base); } }; diff --git a/UnleashedRecomp/stdafx.h b/UnleashedRecomp/stdafx.h index 96152f7b..4eabefad 100644 --- a/UnleashedRecomp/stdafx.h +++ b/UnleashedRecomp/stdafx.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "framework.h" #include "mutex.h" diff --git a/thirdparty/PowerRecomp b/thirdparty/PowerRecomp index d8676283..7dd4f91a 160000 --- a/thirdparty/PowerRecomp +++ b/thirdparty/PowerRecomp @@ -1 +1 @@ -Subproject commit d8676283fd1e8990b415cc0e4810c6db895b9fba +Subproject commit 7dd4f91ac635b001a56cc7a27af48f0436bbad3f