SilentPatch/SilentPatchSA/GeneralSA.cpp

171 lines
4.8 KiB
C++
Raw Normal View History

2014-08-03 15:38:53 +02:00
#include "StdAfxSA.h"
#include "GeneralSA.h"
2014-05-30 20:14:47 +02:00
#include "PedSA.h"
#include "ModelInfoSA.h"
#include "PoolsSA.h"
2018-04-26 00:15:36 +02:00
#include <algorithm>
2014-05-30 20:14:47 +02:00
// Wrappers
2014-08-22 00:10:23 +02:00
static void* EntityRender = AddressByVersion<void*>(0x534310, 0x5347B0, 0x545B30);
WRAPPER void CEntity::Render() { VARJMP(EntityRender); }
2014-05-30 20:14:47 +02:00
2018-02-10 20:04:12 +01:00
static void* varEntityIsVisible = AddressByVersion<void*>( 0x536BC0, Memory::PatternAndOffset("0B F6 41 1C 80 74 05 E9", -5) );
WRAPPER bool CEntity::IsVisible() { VARJMP(varEntityIsVisible); }
2014-08-22 00:10:23 +02:00
static void* varInvertRaster = AddressByVersion<void*>(0x705660, 0x705E90, 0x7497A0);
WRAPPER void CShadowCamera::InvertRaster() { VARJMP(varInvertRaster); }
2014-08-22 00:10:23 +02:00
CWeaponInfo* (*CWeaponInfo::GetWeaponInfo)(eWeaponType, signed char) = AddressByVersion<CWeaponInfo*(*)(eWeaponType, signed char)>(0x743C60, 0x744490, 0x77D940);
2014-08-19 12:57:35 +02:00
static RwTexture*& ms_pRemapTexture = **AddressByVersion<RwTexture***>(0x59F1BD, 0x6D6E53, 0x5B811D);
2014-08-22 00:10:23 +02:00
auto SetEditableMaterialsCB = AddressByVersion<RpAtomic*(*)(RpAtomic*,void*)>(0x4C83E0, 0x4C8460, 0x4D2CE0);
void* (CEntity::*CEntity::orgGetColModel)();
static void ResetEditableMaterials(std::pair<void**,void*> pData[], size_t num)
{
for (size_t i = 0; i < num; ++i)
*pData[i].first = pData[i].second;
}
RpAtomic* ShadowCameraRenderCB(RpAtomic* pAtomic)
{
if ( RpAtomicGetFlags(pAtomic) & rpATOMICRENDER )
{
RpGeometry* pGeometry = RpAtomicGetGeometry(pAtomic);
2017-03-25 13:46:35 +01:00
if ( pGeometry->repEntry != nullptr ) // Only switch to optimized flags if already instanced so as not to break the instanced model
{
RwUInt32 geometryFlags = RpGeometryGetFlags(pGeometry);
pGeometry->flags &= ~(rpGEOMETRYTEXTURED|rpGEOMETRYPRELIT|rpGEOMETRYNORMALS|rpGEOMETRYLIGHT|rpGEOMETRYMODULATEMATERIALCOLOR|rpGEOMETRYTEXTURED2);
pAtomic = AtomicDefaultRenderCallBack(pAtomic);
RpGeometrySetFlags(pGeometry, geometryFlags);
}
else
{
pAtomic = AtomicDefaultRenderCallBack(pAtomic);
}
}
return pAtomic;
}
void CEntity::SetPositionAndAreaCode( CVector position )
{
SetCoords( position );
if ( position.z >= 950.0f )
{
m_areaCode = 13;
}
}
void CObject::Render()
{
2014-08-03 15:38:53 +02:00
if ( m_bDoNotRender || !m_pRwObject )
return;
std::pair<void**,void*> materialRestoreData[256];
size_t numMaterialsToRestore = 0;
2019-03-05 21:26:46 +01:00
RwScopedRenderState cullState(rwRENDERSTATECULLMODE);
2017-09-09 20:46:10 +02:00
const int32_t carPartModelIndex = m_wCarPartModelIndex.Get();
if ( carPartModelIndex != -1 && m_objectCreatedBy == TEMP_OBJECT && bObjectFlag7 && RwObjectGetType(m_pRwObject) == rpATOMIC )
{
auto* pData = materialRestoreData;
ms_pRemapTexture = m_pPaintjobTex;
2017-09-09 20:46:10 +02:00
static_cast<CVehicleModelInfo*>(ms_modelInfoPtrs[ carPartModelIndex ])->SetVehicleColour( m_nCarColor[0].Get(),
m_nCarColor[1].Get(), m_nCarColor[2].Get(), m_nCarColor[3].Get() );
SetEditableMaterialsCB(reinterpret_cast<RpAtomic*>(m_pRwObject), &pData);
assert( pData >= std::begin(materialRestoreData) && pData < std::end(materialRestoreData) );
numMaterialsToRestore = std::distance(materialRestoreData, pData);
// Disable backface culling for the part
RwRenderStateSet(rwRENDERSTATECULLMODE, reinterpret_cast<void*>(rwCULLMODECULLNONE));
}
CEntity::Render();
ResetEditableMaterials(materialRestoreData, numMaterialsToRestore);
}
extern void (*WorldRemove)(CEntity*);
void CObject::TryToFreeUpTempObjects_SilentPatch( int numObjects )
{
const auto [ numProcessed, numFreed ] = TryOrFreeUpTempObjects( numObjects, false );
2018-04-26 00:15:36 +02:00
if ( numFreed < numObjects )
{
2018-04-26 00:15:36 +02:00
TryOrFreeUpTempObjects( std::min(numProcessed, numObjects - numFreed), true );
}
}
std::tuple<int,int> CObject::TryOrFreeUpTempObjects( int numObjects, bool force )
{
int numProcessed = 0, numFreed = 0;
auto& pool = CPools::GetObjectPool();
2017-12-22 00:13:16 +01:00
for ( auto obj : pool )
{
if ( numFreed >= numObjects ) break;
2017-12-22 00:13:16 +01:00
if ( pool.IsValidPtr( obj ) )
{
2017-12-22 00:13:16 +01:00
if ( obj->m_objectCreatedBy == TEMP_OBJECT )
{
numProcessed++;
2017-12-22 00:13:16 +01:00
if ( force || !obj->IsVisible() )
{
numFreed++;
2017-12-22 00:13:16 +01:00
WorldRemove( obj );
delete obj;
}
}
}
}
return std::make_tuple( numProcessed, numFreed );
}
RwCamera* CShadowCamera::Update(CEntity* pEntity)
{
RwRGBA ClearColour = { 255, 255, 255, 0 };
RwCameraClear(m_pCamera, &ClearColour, rwCAMERACLEARIMAGE|rwCAMERACLEARZ);
if ( RwCameraBeginUpdate(m_pCamera ) )
{
if ( pEntity )
{
if ( pEntity->nType == 3 )
static_cast<CPed*>(pEntity)->RenderForShadow();
else
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(pEntity->m_pRwObject), ShadowCameraRenderCB);
}
InvertRaster();
RwCameraEndUpdate(m_pCamera);
}
return m_pCamera;
2016-04-24 20:37:14 +02:00
}
std::vector<CEntity*> CEscalator::ms_entitiesToRemove;
void CEscalator::SwitchOffNoRemove()
{
if ( !m_bExists )
return;
2016-09-12 00:11:17 +02:00
for ( ptrdiff_t i = 0, j = field_7C + field_80 + field_84; i < j; ++i )
2016-04-24 20:37:14 +02:00
{
if ( m_pSteps[i] != nullptr )
{
ms_entitiesToRemove.push_back( m_pSteps[i] );
m_pSteps[i] = nullptr;
}
}
m_bExists = false;
}