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 "ModelInfoSA.h"
|
||||
#include "PoolsSA.h"
|
||||
|
||||
// Wrappers
|
||||
static void* EntityRender = AddressByVersion<void*>(0x534310, 0x5347B0, 0x545B30);
|
||||
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);
|
||||
WRAPPER void CShadowCamera::InvertRaster() { VARJMP(varInvertRaster); }
|
||||
|
||||
|
@ -53,7 +57,7 @@ void CObject::Render()
|
|||
std::pair<void*,int> materialRestoreData[16];
|
||||
|
||||
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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
RwRGBA ClearColour = { 255, 255, 255, 0 };
|
||||
|
|
|
@ -180,9 +180,7 @@ public:
|
|||
//********* END CEntityInfo ************//
|
||||
|
||||
public:
|
||||
void UpdateRW();
|
||||
void RegisterReference(CEntity** pAddress);
|
||||
void CleanUpOldReference(CEntity** pAddress);
|
||||
bool IsVisible();
|
||||
};
|
||||
|
||||
class NOVMT CPhysical : public CEntity
|
||||
|
@ -263,11 +261,19 @@ private:
|
|||
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
|
||||
{
|
||||
public:
|
||||
void* m_pObjectList;
|
||||
unsigned char m_nObjectType;
|
||||
uint8_t m_objectCreatedBy;
|
||||
__int8 field_13D;
|
||||
__int16 field_13E;
|
||||
bool bObjectFlag0 : 1;
|
||||
|
@ -334,6 +340,9 @@ public:
|
|||
{ CObject::Render(); }
|
||||
|
||||
virtual void Render() override;
|
||||
|
||||
static void TryToFreeUpTempObjects_SilentPatch( int numObjects );
|
||||
static std::tuple<int,int> TryOrFreeUpTempObjects( int numObjects, bool force );
|
||||
};
|
||||
|
||||
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
|
||||
Patch<const void*>(0x6AC2BE + 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()
|
||||
|
|
|
@ -138,6 +138,7 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio
|
|||
<ClCompile Include="ModelInfoSA.cpp" />
|
||||
<ClCompile Include="PedSA.cpp" />
|
||||
<ClCompile Include="PNGFile.cpp" />
|
||||
<ClCompile Include="PoolsSA.cpp" />
|
||||
<ClCompile Include="ScriptSA.cpp" />
|
||||
<ClCompile Include="SilentPatchSA.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="PedSA.h" />
|
||||
<ClInclude Include="PNGFile.h" />
|
||||
<ClInclude Include="PoolsSA.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="rwpred.hpp" />
|
||||
<ClInclude Include="ScriptSA.h" />
|
||||
|
|
|
@ -66,6 +66,9 @@
|
|||
<ClCompile Include="..\SilentPatch\TheFLAUtils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PoolsSA.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\SilentPatch\MemoryMgr.h">
|
||||
|
@ -146,6 +149,9 @@
|
|||
<ClInclude Include="..\SilentPatch\TheFLAUtils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PoolsSA.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Shaders.rc">
|
||||
|
|
Loading…
Reference in a new issue