Make freeing temp objects more aggressive to fix vending crash - SA 1.0

This commit is contained in:
Silent 2017-09-09 18:47:07 +02:00
parent 1f800587f1
commit 36d9f1a29a
7 changed files with 179 additions and 5 deletions

View file

@ -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 };

View file

@ -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

View 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
View 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

View file

@ -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()

View file

@ -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" />

View file

@ -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">