diff --git a/MarathonRecomp/api/Marathon.h b/MarathonRecomp/api/Marathon.h index 811d11fd..dd86e5d3 100644 --- a/MarathonRecomp/api/Marathon.h +++ b/MarathonRecomp/api/Marathon.h @@ -37,6 +37,12 @@ #include "Sonicteam/Enemy/EnemyShotNormal.h" #include "Sonicteam/Enemy/EnemyShotPoint.h" #include "Sonicteam/Fixture.h" +#include "Sonicteam/GE1PE/EffectBank.h" +#include "Sonicteam/GE1PE/EmitterListener.h" +#include "Sonicteam/GE1PE/Manager.h" +#include "Sonicteam/GE1PE/ParticleEngine.h" +#include "Sonicteam/GE1PE/Plugin.h" +#include "Sonicteam/GE1PE/RefCountObject.h" #include "Sonicteam/Game.h" #include "Sonicteam/GameImp.h" #include "Sonicteam/GameMode.h" @@ -55,7 +61,12 @@ #include "Sonicteam/HintWindowTask.h" #include "Sonicteam/HudTextParts.h" #include "Sonicteam/ImageFilter.h" +#include "Sonicteam/LuaNode.h" +#include "Sonicteam/LuaNodeImp.h" +#include "Sonicteam/LuaSystem.h" +#include "Sonicteam/LuaSystemManager.h" #include "Sonicteam/MainDisplayTask.h" +#include "Sonicteam/MainMenuExpositionTask.h" #include "Sonicteam/MainMenuTask.h" #include "Sonicteam/MainMode.h" #include "Sonicteam/Message/MsgCameramanChangeMode.h" @@ -76,7 +87,13 @@ #include "Sonicteam/MyCueAdx.h" #include "Sonicteam/MyCueAttenuate.h" #include "Sonicteam/MyGraphicsDevice.h" +#include "Sonicteam/MyPE/CManageParticle.h" +#include "Sonicteam/MyPE/EffectBankLoad.h" +#include "Sonicteam/MyPE/EffectBankLoadManager.h" +#include "Sonicteam/MyPE/MyEffectBank.h" +#include "Sonicteam/MyPE/MyEmitterListener.h" #include "Sonicteam/MyPhantom.h" +#include "Sonicteam/MyRenderProcess.h" #include "Sonicteam/MyTexture.h" #include "Sonicteam/MyTransforms.h" #include "Sonicteam/NamedActor.h" @@ -84,8 +101,16 @@ #include "Sonicteam/NoSyncThread.h" #include "Sonicteam/ObjectVehicle.h" #include "Sonicteam/ObjectVehicleBike.h" +#include "Sonicteam/Particles/Particle.h" +#include "Sonicteam/Particles/ParticleContainer.h" +#include "Sonicteam/Particles/ParticleContainerMgr.h" +#include "Sonicteam/Particles/ParticleManager.h" +#include "Sonicteam/Particles/ParticleManagerUnit.h" +#include "Sonicteam/Particles/ParticleRef.h" #include "Sonicteam/PauseAdapter.h" #include "Sonicteam/PauseTask.h" +#include "Sonicteam/Player/Effect/ParticleJoint.h" +#include "Sonicteam/Player/Effect/ParticleLuaTable.h" #include "Sonicteam/Player/GroundRayListener.h" #include "Sonicteam/Player/ICollisionListener.h" #include "Sonicteam/Player/ICollisionListenerTemplate.h" @@ -134,13 +159,18 @@ #include "Sonicteam/Player/Unit/ITestCase.h" #include "Sonicteam/Player/Weapon/SonicWeapons.h" #include "Sonicteam/Player/Zock.h" +#include "Sonicteam/PopupScreenTask.h" #include "Sonicteam/PropFixture.h" #include "Sonicteam/RaderMapManager.h" +#include "Sonicteam/RenderTargetContainer.h" +#include "Sonicteam/RootGTask.h" +#include "Sonicteam/SFXAgent.h" #include "Sonicteam/SaveDataTask.h" #include "Sonicteam/SaveDataTaskXENON.h" #include "Sonicteam/SelectWindowTask.h" #include "Sonicteam/SoX/AI/StateMachine.h" #include "Sonicteam/SoX/ApplicationXenon.h" +#include "Sonicteam/SoX/Array.h" #include "Sonicteam/SoX/Audio/Cue.h" #include "Sonicteam/SoX/Audio/IAudioEngine.h" #include "Sonicteam/SoX/Audio/Player.h" @@ -149,16 +179,24 @@ #include "Sonicteam/SoX/Engine/Application.h" #include "Sonicteam/SoX/Engine/Doc.h" #include "Sonicteam/SoX/Engine/DocMode.h" +#include "Sonicteam/SoX/Engine/GTask.h" +#include "Sonicteam/SoX/Engine/RenderProcess.h" +#include "Sonicteam/SoX/Engine/RenderScheduler.h" #include "Sonicteam/SoX/Engine/Task.h" #include "Sonicteam/SoX/Graphics/Device.h" #include "Sonicteam/SoX/Graphics/Frame.h" #include "Sonicteam/SoX/Graphics/FrameGP.h" #include "Sonicteam/SoX/Graphics/FrameObserver.h" +#include "Sonicteam/SoX/Graphics/Surface.h" +#include "Sonicteam/SoX/Graphics/SurfaceMgr.h" #include "Sonicteam/SoX/Graphics/Technique.h" #include "Sonicteam/SoX/Graphics/TechniqueFXL.h" +#include "Sonicteam/SoX/Graphics/Texture.h" +#include "Sonicteam/SoX/Graphics/TextureMgr.h" #include "Sonicteam/SoX/Graphics/Transforms.h" #include "Sonicteam/SoX/Graphics/Vertex.h" #include "Sonicteam/SoX/Graphics/Xenon/DeviceXenon.h" +#include "Sonicteam/SoX/Graphics/Xenon/SurfaceXenon.h" #include "Sonicteam/SoX/Graphics/Xenon/TextureXenon.h" #include "Sonicteam/SoX/IResource.h" #include "Sonicteam/SoX/IResource2.h" @@ -186,11 +224,17 @@ #include "Sonicteam/SoX/Physics/World.h" #include "Sonicteam/SoX/RefCountObject.h" #include "Sonicteam/SoX/RefSharedPointer.h" +#include "Sonicteam/SoX/ResourceManager.h" #include "Sonicteam/SoX/Scenery/Camera.h" #include "Sonicteam/SoX/Scenery/CameraEventCallback.h" #include "Sonicteam/SoX/Scenery/CameraImp.h" #include "Sonicteam/SoX/Scenery/Drawable.h" #include "Sonicteam/SoX/Thread.h" +#include "Sonicteam/Spanverse/AckResource.h" +#include "Sonicteam/Spanverse/AckResourceMgr.h" +#include "Sonicteam/Spanverse/SpanABDT.h" +#include "Sonicteam/Spanverse/SpanACBS.h" +#include "Sonicteam/Spanverse/SpanBASE.h" #include "Sonicteam/StdImageFilters/BurnoutBlurFilter.h" #include "Sonicteam/StdImageFilters/SingleTechniqueFilter.h" #include "Sonicteam/System/CreateStatic.h" @@ -209,6 +253,7 @@ #include "Sonicteam/sonicXmaPlayer.h" #include "boost/smart_ptr/make_shared_object.h" #include "boost/smart_ptr/shared_ptr.h" +#include "d3dxb.h" #include "hk330/hkArray.h" #include "hk330/hkReferencedObject.h" #include "hk330/hkpBroadPhaseHandle.h" @@ -228,6 +273,9 @@ #include "hk330/hkpTypedBroadPhaseHandle.h" #include "hk330/hkpWorld.h" #include "hk330/hkpWorldObject.h" +#include "lua50/lua.h" +#include "stdx/list.h" +#include "stdx/map.h" #include "stdx/string.h" #include "stdx/vector.h" #include "stdx/wstring.h" diff --git a/MarathonRecomp/api/Marathon.inl b/MarathonRecomp/api/Marathon.inl index c6b017eb..d8facd5a 100644 --- a/MarathonRecomp/api/Marathon.inl +++ b/MarathonRecomp/api/Marathon.inl @@ -24,7 +24,15 @@ constexpr double DEG2RAD = 0.01745329238474369; #define MARATHON_VIRTUAL_FUNCTION(returnType, virtualIndex, ...) \ GuestToHostFunction(*(be*)(g_memory.Translate(*(be*)(this) + (4 * virtualIndex))), __VA_ARGS__) -struct marathon_null_ctor {}; +struct MARATHON_NULL_CTOR {}; + +struct MARATHON_STD_MAP_CONST_CHAR_COMPARE +{ + bool operator()(xpointer lhs, xpointer rhs) const + { + return std::strcmp(lhs.get(), rhs.get()) < 0; + } +}; inline std::vector ParseTextVariables(const char* pVariables) { diff --git a/MarathonRecomp/api/Sonicteam/AppMarathon.h b/MarathonRecomp/api/Sonicteam/AppMarathon.h index f649d5d2..3cd08868 100644 --- a/MarathonRecomp/api/Sonicteam/AppMarathon.h +++ b/MarathonRecomp/api/Sonicteam/AppMarathon.h @@ -12,7 +12,10 @@ namespace Sonicteam public: xpointer m_pDoc; - static AppMarathon* GetInstance(); + AppMarathon* GetInstance() + { + return *(xpointer*)MmGetHostAddress(0x82D3B348); + } GameImp* GetGame() const { @@ -25,5 +28,3 @@ namespace Sonicteam MARATHON_ASSERT_OFFSETOF(AppMarathon, m_pDoc, 0x180); } - -#include diff --git a/MarathonRecomp/api/Sonicteam/AppMarathon.inl b/MarathonRecomp/api/Sonicteam/AppMarathon.inl deleted file mode 100644 index 866b481a..00000000 --- a/MarathonRecomp/api/Sonicteam/AppMarathon.inl +++ /dev/null @@ -1,7 +0,0 @@ -namespace Sonicteam -{ - inline AppMarathon* AppMarathon::GetInstance() - { - return *(xpointer*)MmGetHostAddress(0x82D3B348); - } -} diff --git a/MarathonRecomp/api/Sonicteam/DocMarathonImp.h b/MarathonRecomp/api/Sonicteam/DocMarathonImp.h index 5284d332..1bc3bbf9 100644 --- a/MarathonRecomp/api/Sonicteam/DocMarathonImp.h +++ b/MarathonRecomp/api/Sonicteam/DocMarathonImp.h @@ -1,26 +1,47 @@ #pragma once #include +#include +#include #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include namespace Sonicteam { class DocMarathonImp : public SoX::Engine::Doc { public: - MARATHON_INSERT_PADDING(0x40); - stdx::vector> m_vspInputManager; + MARATHON_INSERT_PADDING(4); + xpointer m_pMyGraphicsDevice; + MARATHON_INSERT_PADDING(0x38); + stdx::vector> m_vspInputManagers; MARATHON_INSERT_PADDING(0x24); bool m_VFrame; - MARATHON_INSERT_PADDING(0x55B58); + MARATHON_INSERT_PADDING(4); + xpointer m_pRenderTargetContainer; + xpointer m_pSFXAgent; + MARATHON_INSERT_PADDING(0xC); + be m_PauseFlags; + MARATHON_INSERT_PADDING(0x8); + xpointer> m_lnThread; + MARATHON_INSERT_PADDING(0x288); + xpointer m_pParticleManager; + MARATHON_INSERT_PADDING(0x15D0); + xpointer m_pRaderMapManager; + MARATHON_INSERT_PADDING(0x542D0); be m_aPadIDs[4]; MARATHON_INSERT_PADDING(0x2C); }; - MARATHON_ASSERT_OFFSETOF(DocMarathonImp, m_vspInputManager, 0x9C); + MARATHON_ASSERT_OFFSETOF(DocMarathonImp, m_PauseFlags, 0xEC); + MARATHON_ASSERT_OFFSETOF(DocMarathonImp, m_vspInputManagers, 0x9C); MARATHON_ASSERT_OFFSETOF(DocMarathonImp, m_VFrame, 0xD0); MARATHON_ASSERT_OFFSETOF(DocMarathonImp, m_aPadIDs, 0x55C2C); MARATHON_ASSERT_SIZEOF(DocMarathonImp, 0x55C68); diff --git a/MarathonRecomp/api/Sonicteam/GE1PE/EffectBank.h b/MarathonRecomp/api/Sonicteam/GE1PE/EffectBank.h new file mode 100644 index 00000000..11975b3d --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/GE1PE/EffectBank.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include +#include +#include + +namespace Sonicteam::GE1PE +{ + class ParticleEngine; + + struct EffectBankData + { + be Field00; + stdx::string Name; + xpointer pData1; + xpointer pData2; + xpointer pData3; + stdx::map> mEffectDataIndices; + }; + + class EffectBank : public RefCountObject + { + public: + xpointer m_pParticleEngine; + be m_Field0C; // Index? + xpointer m_pEffectBankA; + }; + + MARATHON_ASSERT_OFFSETOF(EffectBankData, Field00, 0x00); + MARATHON_ASSERT_OFFSETOF(EffectBankData, Name, 0x04); + MARATHON_ASSERT_OFFSETOF(EffectBankData, pData1, 0x20); + MARATHON_ASSERT_OFFSETOF(EffectBankData, pData2, 0x24); + MARATHON_ASSERT_OFFSETOF(EffectBankData, pData3, 0x28); + MARATHON_ASSERT_OFFSETOF(EffectBankData, mEffectDataIndices, 0x2C); + MARATHON_ASSERT_SIZEOF(EffectBankData, 0x38); + + MARATHON_ASSERT_OFFSETOF(EffectBank, m_pParticleEngine, 0x08); + MARATHON_ASSERT_OFFSETOF(EffectBank, m_Field0C, 0x0C); + MARATHON_ASSERT_OFFSETOF(EffectBank, m_pEffectBankA, 0x10); + MARATHON_ASSERT_SIZEOF(EffectBank, 0x14); +} diff --git a/MarathonRecomp/api/Sonicteam/GE1PE/EmitterListener.h b/MarathonRecomp/api/Sonicteam/GE1PE/EmitterListener.h new file mode 100644 index 00000000..744de307 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/GE1PE/EmitterListener.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +namespace Sonicteam::GE1PE +{ + class EmitterListener + { + public: + xpointer m_pVftable; + }; +} diff --git a/MarathonRecomp/api/Sonicteam/GE1PE/Manager.h b/MarathonRecomp/api/Sonicteam/GE1PE/Manager.h new file mode 100644 index 00000000..ee8b07ed --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/GE1PE/Manager.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +namespace Sonicteam::GE1PE +{ + class Effect; + class Emitter; + class Particle; + class ParticleEngine; + + class Manager + { + public: + struct Vftable + { + be fpDestroy; + }; + + xpointer m_pVftable; + xpointer m_pParticleEngine; + SoX::LinkNode m_lnManager; + SoX::LinkNode m_lnField14; + SoX::LinkNode m_lnParticle; + SoX::LinkNode m_lnField2C; + SoX::LinkNode m_lnField38; + SoX::LinkNode m_lnEmitter; + SoX::LinkNode m_lnEffect; + SoX::LinkNode m_lnField5C; + MARATHON_INSERT_PADDING(0x24); + }; + + MARATHON_ASSERT_OFFSETOF(Manager, m_pParticleEngine, 0x04); + MARATHON_ASSERT_OFFSETOF(Manager, m_lnManager, 0x08); + MARATHON_ASSERT_OFFSETOF(Manager, m_lnField14, 0x14); + MARATHON_ASSERT_OFFSETOF(Manager, m_lnParticle, 0x20); + MARATHON_ASSERT_OFFSETOF(Manager, m_lnField2C, 0x2C); + MARATHON_ASSERT_OFFSETOF(Manager, m_lnField38, 0x38); + MARATHON_ASSERT_OFFSETOF(Manager, m_lnEmitter, 0x44); + MARATHON_ASSERT_OFFSETOF(Manager, m_lnEffect, 0x50); + MARATHON_ASSERT_OFFSETOF(Manager, m_lnField5C, 0x5C); +} diff --git a/MarathonRecomp/api/Sonicteam/GE1PE/ParticleEngine.h b/MarathonRecomp/api/Sonicteam/GE1PE/ParticleEngine.h new file mode 100644 index 00000000..66bae9c1 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/GE1PE/ParticleEngine.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Sonicteam::GE1PE +{ + class EffectBank; + class Manager; + class Material; + class TextureBank; + + class ParticleEngine : public System::Singleton> + { + public: + xpointer m_pVftable; + boost::shared_ptr m_spPlugin; + stdx::map> m_mEffectIndices; + stdx::map> m_mTextureIndices; + stdx::map> m_mMaterialIndices; + stdx::vector> m_vpEffectBank; + stdx::vector> m_vpTextureBank; + stdx::vector> m_vpMaterialBank; + SoX::LinkNode m_lnManager; + stdx::vector> m_vField6C; + }; + + MARATHON_ASSERT_OFFSETOF(ParticleEngine, m_spPlugin, 0x04); + MARATHON_ASSERT_OFFSETOF(ParticleEngine, m_mEffectIndices, 0x0C); + MARATHON_ASSERT_OFFSETOF(ParticleEngine, m_mTextureIndices, 0x18); + MARATHON_ASSERT_OFFSETOF(ParticleEngine, m_mMaterialIndices, 0x24); + MARATHON_ASSERT_OFFSETOF(ParticleEngine, m_vpEffectBank, 0x30); + MARATHON_ASSERT_OFFSETOF(ParticleEngine, m_vpTextureBank, 0x40); + MARATHON_ASSERT_OFFSETOF(ParticleEngine, m_vpMaterialBank, 0x50); + MARATHON_ASSERT_OFFSETOF(ParticleEngine, m_lnManager, 0x60); + MARATHON_ASSERT_OFFSETOF(ParticleEngine, m_vField6C, 0x6C); +} diff --git a/MarathonRecomp/api/Sonicteam/GE1PE/Plugin.h b/MarathonRecomp/api/Sonicteam/GE1PE/Plugin.h new file mode 100644 index 00000000..e55d3ca5 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/GE1PE/Plugin.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +namespace Sonicteam::GE1PE +{ + class Plugin + { + public: + struct Vftable + { + be fpDestroy; + }; + + xpointer m_pVftable; + xpointer m_pDoc; + }; +} diff --git a/MarathonRecomp/api/Sonicteam/GE1PE/RefCountObject.h b/MarathonRecomp/api/Sonicteam/GE1PE/RefCountObject.h new file mode 100644 index 00000000..b0026448 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/GE1PE/RefCountObject.h @@ -0,0 +1,36 @@ +#pragma once + +#include + +namespace Sonicteam::GE1PE +{ + class RefCountObject + { + public: + struct Vftable + { + be fpDestroy; + }; + + xpointer m_pVftable; + be m_ReferenceCount; + + void* Destroy(uint32_t flag = 1) + { + return GuestToHostFunction(m_pVftable->fpDestroy, this, flag); + } + + void Release(uint32_t flag = 1) + { + m_ReferenceCount = m_ReferenceCount - 1; + + if (!m_ReferenceCount.get()) + Destroy(flag); + } + + void AddReference() + { + m_ReferenceCount = m_ReferenceCount + 1; + } + }; +} diff --git a/MarathonRecomp/api/Sonicteam/GameImp.h b/MarathonRecomp/api/Sonicteam/GameImp.h index 8eb73a91..a85112ad 100644 --- a/MarathonRecomp/api/Sonicteam/GameImp.h +++ b/MarathonRecomp/api/Sonicteam/GameImp.h @@ -7,8 +7,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -84,7 +86,9 @@ namespace Sonicteam xpointer m_pHintTextBook; MARATHON_INSERT_PADDING(4); xpointer m_pMissionCore; - MARATHON_INSERT_PADDING(0x2A4); + MARATHON_INSERT_PADDING(0x248); + SoX::LinkRef m_lrPopupScreenTask; + MARATHON_INSERT_PADDING(0x4C); SoX::RefSharedPointer m_spPhysicsWorld; xpointer m_pMyCollisionFilter; MARATHON_INSERT_PADDING(0x0C); diff --git a/MarathonRecomp/api/Sonicteam/Globals.h b/MarathonRecomp/api/Sonicteam/Globals.h index 896ecddf..ca141073 100644 --- a/MarathonRecomp/api/Sonicteam/Globals.h +++ b/MarathonRecomp/api/Sonicteam/Globals.h @@ -1,9 +1,13 @@ #pragma once #include +#include +#include namespace Sonicteam { + class MyRenderProcess; + enum Character : uint32_t { Character_Sonic, @@ -21,10 +25,27 @@ namespace Sonicteam { static inline be* ms_MainDisplayColours[9]; + static inline stdx::list* ms_lMyRenderProcess; + + static inline stdx::string* ms_CurrentRenderScript; + + static inline const char* ms_strBuild; // Build + static inline const char* ms_strRenderSpanverse; // RenderSpanverse + static inline const char* ms_strRenderGE1Particle; // RenderGE1Particle + + static void Init() { for (int i = 0; i < 9; i++) ms_MainDisplayColours[i] = (be*)MmGetHostAddress(0x82036BE4 + (i * 4)); + + ms_lMyRenderProcess = (stdx::list*)MmGetHostAddress(0x82D3C568); + + ms_CurrentRenderScript = (stdx::string*)MmGetHostAddress(0x82B814F8); + + ms_strBuild = (const char*)MmGetHostAddress(0x82024000); + ms_strRenderSpanverse = (const char*)MmGetHostAddress(0x8204C0C8); + ms_strRenderGE1Particle = (const char*)MmGetHostAddress(0x8204C05C); } }; } diff --git a/MarathonRecomp/api/Sonicteam/HUDPopupScreen.h b/MarathonRecomp/api/Sonicteam/HUDPopupScreen.h index 2bb7645c..aec87808 100644 --- a/MarathonRecomp/api/Sonicteam/HUDPopupScreen.h +++ b/MarathonRecomp/api/Sonicteam/HUDPopupScreen.h @@ -2,12 +2,15 @@ #include #include +#include +#include +#include #include #include namespace Sonicteam { - class HUDPopupScreen : public SoX::Engine::Task + class HUDPopupScreen : public SoX::RefCountObject, public SoX::Engine::Task { public: enum HUDPopupScreenState : uint32_t @@ -18,8 +21,8 @@ namespace Sonicteam }; xpointer m_pCsdObject; - xpointer m_pMainTexture; - xpointer m_pMaskTexture; + SoX::RefSharedPointer m_pMainTexture; + SoX::RefSharedPointer m_pMaskTexture; xpointer m_pTechnique; stdx::string m_SceneName; stdx::string m_SpriteName; @@ -33,16 +36,16 @@ namespace Sonicteam MARATHON_INSERT_PADDING(8); }; - MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_pCsdObject, 0x4C); - MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_pMainTexture, 0x50); - MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_pMaskTexture, 0x54); - MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_pTechnique, 0x58); - MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_SceneName, 0x5C); - MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_SpriteName, 0x78); - MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_State, 0x94); - MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_IsClosing, 0x99); - MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_ClosingTime, 0x9C); - MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_X, 0xA0); - MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_Y, 0xA4); - MARATHON_ASSERT_SIZEOF(HUDPopupScreen, 0xB0); + MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_pCsdObject, 0x54); + MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_pMainTexture, 0x58); + MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_pMaskTexture, 0x5C); + MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_pTechnique, 0x60); + MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_SceneName, 0x64); + MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_SpriteName, 0x80); + MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_State, 0x9C); + MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_IsClosing, 0xA1); + MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_ClosingTime, 0xA4); + MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_X, 0xA8); + MARATHON_ASSERT_OFFSETOF(HUDPopupScreen, m_Y, 0xAC); + MARATHON_ASSERT_SIZEOF(HUDPopupScreen, 0xB8); } diff --git a/MarathonRecomp/api/Sonicteam/HUDRaderMap.h b/MarathonRecomp/api/Sonicteam/HUDRaderMap.h index 988650a7..f2dcad08 100644 --- a/MarathonRecomp/api/Sonicteam/HUDRaderMap.h +++ b/MarathonRecomp/api/Sonicteam/HUDRaderMap.h @@ -1,10 +1,11 @@ #pragma once #include +#include namespace Sonicteam { class HUDRaderMap : public HUDPopupScreen {}; - MARATHON_ASSERT_SIZEOF(HUDRaderMap, 0xB0); + MARATHON_ASSERT_SIZEOF(HUDRaderMap, 0xB8); } diff --git a/MarathonRecomp/api/Sonicteam/LuaNode.h b/MarathonRecomp/api/Sonicteam/LuaNode.h new file mode 100644 index 00000000..edf41436 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/LuaNode.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include +#include + +namespace Sonicteam +{ + class LuaNode + { + public: + struct Vftable + { + be fpDestroy; + be fpGetTableString; + be fpGetTableConstString; + be fpGetTableConstStringFast; + be fpGetRoot; + be fpGetEmptyNode; + be fpIsTableExist; + be fpIsRoot; + be fpSetTablePath; + be fpCallFunction; // (path, custom_data, funcName) + be fpCallFunction2; // (path, custom_data, funcName) + be fpCallFunction3; // (funcName, custom_data) + be fpIsNumber; // (path) + be fpGetNumber; // (path) + be fpSetNumber; // (path, number) + be fpGetNumberFloat; // (path) + be fpSetNumberFloat; // (path, number) + be fpGetString; // (path) + be fpSetString; // (path, string) + be fpIsBoolean; // (path) + be fpGetBoolean; // (path) + be fpSetBoolean; // (path) + be fpSetNil; // (path) + be fpRegisterFunctions; // (LuaTFunc array, count) + be fpFunc60; + }; + + xpointer m_pVftable; + lua50::lua_State m_pLuaState; + + boost::shared_ptr GetTable(stdx::string* tablePath) + { + auto result = guest_stack_var>(); + + GuestToHostFunction(m_pVftable->fpGetTableString, result.get(), this, tablePath); + + return *result.get(); + } + + void CallFunction3(const char* functionName, void* customData) + { + GuestToHostFunction(m_pVftable->fpCallFunction3, this, functionName, customData); + } + + void RegisterFunctions(lua50::luaL_reg* functions, uint32_t count) + { + GuestToHostFunction(m_pVftable->fpRegisterFunctions, this, functions, count); + } + }; + + MARATHON_ASSERT_SIZEOF(LuaNode, 8); +} diff --git a/MarathonRecomp/api/Sonicteam/LuaNodeImp.h b/MarathonRecomp/api/Sonicteam/LuaNodeImp.h new file mode 100644 index 00000000..4ea308b1 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/LuaNodeImp.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include + +namespace Sonicteam +{ + class LuaNodeImp : public LuaNode + { + public: + stdx::string m_LuaTable; + }; +} diff --git a/MarathonRecomp/api/Sonicteam/LuaSystem.h b/MarathonRecomp/api/Sonicteam/LuaSystem.h new file mode 100644 index 00000000..ebcca2e1 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/LuaSystem.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include +#include + +namespace Sonicteam +{ + class LuaSystemManager; + + class LuaSystem : public LuaNodeImp, public SoX::IResource2 {}; +} diff --git a/MarathonRecomp/api/Sonicteam/LuaSystemManager.h b/MarathonRecomp/api/Sonicteam/LuaSystemManager.h new file mode 100644 index 00000000..2b2cb472 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/LuaSystemManager.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +namespace Sonicteam +{ + class LuaSystemManager : public SoX::IResourceMgr, public System::Singleton> {}; +} diff --git a/MarathonRecomp/api/Sonicteam/MainMenuExpositionTask.h b/MarathonRecomp/api/Sonicteam/MainMenuExpositionTask.h new file mode 100644 index 00000000..ea221e33 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/MainMenuExpositionTask.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +namespace Sonicteam +{ + class MainMenuExpositionTask : public SoX::RefCountObject, public SoX::Engine::Task + { + public: + be m_TextMotionState; + }; + + MARATHON_ASSERT_OFFSETOF(MainMenuExpositionTask, m_TextMotionState, 0x54); +} diff --git a/MarathonRecomp/api/Sonicteam/MainMenuTask.h b/MarathonRecomp/api/Sonicteam/MainMenuTask.h index 8752f17d..0572fac2 100644 --- a/MarathonRecomp/api/Sonicteam/MainMenuTask.h +++ b/MarathonRecomp/api/Sonicteam/MainMenuTask.h @@ -1,9 +1,11 @@ #pragma once #include -#include #include +#include +#include #include +#include namespace Sonicteam { @@ -39,7 +41,7 @@ namespace Sonicteam xpointer m_pHUDMainMenu; MARATHON_INSERT_PADDING(0x20); xpointer m_pButtonWindowTask; - MARATHON_INSERT_PADDING(4); + SoX::RefSharedPointer m_spMainMenuExpositionTask; be m_MainMenuSelectedIndex; MARATHON_INSERT_PADDING(0x1D8); be m_PressedButtons; @@ -52,6 +54,7 @@ namespace Sonicteam MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_State, 0x4C); MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_pHUDMainMenu, 0x74); MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_pButtonWindowTask, 0x98); + MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_spMainMenuExpositionTask, 0x9C); MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_MainMenuSelectedIndex, 0xA0); MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_PressedButtons, 0x27C); MARATHON_ASSERT_OFFSETOF(MainMenuTask, m_Field298, 0x298); diff --git a/MarathonRecomp/api/Sonicteam/MainMode.h b/MarathonRecomp/api/Sonicteam/MainMode.h index 9fa2c5db..6a5710a8 100644 --- a/MarathonRecomp/api/Sonicteam/MainMode.h +++ b/MarathonRecomp/api/Sonicteam/MainMode.h @@ -12,10 +12,13 @@ namespace Sonicteam MARATHON_INSERT_PADDING(0x24); boost::shared_ptr m_spSelectCamera; xpointer m_pFrameGP; - MARATHON_INSERT_PADDING(0x0C); + MARATHON_INSERT_PADDING(4); + xpointer m_pMainTask; + MARATHON_INSERT_PADDING(4); }; MARATHON_ASSERT_OFFSETOF(MainMode, m_spSelectCamera, 0x74); MARATHON_ASSERT_OFFSETOF(MainMode, m_pFrameGP, 0x7C); + MARATHON_ASSERT_OFFSETOF(MainMode, m_pMainTask, 0x84); MARATHON_ASSERT_SIZEOF(MainMode, 0x8C); } diff --git a/MarathonRecomp/api/Sonicteam/MyGraphicsDevice.h b/MarathonRecomp/api/Sonicteam/MyGraphicsDevice.h index 9b2d8dbe..fa64ff20 100644 --- a/MarathonRecomp/api/Sonicteam/MyGraphicsDevice.h +++ b/MarathonRecomp/api/Sonicteam/MyGraphicsDevice.h @@ -2,14 +2,31 @@ #include #include +#include namespace Sonicteam { class MyGraphicsDevice : public SoX::Graphics::Xenon::DeviceXenon { public: - MARATHON_INSERT_PADDING(0x1C0); + // Info : sub_8289CF60(this, CreationDeviceLocal*) + struct CreationDeviceLocal + { + xpointer pDevice; + D3DXBSURFACE_PARAMETERS SurfaceParamsA; + D3DXBSURFACE_PARAMETERS SurfaceParamsB; + D3DXBSURFACE_PARAMETERS SurfaceParamsC; + xpointer pColorTile2x; + xpointer pDepthTile2x; + xpointer pColorTile4x; + xpointer pDepthTile4x; + be BackBufferWidth; + be BackBufferHeight; + xpointer pAtgFontFile; + }; + + MARATHON_INSERT_PADDING(0x180); }; - MARATHON_ASSERT_SIZEOF(MyGraphicsDevice, 0x350); + MARATHON_ASSERT_SIZEOF(MyGraphicsDevice, 0x30C); } diff --git a/MarathonRecomp/api/Sonicteam/MyPE/CManageParticle.h b/MarathonRecomp/api/Sonicteam/MyPE/CManageParticle.h new file mode 100644 index 00000000..930ec084 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/MyPE/CManageParticle.h @@ -0,0 +1,54 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Sonicteam::MyPE +{ + class ManageParticleTask; + class Manager; + class MyPlugin; + + struct CManageParticleContainer + { + xpointer Field00; + xpointer Field04; + xpointer Field08; + }; + + class CManageParticle : public Particles::ParticleManagerUnit + { + public: + xpointer m_pDoc; + XRTL_CRITICAL_SECTION m_CriticalSection; + stdx::list m_lContainer; + SoX::LinkNode m_lnParticle; + xpointer m_pManagerParticleTask; + MARATHON_INSERT_PADDING(4); + boost::shared_ptr m_spManager; + boost::shared_ptr m_spMyPlugin; + MyEmitterListener m_MyEmitterListener; + MARATHON_INSERT_PADDING(0x2C); + + static CManageParticle* GetInstance() + { + return *(xpointer*)MmGetHostAddress(0x82D3C54C); + }; + }; + + MARATHON_ASSERT_OFFSETOF(CManageParticle, m_pDoc, 0x04); + MARATHON_ASSERT_OFFSETOF(CManageParticle, m_CriticalSection, 0x08); + MARATHON_ASSERT_OFFSETOF(CManageParticle, m_lContainer, 0x24); + MARATHON_ASSERT_OFFSETOF(CManageParticle, m_lnParticle, 0x30); + MARATHON_ASSERT_OFFSETOF(CManageParticle, m_pManagerParticleTask, 0x3C); + MARATHON_ASSERT_OFFSETOF(CManageParticle, m_spManager, 0x44); + MARATHON_ASSERT_OFFSETOF(CManageParticle, m_spMyPlugin, 0x4C); + MARATHON_ASSERT_OFFSETOF(CManageParticle, m_MyEmitterListener, 0x54); + MARATHON_ASSERT_SIZEOF(CManageParticle, 0x84); +} diff --git a/MarathonRecomp/api/Sonicteam/MyPE/EffectBankLoad.h b/MarathonRecomp/api/Sonicteam/MyPE/EffectBankLoad.h new file mode 100644 index 00000000..e77afffc --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/MyPE/EffectBankLoad.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include +#include + +namespace Sonicteam::MyPE +{ + class EffectBankLoadManager; + class TextureBankLoad; + + class EffectBankLoad : public SoX::IResource2 + { + public: + SoX::RefSharedPointer m_spMyEffectBank; + }; + + MARATHON_ASSERT_OFFSETOF(EffectBankLoad, m_spMyEffectBank, 0x64); +} diff --git a/MarathonRecomp/api/Sonicteam/MyPE/EffectBankLoadManager.h b/MarathonRecomp/api/Sonicteam/MyPE/EffectBankLoadManager.h new file mode 100644 index 00000000..03ad3eac --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/MyPE/EffectBankLoadManager.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include +#include +#include + +namespace Sonicteam::MyPE +{ + class EffectBankLoadManager : public SoX::IResourceMgr, System::Singleton> {}; +} diff --git a/MarathonRecomp/api/Sonicteam/MyPE/MyEffectBank.h b/MarathonRecomp/api/Sonicteam/MyPE/MyEffectBank.h new file mode 100644 index 00000000..54cce6f9 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/MyPE/MyEffectBank.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +namespace Sonicteam::MyPE +{ + class MyEffectBank : public GE1PE::EffectBank {}; +} diff --git a/MarathonRecomp/api/Sonicteam/MyPE/MyEmitterListener.h b/MarathonRecomp/api/Sonicteam/MyPE/MyEmitterListener.h new file mode 100644 index 00000000..ddd71350 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/MyPE/MyEmitterListener.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +namespace Sonicteam::MyPE +{ + class MyEmitterListener : public GE1PE::EmitterListener {}; +} diff --git a/MarathonRecomp/api/Sonicteam/MyRenderProcess.h b/MarathonRecomp/api/Sonicteam/MyRenderProcess.h new file mode 100644 index 00000000..98ca379d --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/MyRenderProcess.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +namespace Sonicteam +{ + class MyGraphicsDevice; + + class MyRenderProcess : public SoX::Engine::RenderProcess + { + public: + xpointer m_pDoc; + xpointer m_pMyGraphicsDevice; + }; + + MARATHON_ASSERT_OFFSETOF(MyRenderProcess, m_pDoc, 0x30); + MARATHON_ASSERT_OFFSETOF(MyRenderProcess, m_pMyGraphicsDevice, 0x34); +} diff --git a/MarathonRecomp/api/Sonicteam/NoSyncThread.h b/MarathonRecomp/api/Sonicteam/NoSyncThread.h index 9dbca0dd..fb65f1c7 100644 --- a/MarathonRecomp/api/Sonicteam/NoSyncThread.h +++ b/MarathonRecomp/api/Sonicteam/NoSyncThread.h @@ -5,11 +5,7 @@ namespace Sonicteam { - class NoSyncThread : SoX::Thread - { - public: - MARATHON_INSERT_PADDING(4); - }; + class NoSyncThread : SoX::Thread {}; MARATHON_ASSERT_SIZEOF(NoSyncThread, 0x4C); } diff --git a/MarathonRecomp/api/Sonicteam/Particles/Particle.h b/MarathonRecomp/api/Sonicteam/Particles/Particle.h new file mode 100644 index 00000000..2a1b9b61 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/Particles/Particle.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +namespace Sonicteam::Particles +{ + class Particle : public ParticleRef + { + struct Vftable : ParticleRef::Vftable + { + be fpFunc08; + be fpFunc0C; + be fpFunc10; // Hint: used before Release() with arg 0. + be fpFunc14; + be fpFunc18; + be fpFunc1C; + be fpFunc20; + }; + + void Func10(uint32_t flags) + { + GuestToHostFunction(((Vftable*)m_pVftable.get())->fpFunc10, this, flags); + } + }; +} diff --git a/MarathonRecomp/api/Sonicteam/Particles/ParticleContainer.h b/MarathonRecomp/api/Sonicteam/Particles/ParticleContainer.h new file mode 100644 index 00000000..69ae8f74 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/Particles/ParticleContainer.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Sonicteam::Particles +{ + class ParticleContainerMgr; + class ParticleManager; + + struct ParticleBank + { + xpointer pEffectBankFile; + xpointer pEffectName; + be Field08; + MARATHON_INSERT_PADDING(4); + }; + + struct ParticleBankArray + { + be m_Length; + ParticleBank m_First; + + ParticleBank* operator[](uint32_t index) + { + return (ParticleBank*)((uint8_t*)this + sizeof(ParticleBank) * index); + } + }; + + class ParticleContainer : public SoX::IResource2 + { + public: + xpointer m_pParticleManager; + be m_Index; + stdx::string m_ContainerName; + stdx::map> m_mParticleIndices; + xpointer m_pParticleBank; // Hint: Destructor should recast back to 0 position from + 4, then destroy pointers. + be m_Field98; + stdx::vector> m_vspAckResource; + stdx::vector> m_vspEffectBankLoad; + stdx::vector> m_vspTextureBankLoad; + }; + + MARATHON_ASSERT_OFFSETOF(ParticleContainer, m_Index, 0x68); + MARATHON_ASSERT_OFFSETOF(ParticleContainer, m_ContainerName, 0x6C); + MARATHON_ASSERT_OFFSETOF(ParticleContainer, m_mParticleIndices, 0x88); + MARATHON_ASSERT_OFFSETOF(ParticleContainer, m_pParticleBank, 0x94); + MARATHON_ASSERT_OFFSETOF(ParticleContainer, m_Field98, 0x98); + MARATHON_ASSERT_OFFSETOF(ParticleContainer, m_vspAckResource, 0x9C); + MARATHON_ASSERT_OFFSETOF(ParticleContainer, m_vspEffectBankLoad, 0xAC); + MARATHON_ASSERT_OFFSETOF(ParticleContainer, m_vspTextureBankLoad, 0xBC); +} diff --git a/MarathonRecomp/api/Sonicteam/Particles/ParticleContainerMgr.h b/MarathonRecomp/api/Sonicteam/Particles/ParticleContainerMgr.h new file mode 100644 index 00000000..bc4ed4c0 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/Particles/ParticleContainerMgr.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include +#include +#include + +namespace Sonicteam::Particles +{ + class ParticleContainerMgr : public SoX::IResourceMgr, public System::Singleton> {}; +} diff --git a/MarathonRecomp/api/Sonicteam/Particles/ParticleManager.h b/MarathonRecomp/api/Sonicteam/Particles/ParticleManager.h new file mode 100644 index 00000000..c0117c76 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/Particles/ParticleManager.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace Sonicteam::Particles +{ + class ParticleManager + { + public: + xpointer m_pDoc; + stdx::vector> m_vspManagerUnits; + be m_PlayCount1; // Almost for any particle + be m_PlayCount2; // Always 1 + be m_PlayCount3; // Always 1? + be m_Field20; + stdx::map> m_mParticleContainerIndices; // TODO: check if these are uint16_t. + stdx::map, xpointer> m_mParticleContainer; // TODO: check if these are uint16_t. + be m_ParticleSpeed; + }; + + MARATHON_ASSERT_OFFSETOF(ParticleManager, m_pDoc, 0x00); + MARATHON_ASSERT_OFFSETOF(ParticleManager, m_vspManagerUnits, 0x04); + MARATHON_ASSERT_OFFSETOF(ParticleManager, m_PlayCount1,0x14); + MARATHON_ASSERT_OFFSETOF(ParticleManager, m_PlayCount2,0x18); + MARATHON_ASSERT_OFFSETOF(ParticleManager, m_PlayCount3,0x1C); + MARATHON_ASSERT_OFFSETOF(ParticleManager, m_Field20,0x20); + MARATHON_ASSERT_OFFSETOF(ParticleManager, m_mParticleContainerIndices,0x24); + MARATHON_ASSERT_OFFSETOF(ParticleManager, m_mParticleContainer,0x30); + MARATHON_ASSERT_SIZEOF(ParticleManager, 0x40); +} diff --git a/MarathonRecomp/api/Sonicteam/Particles/ParticleManagerUnit.h b/MarathonRecomp/api/Sonicteam/Particles/ParticleManagerUnit.h new file mode 100644 index 00000000..50499ce6 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/Particles/ParticleManagerUnit.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +namespace Sonicteam::Particles +{ + class ParticleManagerUnit + { + public: + struct Vftable + { + be fpDestroy; + be fpFunc04; // RefSharedPointer LoadBank(return, this, ?, ?) + be fpFunc08; + be fpFunc0C; + be fpFunc10; + be fpFunc14; + be fpFunc18; + be fpFunc1C; + be fpFunc20; + be fpFunc24; + be fpFunc2C; + }; + + xpointer m_pVftable; + }; +} diff --git a/MarathonRecomp/api/Sonicteam/Particles/ParticleRef.h b/MarathonRecomp/api/Sonicteam/Particles/ParticleRef.h new file mode 100644 index 00000000..b73534ee --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/Particles/ParticleRef.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +namespace Sonicteam::Particles +{ + class ParticleRef + { + public: + struct Vftable + { + be fpDestroy; + be fpRelease; + }; + + xpointer m_pVftable; + be m_ReferenceCount; + + void Destroy(uint8_t flags = 1) + { + GuestToHostFunction(m_pVftable->fpDestroy, this, flags); + } + + void Release() + { + GuestToHostFunction(m_pVftable->fpRelease, this); + } + }; +} diff --git a/MarathonRecomp/api/Sonicteam/Player/Effect/ParticleJoint.h b/MarathonRecomp/api/Sonicteam/Player/Effect/ParticleJoint.h new file mode 100644 index 00000000..b322a749 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/Player/Effect/ParticleJoint.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace Sonicteam::Player::Effect +{ + class ParticleJoint : public SoX::Graphics::FrameObserver + { + public: + xpointer m_pParticle; + bool m_IsAcroarts; + bool m_IsReverse; + be m_Direction; + xpointer m_pNodeName; + SoX::Math::Vector m_Offset; + SoX::Math::Vector m_Position; + SoX::Math::Vector m_Rotation; + }; + + MARATHON_ASSERT_OFFSETOF(ParticleJoint, m_pParticle, 0x14); + MARATHON_ASSERT_OFFSETOF(ParticleJoint, m_IsAcroarts, 0x18); + MARATHON_ASSERT_OFFSETOF(ParticleJoint, m_IsReverse, 0x19); + MARATHON_ASSERT_OFFSETOF(ParticleJoint, m_Direction, 0x1C); + MARATHON_ASSERT_OFFSETOF(ParticleJoint, m_pNodeName, 0x20); + MARATHON_ASSERT_OFFSETOF(ParticleJoint, m_Offset, 0x30); + MARATHON_ASSERT_OFFSETOF(ParticleJoint, m_Position, 0x40); + MARATHON_ASSERT_OFFSETOF(ParticleJoint, m_Rotation, 0x50); + MARATHON_ASSERT_SIZEOF(ParticleJoint, 0x60); +} diff --git a/MarathonRecomp/api/Sonicteam/Player/Effect/ParticleLuaTable.h b/MarathonRecomp/api/Sonicteam/Player/Effect/ParticleLuaTable.h new file mode 100644 index 00000000..54f28eb3 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/Player/Effect/ParticleLuaTable.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +namespace Sonicteam::Player::Effect +{ + struct ParticleLuaInfo + { + be BankID; + be ParticleID; + bool IsAcroarts; + bool IsReverse; + be Direction; + xpointer pNodeName; + be OffsetX; + be OffsetY; + be OffsetZ; + }; + + MARATHON_ASSERT_OFFSETOF(ParticleLuaInfo, BankID, 0x00); + MARATHON_ASSERT_OFFSETOF(ParticleLuaInfo, IsAcroarts, 0x04); + MARATHON_ASSERT_OFFSETOF(ParticleLuaInfo, IsReverse, 0x05); + MARATHON_ASSERT_OFFSETOF(ParticleLuaInfo, Direction, 0x08); + MARATHON_ASSERT_OFFSETOF(ParticleLuaInfo, pNodeName, 0x0C); + MARATHON_ASSERT_OFFSETOF(ParticleLuaInfo, OffsetX, 0x10); + MARATHON_ASSERT_OFFSETOF(ParticleLuaInfo, OffsetY, 0x14); + MARATHON_ASSERT_OFFSETOF(ParticleLuaInfo, OffsetZ, 0x18); + MARATHON_ASSERT_SIZEOF(ParticleLuaInfo, 0x1C); +} diff --git a/MarathonRecomp/api/Sonicteam/Player/Object.h b/MarathonRecomp/api/Sonicteam/Player/Object.h index 52e59781..586b5c82 100644 --- a/MarathonRecomp/api/Sonicteam/Player/Object.h +++ b/MarathonRecomp/api/Sonicteam/Player/Object.h @@ -90,7 +90,7 @@ namespace Sonicteam::Player auto playerIndex = pGame->PlayerActorIDToIndex(m_ActorID); auto padID = pDoc->m_aPadIDs[playerIndex]; - return pDoc->m_vspInputManager[padID].get(); + return pDoc->m_vspInputManagers[padID].get(); } }; diff --git a/MarathonRecomp/api/Sonicteam/PopupScreenTask.h b/MarathonRecomp/api/Sonicteam/PopupScreenTask.h new file mode 100644 index 00000000..b2b336aa --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/PopupScreenTask.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include +#include +#include + +namespace Sonicteam +{ + class PopupScreenTask : public SoX::Engine::Task + { + public: + SoX::RefSharedPointer m_spHUDPopupScreen; + + template + T* GetHUDPopupScreen() + { + return static_cast(m_spHUDPopupScreen.get()); + } + }; +} diff --git a/MarathonRecomp/api/Sonicteam/RaderMapManager.h b/MarathonRecomp/api/Sonicteam/RaderMapManager.h index 5999dfe6..089df561 100644 --- a/MarathonRecomp/api/Sonicteam/RaderMapManager.h +++ b/MarathonRecomp/api/Sonicteam/RaderMapManager.h @@ -1,6 +1,8 @@ #pragma once #include +#include +#include namespace Sonicteam { diff --git a/MarathonRecomp/api/Sonicteam/RenderTargetContainer.h b/MarathonRecomp/api/Sonicteam/RenderTargetContainer.h new file mode 100644 index 00000000..a49ce683 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/RenderTargetContainer.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Sonicteam +{ + class RenderTargetContainer + { + public: + struct Vftable + { + be fpDestroy; + }; + + xpointer m_pVftable; + xpointer m_pDevice; + stdx::map> m_mspDepthStencil_1_4; + stdx::map> m_mspDepthStencil_256; + stdx::map> m_mspFrameBuffer; + stdx::map> m_mspPostEffect; // reflection, csm, radermap + stdx::map> m_mspPostEffectAfter; // radermap_mask + }; +} diff --git a/MarathonRecomp/api/Sonicteam/RootGTask.h b/MarathonRecomp/api/Sonicteam/RootGTask.h new file mode 100644 index 00000000..93d3a2c4 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/RootGTask.h @@ -0,0 +1,6 @@ +#pragma once + +#include +#include + +class RootGTask : public Sonicteam::SoX::Engine::GTask {}; diff --git a/MarathonRecomp/api/Sonicteam/SFXAgent.h b/MarathonRecomp/api/Sonicteam/SFXAgent.h new file mode 100644 index 00000000..d4cd37e0 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SFXAgent.h @@ -0,0 +1,55 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace Sonicteam +{ + struct SFXMatrixArray; + + struct SFXMatrixNode + { + xpointer pData[4]; + + SFXMatrixArray* GetArray() + { + return reinterpret_cast((uint8_t*)this - 4); + } + }; + + struct SFXMatrixArray + { + be Length; + SFXMatrixNode First; + }; + + class SFXAgent : public SoX::MessageReceiver + { + public: + struct Vftable : public SoX::MessageReceiver::Vftable + { + be fpReload; + be fpField0C; + be fpField10; + }; + + xpointer m_pDoc; + xpointer m_aSFXMatrices1; + xpointer m_aSFXMatrices2; + stdx::map> m_mRenderProcesses; + MARATHON_INSERT_PADDING(8); + + void Reload() + { + GuestToHostFunction(((Vftable*)m_pVftable.get())->fpReload, this); + } + }; + + MARATHON_ASSERT_OFFSETOF(SFXAgent, m_mRenderProcesses, 0x10); + MARATHON_ASSERT_SIZEOF(SFXAgent, 0x24); +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/ApplicationXenon.h b/MarathonRecomp/api/Sonicteam/SoX/ApplicationXenon.h index 8a39ff4d..70fa3065 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/ApplicationXenon.h +++ b/MarathonRecomp/api/Sonicteam/SoX/ApplicationXenon.h @@ -2,18 +2,49 @@ #include #include +#include namespace Sonicteam::SoX { class ApplicationXenon : public Engine::Application { public: - MARATHON_INSERT_PADDING(0x174); + struct DeviceInfo + { + be DeviceState; + xpointer pDevice; + D3DXBSURFACE_PARAMETERS SurfaceParamsA; + D3DXBSURFACE_PARAMETERS SurfaceParamsB; + D3DXBSURFACE_PARAMETERS SurfaceParamsC; + xpointer pColorTile2x; + xpointer pDepthTile2x; + xpointer pColorTile4x; + xpointer pDepthTile4x; + D3DXBPRESENT_PARAMETERS PresentParameters; + }; - static ApplicationXenon* GetInstance(); + MARATHON_INSERT_PADDING(4); + be m_FirstTimeBase; + be m_FirstPerformanceFrequency; + be m_DeviceState; + xpointer m_pDevice; + DeviceInfo m_DeviceInfo; + be m_DeltaTimePost; // TODO: check if these are in the correct order. + be m_DeltaTimePre; // TODO: check if these are in the correct order. + bool m_IsInitBuffers; + MARATHON_INSERT_PADDING(7); + xpointer m_pFrontBufferTexture; + xpointer m_pBackBufferSurface; + xpointer m_pDepthStencilSurface; + xpointer m_pColorTile2x; + xpointer m_pDepthTile2x; + xpointer m_pColorTile4x; + xpointer m_pDepthTile4x; + be m_ShaderVertexCount; + be m_PixelShaderVertexCount; + be m_hNotification; + MARATHON_INSERT_PADDING(0x60); }; MARATHON_ASSERT_SIZEOF(ApplicationXenon, 0x180); } - -#include diff --git a/MarathonRecomp/api/Sonicteam/SoX/ApplicationXenon.inl b/MarathonRecomp/api/Sonicteam/SoX/ApplicationXenon.inl deleted file mode 100644 index 46ba52de..00000000 --- a/MarathonRecomp/api/Sonicteam/SoX/ApplicationXenon.inl +++ /dev/null @@ -1,7 +0,0 @@ -namespace Sonicteam::SoX -{ - inline ApplicationXenon* ApplicationXenon::GetInstance() - { - return *(xpointer*)MmGetHostAddress(0x82D3B348); - } -} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Array.h b/MarathonRecomp/api/Sonicteam/SoX/Array.h new file mode 100644 index 00000000..4b7feeb1 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/Array.h @@ -0,0 +1,32 @@ +#pragma once + +#include + +namespace Sonicteam::SoX +{ + template + class Array + { + private: + T m_container[Length]; + + public: + Array() {} + ~Array() = default; + + T& operator[](uint32_t index) + { + return m_container[index]; + } + + const T& operator[](uint32_t index) const + { + return m_container[index]; + } + + uint32_t size() const + { + return Length; + } + }; +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Component.h b/MarathonRecomp/api/Sonicteam/SoX/Component.h index 6483e1e6..c7871ae2 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/Component.h +++ b/MarathonRecomp/api/Sonicteam/SoX/Component.h @@ -1,28 +1,36 @@ #pragma once #include +#include #include namespace Sonicteam::SoX { - namespace Engine - { - class DocMode; - } - class Component : public Object { public: - xpointer m_pDocMode; - MARATHON_INSERT_PADDING(0x18); + struct Vftable : public Object::Vftable + { + be fpDestroy; + be fpUpdate; + }; + + xpointer m_pParent; + LinkNode m_lnComponent; + LinkedList m_llComponent; + + template + T* GetParent() + { + return (T*)m_pParent.get(); + } - template - T* GetDocMode() + void Update(float deltaTime) { - return (T*)m_pDocMode.get(); + GuestToHostFunction(((Vftable*)m_pVftable.get())->fpUpdate, this, deltaTime); } }; - MARATHON_ASSERT_OFFSETOF(Component, m_pDocMode, 0x04); + MARATHON_ASSERT_OFFSETOF(Component, m_pParent, 0x04); MARATHON_ASSERT_SIZEOF(Component, 0x20); } diff --git a/MarathonRecomp/api/Sonicteam/SoX/Engine/Application.h b/MarathonRecomp/api/Sonicteam/SoX/Engine/Application.h index dc5fd7e5..ce73c00e 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/Engine/Application.h +++ b/MarathonRecomp/api/Sonicteam/SoX/Engine/Application.h @@ -1,16 +1,17 @@ #pragma once #include +#include +#include namespace Sonicteam::SoX::Engine { - class Application + class Application : Object { public: - xpointer m_pVftable; - MARATHON_INSERT_PADDING(8); + bool IsField04; + xpointer m_pParent; }; - MARATHON_ASSERT_OFFSETOF(Application, m_pVftable, 0x00); MARATHON_ASSERT_SIZEOF(Application, 0x0C); } diff --git a/MarathonRecomp/api/Sonicteam/SoX/Engine/Doc.h b/MarathonRecomp/api/Sonicteam/SoX/Engine/Doc.h index a21a9e92..3b3be5a6 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/Engine/Doc.h +++ b/MarathonRecomp/api/Sonicteam/SoX/Engine/Doc.h @@ -3,6 +3,8 @@ #include #include #include +#include +#include namespace Sonicteam::SoX::Engine { @@ -13,13 +15,15 @@ namespace Sonicteam::SoX::Engine MARATHON_INSERT_PADDING(4); xpointer m_pDocMode; xpointer m_pRootTask; - xpointer m_pRootGTask; + xpointer m_pRootGTask; MARATHON_INSERT_PADDING(8); xpointer m_pDocModeExecutor; - MARATHON_INSERT_PADDING(0x3C); + xpointer m_pRenderScheduler; + XRTL_CRITICAL_SECTION m_CriticalSection1; + XRTL_CRITICAL_SECTION m_CriticalSection2; template - inline T* GetDocMode() + T* GetDocMode() { return (T*)m_pDocMode.get(); } @@ -30,5 +34,8 @@ namespace Sonicteam::SoX::Engine MARATHON_ASSERT_OFFSETOF(Doc, m_pRootTask, 0x0C); MARATHON_ASSERT_OFFSETOF(Doc, m_pRootGTask, 0x10); MARATHON_ASSERT_OFFSETOF(Doc, m_pDocModeExecutor, 0x1C); + MARATHON_ASSERT_OFFSETOF(Doc, m_pRenderScheduler, 0x20); + MARATHON_ASSERT_OFFSETOF(Doc, m_CriticalSection1, 0x24); + MARATHON_ASSERT_OFFSETOF(Doc, m_CriticalSection2, 0x40); MARATHON_ASSERT_SIZEOF(Doc, 0x5C); } diff --git a/MarathonRecomp/api/Sonicteam/SoX/Engine/GTask.h b/MarathonRecomp/api/Sonicteam/SoX/Engine/GTask.h new file mode 100644 index 00000000..29f8a43d --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/Engine/GTask.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include + +namespace Sonicteam::SoX::Engine +{ + class Doc; + + class GTask : public Component + { + public: + be m_Flags; + xpointer m_pPrevSibling; + xpointer m_pNextSibling; + xpointer m_pDependency; + xpointer m_pDependencies; + + GTask* GetFirstDependency() const + { + if (!m_pDependencies) + return nullptr; + + auto pCurrent = m_pDependencies.get(); + + while (pCurrent->m_pPrevSibling && pCurrent->m_pPrevSibling != m_pDependencies.get()) + pCurrent = pCurrent->m_pPrevSibling.get(); + + return pCurrent; + } + + GTask* GetLastDependency() const + { + return m_pDependencies.get(); + } + }; +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Engine/RenderProcess.h b/MarathonRecomp/api/Sonicteam/SoX/Engine/RenderProcess.h new file mode 100644 index 00000000..fc42b1b8 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/Engine/RenderProcess.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +#include + +namespace Sonicteam::SoX::Engine +{ + class RenderScheduler; + + class RenderProcess + { + public: + struct Vftable + { + be fpDestroy; + be fpFunc04; + be fpFunc08; + be fpFunc0C; + }; + + xpointer m_pVftable; + xpointer m_Flag1; // or Type? + xpointer m_pGTask; + be m_Flag2; + MARATHON_INSERT_PADDING(8); + be m_Field18; + MARATHON_INSERT_PADDING(4); + xpointer m_pRenderScheduler; + LinkNode m_lnRenderProcess; // TODO: verify. + }; + + MARATHON_ASSERT_OFFSETOF(RenderProcess, m_Flag1, 0x04); + MARATHON_ASSERT_OFFSETOF(RenderProcess, m_pGTask, 0x08); + MARATHON_ASSERT_OFFSETOF(RenderProcess, m_Flag2, 0x0C); + MARATHON_ASSERT_OFFSETOF(RenderProcess, m_Field18, 0x18); + MARATHON_ASSERT_OFFSETOF(RenderProcess, m_pRenderScheduler, 0x20); + MARATHON_ASSERT_OFFSETOF(RenderProcess, m_lnRenderProcess, 0x24); +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Engine/RenderScheduler.h b/MarathonRecomp/api/Sonicteam/SoX/Engine/RenderScheduler.h new file mode 100644 index 00000000..30584c04 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/Engine/RenderScheduler.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include +#include + +namespace Sonicteam::SoX::Engine +{ + class RenderProcess; + + class RenderScheduler + { + public: + struct Vftable + { + be fpDestroy; + be fpFunc04; + }; + + xpointer m_pVftable; + stdx::list>> m_lRenderProcesses; + }; +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Engine/Task.h b/MarathonRecomp/api/Sonicteam/SoX/Engine/Task.h index f5edcef8..3a2eaed5 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/Engine/Task.h +++ b/MarathonRecomp/api/Sonicteam/SoX/Engine/Task.h @@ -12,7 +12,8 @@ namespace Sonicteam::SoX::Engine class Task : public Component, public MessageReceiver { public: - be m_Flags; + char m_Flag1; + MARATHON_INSERT_PADDING(3); be m_Timestamp; xpointer m_pPrevSibling; xpointer m_pNextSibling; @@ -21,7 +22,48 @@ namespace Sonicteam::SoX::Engine xpointer m_pDoc; LinkNode m_lnTask; - Task* GetFirstDependency() const + class iterator + { + Task* m_pCurrent; + + public: + iterator(Task* pCurrent = nullptr) : m_pCurrent(pCurrent) {} + + Task& operator*() const + { + return *m_pCurrent; + } + + Task* operator->() const + { + return m_pCurrent; + } + + iterator& operator++() + { + if (m_pCurrent) + m_pCurrent = m_pCurrent->m_pPrevSibling.get(); + + return *this; + } + + bool operator!=(const iterator& other) const + { + return m_pCurrent != other.m_pCurrent; + } + }; + + iterator begin() + { + return iterator(this); + } + + iterator end() + { + return iterator(nullptr); + } + + Task* GetFirstDependency() const { if (!m_pDependencies) return nullptr; @@ -39,14 +81,14 @@ namespace Sonicteam::SoX::Engine return m_pDependencies.get(); } - template + template T* GetDoc() { return (T*)m_pDoc.get(); } }; - MARATHON_ASSERT_OFFSETOF(Task, m_Flags, 0x24); + MARATHON_ASSERT_OFFSETOF(Task, m_Flag1, 0x24); MARATHON_ASSERT_OFFSETOF(Task, m_Timestamp, 0x28); MARATHON_ASSERT_OFFSETOF(Task, m_pPrevSibling, 0x2C); MARATHON_ASSERT_OFFSETOF(Task, m_pNextSibling, 0x30); diff --git a/MarathonRecomp/api/Sonicteam/SoX/Graphics/Device.h b/MarathonRecomp/api/Sonicteam/SoX/Graphics/Device.h index dd8da675..5b056fa5 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/Graphics/Device.h +++ b/MarathonRecomp/api/Sonicteam/SoX/Graphics/Device.h @@ -2,6 +2,8 @@ #include #include +#include +#include namespace Sonicteam::SoX::Graphics { @@ -9,14 +11,35 @@ namespace Sonicteam::SoX::Graphics { public: xpointer m_pVftable; - MARATHON_INSERT_PADDING(0x3C); + MARATHON_INSERT_PADDING(0x14); + be m_DBRFlag; + MARATHON_INSERT_PADDING(0x24); Math::Matrix4x4 m_Field40; be m_Field80; - MARATHON_INSERT_PADDING(0x4C); + be m_Field84; // Viewport? + MARATHON_INSERT_PADDING(4); + be m_Width1; + be m_Height1; + be m_Field94; + be m_Field98; + be m_Width2; + be m_Height2; + MARATHON_INSERT_PADDING(0x1C); + RefSharedPointer m_FrameBufferObject; + MARATHON_INSERT_PADDING(0x0C); }; - MARATHON_ASSERT_OFFSETOF(Device, m_pVftable, 0x00); + MARATHON_ASSERT_OFFSETOF(Device, m_DBRFlag, 0x18); MARATHON_ASSERT_OFFSETOF(Device, m_Field40, 0x40); MARATHON_ASSERT_OFFSETOF(Device, m_Field80, 0x80); + MARATHON_ASSERT_OFFSETOF(Device, m_Field84, 0x84); + MARATHON_ASSERT_OFFSETOF(Device, m_Field84, 0x84); + MARATHON_ASSERT_OFFSETOF(Device, m_Width1, 0x8C); + MARATHON_ASSERT_OFFSETOF(Device, m_Height1, 0x90); + MARATHON_ASSERT_OFFSETOF(Device, m_Field94, 0x94); + MARATHON_ASSERT_OFFSETOF(Device, m_Field98, 0x98); + MARATHON_ASSERT_OFFSETOF(Device, m_Width2, 0x9C); + MARATHON_ASSERT_OFFSETOF(Device, m_Height2, 0xA0); + MARATHON_ASSERT_OFFSETOF(Device, m_FrameBufferObject, 0xC0); MARATHON_ASSERT_SIZEOF(Device, 0xD0); } diff --git a/MarathonRecomp/api/Sonicteam/SoX/Graphics/Surface.h b/MarathonRecomp/api/Sonicteam/SoX/Graphics/Surface.h new file mode 100644 index 00000000..62d2cbcf --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/Graphics/Surface.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include + +namespace Sonicteam::SoX::Graphics +{ + class Texture; + + class Surface : public Sonicteam::SoX::IResource + { + public: + be m_Width; + be m_Height; + MARATHON_INSERT_PADDING(4); + xpointer m_pSurface; + xpointer m_spTexture; // RefSharedPointer + xpointer m_pTexture; + MARATHON_INSERT_PADDING(0xC); + }; +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Graphics/SurfaceMgr.h b/MarathonRecomp/api/Sonicteam/SoX/Graphics/SurfaceMgr.h new file mode 100644 index 00000000..e285cb4b --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/Graphics/SurfaceMgr.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +namespace Sonicteam::SoX::Graphics +{ + class SurfaceMgr : public SoX::IResourceMgr, public System::Singleton> {}; +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Graphics/Texture.h b/MarathonRecomp/api/Sonicteam/SoX/Graphics/Texture.h new file mode 100644 index 00000000..c5844e1f --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/Graphics/Texture.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace Sonicteam::SoX::Graphics +{ + class Texture : public IResource + { + public: + xpointer m_pTexture; + SoX::Array, 6> m_aspSurfaces; + be m_Width; + be m_Height; + xpointer m_pDevice; + }; +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Graphics/TextureMgr.h b/MarathonRecomp/api/Sonicteam/SoX/Graphics/TextureMgr.h new file mode 100644 index 00000000..c53c4cda --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/Graphics/TextureMgr.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +namespace Sonicteam::SoX::Graphics +{ + class TextureMgr : public SoX::IResourceMgr, public System::Singleton> {}; +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Graphics/Xenon/DeviceXenon.h b/MarathonRecomp/api/Sonicteam/SoX/Graphics/Xenon/DeviceXenon.h index ec737a0f..a86b2292 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/Graphics/Xenon/DeviceXenon.h +++ b/MarathonRecomp/api/Sonicteam/SoX/Graphics/Xenon/DeviceXenon.h @@ -2,14 +2,40 @@ #include #include +#include +#include +#include +#include +#include namespace Sonicteam::SoX::Graphics::Xenon { class DeviceXenon : public Device { public: - MARATHON_INSERT_PADDING(0xC0); + SoX::RefSharedPointer m_spBackBuffer; + SoX::RefSharedPointer m_spDepthStencil; + MARATHON_INSERT_PADDING(0x30); + SoX::Array, 10> m_apTextures; + MARATHON_INSERT_PADDING(0x28); + D3DXBSURFACE_PARAMETERS m_SurfaceParamsA; + D3DXBSURFACE_PARAMETERS m_SurfaceParamsB; + D3DXBSURFACE_PARAMETERS m_SurfaceParamsC; + SoX::RefSharedPointer m_spColorTile2X; + SoX::RefSharedPointer m_spDepthTile2X; + SoX::RefSharedPointer m_spColorTile4X; + SoX::RefSharedPointer m_spDepthTile4X; }; - MARATHON_ASSERT_SIZEOF(DeviceXenon, 0x190); + MARATHON_ASSERT_OFFSETOF(DeviceXenon, m_spBackBuffer, 0xD0); + MARATHON_ASSERT_OFFSETOF(DeviceXenon, m_spDepthStencil, 0xD4); + MARATHON_ASSERT_OFFSETOF(DeviceXenon, m_apTextures, 0x108); + MARATHON_ASSERT_OFFSETOF(DeviceXenon, m_SurfaceParamsA, 0x158); + MARATHON_ASSERT_OFFSETOF(DeviceXenon, m_SurfaceParamsB, 0x164); + MARATHON_ASSERT_OFFSETOF(DeviceXenon, m_SurfaceParamsC, 0x170); + MARATHON_ASSERT_OFFSETOF(DeviceXenon, m_spColorTile2X, 0x17C); + MARATHON_ASSERT_OFFSETOF(DeviceXenon, m_spDepthTile2X, 0x180); + MARATHON_ASSERT_OFFSETOF(DeviceXenon, m_spColorTile4X, 0x184); + MARATHON_ASSERT_OFFSETOF(DeviceXenon, m_spDepthTile4X, 0x188); + MARATHON_ASSERT_SIZEOF(DeviceXenon, 0x18C); } diff --git a/MarathonRecomp/api/Sonicteam/SoX/Graphics/Xenon/SurfaceXenon.h b/MarathonRecomp/api/Sonicteam/SoX/Graphics/Xenon/SurfaceXenon.h new file mode 100644 index 00000000..c0a55328 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/Graphics/Xenon/SurfaceXenon.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +namespace Sonicteam::SoX::Graphics::Xenon +{ + class SurfaceXenon : public Surface {}; +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Graphics/Xenon/TextureXenon.h b/MarathonRecomp/api/Sonicteam/SoX/Graphics/Xenon/TextureXenon.h index eb619eb5..05dba109 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/Graphics/Xenon/TextureXenon.h +++ b/MarathonRecomp/api/Sonicteam/SoX/Graphics/Xenon/TextureXenon.h @@ -1,20 +1,9 @@ #pragma once #include -#include +#include namespace Sonicteam::SoX::Graphics::Xenon { - class TextureXenon : public IResource - { - public: - MARATHON_INSERT_PADDING(0x1C); - be m_Width; - be m_Height; - MARATHON_INSERT_PADDING(4); - }; - - MARATHON_ASSERT_OFFSETOF(TextureXenon, m_Width, 0x80); - MARATHON_ASSERT_OFFSETOF(TextureXenon, m_Height, 0x84); - MARATHON_ASSERT_SIZEOF(TextureXenon, 0x8C); + class TextureXenon : public Texture {}; } diff --git a/MarathonRecomp/api/Sonicteam/SoX/IResource.h b/MarathonRecomp/api/Sonicteam/SoX/IResource.h index b4072464..482c2d4c 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/IResource.h +++ b/MarathonRecomp/api/Sonicteam/SoX/IResource.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace Sonicteam::SoX @@ -8,11 +9,40 @@ namespace Sonicteam::SoX class IResource : public RefCountObject { public: - MARATHON_INSERT_PADDING(4); - stdx::string m_FilePath; - MARATHON_INSERT_PADDING(0x3C); + struct Vftable : RefCountObject::Vftable + { + be fpInit; + be fpGetPath; + be fpIsInARC; + }; + + be m_MgrRegistryIndex; // Used to free resource. + stdx::string m_MgrResourceName; + stdx::string m_ResourceNameInitial; + stdx::string m_ResourceName; + bool m_IsInResourceManager; + MARATHON_INSERT_PADDING(3); + + void Init(void* file, uint64_t size) + { + GuestToHostFunction(((Vftable*)m_pVftable.get())->fpInit, this, file, size); + } + + stdx::string GetPath(stdx::string* fileName) + { + guest_stack_var out{}; + + GuestToHostFunction(((Vftable*)m_pVftable.get())->fpGetPath, out.get(), this, fileName); + + return *out; + } + + bool IsInARC() + { + return GuestToHostFunction(((Vftable*)m_pVftable.get())->fpIsInARC, this); + } }; - MARATHON_ASSERT_OFFSETOF(IResource, m_FilePath, 0x0C); + MARATHON_ASSERT_OFFSETOF(IResource, m_MgrResourceName, 0x0C); MARATHON_ASSERT_SIZEOF(IResource, 0x64); } diff --git a/MarathonRecomp/api/Sonicteam/SoX/IResourceMgr.h b/MarathonRecomp/api/Sonicteam/SoX/IResourceMgr.h index 977ced4f..7d6dbd1a 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/IResourceMgr.h +++ b/MarathonRecomp/api/Sonicteam/SoX/IResourceMgr.h @@ -1,21 +1,46 @@ #pragma once #include +#include namespace Sonicteam::SoX { + // Different for each implementation. + struct IResourceMgrCreationParams; + class IResourceMgr { public: struct Vftable { be fpDestroy; - be fpMakeResource; - MARATHON_INSERT_PADDING(4); + be fpCreateResource; + be fpGetPath; + MARATHON_INSERT_PADDING(8); }; xpointer m_pVftable; - MARATHON_INSERT_PADDING(0x0C); + be m_MgrIndex; + MARATHON_INSERT_PADDING(8); + + void* Destroy(uint32_t flag) + { + return GuestToHostFunction(m_pVftable->fpDestroy, this, flag); + } + + Sonicteam::SoX::IResource* CreateResource(IResourceMgrCreationParams& param) + { + return GuestToHostFunction(m_pVftable->fpCreateResource, this, ¶m); + } + + stdx::string GetPath(stdx::string* fileName) + { + guest_stack_var out{}; + + GuestToHostFunction(m_pVftable->fpGetPath, out.get(), this, fileName); + + return *out; + } }; MARATHON_ASSERT_OFFSETOF(IResourceMgr, m_pVftable, 0x00); diff --git a/MarathonRecomp/api/Sonicteam/SoX/LinkNode.h b/MarathonRecomp/api/Sonicteam/SoX/LinkNode.h index 9c650442..b62dda46 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/LinkNode.h +++ b/MarathonRecomp/api/Sonicteam/SoX/LinkNode.h @@ -8,6 +8,186 @@ namespace Sonicteam::SoX public: xpointer m_pPrev; xpointer m_pNext; + + class iterator + { + T* m_pCurrent; + T* m_pStart; + + public: + using iterator_category = std::forward_iterator_tag; + using value_type = T; + using difference_type = std::ptrdiff_t; + using pointer = T*; + using reference = T&; + + explicit iterator(T* start = nullptr) + : m_pCurrent(start ? start->m_pNext.get() : nullptr) + , m_pStart(start) + { + if (m_pStart && m_pStart->m_pNext.get() == m_pStart) + { + m_pCurrent = nullptr; + } + else if (m_pStart) + { + m_pCurrent = m_pStart->m_pNext.get(); + } + } + + reference operator*() const + { + return *m_pCurrent; + } + + pointer operator->() const + { + return m_pCurrent; + } + + iterator& operator++() + { + if (m_pCurrent && m_pCurrent->m_pNext) + { + m_pCurrent = m_pCurrent->m_pNext.get(); + + // Stop if we reach the start node again. + if (m_pCurrent == m_pStart) + m_pCurrent = nullptr; + } + else + { + m_pCurrent = nullptr; + } + + return *this; + } + + iterator operator++(int) + { + iterator tmp = *this; + ++(*this); + return tmp; + } + + bool operator==(const iterator& other) const + { + return m_pCurrent == other.m_pCurrent; + } + + bool operator!=(const iterator& other) const + { + return m_pCurrent != other.m_pCurrent; + } + }; + + class const_iterator + { + const T* m_pCurrent; + const T* m_pStart; + + public: + using iterator_category = std::forward_iterator_tag; + using value_type = const T; + using difference_type = std::ptrdiff_t; + using pointer = const T*; + using reference = const T&; + + explicit const_iterator(const T* start = nullptr) + : m_pCurrent(start ? start->m_pNext.get() : nullptr) + , m_pStart(start) + { + if (m_pStart && m_pStart->m_pNext.get() == m_pStart) + { + m_pCurrent = nullptr; + } + else if (m_pStart) + { + m_pCurrent = m_pStart->m_pNext.get(); + } + } + + const_iterator(const iterator& it) + : m_pCurrent(it.m_pCurrent) + , m_pStart(it.m_pStart) + { + } + + reference operator*() const + { + return *m_pCurrent; + } + + pointer operator->() const + { + return m_pCurrent; + } + + const_iterator& operator++() + { + if (m_pCurrent && m_pCurrent->m_pNext) + { + m_pCurrent = m_pCurrent->m_pNext.get(); + + // Stop if we reach the start node again. + if (m_pCurrent == m_pStart) + m_pCurrent = nullptr; + } + else + { + m_pCurrent = nullptr; + } + + return *this; + } + + const_iterator operator++(int) + { + const_iterator tmp = *this; + ++(*this); + return tmp; + } + + bool operator==(const const_iterator& other) const + { + return m_pCurrent == other.m_pCurrent; + } + + bool operator!=(const const_iterator& other) const + { + return m_pCurrent != other.m_pCurrent; + } + }; + + iterator begin() + { + return iterator(static_cast(this)); + } + + iterator end() + { + return iterator(nullptr); + } + + const_iterator begin() const + { + return const_iterator(static_cast(this)); + } + + const_iterator end() const + { + return const_iterator(nullptr); + } + + const_iterator cbegin() const + { + return begin(); + } + + const_iterator cend() const + { + return end(); + } }; template @@ -17,6 +197,9 @@ namespace Sonicteam::SoX xpointer m_pThis; }; + template + using LinkedList = LinkNode; + template class LinkRef { diff --git a/MarathonRecomp/api/Sonicteam/SoX/Object.h b/MarathonRecomp/api/Sonicteam/SoX/Object.h index 28ced9c1..14f1871a 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/Object.h +++ b/MarathonRecomp/api/Sonicteam/SoX/Object.h @@ -16,7 +16,7 @@ namespace Sonicteam::SoX const char* GetName() const { - return GuestToHostFunction(m_pVftable->fpGetName.get()); + return GuestToHostFunction(m_pVftable->fpGetName.get(), this); } }; diff --git a/MarathonRecomp/api/Sonicteam/SoX/RefSharedPointer.h b/MarathonRecomp/api/Sonicteam/SoX/RefSharedPointer.h index ac87501e..20cb1730 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/RefSharedPointer.h +++ b/MarathonRecomp/api/Sonicteam/SoX/RefSharedPointer.h @@ -12,22 +12,27 @@ namespace Sonicteam::SoX xpointer m_ptr; public: - explicit RefSharedPointer(T* value) : m_ptr(value) + RefSharedPointer() + { + m_ptr = nullptr; + } + + RefSharedPointer(T* value) : m_ptr(value) { if (m_ptr.get()) - m_ptr->AddRef(); + m_ptr->AddReference(); } explicit RefSharedPointer(xpointer value) : m_ptr(value) { if (m_ptr.get()) - m_ptr->AddRef(); + m_ptr->AddReference(); } RefSharedPointer(const RefSharedPointer& other) : m_ptr(other.m_ptr) { if (m_ptr.get()) - m_ptr->AddRef(); + m_ptr->AddReference(); } RefSharedPointer(RefSharedPointer&& other) noexcept : m_ptr(std::move(other.m_ptr)) @@ -50,7 +55,7 @@ namespace Sonicteam::SoX m_ptr = other.m_ptr; if (m_ptr.get()) - m_ptr->AddRef(); + m_ptr->AddReference(); } return *this; diff --git a/MarathonRecomp/api/Sonicteam/SoX/ResourceManager.h b/MarathonRecomp/api/Sonicteam/SoX/ResourceManager.h new file mode 100644 index 00000000..a38c215a --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/ResourceManager.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include +#include + +namespace Sonicteam::SoX +{ + struct ResourceManagerMgrTemplate + { + be Field00; // Usually a function pointer to 0x82595818. + be Field04; // Usually a function pointer to 0x82631500. + xpointer pManager; + char Flag01; // 01 (enabled?), referenced in 82581FD4 and 825BDB54 (when template is created). + MARATHON_INSERT_PADDING(3); + char Flag02; // Referenced in 825BDB90 and *Field04, then set Flag02 to 0, for what? + }; + + class ResourceManager : public System::Singleton> + { + public: + struct Vftable + { + be fpDestroy; + }; + + xpointer m_pVftable; + stdx::map, stdx::map>> m_mResources; // m_mResources[IResourceMgr->m_MgrIndex][Resource->m_Name] -> IResource* + MARATHON_INSERT_PADDING(4); + MARATHON_INSERT_PADDING(0x0C); // std::list> + stdx::map, ResourceManagerMgrTemplate> m_mManagers; + MARATHON_INSERT_PADDING(4); + stdx::map, be, MARATHON_STD_MAP_CONST_CHAR_COMPARE> m_mManagerIndices; + }; +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Thread.h b/MarathonRecomp/api/Sonicteam/SoX/Thread.h index 9c2d80d9..0b277b17 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/Thread.h +++ b/MarathonRecomp/api/Sonicteam/SoX/Thread.h @@ -1,30 +1,50 @@ #pragma once #include +#include namespace Sonicteam::SoX { class Thread { public: - xpointer m_pVftable; - MARATHON_INSERT_PADDING(8); - xpointer m_pParent; - be m_EventHandleA; - be m_EventHandleB; - MARATHON_INSERT_PADDING(4); - be m_ThreadHandle; - bool m_Field20; + struct Vftable + { + be fpDestroy; + be fpFunc04; + be fpFunc08; + be fpFunc0C; + }; + + xpointer m_pVftable; + LinkNode m_lnThread; + be m_StartEvent; + be m_EndEvent; + be m_ID; + be m_Handle; + bool m_IsExecutable; MARATHON_INSERT_PADDING(3); be m_DeltaTime; - MARATHON_INSERT_PADDING(8); - xpointer m_pName; MARATHON_INSERT_PADDING(4); - bool m_Field38; - bool m_Field39; - MARATHON_INSERT_PADDING(6); + be m_StepCount; + xpointer m_pName; + be m_StepTime; + bool m_IsThreadReady; + bool m_IsWaitForStartEvent; + MARATHON_INSERT_PADDING(2); + be m_WaitForEndMicroSeconds; xpointer m_pContext; - MARATHON_INSERT_PADDING(4); + MARATHON_INSERT_PADDING(8); + + void Func04() + { + GuestToHostFunction(m_pVftable->fpFunc04, this); + } + + void Func08(float deltaTime) + { + GuestToHostFunction(m_pVftable->fpFunc08, this, deltaTime); + } template T* GetContext() @@ -33,16 +53,6 @@ namespace Sonicteam::SoX } }; - MARATHON_ASSERT_OFFSETOF(Thread, m_pVftable, 0x00); - MARATHON_ASSERT_OFFSETOF(Thread, m_pParent, 0x0C); - MARATHON_ASSERT_OFFSETOF(Thread, m_EventHandleA, 0x10); - MARATHON_ASSERT_OFFSETOF(Thread, m_EventHandleB, 0x14); - MARATHON_ASSERT_OFFSETOF(Thread, m_ThreadHandle, 0x1C); - MARATHON_ASSERT_OFFSETOF(Thread, m_Field20, 0x20); - MARATHON_ASSERT_OFFSETOF(Thread, m_DeltaTime, 0x24); - MARATHON_ASSERT_OFFSETOF(Thread, m_pName, 0x30); - MARATHON_ASSERT_OFFSETOF(Thread, m_Field38, 0x38); - MARATHON_ASSERT_OFFSETOF(Thread, m_Field39, 0x39); - MARATHON_ASSERT_OFFSETOF(Thread, m_pContext, 0x40); - MARATHON_ASSERT_SIZEOF(Thread, 0x48); + MARATHON_ASSERT_OFFSETOF(Thread, m_StartEvent, 0x10); + MARATHON_ASSERT_OFFSETOF(Thread, m_IsThreadReady, 0x38); } diff --git a/MarathonRecomp/api/Sonicteam/Spanverse/AckResource.h b/MarathonRecomp/api/Sonicteam/Spanverse/AckResource.h new file mode 100644 index 00000000..9ead2b9b --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/Spanverse/AckResource.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include +#include + +namespace Sonicteam::Spanverse +{ + class AckResourceMgr; + + class AckResourceData + { + public: + be m_Field00; + be m_Field02; + be m_Size; + be m_Field08; + be m_Field0C; + be m_Field10; + xpointer m_Field14; + xpointer m_Field18; + xpointer m_Field1C; + xpointer m_Field20; + xpointer m_Field24; + }; + + class AckResource : public SoX::IResource2 + { + public: + be m_Index; + xpointer m_pData; + xpointer m_pSpanverseFile; + xpointer m_pABDTChunk; + be m_SpanIndex; + }; + + MARATHON_ASSERT_OFFSETOF(AckResource, m_Index, 0x64); + MARATHON_ASSERT_OFFSETOF(AckResource, m_pData, 0x68); + MARATHON_ASSERT_OFFSETOF(AckResource, m_pSpanverseFile, 0x6C); + MARATHON_ASSERT_OFFSETOF(AckResource, m_pABDTChunk, 0x70); + MARATHON_ASSERT_OFFSETOF(AckResource, m_SpanIndex, 0x74); +} diff --git a/MarathonRecomp/api/Sonicteam/Spanverse/AckResourceMgr.h b/MarathonRecomp/api/Sonicteam/Spanverse/AckResourceMgr.h new file mode 100644 index 00000000..e589e1ab --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/Spanverse/AckResourceMgr.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include +#include +#include + +namespace Sonicteam::Spanverse +{ + class AckResourceMgr : public SoX::IResourceMgr, public System::Singleton> {}; +} diff --git a/MarathonRecomp/api/Sonicteam/Spanverse/SpanABDT.h b/MarathonRecomp/api/Sonicteam/Spanverse/SpanABDT.h new file mode 100644 index 00000000..d0897dad --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/Spanverse/SpanABDT.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +namespace Sonicteam::Spanverse +{ + class CustomEssenceTextureBase; + + class SpanABDT : public SpanACBS + { + public: + struct Vftable : SpanACBS::Vftable + { + be fpInitResource; + be fpDestroyResource; + }; + + xpointer m_pABDAChunk; + xpointer m_pNode; + MARATHON_INSERT_PADDING(0xC); + xpointer m_pSpanNode; + xpointer> m_ppEssenceTexture; + xpointer m_pResourceIndices; + xpointer m_pResourceTable2; + xpointer m_pResourceTable3; + be m_ResourceCount; + be m_InitializedResourceCount; + be m_Field40; + be m_InitializedResourceFlag; + }; + + MARATHON_ASSERT_OFFSETOF(SpanABDT, m_pSpanNode, 0x24); + MARATHON_ASSERT_OFFSETOF(SpanABDT, m_ppEssenceTexture, 0x28); + MARATHON_ASSERT_OFFSETOF(SpanABDT, m_pResourceIndices, 0x2C); + MARATHON_ASSERT_OFFSETOF(SpanABDT, m_pResourceTable2, 0x30); + MARATHON_ASSERT_OFFSETOF(SpanABDT, m_pResourceTable3, 0x34); + MARATHON_ASSERT_OFFSETOF(SpanABDT, m_ResourceCount, 0x38); + MARATHON_ASSERT_OFFSETOF(SpanABDT, m_InitializedResourceCount, 0x3C); + MARATHON_ASSERT_OFFSETOF(SpanABDT, m_Field40, 0x40); + MARATHON_ASSERT_OFFSETOF(SpanABDT, m_InitializedResourceFlag, 0x44); + MARATHON_ASSERT_SIZEOF(SpanABDT, 0x48); +} diff --git a/MarathonRecomp/api/Sonicteam/Spanverse/SpanACBS.h b/MarathonRecomp/api/Sonicteam/Spanverse/SpanACBS.h new file mode 100644 index 00000000..05a65b5b --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/Spanverse/SpanACBS.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include + +namespace Sonicteam::Spanverse +{ + class SpanACBS : public SpanBASE + { + public: + static constexpr uint32_t ms_Signature = 0x41434253; // ACBS + }; +} diff --git a/MarathonRecomp/api/Sonicteam/Spanverse/SpanBASE.h b/MarathonRecomp/api/Sonicteam/Spanverse/SpanBASE.h new file mode 100644 index 00000000..99c9e42f --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/Spanverse/SpanBASE.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +namespace Sonicteam::Spanverse +{ + class SpanBASE + { + public: + static constexpr uint32_t ms_Signature = 0x42415345; // BASE + + struct Vftable + { + be fpDestroy; + }; + + xpointer m_pVftable; + be m_Signature; + be m_Field08; + be m_Flags; + }; + + MARATHON_ASSERT_SIZEOF(SpanBASE, 0x10); +} diff --git a/MarathonRecomp/api/boost/smart_ptr/make_shared_object.h b/MarathonRecomp/api/boost/smart_ptr/make_shared_object.h index 9bba6b4b..27809351 100644 --- a/MarathonRecomp/api/boost/smart_ptr/make_shared_object.h +++ b/MarathonRecomp/api/boost/smart_ptr/make_shared_object.h @@ -9,4 +9,20 @@ namespace boost { return shared_ptr(new T(std::forward(args)...)); } + + template + shared_ptr make_shared(T* pointer, uint32_t vftable) + { + boost::shared_ptr pointer_holder; + + auto* counted = (boost::detail::sp_counted_impl_p*)g_userHeap.Alloc(sizeof(boost::detail::sp_counted_impl_p)); + + new (counted) boost::detail::sp_counted_impl_p(pointer); + + pointer_holder.px = pointer; + pointer_holder.pn = (boost::detail::sp_counted_base*)counted; + pointer_holder.pn->vftable_.ptr = vftable; + + return pointer_holder; + } } diff --git a/MarathonRecomp/api/boost/smart_ptr/shared_ptr.h b/MarathonRecomp/api/boost/smart_ptr/shared_ptr.h index 2b63eaab..7c21b5b1 100644 --- a/MarathonRecomp/api/boost/smart_ptr/shared_ptr.h +++ b/MarathonRecomp/api/boost/smart_ptr/shared_ptr.h @@ -18,14 +18,15 @@ namespace boost be destroy; be get_deleter; }; - + public: xpointer vftable_; + protected: be use_count_; be weak_count_; public: // TODO - sp_counted_base() = delete; + sp_counted_base() {} void add_ref() { @@ -85,6 +86,22 @@ namespace boost } }; + template + class sp_counted_impl_p : public sp_counted_base + { + public: + sp_counted_impl_p(T* p) : ptr_(p) + { + use_count_ = 1; + weak_count_ = 1; + } + + ~sp_counted_impl_p() {} + + private: + xpointer ptr_; + }; + template struct sp_dereference { typedef T& type; @@ -99,9 +116,10 @@ namespace boost template class shared_ptr { - private: + public: xpointer px; xpointer pn; + private: void add_ref() { diff --git a/MarathonRecomp/api/d3dxb.h b/MarathonRecomp/api/d3dxb.h new file mode 100644 index 00000000..06ae2234 --- /dev/null +++ b/MarathonRecomp/api/d3dxb.h @@ -0,0 +1,324 @@ +#pragma once + +#include + +struct D3DXBLOCKED_RECT +{ + be Pitch; + xpointer pBits; +}; + +struct D3DXBVERTEXBUFFER_DESC +{ + be Format; + be Type; + be Usage; + be Pool; + be Size; + be FVF; +}; + +struct D3DXBSURFACE_DESC +{ + be Format; + be Type; + be Usage; + be Pool; + be MultiSampleType; + be MultiSampleQuality; + be Width; + be Height; +}; + +enum D3DXBDECLTYPE +{ + D3DXBDECLTYPE_FLOAT1 = 0x2C83A4, + D3DXBDECLTYPE_FLOAT2 = 0x2C23A5, + D3DXBDECLTYPE_FLOAT3 = 0x2A23B9, + D3DXBDECLTYPE_FLOAT4 = 0x1A23A6, + D3DXBDECLTYPE_D3DCOLOR = 0x182886, + D3DXBDECLTYPE_UBYTE4 = 0x1A2286, + D3DXBDECLTYPE_UBYTE4_2 = 0x1A2386, + D3DXBDECLTYPE_SHORT2 = 0x2C2359, + D3DXBDECLTYPE_SHORT4 = 0x1A235A, + D3DXBDECLTYPE_UBYTE4N = 0x1A2086, + D3DXBDECLTYPE_UBYTE4N_2 = 0x1A2186, + D3DXBDECLTYPE_SHORT2N = 0x2C2159, + D3DXBDECLTYPE_SHORT4N = 0x1A215A, + D3DXBDECLTYPE_USHORT2N = 0x2C2059, + D3DXBDECLTYPE_USHORT4N = 0x1A205A, + D3DXBDECLTYPE_UINT1 = 0x2C82A1, + D3DXBDECLTYPE_UDEC3 = 0x2A2287, + D3DXBDECLTYPE_DEC3N = 0x2A2187, + D3DXBDECLTYPE_DEC3N_2 = 0x2A2190, + D3DXBDECLTYPE_DEC3N_3 = 0x2A2390, + D3DXBDECLTYPE_FLOAT16_2 = 0x2C235F, + D3DXBDECLTYPE_FLOAT16_4 = 0x1A2360, + D3DXBDECLTYPE_UNUSED = 0xFFFFFFFF +}; + +enum D3DXBDECLUSAGE +{ + D3DXBDECLUSAGE_POSITION = 0, + D3DXBDECLUSAGE_BLENDWEIGHT = 1, + D3DXBDECLUSAGE_BLENDINDICES = 2, + D3DXBDECLUSAGE_NORMAL = 3, + D3DXBDECLUSAGE_PSIZE = 4, + D3DXBDECLUSAGE_TEXCOORD = 5, + D3DXBDECLUSAGE_TANGENT = 6, + D3DXBDECLUSAGE_BINORMAL = 7, + D3DXBDECLUSAGE_TESSFACTOR = 8, + D3DXBDECLUSAGE_POSITIONT = 9, + D3DXBDECLUSAGE_COLOR = 10, + D3DXBDECLUSAGE_FOG = 11, + D3DXBDECLUSAGE_DEPTH = 12, + D3DXBDECLUSAGE_SAMPLE = 13 +}; + +struct D3DXBVERTEXELEMENT +{ + be Stream; + be Offset; + be Type; + uint8_t Method; + uint8_t Usage; + uint8_t UsageIndex; + uint8_t Padding; +}; + +#define D3DXBDECL_END { 255, 0, 0xFFFFFFFF, 0, 0, 0 } + +struct D3DXBVIEWPORT +{ + be X; + be Y; + be Width; + be Height; + be MinZ; + be MaxZ; +}; + +enum D3DXBRENDERSTATETYPE +{ + D3DXBRS_ZENABLE = 40, + D3DXBRS_ZFUNC = 44, + D3DXBRS_ZWRITEENABLE = 48, + D3DXBRS_CULLMODE = 56, + D3DXBRS_ALPHABLENDENABLE = 60, + D3DXBRS_SRCBLEND = 72, + D3DXBRS_DESTBLEND = 76, + D3DXBRS_BLENDOP = 80, + D3DXBRS_SRCBLENDALPHA = 84, + D3DXBRS_DESTBLENDALPHA = 88, + D3DXBRS_BLENDOPALPHA = 92, + D3DXBRS_ALPHATESTENABLE = 96, + D3DXBRS_ALPHAREF = 100, + D3DXBRS_STENCILENABLE = 108, + D3DXBRS_TWOSIDEDSTENCILMODE = 112, + D3DXBRS_STENCILFAIL = 116, + D3DXBRS_STENCILZFAIL = 120, + D3DXBRS_STENCILPASS = 124, + D3DXBRS_STENCILFUNC = 128, + D3DXBRS_STENCILREF = 132, + D3DXBRS_STENCILMASK = 136, + D3DXBRS_STENCILWRITEMASK = 140, + D3DXBRS_CCW_STENCILFAIL = 144, + D3DXBRS_CCW_STENCILZFAIL = 148, + D3DXBRS_CCW_STENCILPASS = 152, + D3DXBRS_CCW_STENCILFUNC = 156, + D3DXBRS_CLIPPLANEENABLE = 172, + D3DXBRS_SCISSORTESTENABLE = 200, + D3DXBRS_SLOPESCALEDEPTHBIAS = 204, + D3DXBRS_DEPTHBIAS = 208, + D3DXBRS_COLORWRITEENABLE = 212 +}; + +enum D3DXBCULL +{ + D3DXBCULL_NONE_CCW = 0, + D3DXBCULL_FRONT_CCW = 1, + D3DXBCULL_BACK_CCW = 2, + D3DXBCULL_NONE_CW = 4, + D3DXBCULL_FRONT_CW = 5, + D3DXBCULL_BACK_CW = 6 +}; + +enum D3DXBBLEND +{ + D3DXBBLEND_ZERO = 0, + D3DXBBLEND_ONE = 1, + D3DXBBLEND_SRCCOLOR = 4, + D3DXBBLEND_INVSRCCOLOR = 5, + D3DXBBLEND_SRCALPHA = 6, + D3DXBBLEND_INVSRCALPHA = 7, + D3DXBBLEND_DESTCOLOR = 8, + D3DXBBLEND_INVDESTCOLOR = 9, + D3DXBBLEND_DESTALPHA = 10, + D3DXBBLEND_INVDESTALPHA = 11 +}; + +enum D3DXBBLENDOP +{ + D3DXBBLENDOP_ADD = 0, + D3DXBBLENDOP_SUBTRACT = 1, + D3DXBBLENDOP_MIN = 2, + D3DXBBLENDOP_MAX = 3, + D3DXBBLENDOP_REVSUBTRACT = 4 +}; + +enum D3DXBCMPFUNC +{ + D3DXBCMP_NEVER = 0, + D3DXBCMP_LESS = 1, + D3DXBCMP_EQUAL = 2, + D3DXBCMP_LESSEQUAL = 3, + D3DXBCMP_GREATER = 4, + D3DXBCMP_NOTEQUAL = 5, + D3DXBCMP_GREATEREQUAL = 6, + D3DXBCMP_ALWAYS = 7 +}; + +enum D3DXBSTENCILOP +{ + D3DXBSTENCILOP_KEEP = 0, + D3DXBSTENCILOP_ZERO = 1, + D3DXBSTENCILOP_REPLACE = 2, + D3DXBSTENCILOP_INCRSAT = 3, + D3DXBSTENCILOP_DECRSAT = 4, + D3DXBSTENCILOP_INVERT = 5, + D3DXBSTENCILOP_INCR = 6, + D3DXBSTENCILOP_DECR = 7 +}; + +enum D3DXBPRIMITIVETYPE +{ + D3DXBPT_POINTLIST = 1, + D3DXBPT_LINELIST = 2, + D3DXBPT_LINESTRIP = 3, + D3DXBPT_TRIANGLELIST = 4, + D3DXBPT_TRIANGLEFAN = 5, + D3DXBPT_TRIANGLESTRIP = 6, + D3DXBPT_QUADLIST = 13 +}; + +enum D3DXBTEXTUREFILTERTYPE +{ + D3DXBTEXF_POINT = 0, + D3DXBTEXF_LINEAR = 1, + D3DXBTEXF_NONE = 2 +}; + +enum D3DXBTEXTUREADDRESS +{ + D3DXBTADDRESS_WRAP = 0, + D3DXBTADDRESS_MIRROR = 1, + D3DXBTADDRESS_CLAMP = 2, + D3DXBTADDRESS_MIRRORONCE = 3, + D3DXBTADDRESS_BORDER = 6 +}; + +enum D3DXBMULTISAMPLE_TYPE : int32_t +{ + D3DXBMULTISAMPLE_NONE = 0x00, + D3DXBMULTISAMPLE_2_SAMPLES = 0x01, + D3DXBMULTISAMPLE_4_SAMPLES = 0x02, + D3DXBMULTISAMPLE_FORCE_DWORD = 0x7FFFFFFF, +}; + +enum D3DXBSWAPEFFECT : int32_t +{ + D3DXBSWAPEFFECT_DISCARD = 0x01, + D3DXBSWAPEFFECT_FLIP = 0x02, + D3DXBSWAPEFFECT_COPY = 0x03, + D3DXBSWAPEFFECT_FORCE_DWORD = 0x7FFFFFFF, +}; + +enum D3DXBCOLORSPACE : int32_t +{ + D3DXBCOLORSPACE_RGB = 0x00, + D3DXBCOLORSPACE_YCbCr601 = 0x01, + D3DXBCOLORSPACE_YCbCr709 = 0x02, + D3DXBCOLORSPACE_FORCE_DWORD = 0x7FFFFFFF, +}; + +enum D3DXBFORMAT +{ + D3DXBFMT_A16B16G16R16F = 0x1A22AB60, + D3DXBFMT_A16B16G16R16F_2 = 0x1A2201BF, + D3DXBFMT_A16B16G16R16F_EXPAND = 0x1A22AB5D, + D3DXBFMT_DXT1 = 0x1A200152, + D3DXBFMT_DXT4 = 0x1A200154, + D3DXBFMT_A8B8G8R8 = 0x1A200186, + D3DXBFMT_A8R8G8B8 = 0x18280186, + D3DXBFMT_LIN_A8R8G8B8 = 0x18280086, + D3DXBFMT_D24FS8 = 0x1A220197, + D3DXBFMT_D24S8 = 0x2D200196, + D3DXBFMT_R32F = 0x2DA2ABA4, + D3DXBFMT_G16R16F = 0x2D22AB9F, + D3DXBFMT_G16R16F_2 = 0x2D20AB8D, + D3DXBFMT_INDEX16 = 1, + D3DXBFMT_INDEX32 = 6, + D3DXBFMT_A8 = 0x4900102, + D3DXBFMT_L8 = 0x28000102, + D3DXBFMT_L8_2 = 0x28000002, + D3DXBFMT_X8R8G8B8 = 0x28280086, + D3DXBFMT_LE_X8R8G8B8 = 0x28280106, + D3DXBFMT_UNKNOWN = 0xFFFFFFFF +}; + +struct D3DXBRECT +{ + be Left; + be Top; + be Right; + be Bottom; +}; + +struct D3DXBRING_BUFFER_PARAMETERS +{ + be Flags; + be PrimarySize; + xpointer pPrimary; + be SecondarySize; + xpointer pSecondary; + be SegmentCount; +}; + +struct D3DXBVIDEO_SCALER_PARAMETERS +{ + D3DXBRECT ScalerSourceRect; + be ScaledOutputWidth; + be ScaledOutputHeight; + be FilterProfile; +}; + +struct D3DXBPRESENT_PARAMETERS +{ + be BackBufferWidth; + be BackBufferHeight; + be BackBufferFormat; + be BackBufferCount; + be MultiSampleType; + be MultiSampleQuality; + be SwapEffect; + xpointer hDeviceWindow; + be Windowed; + be EnableAutoDepthStencil; + be AutoDepthStencilFormat; + be Flags; + be FullScreen_RefreshRateInHz; + be PresentationInterval; + be DisableAutoBackBuffer; + be DisableAutoFrontBuffer; + be FrontBufferFormat; + be FrontBufferColorSpace; + D3DXBRING_BUFFER_PARAMETERS RingBufferParameters; + D3DXBVIDEO_SCALER_PARAMETERS VideoScalerParameters; +}; + +struct D3DXBSURFACE_PARAMETERS +{ + be Base; + be HiZBase; + be ColorExpBias; +}; diff --git a/MarathonRecomp/api/lua50/lua.h b/MarathonRecomp/api/lua50/lua.h new file mode 100644 index 00000000..a6b973a1 --- /dev/null +++ b/MarathonRecomp/api/lua50/lua.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +namespace lua50 +{ + typedef xpointer lua_State; + typedef be lua_CFunction; + + struct luaL_reg + { + xpointer name; + lua_CFunction func; + }; + + inline const void* lua_topointer(lua_State* L, int idx) + { + return GuestToHostFunction(sub_825D5800, L, idx); + } +} diff --git a/MarathonRecomp/api/stdx/list.h b/MarathonRecomp/api/stdx/list.h new file mode 100644 index 00000000..c811e5f3 --- /dev/null +++ b/MarathonRecomp/api/stdx/list.h @@ -0,0 +1,245 @@ +#pragma once + +#include + +namespace stdx +{ + template + class list + { + private: + struct _List_node + { + _List_node(const Value& val) + : _Next(nullptr), _Prev(nullptr), _Myval(val) + { + } + + _List_node(Value&& val) + : _Next(nullptr), _Prev(nullptr), _Myval(std::move(val)) + { + } + + xpointer<_List_node> _Next; + xpointer<_List_node> _Prev; + Value _Myval; + }; + + be _MyProxy; + xpointer<_List_node> _Myhead; + be _Mysize; + + xpointer<_List_node> allocate_node(const Value& value) + { + void* memory = g_userHeap.Alloc(sizeof(_List_node)); + return xpointer<_List_node>(new (memory) _List_node(value)); + } + + xpointer<_List_node> allocate_node(Value&& value) + { + void* memory = g_userHeap.Alloc(sizeof(_List_node)); + return xpointer<_List_node>(new (memory) _List_node(std::move(value))); + } + + void deallocate_node(xpointer<_List_node> node) + { + if (node && node.get()) + { + node->~_List_node(); + g_userHeap.Free(node.get()); + } + } + + void link_nodes(xpointer<_List_node> prev, xpointer<_List_node> next) + { + if (prev) prev->_Next = next; + if (next) next->_Prev = prev; + } + + public: + class iterator + { + private: + xpointer<_List_node> _Ptr; + + public: + iterator(xpointer<_List_node> node = nullptr) : _Ptr(node) {} + + Value& operator*() const { return _Ptr->_Myval; } + Value* operator->() const { return &_Ptr->_Myval; } + + iterator& operator++() + { + if (_Ptr) _Ptr = _Ptr->_Next; + return *this; + } + + iterator operator++(int) + { + iterator tmp = *this; + ++(*this); + return tmp; + } + + iterator& operator--() + { + if (_Ptr) _Ptr = _Ptr->_Prev; + return *this; + } + + iterator operator--(int) + { + iterator tmp = *this; + --(*this); + return tmp; + } + + bool operator==(const iterator& other) const + { + return _Ptr == other._Ptr; + } + + bool operator!=(const iterator& other) const + { + return _Ptr != other._Ptr; + } + + xpointer<_List_node> _Mynode() const { return _Ptr; } + }; + + list() : _Mysize(0) + { + // Create sentinel node + _Myhead = allocate_node(Value()); + _Myhead->_Next = _Myhead; + _Myhead->_Prev = _Myhead; + } + + ~list() + { + clear(); + deallocate_node(_Myhead); + } + + iterator begin() + { + return iterator(_Myhead->_Next); + } + + iterator end() + { + return iterator(_Myhead); + } + + size_t size() const + { + return _Mysize; + } + + bool empty() const + { + return _Mysize == 0; + } + + Value& front() + { + return _Myhead->_Next->_Myval; + } + + Value& back() + { + return _Myhead->_Prev->_Myval; + } + + void push_front(const Value& value) + { + insert_node(_Myhead->_Next, value); + } + + void push_front(Value&& value) + { + insert_node(_Myhead->_Next, std::move(value)); + } + + void push_back(const Value& value) + { + insert_node(_Myhead, value); + } + + void push_back(Value&& value) + { + insert_node(_Myhead, std::move(value)); + } + + void pop_front() + { + if (!empty()) + erase_node(_Myhead->_Next); + } + + void pop_back() + { + if (!empty()) + erase_node(_Myhead->_Prev); + } + + iterator insert(iterator position, const Value& value) + { + return iterator(insert_node(position._Mynode(), value)); + } + + iterator insert(iterator position, Value&& value) + { + return iterator(insert_node(position._Mynode(), std::move(value))); + } + + iterator erase(iterator position) + { + if (position == end()) return end(); + iterator next = position; + ++next; + erase_node(position._Mynode()); + return next; + } + + void clear() + { + while (!empty()) + pop_front(); + } + + private: + xpointer<_List_node> insert_node(xpointer<_List_node> next_node, const Value& value) + { + xpointer<_List_node> new_node = allocate_node(value); + xpointer<_List_node> prev_node = next_node->_Prev; + + link_nodes(prev_node, new_node); + link_nodes(new_node, next_node); + + _Mysize = _Mysize + 1; + return new_node; + } + + xpointer<_List_node> insert_node(xpointer<_List_node> next_node, Value&& value) + { + xpointer<_List_node> new_node = allocate_node(std::move(value)); + xpointer<_List_node> prev_node = next_node->_Prev; + + link_nodes(prev_node, new_node); + link_nodes(new_node, next_node); + + _Mysize = _Mysize + 1; + return new_node; + } + + void erase_node(xpointer<_List_node> node) + { + if (node == _Myhead || !node) return; + + link_nodes(node->_Prev, node->_Next); + deallocate_node(node); + _Mysize = _Mysize - 1; + } + }; +} diff --git a/MarathonRecomp/api/stdx/map.h b/MarathonRecomp/api/stdx/map.h new file mode 100644 index 00000000..4e3e70be --- /dev/null +++ b/MarathonRecomp/api/stdx/map.h @@ -0,0 +1,278 @@ +#pragma once + +#include + +namespace stdx +{ + template > + class map + { + private: + struct Node + { + xpointer _Left; + xpointer _Parent; + xpointer _Right; + std::pair _Myval; + char _Color; + bool _Isnil; + + Node(const Key& key, const T& value, xpointer parent = nullptr, char color = 0) + : _Left(nullptr), _Parent(parent), _Right(nullptr), _Myval(key, value), + _Color(color), _Isnil(false) + { + + } + + Node(bool isnil = false) + : _Left(nullptr), _Parent(nullptr), _Right(nullptr), _Myval(), + _Color(1), _Isnil(isnil) + { + + } + }; + + be _Myproxy; + xpointer _Myhead; + be _Mysize; + + xpointer allocate_node(const Key& key, const T& value, xpointer parent = nullptr, char color = 0) + { + void* memory = g_userHeap.Alloc(sizeof(Node)); + return xpointer(new (memory) Node(key, value, parent, color)); + } + + xpointer allocate_node(bool isnil = false) + { + void* memory = g_userHeap.Alloc(sizeof(Node)); + return xpointer(new (memory) Node(isnil)); + } + + void deallocate_node(xpointer node) + { + if (node && node.get()) + { + node->~Node(); + g_userHeap.Free(node.get()); + } + } + + bool compare_keys(const Key& a, const Key& b) const + { + return Compare()(a, b); + } + + xpointer insert_node(const Key& key, const T& value) + { + if (_Myhead->_Left == _Myhead) + { + _Mysize = _Mysize + 1; + xpointer newNode = allocate_node(key, value, _Myhead, 1); + _Myhead->_Left = newNode; + _Myhead->_Parent = newNode; + _Myhead->_Right = newNode; + return newNode; + } + + xpointer current = _Myhead->_Parent; + xpointer parent = _Myhead; + + while (current != _Myhead) + { + parent = current; + if (compare_keys(key, current->_Myval.first)) + current = current->_Left; + else if (compare_keys(current->_Myval.first, key)) + current = current->_Right; + else + { + current->_Myval.second = value; + return current; + } + } + + _Mysize = _Mysize + 1; + xpointer newNode = allocate_node(key, value, parent, 0); + + if (compare_keys(key, parent->_Myval.first)) + parent->_Left = newNode; + else + parent->_Right = newNode; + + if (compare_keys(key, _Myhead->_Left->_Myval.first)) + _Myhead->_Left = newNode; + if (compare_keys(_Myhead->_Right->_Myval.first, key)) + _Myhead->_Right = newNode; + + return newNode; + } + + xpointer find_node(const Key& key) const + { + xpointer current = _Myhead->_Parent; + while (current != _Myhead) + { + if (compare_keys(key, current->_Myval.first)) + current = current->_Left; + else if (compare_keys(current->_Myval.first, key)) + current = current->_Right; + else + return current; + } + return _Myhead; + } + + void clear_tree(xpointer node) + { + if (node != _Myhead && node != nullptr) + { + clear_tree(node->_Left); + clear_tree(node->_Right); + deallocate_node(node); + } + } + + xpointer find_min(xpointer node) const + { + while (node->_Left != _Myhead) + node = node->_Left; + return node; + } + + xpointer find_max(xpointer node) const + { + while (node->_Right != _Myhead) + node = node->_Right; + return node; + } + + public: + class iterator + { + private: + xpointer _Ptr; + xpointer _Myhead; + + xpointer find_min(xpointer node) const + { + while (node->_Left != _Myhead) + node = node->_Left; + return node; + } + + public: + iterator(xpointer node = nullptr, xpointer head = nullptr) + : _Ptr(node), _Myhead(head) + { + + } + + std::pair& operator*() const { return _Ptr->_Myval; } + std::pair* operator->() const { return &_Ptr->_Myval; } + + iterator& operator++() + { + if (_Ptr == _Myhead) return *this; + + if (_Ptr->_Right != _Myhead) + { + _Ptr = find_min(_Ptr->_Right); + } + else + { + xpointer parent = _Ptr->_Parent; + while (parent != _Myhead && _Ptr == parent->_Right) + { + _Ptr = parent; + parent = parent->_Parent; + } + _Ptr = parent; + } + return *this; + } + + iterator operator++(int) + { + iterator tmp = *this; + ++(*this); + return tmp; + } + + bool operator==(const iterator& other) const + { + return _Ptr == other._Ptr; + } + + bool operator!=(const iterator& other) const + { + return _Ptr != other._Ptr; + } + }; + + map() : _Mysize(0) + { + _Myhead = allocate_node(true); + _Myhead->_Left = _Myhead; + _Myhead->_Parent = _Myhead; + _Myhead->_Right = _Myhead; + } + + ~map() + { + clear(); + deallocate_node(_Myhead); + } + + iterator begin() + { + return iterator(_Myhead->_Left, _Myhead); + } + + iterator end() + { + return iterator(_Myhead, _Myhead); + } + + size_t size() const + { + return _Mysize; + } + + bool empty() const + { + return _Mysize == 0; + } + + T& operator[](const Key& key) + { + xpointer node = find_node(key); + if (node == _Myhead) + node = insert_node(key, T()); + return node->_Myval.second; + } + + iterator find(const Key& key) + { + return iterator(find_node(key), _Myhead); + } + + void clear() + { + clear_tree(_Myhead->_Parent); + _Myhead->_Left = _Myhead; + _Myhead->_Parent = _Myhead; + _Myhead->_Right = _Myhead; + _Mysize = 0; + } + + std::pair insert(const std::pair& value) + { + xpointer node = find_node(value.first); + if (node != _Myhead) + return std::make_pair(iterator(node, _Myhead), false); + + node = insert_node(value.first, value.second); + return std::make_pair(iterator(node, _Myhead), true); + } + }; +} diff --git a/MarathonRecomp/api/stdx/string.h b/MarathonRecomp/api/stdx/string.h index 1f029ce5..32dd41f2 100644 --- a/MarathonRecomp/api/stdx/string.h +++ b/MarathonRecomp/api/stdx/string.h @@ -2,6 +2,7 @@ #include #include +#include namespace stdx { @@ -59,6 +60,14 @@ namespace stdx from_cstr(str); } + string(const string& other) + { + _Myres = 0xF; + _Mysize = 0; + _bx._buffer[0] = '\0'; + from_cstr(other.c_str()); + } + ~string() { cleanup(); @@ -112,5 +121,50 @@ namespace stdx { return strcmp(c_str(), str) == 0; } + + bool operator<(const char* str) const + { + return strcmp(c_str(), str) < 0; + } + + const char* begin() const + { + return c_str(); + } + + const char* end() const + { + return c_str() + size(); + } + + bool operator<(const string& other) const + { + return std::lexicographical_compare(begin(), end(), other.begin(), other.end()); + } + + bool operator>(const string& other) const + { + return other < *this; + } + + bool operator<=(const string& other) const + { + return !(other < *this); + } + + bool operator>=(const string& other) const + { + return !(*this < other); + } + + bool operator==(const string& other) const + { + return size() == other.size() && std::equal(begin(), end(), other.begin()); + } + + bool operator!=(const string& other) const + { + return !(*this == other); + } }; }; diff --git a/MarathonRecomp/app.cpp b/MarathonRecomp/app.cpp index 4c08a7ef..3408c577 100644 --- a/MarathonRecomp/app.cpp +++ b/MarathonRecomp/app.cpp @@ -64,6 +64,138 @@ PPC_FUNC(sub_8262A568) InitPatches(); } +std::array g_PauseModeTaskList = +{ + "root", + "TL_Debug", + "TL_PrepareMain", + "TL_Main", + //"TL_Particle", + "TL_HeadUpDisplay", + "TL_PrepareRender", + "TL_NonStopTask", + + "ResumeWorkerThreadTask", + "ThreadResumeTask", + + //"Cameras", + "Cameraman", + //"DependCameras", + //"SystemDependCameras", + + "PrepareShadowTask", + "GameRootTask", + //"SpkManageTask", + "Task", + "TaskAdapter", + "HUDMainDisplay", + "PostprocessControllerTask", + "PrepareRenderTask", + "PrepareFrameSynchronizerTask", + "FrameSynchronizerTask", + "BoundingBoxSynchronizerTask", + "FrustumCullingTask", + "UpdateResourceInFrustumTask", + "GameModeNonStop", + + //AQA + "ObjectAqaMercurySmall", + "ObjectAqaPond", + "ObjectAqaPond", // Duplicate entry + "ReflectionManager", + "ReflectionArea", + + // + "HintWindowTask", + "HUDMessageWindow" + + //"DocModeExecutor", + //"GameMode", + //"DependGame", + //"PhysicsMaterialMgrRunner", + //"StageSetManagerRunner", + //"ActivationMgrRunner", + // + //"ImpactManager", + //"Entities", + //"RadarMapIcon", + //"CTownsKeeper", + //"CTownsmanActor", + //"ObjParticle", + //"CommonPathObj", + //"BellObj", + //"WarpGateObj", + //"TownsDoorObj", + //"ObjSpring", + //"ObjectPhysicsSingle", + //"ObjRadarMapMark", + //"ObjectPointSample", + //"StartObj", + //"Townsman(townsman998)", + //"CObjBalloonIcon", + //"ObjWideSpring", + //"Townsman(townsman021)", + //"CObjBalloonIcon", + //"ObjEventCollision", + //"BellObj", + //"Townsman(townsman070)", + //"CObjBalloonIcon", + //"GondolaObj", + //"ObjectPointSample", + //"ObjCameraCollision", + //"ObjSpring", + //"Townsman(gondolaman31)", + //"CTownsmanEquipmentObject", + //"Townsman(gondolaman29)", + //"Townsman(gondolaman30)", + //"ObjSpring", + //"ObjectPointSample", + //"TownsDoorObj", + //"EnemyThread", + //"Players", + //"class Sonicteam::Player::Object", + //"KhronoController", + //"SceneParamManagerTask", + //"CommonObjectLensFlare", + //"KynapseRunnerTask", + //"KynapseMessenger", + //"RaderMapManager", + //"EnemyLifeTask", + //"MainDisplayTask", + //"HUDLimitTime", + //"InputListenTask", + //"AudioRunner", + //"PauseTask", + //"HUDPause" +}; + + +void UpateSpecificTasksPause(Sonicteam::SoX::Engine::Task* ttask) +{ + for (auto& task : *ttask) + { + const char* taskName = (&task)->GetName(); + + if ((task.m_Flag1 & 4) == 0) + { + + auto shouldIgnore = std::find_if(g_PauseModeTaskList.begin(), g_PauseModeTaskList.end(), + [taskName](const char* task) + { + return strcmp(task ? task : "", taskName) == 0; + }); + + if (shouldIgnore != g_PauseModeTaskList.end()) + { + (&task)->Update(0.0); + } + + if (task.m_pDependencies.get()) + UpateSpecificTasksPause(task.m_pDependencies.get()); + } + } +} + // Sonicteam::DocMarathonState::Update PPC_FUNC_IMPL(__imp__sub_825EA610); PPC_FUNC(sub_825EA610) @@ -90,8 +222,10 @@ PPC_FUNC(sub_825EA610) { SDL_PumpEvents(); SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT); + GameWindow::Update(); } + auto pDocState = App::s_pApp->m_pDoc; // Allow variable FPS when config is not 60 FPS. App::s_pApp->m_pDoc->m_VFrame = Config::FPS != 60; @@ -99,6 +233,17 @@ PPC_FUNC(sub_825EA610) AudioPatches::Update(App::s_deltaTime); __imp__sub_825EA610(ctx, base); + + + //Always Do Specic Tasks during pause, to not + if (pDocState->m_PauseFlags.get() != 0) + { + + GuestToHostFunction(sub_825D49E0, &pDocState->m_CriticalSection1); + UpateSpecificTasksPause(pDocState->m_pRootTask.get()); + GuestToHostFunction(sub_82580920, &pDocState->m_CriticalSection1); + } + } PPC_FUNC_IMPL(__imp__sub_82582648); diff --git a/MarathonRecomp/gpu/video.cpp b/MarathonRecomp/gpu/video.cpp index 08c8c74e..0cf3468b 100644 --- a/MarathonRecomp/gpu/video.cpp +++ b/MarathonRecomp/gpu/video.cpp @@ -372,6 +372,7 @@ static std::unique_ptr g_renderSemaphores[NUM_FRAMES]; static uint32_t g_backBufferIndex; static std::unique_ptr g_backBufferHolder; static GuestSurface* g_backBuffer; +static std::vector> g_surfaceCache; static std::unique_ptr g_intermediaryBackBufferTexture; static uint32_t g_intermediaryBackBufferTextureWidth; @@ -2368,6 +2369,13 @@ static uint32_t CreateDevice(uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, return 0; } +static void DestructResourceImm(GuestResource* resource) +{ + resource->~GuestResource(); + resource = 0; + g_userHeap.Free(resource); +} + static void DestructResource(GuestResource* resource) { // Needed for hack in CreateSurface (remove if fix it) @@ -3110,6 +3118,125 @@ void Video::WaitOnSwapChain() static bool g_shouldPrecompilePipelines; static std::atomic g_executedCommandList; +void CreateTextureLocal(Sonicteam::SoX::Graphics::Xenon::TextureXenon* pTextureXenon, uint32_t width, uint32_t height, uint32_t depth, uint32_t levels, uint32_t usage, uint32_t format, uint32_t pool, uint32_t type) +{ + // Save current reference count to preserve it + auto pGuestTexture = (GuestTexture*)pTextureXenon->m_pTexture.get(); + auto refCount = pGuestTexture->refCount; + + // Destroy the existing texture + pGuestTexture->~GuestTexture(); + + // Create a new texture with the specified parameters + GuestTexture* pGuestTextureNew = CreateTexture(width, height, depth, levels, usage, format, pool, type); + + // Copy the new texture data over the old texture memory + memcpy((void*)pGuestTexture, pGuestTextureNew, sizeof(GuestTexture)); + + // Free the temporary texture buffer + g_userHeap.Free(pGuestTextureNew); + + // Restore the original reference count to prevent issues with Release() calls + pGuestTexture->refCount = refCount; + + // Update the XenonTexture dimensions + pTextureXenon->m_Width = width; + pTextureXenon->m_Height = height; +} + +struct CallbackData +{ + xpointer pDoc; + xpointer pDevice; + xpointer pRenderTargetContainer; + xpointer pRenderScheduler; + Sonicteam::SoX::RefSharedPointer Field04; + stdx::string customName; + be Field30; + be Field34; + be Field38; + stdx::map> mMap; //????? + + CallbackData + ( + xpointer doc, + xpointer device, + xpointer renderTarget, + xpointer scheduler, + Sonicteam::SoX::RefSharedPointer field04, + be field30, + be field34, + be field38, + const char* name + ) + : pDoc(doc), + pDevice(device), + pRenderTargetContainer(renderTarget), + pRenderScheduler(scheduler), + Field04(field04), + Field30(field30), + Field34(field34), + Field38(field38), + customName(name), + mMap() + { + + } + +}; + +static std::vector>> g_renderProcessCache; + +PPC_FUNC_IMPL(__imp__sub_8260A9D0); +PPC_FUNC(sub_8260A9D0) +{ + auto L = (lua50::lua_State*)(ctx.r3.u32 + base); + auto data = (CallbackData*)lua50::lua_topointer(L, 1); + + auto it = std::find_if(g_renderProcessCache.begin(), g_renderProcessCache.end(), [](const auto& pair) + { + return pair.first == "Spanverse"; + }); + + if (it != g_renderProcessCache.end()) + { + data->pRenderScheduler->m_lRenderProcesses.push_back(*it); + + g_renderProcessCache.erase(it); + + ctx.r3.u32 = 1; + } + else + { + __imp__sub_8260A9D0(ctx, base); + } +} + +PPC_FUNC_IMPL(__imp__sub_8260AAB0); +PPC_FUNC(sub_8260AAB0) +{ + auto L = (lua50::lua_State*)(ctx.r3.u32 + base); + auto data = (CallbackData*)lua50::lua_topointer(L, 1); + + auto it = std::find_if(g_renderProcessCache.begin(), g_renderProcessCache.end(), [](const auto& pair) + { + return pair.first == "GE1Particle"; + }); + + if (it != g_renderProcessCache.end()) + { + data->pRenderScheduler->m_lRenderProcesses.push_back(*it); + + g_renderProcessCache.erase(it); + + ctx.r3.u32 = 1; + } + else + { + __imp__sub_8260AAB0(ctx, base); + } +} + void Video::Present() { g_readyForCommands = false; @@ -3126,7 +3253,7 @@ void Video::Present() // All the shaders are available at this point. We can precompile embedded PSOs then. if (g_shouldPrecompilePipelines) { -// EnqueuePipelineTask(PipelineTaskType::PrecompilePipelines, {}); + // EnqueuePipelineTask(PipelineTaskType::PrecompilePipelines, {}); g_shouldPrecompilePipelines = false; } @@ -3198,6 +3325,356 @@ void Video::Present() s_next += 1000000000ns / Config::FPS; } + // NOTICE: guest_stack_var may cause stack corruption here. + if (App::s_pApp && g_needsResize) + { + g_needsResize = false; + + auto pApp = App::s_pApp; + auto pDocState = pApp->m_pDoc.get(); + auto pResourceManager = Sonicteam::SoX::ResourceManager::GetInstance(); + auto pSurfaceMgr = Sonicteam::SoX::Graphics::SurfaceMgr::GetInstance(); + auto pTextureMgr = Sonicteam::SoX::Graphics::TextureMgr::GetInstance(); + + if (!pDocState || !pResourceManager || !pSurfaceMgr || !pTextureMgr) + goto PostResize; + + auto pRenderTargetContainer = pDocState->m_pRenderTargetContainer.get(); + auto pMyGraphicsDevice = pDocState->m_pMyGraphicsDevice.get(); + + if (!pRenderTargetContainer || !pMyGraphicsDevice) + goto PostResize; + + auto width = s_viewportWidth; + auto height = s_viewportHeight; + + struct BufferSize + { + uint32_t Width; + uint32_t Height; + uint32_t R8; + uint32_t R10; + }; + + static std::map buffers; + + // Update dimensions. + buffers["framebuffer0"] = { width, height, 0, 4 }; + buffers["framebuffer1"] = { width, height, 0, 0 }; + buffers["framebuffer_1_4_0"] = { width >> 2, height >> 2, 3, 2 }; + buffers["framebuffer_1_4_1"] = { width >> 2, height >> 2, 0, 2 }; + buffers["framebuffer_1_8_0"] = { width >> 3, height >> 3, 3, 2 }; + buffers["framebuffer_1_8_1"] = { width >> 3, height >> 3, 0, 2 }; + buffers["framebuffer_1_16_0"] = { width >> 4, height >> 4, 3, 2 }; + buffers["framebuffer_1_16_1"] = { width >> 4, height >> 4, 0, 2 }; + buffers["framebuffer_1_32_0"] = { width >> 5, height >> 5, 3, 2 }; + buffers["framebuffer_1_32_1"] = { width >> 5, height >> 5, 0, 2 }; + buffers["depthstencil_1_4"] = { width >> 2, height >> 2, 6, 0 }; + + auto pCreationDeviceData = &pApp->m_DeviceInfo; + + struct GraphicsFormatConfig + { + be SurfaceFormat; + be TextureFormat; + be Usage; + }; + + // Clear cache (experimental). + auto it = g_surfaceCache.begin(); + while (it != g_surfaceCache.end()) + { + printf("Cache Surface : %d\n", it->first->refCount.get()); + + if (it->first->refCount.get() == 0 && it->first != g_depthStencil && it->first != g_backBuffer) + { + it->first->wasCached = false; + DestructResourceImm(it->first); + it = g_surfaceCache.erase(it); + } + else + { + ++it; + } + } + + auto pFormatConfig = (GraphicsFormatConfig*)(g_memory.base + 0x82B7BD20); + + // Kill Auto Surfaces + + if (g_backBuffer && g_backBuffer != pApp->m_pBackBufferSurface.get()) + DestructResourceImm(g_backBuffer); + + if (g_depthStencil && g_depthStencil != pApp->m_pDepthStencilSurface.get()) + DestructResourceImm(g_depthStencil); + + // Recreate main buffers + DestructResourceImm((GuestTexture*)pApp->m_pFrontBufferTexture.get()); + pApp->m_pFrontBufferTexture = CreateTexture(width, height, 1, 1, 1, D3DFMT_LE_X8R8G8B8, 0, 3); + //((GuestTexture*)pApp->m_pFrontBufferTexture.get())->AddRef(); + + auto surfaceParams = g_userHeap.AllocPhysical(0, 0, 0); + + DestructResourceImm((GuestSurface*)pApp->m_pBackBufferSurface.get()); + pApp->m_pBackBufferSurface = CreateSurface(width, height, D3DFMT_A8R8G8B8, 0, (GuestSurfaceCreateParams*)surfaceParams); + //((GuestSurface*)pApp->m_pBackBufferSurface.get())->AddRef(); + + pCreationDeviceData->SurfaceParamsA = *(D3DXBSURFACE_PARAMETERS*)surfaceParams; + + // 0x340 default (for 720 mb?) + uint32_t cSurfaceBase = height * 1.155555555555556; + + surfaceParams->Base = surfaceParams->Base + cSurfaceBase; + + DestructResourceImm((GuestSurface*)pApp->m_pDepthStencilSurface.get()); + pApp->m_pDepthStencilSurface = CreateSurface(width, height, D3DFMT_D24FS8, 0, (GuestSurfaceCreateParams*)surfaceParams); + //((GuestSurface*)pApp->m_pDepthStencilSurface.get())->AddRef(); + + pCreationDeviceData->SurfaceParamsB = *(D3DXBSURFACE_PARAMETERS*)surfaceParams; + pCreationDeviceData->SurfaceParamsC = pCreationDeviceData->SurfaceParamsB; + pCreationDeviceData->SurfaceParamsC.Base = pCreationDeviceData->SurfaceParamsB.Base + cSurfaceBase; + g_userHeap.Free(surfaceParams); + + // Viewport is reset here because we're using the game's backbuffer directly (Auto mode disabled) + SetRenderTarget((GuestDevice*)pApp->m_pDevice.get(), 0, (GuestSurface*)pApp->m_pBackBufferSurface.get()); + SetDepthStencilSurface((GuestDevice*)pApp->m_pDevice.get(), (GuestSurface*)pApp->m_pDepthStencilSurface.get()); + + + g_backBuffer = (GuestSurface*)pApp->m_pBackBufferSurface.get(); + g_depthStencil = (GuestSurface*)pApp->m_pDepthStencilSurface.get(); + + // Secondary reference only - no reference counting needed + pCreationDeviceData->PresentParameters.BackBufferWidth = width; + pCreationDeviceData->PresentParameters.BackBufferHeight = height; + pCreationDeviceData->pColorTile2x = pApp->m_pColorTile2x; + pCreationDeviceData->pDepthTile2x = pApp->m_pDepthTile2x; + pCreationDeviceData->pColorTile4x = pApp->m_pColorTile4x; + pCreationDeviceData->pDepthTile4x = pApp->m_pDepthTile4x; + + // auto local = (CreationDeviceLocal*)g_userHeap.Alloc(sizeof(CreationDeviceLocal)); + // local->pDevice = cdata->pDevice; + // local->SurfaceParamsA = cdata->SurfaceParamsA; + // local->SurfaceParamsB = cdata->SurfaceParamsB; + // local->SurfaceParamsC = cdata->SurfaceParamsC; + // local->pColorTile2x = cdata->pColorTile2x; + // local->pDepthTile2x = cdata->pDepthTile2x; + // local->pColorTile4x = cdata->pColorTile4x; + // local->pDepthTile4x = cdata->pDepthTile4x; + // local->BackBufferWidth = cdata->PresentParameters.BackBufferWidth; + // local->BackBufferHeight = cdata->PresentParameters.BackBufferHeight; + // local->pAtgFontFile = 0; + + pMyGraphicsDevice->m_SurfaceParamsA = pCreationDeviceData->SurfaceParamsA; + pMyGraphicsDevice->m_SurfaceParamsB = pCreationDeviceData->SurfaceParamsB; + pMyGraphicsDevice->m_SurfaceParamsC = pCreationDeviceData->SurfaceParamsC; + + // Old Method (Fail) + // GuestToHostFunction(sub_8289CF60, doc->m_pMyGraphicsDevice.get(), local.get()); + + auto SetSurface = [&](Sonicteam::SoX::Graphics::Surface* surface, GuestSurface* guestSurface) + { + if (surface) + { + GuestToHostFunction(sub_82593038, surface, guestSurface); + LOGFN_UTILITY("- \"{}\" ({}x{}) ({:08X})", surface->m_MgrResourceName.c_str(), surface->m_Width.get(), surface->m_Height.get(), (uint64_t)surface->m_pSurface.get()); + } + }; + + LOGN_UTILITY("----------------------------[Surfaces]-----------------------------------"); + + SetSurface(pMyGraphicsDevice->m_spBackBuffer.get(), (GuestSurface*)pApp->m_pBackBufferSurface.get()); + SetSurface(pMyGraphicsDevice->m_spDepthStencil.get(), (GuestSurface*)pApp->m_pDepthStencilSurface.get()); + + GuestToHostFunction(sub_82637418, pMyGraphicsDevice); + GuestToHostFunction(sub_825BAE48, pMyGraphicsDevice->m_FrameBufferObject.get(), 0, &pMyGraphicsDevice->m_spBackBuffer); + GuestToHostFunction(sub_825BAEB8, pMyGraphicsDevice->m_FrameBufferObject.get(), &pMyGraphicsDevice->m_spDepthStencil); + + // Update surfaces and textures + for (auto& surface : pRenderTargetContainer->m_mspDepthStencil_1_4) + { + const auto surfaceName = surface.first.c_str(); + + if (!buffers.contains(surfaceName)) + continue; + + auto params = buffers[surfaceName]; + D3DXBSURFACE_PARAMETERS* surfaceParams = nullptr; + + if (pFormatConfig[params.R8].Usage != 1 || (params.R10 & 1) != 0) + { + surfaceParams = &pMyGraphicsDevice->m_SurfaceParamsB; + } + else + { + surfaceParams = (params.R10 & 2) == 0 ? &pMyGraphicsDevice->m_SurfaceParamsA : &pMyGraphicsDevice->m_SurfaceParamsC; + } + + // TODO: Until cache system is gone for good + // auto gSurface = CreateSurface(params.width, params.height, pFormatConfig[params.r8].SurfaceFormat, 0, (GuestSurfaceCreateParams*)surfaceParams); + // GuestToHostFunction(sub_82592E98, surface.second.get(), gSurface, params.width, params.height); + } + + LOGN_UTILITY("----------------------------[Textures]-----------------------------------"); + + // Update textures + for (auto& texture : pRenderTargetContainer->m_mspFrameBuffer) + { + const auto textureName = texture.first.c_str(); + + if (!buffers.contains(textureName)) + continue; + + auto& texturePtr = texture.second; + auto params = buffers[textureName]; + + CreateTextureLocal(texturePtr.get(), params.Width, params.Height, 1, 1, pFormatConfig[params.R8].Usage, pFormatConfig[params.R8].TextureFormat, 0, 3); + // GuestToHostFunction(sub_82592FD8, texturePtr.get(), tex, params.width, params.height); + + // Determine surface type + auto s2 = (params.R10 & 4) == 0 ? params.R8 : 3; + auto surface = texturePtr->m_aspSurfaces[0].get(); + + // Determine surface parameters + D3DXBSURFACE_PARAMETERS* surfaceParams = nullptr; + if (pFormatConfig[s2].Usage != 1 || (params.R10 & 1) != 0) + { + surfaceParams = &pMyGraphicsDevice->m_SurfaceParamsB; + } + else + { + surfaceParams = (params.R10 & 2) == 0 ? &pMyGraphicsDevice->m_SurfaceParamsA : &pMyGraphicsDevice->m_SurfaceParamsC; + } + + // Create and configure guest surface + auto PrevSuface = surface->m_pSurface; + auto gSurface = CreateSurface(params.Width, params.Height, pFormatConfig[s2].SurfaceFormat, 0, (GuestSurfaceCreateParams*)surfaceParams); + + GuestToHostFunction(sub_82592E98, surface, gSurface, params.Width, params.Height); + + LOGFN_UTILITY("- \"{}\" ({}x{}) ({:08X})", texturePtr->m_MgrResourceName.c_str(), texturePtr->m_Width.get(), texturePtr->m_Height.get(), (uint64_t)texturePtr->m_pTexture.get()); + LOGFN_UTILITY(" Surface ({:08X}) ({}x{}) {:08X}", (uint64_t)surface, surface->m_Width.get(), surface->m_Height.get(), (uint64_t)surface->m_spTexture.get()); + } + + LOGN_UTILITY("----------------------------[m_mspDepthStencil_256]-----------------------------------"); + + for (auto& surface : pRenderTargetContainer->m_mspDepthStencil_256) + { + auto& surfacePtr = surface.second; + // surfacePtr->m_Width = width; + // surfacePtr->m_Height = height; + LOGFN_UTILITY("- \"{}\" ({}x{}) ({:08X})", surfacePtr->m_MgrResourceName.c_str(), surfacePtr->m_Width.get(), surfacePtr->m_Height.get(), (uint64_t)surfacePtr.get()); + } + + LOGN_UTILITY("----------------------------[m_mspPostEffect]-----------------------------------"); + + for (auto& texture : pRenderTargetContainer->m_mspPostEffect) + { + auto& texturePtr = texture.second; + // texturePtr->m_Width = width; + // texturePtr->m_Height = height; + LOGFN_UTILITY("- \"{}\" ({}x{}) ({:08X})", texturePtr->m_MgrResourceName.c_str(), texturePtr->m_Width.get(), texturePtr->m_Height.get(), (uint64_t)texturePtr.get()); + } + + LOGN_UTILITY("----------------------------[m_mspPostEffectAfter]-----------------------------------"); + + for (auto& texture : pRenderTargetContainer->m_mspPostEffectAfter) + { + auto& texturePtr = texture.second; + // texturePtr->m_Width = width; + // texturePtr->m_Height = height; + LOGFN_UTILITY("- \"{}\" ({}x{}) ({:08X})", texturePtr->m_MgrResourceName.c_str(), texturePtr->m_Width.get(), texturePtr->m_Height.get(), (uint64_t)texturePtr.get()); + } + + // Clear Post Buffers + pRenderTargetContainer->m_mspDepthStencil_256.clear(); + pRenderTargetContainer->m_mspPostEffect.clear(); + pRenderTargetContainer->m_mspPostEffectAfter.clear(); + + //Reset radermap, textures + auto& rmTextureResources = pResourceManager->m_mResources[pTextureMgr->m_MgrIndex]; + auto* pGame = pApp->GetGame(); + if (pGame) + { + if (auto it = rmTextureResources.find("radermap"); it != rmTextureResources.end()) + { + if (auto pPopupScreenTask = pGame->m_lrPopupScreenTask.m_pElement) + { + auto pHUDRaderMap = pPopupScreenTask->GetHUDPopupScreen(); + pHUDRaderMap->m_pMainTexture.reset(); + pHUDRaderMap->m_pMaskTexture.reset(); + } + } + } + + auto pManageParticle = Sonicteam::MyPE::CManageParticle::GetInstance(); + auto pRenderScheduler = pDocState->m_pRenderScheduler.get(); + + auto CacheRenderProcess = [&](const char* name) + { + bool found = false; + for (auto& it : pDocState->m_pRenderScheduler->m_lRenderProcesses) + { + if (it.first == name) + { + g_renderProcessCache.push_back(it); + found = true; + } + } + return found; + }; + + // Cache particles. + CacheRenderProcess("Spanverse"); + CacheRenderProcess("GE1Particle"); + + auto sfx1 = pDocState->m_pSFXAgent->m_aSFXMatrices1; + auto sfx2 = pDocState->m_pSFXAgent->m_aSFXMatrices2; + pDocState->m_pSFXAgent->m_aSFXMatrices1 = 0; + pDocState->m_pSFXAgent->m_aSFXMatrices2 = 0; + + GuestToHostFunction(sub_8260DF88, pDocState, 0x82B814F8, 1); + g_renderProcessCache.clear(); + + if (pDocState->m_pSFXAgent->m_aSFXMatrices1) + g_userHeap.Free(pDocState->m_pSFXAgent->m_aSFXMatrices1->GetArray()); + + if (pDocState->m_pSFXAgent->m_aSFXMatrices2) + g_userHeap.Free(pDocState->m_pSFXAgent->m_aSFXMatrices2->GetArray()); + + pDocState->m_pSFXAgent->m_aSFXMatrices1 = sfx1; + pDocState->m_pSFXAgent->m_aSFXMatrices2 = sfx2; + + // Fix radermap. + auto SetResource = [&](auto* spTextureTo, const char* name) + { + if (auto it = rmTextureResources.find(name); it != rmTextureResources.end()) + *spTextureTo = static_cast(it->second.get()); + }; + + if (pGame) + { + if (rmTextureResources.find("radermap") != rmTextureResources.end()) + { + if (auto pPopupScreenTask = pGame->m_lrPopupScreenTask.m_pElement) + { + auto pHUDRaderMap = pPopupScreenTask->GetHUDPopupScreen(); + + SetResource(&pHUDRaderMap->m_pMainTexture, "radermap"); + SetResource(&pHUDRaderMap->m_pMaskTexture, "radermap_mask"); + } + } + } + + if (auto pMainMode = App::s_pApp->m_pDoc->GetDocMode()) + { + auto pMainTask = (Sonicteam::MainMenuTask*)pMainMode->m_pMainTask.get(); + + if (pMainTask && strcmp(pMainTask->GetName(), "MainMenuTask") == 0) + pMainTask->m_spMainMenuExpositionTask->m_TextMotionState = 1; + } + } +PostResize: + g_presentProfiler.Reset(); } @@ -3313,15 +3790,19 @@ static void ProcBeginCommandList(const RenderCommand& cmd) BeginCommandList(); } -static GuestSurface* GetBackBuffer() +static GuestSurface* GetBackBuffer() { - g_backBuffer->AddRef(); + if (g_backBuffer) + g_backBuffer->AddRef(); + return g_backBuffer; } static GuestSurface* GetDepthStencil() { - g_depthStencil->AddRef(); + if (g_depthStencil) + g_depthStencil->AddRef(); + return g_depthStencil; } @@ -3511,8 +3992,6 @@ static GuestBuffer* CreateIndexBuffer(uint32_t length, uint32_t, uint32_t format return buffer; } -static std::vector> g_surfaceCache; - // TODO: Singleplayer (possibly) uses the same memory location in EDRAM for HDR and FB0 surfaces, // so we just remember who was created first and use that instead of creating a new one. static GuestSurface* CreateSurface(uint32_t width, uint32_t height, uint32_t format, uint32_t multiSample, GuestSurfaceCreateParams* params) @@ -3529,6 +4008,7 @@ static GuestSurface* CreateSurface(uint32_t width, uint32_t height, uint32_t for cachedSurface->guestFormat == format && cachedBase == baseValue) { surface = cachedSurface; + surface->AddRef(); break; } } @@ -7741,8 +8221,8 @@ void VideoConfigValueChangedCallback(IConfigDef* config) config == &Config::AntiAliasing || config == &Config::TransparencyAntiAliasing; -// if (shouldRecompile) -// EnqueuePipelineTask(PipelineTaskType::RecompilePipelines, {}); + // if (shouldRecompile) + // EnqueuePipelineTask(PipelineTaskType::RecompilePipelines, {}); } // There is a bug on AMD where restart indices cause incorrect culling and prevent some triangles from being rendered. diff --git a/MarathonRecomp/gpu/video.h b/MarathonRecomp/gpu/video.h index 09f78f26..a592810e 100644 --- a/MarathonRecomp/gpu/video.h +++ b/MarathonRecomp/gpu/video.h @@ -36,7 +36,8 @@ struct Video static void ComputeViewportDimensions(); }; -enum class Backend { +enum class Backend +{ VULKAN, D3D12, METAL @@ -473,6 +474,14 @@ enum GuestTextureAddress inline bool g_needsResize; +static GuestSurface* GetBackBuffer(); + +static void SetRenderTarget(GuestDevice* device, uint32_t index, GuestSurface* renderTarget); +static void SetDepthStencilSurface(GuestDevice* device, GuestSurface* depthStencil); +static GuestTexture* CreateTexture(uint32_t width, uint32_t height, uint32_t depth, uint32_t levels, uint32_t usage, uint32_t format, uint32_t pool, uint32_t type); +static GuestSurface* CreateSurface(uint32_t width, uint32_t height, uint32_t format, uint32_t multiSample, GuestSurfaceCreateParams* params); + extern std::unique_ptr LoadTexture(const uint8_t* data, size_t dataSize, RenderComponentMapping componentMapping = RenderComponentMapping()); extern void VideoConfigValueChangedCallback(class IConfigDef* config); + diff --git a/MarathonRecomp/patches/TitleTask_patches.cpp b/MarathonRecomp/patches/TitleTask_patches.cpp index 70e114de..5148afe0 100644 --- a/MarathonRecomp/patches/TitleTask_patches.cpp +++ b/MarathonRecomp/patches/TitleTask_patches.cpp @@ -110,7 +110,7 @@ PPC_FUNC(sub_825126A0) if (g_isSecretDone) break; - if (auto& spInputManager = App::s_pApp->m_pDoc->m_vspInputManager[0]) + if (auto& spInputManager = App::s_pApp->m_pDoc->m_vspInputManagers[0]) { auto& rPadState = spInputManager->m_PadState; @@ -138,7 +138,7 @@ PPC_FUNC(sub_825126A0) case Sonicteam::TitleTask::TitleState_OptionsWait: { - if (auto& spInputManager = App::s_pApp->m_pDoc->m_vspInputManager[0]) + if (auto& spInputManager = App::s_pApp->m_pDoc->m_vspInputManagers[0]) { auto& rPadState = spInputManager->m_PadState; @@ -196,7 +196,7 @@ PPC_FUNC(sub_825126A0) } else { - if (auto& spInputManager = App::s_pApp->m_pDoc->m_vspInputManager[0]) + if (auto& spInputManager = App::s_pApp->m_pDoc->m_vspInputManagers[0]) { auto& rPadState = spInputManager->m_PadState; diff --git a/MarathonRecomp/patches/aspect_ratio_patches.cpp b/MarathonRecomp/patches/aspect_ratio_patches.cpp index 8691b520..42fea12f 100644 --- a/MarathonRecomp/patches/aspect_ratio_patches.cpp +++ b/MarathonRecomp/patches/aspect_ratio_patches.cpp @@ -341,8 +341,7 @@ PPC_FUNC(sub_828C8F60) if ((g_sceneModifier->Flags & CSD_MODIFIER_ULTRAWIDE_ONLY) != 0 && g_aspectRatio <= WIDE_ASPECT_RATIO) g_sceneModifier->Flags &= (~g_sceneModifier->Flags) | CSD_MODIFIER_ULTRAWIDE_ONLY; - if ((g_sceneModifier->Flags & CSD_SCENE_DISABLE_MOTION) != 0) - pScene->FPS = 0; + pScene->FPS = ((g_sceneModifier->Flags & CSD_SCENE_DISABLE_MOTION) != 0) ? 0 : 60; if (g_aspectRatio > WIDE_ASPECT_RATIO) { @@ -1287,7 +1286,7 @@ PPC_FUNC(sub_824D6E50) PPC_FUNC_IMPL(__imp__sub_824F1538); PPC_FUNC(sub_824F1538) { - auto pHUDRaderMap = (Sonicteam::HUDRaderMap*)(base + ctx.r3.u32); + auto pHUDRaderMap = (Sonicteam::HUDRaderMap*)(base + ctx.r3.u32 - 8); __imp__sub_824F1538(ctx, base); diff --git a/MarathonRecomp/patches/camera_patches.cpp b/MarathonRecomp/patches/camera_patches.cpp index 3fbd05e6..28801b52 100644 --- a/MarathonRecomp/patches/camera_patches.cpp +++ b/MarathonRecomp/patches/camera_patches.cpp @@ -9,7 +9,7 @@ static class MainMenuCameraUpdateEvent : public ContextHookEventGetDocMode(); + auto pMainMode = pThis->GetParent(); if (!pMainMode) return; diff --git a/MarathonRecomp/patches/misc_patches.cpp b/MarathonRecomp/patches/misc_patches.cpp index a8a8e320..714a701e 100644 --- a/MarathonRecomp/patches/misc_patches.cpp +++ b/MarathonRecomp/patches/misc_patches.cpp @@ -43,8 +43,8 @@ void SetLifeBarAnimation(PPCRegister& r3, PPCRegister& r4, PPCRegister& r5, PPCR // Redirect "life_ber_anime" to "life_bar_anime", as they // actually spelt "bar" correctly in the tag XNCP scene names... - if ((pCsdObject->m_pCsdResource->m_FilePath == "sprite/tagdisplay_1p" || - pCsdObject->m_pCsdResource->m_FilePath == "sprite/tagdisplay_2p") && + if ((pCsdObject->m_pCsdResource->m_MgrResourceName == "sprite/tagdisplay_1p" || + pCsdObject->m_pCsdResource->m_MgrResourceName == "sprite/tagdisplay_2p") && strcmp(pSceneName, "life_ber_anime") == 0) { r4.u32 = g_memory.MapVirtual(s_lifeBarSceneName); diff --git a/MarathonRecomp/ui/game_window.cpp b/MarathonRecomp/ui/game_window.cpp index a11e23df..ccfa7133 100644 --- a/MarathonRecomp/ui/game_window.cpp +++ b/MarathonRecomp/ui/game_window.cpp @@ -14,8 +14,8 @@ #include -bool m_isFullscreenKeyReleased = true; -bool m_isResizing = false; +static bool g_isFullscreenKeyReleased = true; +static bool g_isResizing = false; int Window_OnSDLEvent(void*, SDL_Event* event) { @@ -49,7 +49,7 @@ int Window_OnSDLEvent(void*, SDL_Event* event) // Toggle fullscreen on ALT+ENTER. case SDLK_RETURN: { - if (!(event->key.keysym.mod & KMOD_ALT) || !m_isFullscreenKeyReleased) + if (!(event->key.keysym.mod & KMOD_ALT) || !g_isFullscreenKeyReleased) break; Config::Fullscreen = GameWindow::SetFullscreen(!GameWindow::IsFullscreen()); @@ -64,7 +64,7 @@ int Window_OnSDLEvent(void*, SDL_Event* event) } // Block holding ALT+ENTER spamming window changes. - m_isFullscreenKeyReleased = false; + g_isFullscreenKeyReleased = false; break; } @@ -96,7 +96,7 @@ int Window_OnSDLEvent(void*, SDL_Event* event) { // Allow user to input ALT+ENTER again. case SDLK_RETURN: - m_isFullscreenKeyReleased = true; + g_isFullscreenKeyReleased = true; break; } } @@ -129,7 +129,7 @@ int Window_OnSDLEvent(void*, SDL_Event* event) break; case SDL_WINDOWEVENT_RESIZED: - m_isResizing = true; + g_isResizing = true; Config::WindowSize = -1; GameWindow::s_width = event->window.data1; GameWindow::s_height = event->window.data2; @@ -238,10 +238,10 @@ void GameWindow::Update() Config::WindowHeight = GameWindow::s_height; } - if (m_isResizing) + if (g_isResizing) { SetTitle(); - m_isResizing = false; + g_isResizing = false; } if (g_needsResize) diff --git a/MarathonRecomp/ui/message_window.cpp b/MarathonRecomp/ui/message_window.cpp index 96023d4d..189c1b99 100644 --- a/MarathonRecomp/ui/message_window.cpp +++ b/MarathonRecomp/ui/message_window.cpp @@ -325,7 +325,7 @@ void MessageWindow::Draw() // Always assume keyboard to prevent mouse from blocking control in-game. isKeyboard = true; - if (auto& spInputManager = App::s_pApp->m_pDoc->m_vspInputManager[0]) + if (auto& spInputManager = App::s_pApp->m_pDoc->m_vspInputManagers[0]) { auto& rPadState = spInputManager->m_PadState; diff --git a/MarathonRecomp/ui/options_menu.cpp b/MarathonRecomp/ui/options_menu.cpp index d478490f..c7f1f937 100644 --- a/MarathonRecomp/ui/options_menu.cpp +++ b/MarathonRecomp/ui/options_menu.cpp @@ -842,12 +842,9 @@ static void DrawOptions(ImVec2 min, ImVec2 max) case OptionsMenuCategory::Video: { - // TODO: implement buffer resize. - DrawOption(rowCount++, &Config::WindowSize, false, devReason, 0, 0, 1, false); - - // DrawOption(rowCount++, &Config::WindowSize, !Config::Fullscreen, - // &Localise("Options_Desc_NotAvailableFullscreen"), - // 0, 0, (int)GameWindow::GetDisplayModes().size() - 1, false); + DrawOption(rowCount++, &Config::WindowSize, !Config::Fullscreen, + &Localise("Options_Desc_NotAvailableFullscreen"), + 0, 0, (int)GameWindow::GetDisplayModes().size() - 1, false); auto displayCount = GameWindow::GetDisplayCount(); auto canChangeMonitor = Config::Fullscreen && displayCount > 1; @@ -856,10 +853,10 @@ static void DrawOptions(ImVec2 min, ImVec2 max) if (Config::Fullscreen && displayCount <= 1) monitorReason = &Localise("Options_Desc_NotAvailableHardware"); - DrawOption(rowCount++, &Config::Monitor, false, devReason, 0, 0, 1, false); // TODO: implement buffer resize. DrawOption(rowCount++, &Config::Monitor, canChangeMonitor, monitorReason, 0, 0, displayCount - 1, false); - DrawOption(rowCount++, &Config::AspectRatio, false, devReason); // TODO: implement buffer resize. DrawOption(rowCount++, &Config::AspectRatio, true); + DrawOption(rowCount++, &Config::Monitor, canChangeMonitor, monitorReason, 0, 0, displayCount - 1, false); + DrawOption(rowCount++, &Config::AspectRatio, true); DrawOption(rowCount++, &Config::ResolutionScale, false, devReason); // TODO: implement buffer resize. DrawOption(rowCount++, &Config::ResolutionScale, true, nullptr, 0.25f, 1.0f, 2.0f); - DrawOption(rowCount++, &Config::Fullscreen, false, devReason); // TODO: implement buffer resize. DrawOption(rowCount++, &Config::Fullscreen, true); + DrawOption(rowCount++, &Config::Fullscreen, true); DrawOption(rowCount++, &Config::VSync, true); DrawOption(rowCount++, &Config::FPS, true, nullptr, FPS_MIN, 120, FPS_MAX); DrawOption(rowCount++, &Config::Brightness, true); @@ -1034,7 +1031,7 @@ void OptionsMenu::Draw() { if (s_commonMenu.IsOpen()) { - for (auto& spInputManager : App::s_pApp->m_pDoc->m_vspInputManager) + for (auto& spInputManager : App::s_pApp->m_pDoc->m_vspInputManagers) { auto& rPadState = spInputManager->m_PadState;