mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2025-01-31 06:57:28 +05:00
Make freeing temp objects more aggressive to fix vending crash - SA 1.0
This commit is contained in:
parent
1f800587f1
commit
36d9f1a29a
7 changed files with 179 additions and 5 deletions
|
@ -3,11 +3,15 @@
|
||||||
|
|
||||||
#include "PedSA.h"
|
#include "PedSA.h"
|
||||||
#include "ModelInfoSA.h"
|
#include "ModelInfoSA.h"
|
||||||
|
#include "PoolsSA.h"
|
||||||
|
|
||||||
// Wrappers
|
// Wrappers
|
||||||
static void* EntityRender = AddressByVersion<void*>(0x534310, 0x5347B0, 0x545B30);
|
static void* EntityRender = AddressByVersion<void*>(0x534310, 0x5347B0, 0x545B30);
|
||||||
WRAPPER void CEntity::Render() { VARJMP(EntityRender); }
|
WRAPPER void CEntity::Render() { VARJMP(EntityRender); }
|
||||||
|
|
||||||
|
static void* varEntityIsVisible = AddressByVersion<void*>( 0x536BC0, 0, 0 ); // TODO
|
||||||
|
WRAPPER bool CEntity::IsVisible() { VARJMP(varEntityIsVisible); }
|
||||||
|
|
||||||
static void* varInvertRaster = AddressByVersion<void*>(0x705660, 0x705E90, 0x7497A0);
|
static void* varInvertRaster = AddressByVersion<void*>(0x705660, 0x705E90, 0x7497A0);
|
||||||
WRAPPER void CShadowCamera::InvertRaster() { VARJMP(varInvertRaster); }
|
WRAPPER void CShadowCamera::InvertRaster() { VARJMP(varInvertRaster); }
|
||||||
|
|
||||||
|
@ -53,7 +57,7 @@ void CObject::Render()
|
||||||
std::pair<void*,int> materialRestoreData[16];
|
std::pair<void*,int> materialRestoreData[16];
|
||||||
|
|
||||||
const int32_t carPartModelIndex = FLAUtils::GetExtendedID( &m_wCarPartModelIndex );
|
const int32_t carPartModelIndex = FLAUtils::GetExtendedID( &m_wCarPartModelIndex );
|
||||||
if ( carPartModelIndex != -1 && m_nObjectType == 3 && bObjectFlag7 && RwObjectGetType(m_pRwObject) == rpATOMIC )
|
if ( carPartModelIndex != -1 && m_objectCreatedBy == TEMP_OBJECT && bObjectFlag7 && RwObjectGetType(m_pRwObject) == rpATOMIC )
|
||||||
{
|
{
|
||||||
auto* pData = materialRestoreData;
|
auto* pData = materialRestoreData;
|
||||||
|
|
||||||
|
@ -87,6 +91,45 @@ void CObject::Render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void (*WorldRemove)(CEntity*);
|
||||||
|
void CObject::TryToFreeUpTempObjects_SilentPatch( int numObjects )
|
||||||
|
{
|
||||||
|
int numProcessed, numFreed;
|
||||||
|
std::tie( numProcessed, numFreed ) = TryOrFreeUpTempObjects( numObjects, false );
|
||||||
|
if ( numProcessed >= numObjects && numObjects > numFreed )
|
||||||
|
{
|
||||||
|
TryOrFreeUpTempObjects( numObjects - numFreed, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<int,int> CObject::TryOrFreeUpTempObjects( int numObjects, bool force )
|
||||||
|
{
|
||||||
|
int numProcessed = 0, numFreed = 0;
|
||||||
|
|
||||||
|
auto& pool = CPools::GetObjectPool();
|
||||||
|
for ( auto& obj : pool )
|
||||||
|
{
|
||||||
|
if ( numFreed >= numObjects ) break;
|
||||||
|
|
||||||
|
CObject* const objPtr = &obj;
|
||||||
|
if ( pool.IsValidPtr( objPtr ) )
|
||||||
|
{
|
||||||
|
if ( objPtr->m_objectCreatedBy == TEMP_OBJECT )
|
||||||
|
{
|
||||||
|
numProcessed++;
|
||||||
|
if ( force || !objPtr->IsVisible() )
|
||||||
|
{
|
||||||
|
numFreed++;
|
||||||
|
WorldRemove( objPtr );
|
||||||
|
delete objPtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_tuple( numProcessed, numFreed );
|
||||||
|
}
|
||||||
|
|
||||||
RwCamera* CShadowCamera::Update(CEntity* pEntity)
|
RwCamera* CShadowCamera::Update(CEntity* pEntity)
|
||||||
{
|
{
|
||||||
RwRGBA ClearColour = { 255, 255, 255, 0 };
|
RwRGBA ClearColour = { 255, 255, 255, 0 };
|
||||||
|
|
|
@ -180,9 +180,7 @@ public:
|
||||||
//********* END CEntityInfo ************//
|
//********* END CEntityInfo ************//
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void UpdateRW();
|
bool IsVisible();
|
||||||
void RegisterReference(CEntity** pAddress);
|
|
||||||
void CleanUpOldReference(CEntity** pAddress);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class NOVMT CPhysical : public CEntity
|
class NOVMT CPhysical : public CEntity
|
||||||
|
@ -263,11 +261,19 @@ private:
|
||||||
BYTE pad3a[4]; // 0x134
|
BYTE pad3a[4]; // 0x134
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum // m_objectCreatedBy
|
||||||
|
{
|
||||||
|
GAME_OBJECT = 1,
|
||||||
|
MISSION_OBJECT = 2,
|
||||||
|
TEMP_OBJECT = 3,
|
||||||
|
MISSION_BRAIN_OBJECT = 6,
|
||||||
|
};
|
||||||
|
|
||||||
class NOVMT CObject : public CPhysical
|
class NOVMT CObject : public CPhysical
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void* m_pObjectList;
|
void* m_pObjectList;
|
||||||
unsigned char m_nObjectType;
|
uint8_t m_objectCreatedBy;
|
||||||
__int8 field_13D;
|
__int8 field_13D;
|
||||||
__int16 field_13E;
|
__int16 field_13E;
|
||||||
bool bObjectFlag0 : 1;
|
bool bObjectFlag0 : 1;
|
||||||
|
@ -334,6 +340,9 @@ public:
|
||||||
{ CObject::Render(); }
|
{ CObject::Render(); }
|
||||||
|
|
||||||
virtual void Render() override;
|
virtual void Render() override;
|
||||||
|
|
||||||
|
static void TryToFreeUpTempObjects_SilentPatch( int numObjects );
|
||||||
|
static std::tuple<int,int> TryOrFreeUpTempObjects( int numObjects, bool force );
|
||||||
};
|
};
|
||||||
|
|
||||||
class CZoneInfo
|
class CZoneInfo
|
||||||
|
|
4
SilentPatchSA/PoolsSA.cpp
Normal file
4
SilentPatchSA/PoolsSA.cpp
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#include "StdAfxSA.h"
|
||||||
|
#include "PoolsSA.h"
|
||||||
|
|
||||||
|
CObjectPool*& CPools::ms_pObjectPool = **AddressByVersion<CObjectPool***>(0x5A18B2 + 2, 0, 0); // TODO
|
106
SilentPatchSA/PoolsSA.h
Normal file
106
SilentPatchSA/PoolsSA.h
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
#ifndef __POOLS
|
||||||
|
#define __POOLS
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
template <class T, class U = T>
|
||||||
|
class CPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T ReturnType;
|
||||||
|
typedef uint8_t StorageType[sizeof(U)];
|
||||||
|
|
||||||
|
private:
|
||||||
|
StorageType* m_pSlots;
|
||||||
|
union tSlotInfos
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned char m_uID : 7;
|
||||||
|
bool m_bFree : 1;
|
||||||
|
} a;
|
||||||
|
signed char b;
|
||||||
|
}* m_pSlotInfos;
|
||||||
|
int m_nNumSlots;
|
||||||
|
int m_nFirstFree;
|
||||||
|
bool m_bOwnsAllocations;
|
||||||
|
bool m_bDealWithNoMemory;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ReturnType* GetSlot( int32_t index )
|
||||||
|
{
|
||||||
|
return !m_pSlotInfos[index].a.m_bFree ? reinterpret_cast<ReturnType*>(&m_pSlots[index]) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnType* GetAt( int32_t index )
|
||||||
|
{
|
||||||
|
const int ID = index >> 8;
|
||||||
|
return m_pSlotInfos[ID].b == (index && 0xFF) ? reinterpret_cast<ReturnType*>(&m_pSlots[ID]) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t GetStorageSize() { return sizeof(StorageType); }
|
||||||
|
int GetSize() const { return m_nNumSlots; }
|
||||||
|
int GetFreeIndex() const { return m_nFirstFree; }
|
||||||
|
bool GetIsFree( int32_t index ) const { return m_pSlotInfos[index].a.m_bFree; }
|
||||||
|
|
||||||
|
bool IsValidPtr( T* ptr ) const
|
||||||
|
{
|
||||||
|
const ptrdiff_t index = reinterpret_cast<StorageType*>(ptr) - &m_pSlots[0];
|
||||||
|
if( index < 0 || index >= m_nNumSlots )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !GetIsFree( index );
|
||||||
|
}
|
||||||
|
|
||||||
|
class iterator : public std::iterator<std::random_access_iterator_tag, ReturnType>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
iterator() : m_ptr(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit iterator( T* ptr ) : m_ptr( reinterpret_cast<StorageType*>(ptr) )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
reference operator* () const { return *reinterpret_cast<ReturnType*>(m_ptr); }
|
||||||
|
pointer operator->() const { return reinterpret_cast<ReturnType*>(m_ptr); }
|
||||||
|
|
||||||
|
iterator& operator ++ () { ++m_ptr; return *this; }
|
||||||
|
bool operator == ( const iterator& rhs ) const { return m_ptr == rhs.m_ptr; }
|
||||||
|
bool operator != ( const iterator& rhs ) const { return m_ptr != rhs.m_ptr; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
StorageType* m_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
iterator begin()
|
||||||
|
{
|
||||||
|
return iterator( reinterpret_cast<ReturnType*>(&m_pSlots[0]) );
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator end()
|
||||||
|
{
|
||||||
|
return iterator( reinterpret_cast<ReturnType*>(&m_pSlots[m_nNumSlots]) );
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Type definitions for specific pool types
|
||||||
|
#include "General.h"
|
||||||
|
|
||||||
|
typedef CPool<class CObject, uint8_t[0x19C]> CObjectPool;
|
||||||
|
|
||||||
|
class CPools
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static CObjectPool*& ms_pObjectPool;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static CObjectPool& GetObjectPool() { return *ms_pObjectPool; }
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(CPool<bool>) == 0x14, "Wrong size: CPool");
|
||||||
|
|
||||||
|
#endif
|
|
@ -3443,6 +3443,10 @@ void Patch_SA_10()
|
||||||
// Stop BF Injection/Bandito/Hotknife rotating engine components when engine is off
|
// Stop BF Injection/Bandito/Hotknife rotating engine components when engine is off
|
||||||
Patch<const void*>(0x6AC2BE + 2, &CAutomobile::ms_engineCompSpeed);
|
Patch<const void*>(0x6AC2BE + 2, &CAutomobile::ms_engineCompSpeed);
|
||||||
Patch<const void*>(0x6ACB91 + 2, &CAutomobile::ms_engineCompSpeed);
|
Patch<const void*>(0x6ACB91 + 2, &CAutomobile::ms_engineCompSpeed);
|
||||||
|
|
||||||
|
|
||||||
|
// Make freeing temp objects more aggressive to fix vending crash
|
||||||
|
InjectHook( 0x5A1840, CObject::TryToFreeUpTempObjects_SilentPatch, PATCH_JUMP );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Patch_SA_11()
|
void Patch_SA_11()
|
||||||
|
|
|
@ -138,6 +138,7 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio
|
||||||
<ClCompile Include="ModelInfoSA.cpp" />
|
<ClCompile Include="ModelInfoSA.cpp" />
|
||||||
<ClCompile Include="PedSA.cpp" />
|
<ClCompile Include="PedSA.cpp" />
|
||||||
<ClCompile Include="PNGFile.cpp" />
|
<ClCompile Include="PNGFile.cpp" />
|
||||||
|
<ClCompile Include="PoolsSA.cpp" />
|
||||||
<ClCompile Include="ScriptSA.cpp" />
|
<ClCompile Include="ScriptSA.cpp" />
|
||||||
<ClCompile Include="SilentPatchSA.cpp" />
|
<ClCompile Include="SilentPatchSA.cpp" />
|
||||||
<ClCompile Include="StdAfxSA.cpp">
|
<ClCompile Include="StdAfxSA.cpp">
|
||||||
|
@ -185,6 +186,7 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio
|
||||||
<ClInclude Include="ModelInfoSA.h" />
|
<ClInclude Include="ModelInfoSA.h" />
|
||||||
<ClInclude Include="PedSA.h" />
|
<ClInclude Include="PedSA.h" />
|
||||||
<ClInclude Include="PNGFile.h" />
|
<ClInclude Include="PNGFile.h" />
|
||||||
|
<ClInclude Include="PoolsSA.h" />
|
||||||
<ClInclude Include="resource.h" />
|
<ClInclude Include="resource.h" />
|
||||||
<ClInclude Include="rwpred.hpp" />
|
<ClInclude Include="rwpred.hpp" />
|
||||||
<ClInclude Include="ScriptSA.h" />
|
<ClInclude Include="ScriptSA.h" />
|
||||||
|
|
|
@ -66,6 +66,9 @@
|
||||||
<ClCompile Include="..\SilentPatch\TheFLAUtils.cpp">
|
<ClCompile Include="..\SilentPatch\TheFLAUtils.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="PoolsSA.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\SilentPatch\MemoryMgr.h">
|
<ClInclude Include="..\SilentPatch\MemoryMgr.h">
|
||||||
|
@ -146,6 +149,9 @@
|
||||||
<ClInclude Include="..\SilentPatch\TheFLAUtils.h">
|
<ClInclude Include="..\SilentPatch\TheFLAUtils.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="PoolsSA.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="Shaders.rc">
|
<ResourceCompile Include="Shaders.rc">
|
||||||
|
|
Loading…
Reference in a new issue