diff --git a/Client/game_sa/C3DMarkerSA.cpp b/Client/game_sa/C3DMarkerSA.cpp index 89a09c309a..dce7d0933c 100644 --- a/Client/game_sa/C3DMarkerSA.cpp +++ b/Client/game_sa/C3DMarkerSA.cpp @@ -1,53 +1,48 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: game_sa/C3DMarkerSA.cpp * PURPOSE: 3D Marker entity * - * Multi Theft Auto is available from http://www.multitheftauto.com/ + * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ #include "StdInc.h" #include "C3DMarkerSA.h" +#include "CMatrix.h" void C3DMarkerSA::GetMatrix(CMatrix* pMatrix) { - CMatrix_Padded* mat = &GetInterface()->m_mat; - MemCpyFast(&pMatrix->vPos, &mat->vPos, sizeof(CVector)); - MemCpyFast(&pMatrix->vFront, &mat->vFront, sizeof(CVector)); - MemCpyFast(&pMatrix->vRight, &mat->vRight, sizeof(CVector)); - MemCpyFast(&pMatrix->vUp, &mat->vUp, sizeof(CVector)); + CMatrixSAInterface* mat = &GetInterface()->m_mat; + MemCpyFast(pMatrix, &mat->GetMatrix(), sizeof(CMatrix)); } void C3DMarkerSA::SetMatrix(CMatrix* pMatrix) { - CMatrix_Padded* mat = &GetInterface()->m_mat; - MemCpyFast(&mat->vPos, &pMatrix->vPos, sizeof(CVector)); - MemCpyFast(&mat->vFront, &pMatrix->vFront, sizeof(CVector)); - MemCpyFast(&mat->vRight, &pMatrix->vRight, sizeof(CVector)); - MemCpyFast(&mat->vUp, &pMatrix->vUp, sizeof(CVector)); + CMatrixSAInterface* mat = &GetInterface()->m_mat; + mat->SetMatrix(pMatrix->vRight, pMatrix->vFront, pMatrix->vUp, pMatrix->vPos); } void C3DMarkerSA::SetPosition(CVector* vecPosition) { - GetInterface()->m_mat.vPos = *vecPosition; + GetInterface()->m_mat.SetTranslateOnly(*vecPosition); } CVector* C3DMarkerSA::GetPosition() { - return &GetInterface()->m_mat.vPos; + return &GetInterface()->m_mat.GetPosition(); } -DWORD C3DMarkerSA::GetType() +e3DMarkerType C3DMarkerSA::GetType() const { - return GetInterface()->m_nType; + return static_cast(GetInterface()->m_nType); } -void C3DMarkerSA::SetType(DWORD dwType) +void C3DMarkerSA::SetType(e3DMarkerType type) { - GetInterface()->m_nType = (unsigned short)(dwType); + GetInterface()->m_nType = type; } bool C3DMarkerSA::IsActive() @@ -60,22 +55,9 @@ DWORD C3DMarkerSA::GetIdentifier() return GetInterface()->m_nIdentifier; } -SharedUtil::SColor C3DMarkerSA::GetColor() -{ - // From ABGR - unsigned long ulABGR = GetInterface()->rwColour; - SharedUtil::SColor color; - color.A = (ulABGR >> 24) & 0xff; - color.B = (ulABGR >> 16) & 0xff; - color.G = (ulABGR >> 8) & 0xff; - color.R = ulABGR & 0xff; - return color; -} - void C3DMarkerSA::SetColor(const SharedUtil::SColor color) { - // To ABGR - GetInterface()->rwColour = (color.A << 24) | (color.B << 16) | (color.G << 8) | color.R; + GetInterface()->rwColour = RwColor{color.R, color.G, color.B, color.A}; } void C3DMarkerSA::SetPulsePeriod(WORD wPulsePeriod) @@ -130,5 +112,5 @@ void C3DMarkerSA::Disable() void C3DMarkerSA::Reset() { - internalInterface->m_lastPosition = internalInterface->m_mat.vPos; + internalInterface->m_lastPosition = internalInterface->m_mat.GetPosition(); } diff --git a/Client/game_sa/C3DMarkerSA.h b/Client/game_sa/C3DMarkerSA.h index 7d843482e8..feb0e32dc9 100644 --- a/Client/game_sa/C3DMarkerSA.h +++ b/Client/game_sa/C3DMarkerSA.h @@ -1,50 +1,18 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: game_sa/C3DMarkerSA.h * PURPOSE: Header file for 3D Marker entity class * - * Multi Theft Auto is available from http://www.multitheftauto.com/ + * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ #pragma once #include -#include - -class C3DMarkerSAInterface -{ -public: - CMatrix_Padded m_mat; // local space to world space transform // 0 - DWORD dwPad, dwPad2; // not sure why we need these, it appears to be this way though (eAi) // 64/68 - RpClump* m_pRwObject; // 72 - DWORD* m_pMaterial; // 76 - - WORD m_nType; // 80 - bool m_bIsUsed; // has this marker been allocated this frame? // 82 - DWORD m_nIdentifier; // 84 - - DWORD rwColour; // 88 - WORD m_nPulsePeriod; // 92 - short m_nRotateRate; // deg per frame (in either direction) // 94 - DWORD m_nStartTime; // 96 - float m_fPulseFraction; // 100 - float m_fStdSize; // 104 - float m_fSize; // 108 - float m_fBrightness; // 112 - float m_fCameraRange; // 116 - - CVector m_normal; // Normal of the object point at // 120 - // the following variables remember the last time we read the heigh of the - // map. Using this we don't have to do this every frame and we can still have moving markers. - WORD m_LastMapReadX, m_LastMapReadY; // 132 / 134 - float m_LastMapReadResultZ; // 136 - float m_roofHeight; // 140 - CVector m_lastPosition; // 144 - DWORD m_OnScreenTestTime; // time last screen check was done // 156 -}; +#include "interfaces/C3DMarkerSAInterface.h" class C3DMarkerSA : public C3DMarker { @@ -55,16 +23,16 @@ class C3DMarkerSA : public C3DMarker C3DMarkerSA(C3DMarkerSAInterface* markerInterface) { internalInterface = markerInterface; }; C3DMarkerSAInterface* GetInterface() { return internalInterface; } + C3DMarkerSAInterface* GetInterface() const { return internalInterface; } void GetMatrix(CMatrix* pMatrix); void SetMatrix(CMatrix* pMatrix); void SetPosition(CVector* vecPosition); CVector* GetPosition(); - DWORD GetType(); // need enum? - void SetType(DWORD dwType); // doesn't work propperly (not virtualed) + e3DMarkerType GetType() const override; + void SetType(e3DMarkerType type); // doesn't work propperly (not virtualed) bool IsActive(); DWORD GetIdentifier(); - SharedUtil::SColor GetColor(); void SetColor(const SharedUtil::SColor color); // actually BGRA void SetPulsePeriod(WORD wPulsePeriod); void SetRotateRate(short RotateRate); @@ -78,5 +46,5 @@ class C3DMarkerSA : public C3DMarker void Disable(); void Reset(); void SetActive() { internalInterface->m_bIsUsed = true; } - RpClump* GetRwObject() { return internalInterface->m_pRwObject; } + RpClump* GetRwObject() { return reinterpret_cast(internalInterface->m_pRwObject); } }; diff --git a/Client/game_sa/CEntitySA.h b/Client/game_sa/CEntitySA.h index bdcbcfce84..1f7130849b 100644 --- a/Client/game_sa/CEntitySA.h +++ b/Client/game_sa/CEntitySA.h @@ -48,37 +48,6 @@ class CReferences CReference* m_pFreeList; }; -class CMatrixEx -{ -public: - CMatrix_Padded matrix; - CMatrix* pMatrix; // usually not initialized - void* haveRwMatrix; // unknown pointer -}; - -class XYZ -{ -public: - CMatrixEx matrix; - class CPlaceableSAInterface* pRef; - XYZ* pPrev; - XYZ* pNext; -}; -static_assert(sizeof(XYZ) == 0x54, "Invalid size for XYZ"); - -class XYZStore -{ -public: - XYZ head; - XYZ tail; - XYZ allocatedListHead; - XYZ allocatedListTail; - XYZ freeListHead; - XYZ freeListTail; - XYZ* pPool; -}; -static_assert(sizeof(XYZStore) == 0x1FC, "Invalid size for XYZStore"); - class CEntitySAInterface : public CPlaceableSAInterface { public: diff --git a/Client/game_sa/CMatrixSA.h b/Client/game_sa/CMatrixSA.h index 7b41c3ea75..4fd13019de 100644 --- a/Client/game_sa/CMatrixSA.h +++ b/Client/game_sa/CMatrixSA.h @@ -11,6 +11,7 @@ #pragma once #include "CVector.h" #include "CRenderWareSA.h" +#include "CMatrix.h" class CMatrixSAInterface { @@ -45,4 +46,17 @@ class CMatrixSAInterface m_up = up; m_pos = pos; } + + CMatrix GetMatrix() const + { + CMatrix matrix; + matrix.vRight = m_right; + matrix.vFront = m_forward; + matrix.vUp = m_up; + matrix.vPos = m_pos; + + return matrix; + } + + CVector GetPosition() const noexcept { return m_pos; } }; diff --git a/Client/game_sa/interfaces/C3DMarkerSAInterface.cpp b/Client/game_sa/interfaces/C3DMarkerSAInterface.cpp new file mode 100644 index 0000000000..fb272e9c3d --- /dev/null +++ b/Client/game_sa/interfaces/C3DMarkerSAInterface.cpp @@ -0,0 +1,48 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/interfaces/C3DMarkerSAInterface.cpp + * PURPOSE: 3D Marker game layer interface + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ +#include "StdInc.h" +#include "C3DMarkerSAInterface.h" + +bool C3DMarkerSAInterface::AddMarker(std::uint32_t id, e3DMarkerType type, float size, std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a, std::uint16_t pulsePeriod, float pulseFraction, std::int16_t rotateRate) +{ + return ((bool(__thiscall*)(C3DMarkerSAInterface*, std::uint32_t, std::uint16_t, float, std::uint8_t, std::uint8_t, std::uint8_t, std::uint8_t, std::uint16_t, float, std::int16_t))0x722230)(this, id, static_cast(type), size, r, g, b, a, pulsePeriod, pulseFraction, rotateRate); +} + +void C3DMarkerSAInterface::DeleteMarkerObject() +{ + ((void(__thiscall*)(C3DMarkerSAInterface*))0x722390)(this); +} + +bool C3DMarkerSAInterface::IsZCoordinateUpToDate() const +{ + const CVector& pos = m_mat.GetPosition(); + return m_LastMapReadX == static_cast(pos.fX) && m_LastMapReadY == static_cast(pos.fY); +} + +void C3DMarkerSAInterface::SetZCoordinateIfNotUpToDate(float newZPos) +{ + if (!IsZCoordinateUpToDate()) + { + CVector& pos = m_mat.GetPosition(); + pos.fZ = newZPos; + } +} + +void C3DMarkerSAInterface::UpdateZCoordinate(CVector point, float zDistance) +{ + ((void(__thiscall*)(C3DMarkerSAInterface*, CVector, float))0x724D40)(this, point, zDistance); +} + +void C3DMarkerSAInterface::DeleteIfHasAtomic() +{ + if (m_pRwObject) + DeleteMarkerObject(); +} diff --git a/Client/game_sa/interfaces/C3DMarkerSAInterface.h b/Client/game_sa/interfaces/C3DMarkerSAInterface.h new file mode 100644 index 0000000000..ab799a67fd --- /dev/null +++ b/Client/game_sa/interfaces/C3DMarkerSAInterface.h @@ -0,0 +1,57 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/interfaces/C3DMarkerSAInterface.h + * PURPOSE: Header file for 3D Marker game layer interface + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include +#include "game/RenderWare.h" +#include "../CMatrixSA.h" + +class C3DMarkerSAInterface +{ +public: + CMatrixSAInterface m_mat; // local space to world space transform + RpAtomic* m_pRwObject; + RpMaterial* m_pMaterial; + std::uint16_t m_nType; // e3DMarkerType + bool m_bIsUsed; // has this marker been allocated this frame? + bool m_mustBeRenderedThisFrame; + std::uint32_t m_nIdentifier; + RwColor rwColour; + std::uint16_t m_nPulsePeriod; + std::int16_t m_nRotateRate; // deg per frame (in either direction) + std::uint32_t m_nStartTime; + float m_fPulseFraction; + float m_fStdSize; + float m_fSize; + float m_fBrightness; + float m_fCameraRange; + CVector m_normal; // Normal of the object point at + + // The following variables remember the last time we read the height of the map. + // Using this we don't have to do this every frame and we can still have moving markers. + std::uint16_t m_LastMapReadX; + std::uint16_t m_LastMapReadY; + float m_LastMapReadResultZ; + float m_roofHeight; + CVector m_lastPosition; + std::uint32_t m_OnScreenTestTime; // time last screen check was done + +public: + inline bool AddMarker(std::uint32_t id, e3DMarkerType type, float size, std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a, std::uint16_t pulsePeriod, + float pulseFraction, std::int16_t rotateRate); + inline void DeleteMarkerObject(); + inline bool IsZCoordinateUpToDate() const; + inline void SetZCoordinateIfNotUpToDate(float newZPos); + inline void UpdateZCoordinate(CVector point, float zDistance); + inline void DeleteIfHasAtomic(); +}; +static_assert(sizeof(C3DMarkerSAInterface) == 0xA0, "Invalid size for C3DMarkerSAInterface"); diff --git a/Client/mods/deathmatch/logic/CClient3DMarker.h b/Client/mods/deathmatch/logic/CClient3DMarker.h index 945bb25b2f..852f8606a0 100644 --- a/Client/mods/deathmatch/logic/CClient3DMarker.h +++ b/Client/mods/deathmatch/logic/CClient3DMarker.h @@ -73,5 +73,5 @@ class CClient3DMarker : public CClientMarkerCommon C3DMarker* m_pMarker; unsigned int m_ulIdentifier; bool m_bMarkerStreamedIn; - bool m_ignoreAlphaLimits; + bool m_ignoreAlphaLimits{false}; }; diff --git a/Client/sdk/game/C3DMarker.h b/Client/sdk/game/C3DMarker.h index b89807fd73..e9ca7e7dce 100644 --- a/Client/sdk/game/C3DMarker.h +++ b/Client/sdk/game/C3DMarker.h @@ -1,11 +1,11 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: sdk/game/C3DMarker.h * PURPOSE: 3D marker entity interface * - * Multi Theft Auto is available from http://www.multitheftauto.com/ + * Multi Theft Auto is available from https://www.multitheftauto.com/ * *****************************************************************************/ @@ -29,10 +29,9 @@ class C3DMarker virtual void SetMatrix(CMatrix* pMatrix) = 0; virtual void SetPosition(CVector* vecPosition) = 0; virtual CVector* GetPosition() = 0; - virtual DWORD GetType() = 0; // need enum? + virtual e3DMarkerType GetType() const = 0; virtual bool IsActive() = 0; virtual DWORD GetIdentifier() = 0; - virtual SharedUtil::SColor GetColor() = 0; virtual void SetColor(const SharedUtil::SColor color) = 0; virtual void SetPulsePeriod(WORD wPulsePeriod) = 0; virtual void SetPulseFraction(float fPulseFraction) = 0; diff --git a/Client/sdk/game/Common.h b/Client/sdk/game/Common.h index be4d18a643..186a577134 100644 --- a/Client/sdk/game/Common.h +++ b/Client/sdk/game/Common.h @@ -753,7 +753,9 @@ enum e3DMarkerType MARKER3D_TORUS, MARKER3D_CONE, MARKER3D_CONE_NO_COLLISION, - MARKER3D_NUM + MARKER3D_NUM, + + NOT_ALLOCATED = 257, // see C3dMarker::DeleteMarkerObject }; enum eMarkerSprite