mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-28 23:03:01 +05:00
refactored to use templated predicates for RW callbacks
This commit is contained in:
parent
d1db161070
commit
a5c0dd54eb
13 changed files with 232 additions and 283 deletions
|
@ -31,10 +31,8 @@ static void ResetEditableMaterials(std::pair<void*,int>* pData)
|
|||
*static_cast<int*>(i->first) = i->second;
|
||||
}
|
||||
|
||||
RpAtomic* ShadowCameraRenderCB(RpAtomic* pAtomic, void* pData)
|
||||
RpAtomic* ShadowCameraRenderCB(RpAtomic* pAtomic)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pData);
|
||||
|
||||
if ( RpAtomicGetFlags(pAtomic) & rpATOMICRENDER )
|
||||
{
|
||||
RpGeometry* pGeometry = RpAtomicGetGeometry(pAtomic);
|
||||
|
@ -106,7 +104,7 @@ RwCamera* CShadowCamera::Update(CEntity* pEntity)
|
|||
if ( pEntity->nType == 3 )
|
||||
static_cast<CPed*>(pEntity)->RenderForShadow();
|
||||
else
|
||||
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(pEntity->m_pRwObject), ShadowCameraRenderCB, nullptr);
|
||||
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(pEntity->m_pRwObject), ShadowCameraRenderCB);
|
||||
}
|
||||
|
||||
InvertRaster();
|
||||
|
|
|
@ -32,17 +32,17 @@ public:
|
|||
|
||||
friend constexpr CRGBA Blend(const CRGBA& From, const CRGBA& To, double BlendVal)
|
||||
{ double InvBlendVal = 1.0 - BlendVal;
|
||||
return CRGBA( To.r * BlendVal + From.r * InvBlendVal,
|
||||
To.g * BlendVal + From.g * InvBlendVal,
|
||||
To.b * BlendVal + From.b * InvBlendVal,
|
||||
To.a * BlendVal + From.a * InvBlendVal); }
|
||||
return CRGBA( uint8_t(To.r * BlendVal + From.r * InvBlendVal),
|
||||
uint8_t(To.g * BlendVal + From.g * InvBlendVal),
|
||||
uint8_t(To.b * BlendVal + From.b * InvBlendVal),
|
||||
uint8_t(To.a * BlendVal + From.a * InvBlendVal)); }
|
||||
|
||||
friend constexpr CRGBA BlendSqr(const CRGBA& From, const CRGBA& To, double BlendVal)
|
||||
{ double InvBlendVal = 1.0 - BlendVal;
|
||||
return CRGBA( sqrt((To.r * To.r) * BlendVal + (From.r * From.r) * InvBlendVal),
|
||||
sqrt((To.g * To.g) * BlendVal + (From.g * From.g) * InvBlendVal),
|
||||
sqrt((To.b * To.b) * BlendVal + (From.b * From.b) * InvBlendVal),
|
||||
sqrt((To.a * To.a) * BlendVal + (From.a * From.a) * InvBlendVal)); }
|
||||
return CRGBA( uint8_t(sqrt((To.r * To.r) * BlendVal + (From.r * From.r) * InvBlendVal)),
|
||||
uint8_t(sqrt((To.g * To.g) * BlendVal + (From.g * From.g) * InvBlendVal)),
|
||||
uint8_t(sqrt((To.b * To.b) * BlendVal + (From.b * From.b) * InvBlendVal)),
|
||||
uint8_t(sqrt((To.a * To.a) * BlendVal + (From.a * From.a) * InvBlendVal))); }
|
||||
|
||||
// SilentPatch
|
||||
CRGBA* BlendGangColour(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
||||
|
@ -587,7 +587,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
RpAtomic* ShadowCameraRenderCB(RpAtomic* pAtomic, void* pData);
|
||||
RpAtomic* ShadowCameraRenderCB(RpAtomic* pAtomic);
|
||||
|
||||
static_assert(sizeof(CEntity) == 0x38, "Wrong size: CEntity");
|
||||
static_assert(sizeof(CPhysical) == 0x138, "Wrong size: CPhysical");
|
||||
|
|
|
@ -17,18 +17,37 @@ void CVehicleModelInfo::Shutdown()
|
|||
CBaseModelInfo::Shutdown();
|
||||
|
||||
delete m_apPlateMaterials;
|
||||
m_apPlateMaterials = nullptr;
|
||||
}
|
||||
|
||||
void CVehicleModelInfo::FindEditableMaterialList()
|
||||
{
|
||||
std::pair<CVehicleModelInfo*,int> MatsPair = std::make_pair(this, 0);
|
||||
int materialCount = 0;
|
||||
|
||||
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(pRwObject), GetEditableMaterialListCB, &MatsPair);
|
||||
auto GetEditableMaterialListCB = [&]( RpAtomic* atomic ) -> RpAtomic* {
|
||||
RpGeometryForAllMaterials( RpAtomicGetGeometry(atomic), [&]( RpMaterial* material ) -> RpMaterial* {
|
||||
if ( RwTexture* texture = RpMaterialGetTexture(material) )
|
||||
{
|
||||
if ( const char* texName = RwTextureGetName(texture) )
|
||||
{
|
||||
if ( _strnicmp(texName, "vehiclegrunge256", 16) == 0 )
|
||||
{
|
||||
if ( materialCount < _countof(m_apDirtMaterials) )
|
||||
m_apDirtMaterials[materialCount++] = material;
|
||||
}
|
||||
}
|
||||
}
|
||||
return material;
|
||||
} );
|
||||
return atomic;
|
||||
};
|
||||
|
||||
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(pRwObject), GetEditableMaterialListCB);
|
||||
|
||||
if ( m_pVehicleStruct->m_nNumExtras > 0 )
|
||||
{
|
||||
for ( int i = 0; i < m_pVehicleStruct->m_nNumExtras; i++ )
|
||||
GetEditableMaterialListCB(m_pVehicleStruct->m_apExtras[i], &MatsPair);
|
||||
GetEditableMaterialListCB(m_pVehicleStruct->m_apExtras[i]);
|
||||
}
|
||||
|
||||
m_nPrimaryColor = -1;
|
||||
|
@ -42,150 +61,61 @@ void CVehicleModelInfo::SetCarCustomPlate()
|
|||
m_plateText[0] = '\0';
|
||||
m_nPlateType = -1;
|
||||
|
||||
m_apPlateMaterials = reinterpret_cast<RpMaterial**>(new DWORD_PTR[2*NUM_MAX_PLATES]);
|
||||
m_apPlateMaterials = new RpMaterial* [2*CCustomCarPlateMgr::NUM_MAX_PLATES];
|
||||
|
||||
for ( int i = 0; i < 2*NUM_MAX_PLATES; i++ )
|
||||
for ( int i = 0; i < 2*CCustomCarPlateMgr::NUM_MAX_PLATES; i++ )
|
||||
m_apPlateMaterials[i] = nullptr;
|
||||
CCustomCarPlateMgr::SetupClump(reinterpret_cast<RpClump*>(pRwObject), m_apPlateMaterials);
|
||||
}
|
||||
|
||||
RpAtomic* CVehicleModelInfo::GetEditableMaterialListCB(RpAtomic* pAtomic, void* pData)
|
||||
void CCustomCarPlateMgr::PollPlates( RpClump* clump, RpMaterial** materials )
|
||||
{
|
||||
RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), GetEditableMaterialListCB, pData);
|
||||
return pAtomic;
|
||||
}
|
||||
RpMaterial** carplates = materials;
|
||||
RpMaterial** carpbacks = materials+NUM_MAX_PLATES;
|
||||
|
||||
RpMaterial* CVehicleModelInfo::GetEditableMaterialListCB(RpMaterial* pMaterial, void* pData)
|
||||
{
|
||||
if ( RpMaterialGetTexture(pMaterial) )
|
||||
{
|
||||
if ( !strncmp(RwTextureGetName(RpMaterialGetTexture(pMaterial)), "vehiclegrunge256", 16) )
|
||||
{
|
||||
std::pair<CVehicleModelInfo*,int>* pMats = static_cast<std::pair<CVehicleModelInfo*,int>*>(pData);
|
||||
int numCarplates = 0, numCarpbacks = 0;
|
||||
|
||||
if ( pMats->second < 32 )
|
||||
pMats->first->m_apDirtMaterials[pMats->second++] = pMaterial;
|
||||
}
|
||||
}
|
||||
return pMaterial;
|
||||
}
|
||||
|
||||
// TODO: FIX IT
|
||||
typedef std::tuple<RpMaterial**, RpMaterial**, int, int> PlateDataTuple;
|
||||
static RpMaterial* PollPlateData(RpMaterial* pMaterial, void* pData)
|
||||
{
|
||||
if ( RwTexture* pTexture = RpMaterialGetTexture(pMaterial) )
|
||||
{
|
||||
const char* pTexName = RwTextureGetName(pTexture);
|
||||
if ( pTexName )
|
||||
{
|
||||
if ( !_strnicmp(pTexName, "carplate", 8) )
|
||||
RpClumpForAllAtomics( clump, [carplates, carpbacks, &numCarplates, &numCarpbacks] ( RpAtomic* atomic ) -> RpAtomic* {
|
||||
RpGeometryForAllMaterials( RpAtomicGetGeometry(atomic), [&] ( RpMaterial* material ) -> RpMaterial* {
|
||||
if ( RwTexture* texture = RpMaterialGetTexture(material) )
|
||||
{
|
||||
auto& pCallbackData = *static_cast<PlateDataTuple*>(pData);
|
||||
|
||||
assert(std::get<2>(pCallbackData) < NUM_MAX_PLATES);
|
||||
if ( std::get<2>(pCallbackData) < NUM_MAX_PLATES )
|
||||
if ( const char* texName = RwTextureGetName(texture) )
|
||||
{
|
||||
// Append data
|
||||
for ( auto ptr = std::get<0>(pCallbackData); *ptr; ptr++ )
|
||||
if ( _strnicmp( texName, "carplate", 8 ) == 0 )
|
||||
{
|
||||
if ( *ptr == pMaterial )
|
||||
return pMaterial;
|
||||
assert(numCarplates < NUM_MAX_PLATES);
|
||||
if ( numCarplates < NUM_MAX_PLATES );
|
||||
{
|
||||
carplates[numCarplates++] = material;
|
||||
}
|
||||
}
|
||||
else if ( _strnicmp( texName, "carpback", 8 ) == 0 )
|
||||
{
|
||||
assert(numCarpbacks < NUM_MAX_PLATES);
|
||||
if ( numCarpbacks < NUM_MAX_PLATES );
|
||||
{
|
||||
carpbacks[numCarpbacks++] = material;
|
||||
}
|
||||
}
|
||||
|
||||
while ( std::get<0>(pCallbackData)[std::get<2>(pCallbackData)] )
|
||||
std::get<2>(pCallbackData)++;
|
||||
|
||||
std::get<0>(pCallbackData)[std::get<2>(pCallbackData)++] = pMaterial;
|
||||
}
|
||||
}
|
||||
else if ( !_strnicmp(pTexName, "carpback", 8) )
|
||||
{
|
||||
auto& pCallbackData = *static_cast<PlateDataTuple*>(pData);
|
||||
|
||||
assert(std::get<3>(pCallbackData) < NUM_MAX_PLATES);
|
||||
if ( std::get<3>(pCallbackData) < NUM_MAX_PLATES )
|
||||
{
|
||||
// Append data
|
||||
for ( auto ptr = std::get<0>(pCallbackData); *ptr; ptr++ )
|
||||
{
|
||||
if ( *ptr == pMaterial )
|
||||
return pMaterial;
|
||||
}
|
||||
|
||||
while ( std::get<1>(pCallbackData)[std::get<3>(pCallbackData)] )
|
||||
std::get<3>(pCallbackData)++;
|
||||
|
||||
std::get<1>(pCallbackData)[std::get<3>(pCallbackData)] = pMaterial;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pMaterial;
|
||||
}
|
||||
|
||||
static RpAtomic* PollPlateData(RpAtomic* pAtomic, void* pData)
|
||||
{
|
||||
RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), PollPlateData, pData);
|
||||
return pAtomic;
|
||||
}
|
||||
|
||||
static RpMaterial* SetPlateData(RpMaterial* pMaterial, void* pData)
|
||||
{
|
||||
if ( RwTexture* pTexture = RpMaterialGetTexture(pMaterial) )
|
||||
{
|
||||
if ( RwTextureGetName(pTexture) )
|
||||
{
|
||||
if ( !_strnicmp(RwTextureGetName(pTexture), "carplate", 8) )
|
||||
{
|
||||
auto& pCallbackData = *static_cast<std::pair<RwTexture*,signed char>*>(pData);
|
||||
|
||||
RpMaterialSetTexture(pMaterial, pCallbackData.first);
|
||||
}
|
||||
else if ( !_strnicmp(RwTextureGetName(pTexture), "carpback", 8) )
|
||||
{
|
||||
auto& pCallbackData = *static_cast<std::pair<RwTexture*,signed char>*>(pData);
|
||||
|
||||
CCustomCarPlateMgr::SetupMaterialPlatebackTexture(pMaterial, pCallbackData.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return pMaterial;
|
||||
}
|
||||
|
||||
static RpAtomic* SetPlateData(RpAtomic* pAtomic, void* pData)
|
||||
{
|
||||
RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), SetPlateData, pData);
|
||||
return pAtomic;
|
||||
return material;
|
||||
} );
|
||||
return atomic;
|
||||
} );
|
||||
}
|
||||
|
||||
void CCustomCarPlateMgr::SetupClump(RpClump* pClump, RpMaterial** pMatsArray)
|
||||
{
|
||||
// Split pMatsArray
|
||||
PlateDataTuple CallbackData = std::make_tuple(pMatsArray, pMatsArray+NUM_MAX_PLATES, 0, 0);
|
||||
|
||||
RpClumpForAllAtomics(pClump, PollPlateData, &CallbackData);
|
||||
PollPlates( pClump, pMatsArray );
|
||||
}
|
||||
|
||||
void CCustomCarPlateMgr::SetupClumpAfterVehicleUpgrade(RpClump* pClump, RpMaterial** pMatsArray, signed char nDesign)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(nDesign);
|
||||
if ( pMatsArray )
|
||||
if ( pMatsArray != nullptr )
|
||||
{
|
||||
// Split pMatsArray
|
||||
PlateDataTuple CallbackData = std::make_tuple(pMatsArray, pMatsArray+NUM_MAX_PLATES, 0, 0);
|
||||
|
||||
RpClumpForAllAtomics(pClump, PollPlateData, &CallbackData);
|
||||
PollPlates( pClump, pMatsArray );
|
||||
}
|
||||
}
|
||||
|
||||
void CCustomCarPlateMgr::SetupPlates(RpClump* pClump, RwTexture* pTexture, signed char nDesign)
|
||||
{
|
||||
std::pair<RwTexture*,signed char> CallbackData = std::make_pair(pTexture, nDesign);
|
||||
|
||||
RpClumpForAllAtomics(pClump, SetPlateData, &CallbackData);
|
||||
}
|
|
@ -292,25 +292,17 @@ public:
|
|||
|
||||
void FindEditableMaterialList();
|
||||
void SetCarCustomPlate();
|
||||
|
||||
static RpAtomic* GetEditableMaterialListCB(RpAtomic* pAtomic, void* pData);
|
||||
static RpMaterial* GetEditableMaterialListCB(RpMaterial* pMaterial, void* pData);
|
||||
};
|
||||
|
||||
extern CBaseModelInfo** const ms_modelInfoPtrs;
|
||||
extern const uint32_t m_numModelInfoPtrs;
|
||||
|
||||
#define NUM_MAX_PLATES 12
|
||||
|
||||
class CCustomCarPlateMgr
|
||||
{
|
||||
// Pretty much rewritten for SilentPatch
|
||||
private:
|
||||
//static RpMaterial** m_pMaterialsWeWorkingWith;
|
||||
//static unsigned char m_nCurPlateMaterial, m_nCurPlateBackMaterial;
|
||||
//static signed char m_nCurPlateDesign;
|
||||
|
||||
public:
|
||||
static const size_t NUM_MAX_PLATES = 12;
|
||||
|
||||
static RwTexture* (*CreatePlateTexture)(const char* pText, signed char nDesign);
|
||||
static bool (*GeneratePlateText)(char* pBuf, int nLen);
|
||||
static signed char (*GetMapRegionPlateDesign)();
|
||||
|
@ -319,7 +311,8 @@ public:
|
|||
static void SetupClump(RpClump* pClump, RpMaterial** pMatsArray);
|
||||
static void SetupClumpAfterVehicleUpgrade(RpClump* pClump, RpMaterial** pMatsArray, signed char nDesign);
|
||||
|
||||
static void SetupPlates(RpClump* pClump, RwTexture* pTexture, signed char nDesign);
|
||||
private:
|
||||
static void PollPlates( RpClump* clump, RpMaterial** materials );
|
||||
};
|
||||
|
||||
static_assert(sizeof(CBaseModelInfo) == 0x20, "Wrong size: CBaseModelInfo");
|
||||
|
|
|
@ -14,16 +14,13 @@ WRAPPER CTaskSimpleJetPack* CPedIntelligence::GetTaskJetPack() const { VARJMP(va
|
|||
static void* varRenderJetPack = AddressByVersion<void*>(0x67F6A0, 0x67FEC0, 0x6AB110);
|
||||
WRAPPER void CTaskSimpleJetPack::RenderJetPack(CPed* pPed) { WRAPARG(pPed); VARJMP(varRenderJetPack); }
|
||||
|
||||
static RwObject* GetFirstObjectCallback(RwObject* pObject, void* pData)
|
||||
{
|
||||
*static_cast<RwObject**>(pData) = pObject;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RwObject* GetFirstObject(RwFrame* pFrame)
|
||||
{
|
||||
RwObject* pObject = nullptr;
|
||||
RwFrameForAllObjects(pFrame, GetFirstObjectCallback, &pObject);
|
||||
RwFrameForAllObjects( pFrame, [&pObject]( RwObject* object ) -> RwObject* {
|
||||
pObject = object;
|
||||
return nullptr;
|
||||
} );
|
||||
return pObject;
|
||||
}
|
||||
|
||||
|
@ -47,13 +44,14 @@ void CPed::RenderWeapon(bool bMuzzleFlash, bool bForShadow)
|
|||
|
||||
RwFrameUpdateObjects(pFrame);
|
||||
if ( bForShadow )
|
||||
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pWeaponObject), ShadowCameraRenderCB, nullptr);
|
||||
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pWeaponObject), ShadowCameraRenderCB);
|
||||
else if ( !bMuzzleFlash )
|
||||
RpClumpRender(reinterpret_cast<RpClump*>(m_pWeaponObject));
|
||||
else if ( m_pMuzzleFlashFrame )
|
||||
{
|
||||
SetGunFlashAlpha(false);
|
||||
RpAtomicRender(reinterpret_cast<RpAtomic*>(GetFirstObject(m_pMuzzleFlashFrame)));
|
||||
RpAtomic* atomic = reinterpret_cast<RpAtomic*>(GetFirstObject(m_pMuzzleFlashFrame));
|
||||
RpAtomicRender( atomic );
|
||||
}
|
||||
|
||||
// Dual weapons
|
||||
|
@ -68,13 +66,14 @@ void CPed::RenderWeapon(bool bMuzzleFlash, bool bForShadow)
|
|||
|
||||
RwFrameUpdateObjects(pFrame);
|
||||
if ( bForShadow )
|
||||
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pWeaponObject), ShadowCameraRenderCB, nullptr);
|
||||
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pWeaponObject), ShadowCameraRenderCB);
|
||||
else if ( !bMuzzleFlash )
|
||||
RpClumpRender(reinterpret_cast<RpClump*>(m_pWeaponObject));
|
||||
else if ( m_pMuzzleFlashFrame )
|
||||
{
|
||||
SetGunFlashAlpha(true);
|
||||
RpAtomicRender(reinterpret_cast<RpAtomic*>(GetFirstObject(m_pMuzzleFlashFrame)));
|
||||
RpAtomic* atomic = reinterpret_cast<RpAtomic*>(GetFirstObject(m_pMuzzleFlashFrame));
|
||||
RpAtomicRender( atomic );
|
||||
}
|
||||
}
|
||||
if ( bMuzzleFlash )
|
||||
|
@ -84,7 +83,7 @@ void CPed::RenderWeapon(bool bMuzzleFlash, bool bForShadow)
|
|||
|
||||
void CPed::RenderForShadow()
|
||||
{
|
||||
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pRwObject), ShadowCameraRenderCB, nullptr);
|
||||
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pRwObject), ShadowCameraRenderCB);
|
||||
RenderWeapon(false, true);
|
||||
|
||||
// Render jetpack
|
||||
|
|
|
@ -261,23 +261,28 @@ static struct
|
|||
|
||||
|
||||
// Regular functions
|
||||
static RpMaterial* AlphaTest(RpMaterial* pMaterial, void* pData)
|
||||
static bool AtomicAlphaTest( RpAtomic* atomic )
|
||||
{
|
||||
if ( RpMaterialGetTexture(pMaterial) )
|
||||
{
|
||||
if ( __rwD3D9TextureHasAlpha(RpMaterialGetTexture(pMaterial)) )
|
||||
bool hasAlpha = false;
|
||||
RpGeometryForAllMaterials( RpAtomicGetGeometry(atomic), [&hasAlpha]( RpMaterial* material ) -> RpMaterial* {
|
||||
if ( RpMaterialGetTexture(material) != nullptr )
|
||||
{
|
||||
*static_cast<BOOL*>(pData) = TRUE;
|
||||
if ( __rwD3D9TextureHasAlpha(RpMaterialGetTexture(material)) )
|
||||
{
|
||||
hasAlpha = true;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else if ( RpMaterialGetColor(material)->alpha < 255 )
|
||||
{
|
||||
hasAlpha = true;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else if ( RpMaterialGetColor(pMaterial)->alpha < 255 )
|
||||
{
|
||||
*static_cast<BOOL*>(pData) = TRUE;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return pMaterial;
|
||||
return material;
|
||||
} );
|
||||
|
||||
return hasAlpha;
|
||||
}
|
||||
|
||||
static RpAtomic* RenderAtomic(RpAtomic* pAtomic, float fComp)
|
||||
|
@ -422,10 +427,7 @@ void RenderVehicleHiDetailAlphaCB_HunterDoor(RpAtomic* pAtomic)
|
|||
template <RpAtomic* renderer(RpAtomic*)>
|
||||
void SetRendererForAtomic(RpAtomic* pAtomic)
|
||||
{
|
||||
BOOL bHasAlpha = FALSE;
|
||||
|
||||
RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), AlphaTest, &bHasAlpha);
|
||||
if ( bHasAlpha )
|
||||
if ( AtomicAlphaTest( pAtomic ) )
|
||||
RpAtomicSetRenderCallBack(pAtomic, renderer);
|
||||
}
|
||||
|
||||
|
@ -487,10 +489,7 @@ void RenderWeaponPedsForPC()
|
|||
template <RpAtomic* renderer(RpAtomic*)>
|
||||
RpAtomic* RenderPedCB(RpAtomic* pAtomic)
|
||||
{
|
||||
BOOL bHasAlpha = FALSE;
|
||||
|
||||
RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), AlphaTest, &bHasAlpha);
|
||||
if ( bHasAlpha )
|
||||
if ( AtomicAlphaTest( pAtomic ) )
|
||||
return renderer(pAtomic);
|
||||
|
||||
return AtomicDefaultRenderCallBack(pAtomic);
|
||||
|
|
|
@ -174,6 +174,7 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio
|
|||
<ClInclude Include="PedSA.h" />
|
||||
<ClInclude Include="PNGFile.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="rwpred.hpp" />
|
||||
<ClInclude Include="ScriptSA.h" />
|
||||
<ClInclude Include="StdAfxSA.h" />
|
||||
<ClInclude Include="TimerSA.h" />
|
||||
|
|
|
@ -140,6 +140,9 @@
|
|||
<ClInclude Include="..\SilentPatch\DelimStringReader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="rwpred.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Shaders.rc">
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "MemoryMgr.h"
|
||||
#include "Maths.h"
|
||||
#include "rwpred.hpp"
|
||||
|
||||
// SA operator delete
|
||||
extern void (*GTAdelete)(void* data);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "StdAfxSA.h"
|
||||
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "VehicleSA.h"
|
||||
|
@ -23,35 +24,50 @@ static int32_t random(int32_t from, int32_t to)
|
|||
return from + ( Int32Rand() % (to-from) );
|
||||
}
|
||||
|
||||
static RwObject* GetCurrentAtomicObjectCB(RwObject* pObject, void* data)
|
||||
static RwObject* GetCurrentAtomicObject( RwFrame* frame )
|
||||
{
|
||||
if ( RpAtomicGetFlags(pObject) & rpATOMICRENDER )
|
||||
{
|
||||
*static_cast<RwObject**>(data) = pObject;
|
||||
return nullptr;
|
||||
}
|
||||
return pObject;
|
||||
RwObject* obj = nullptr;
|
||||
RwFrameForAllObjects( frame, [&obj]( RwObject* object ) -> RwObject* {
|
||||
if ( RpAtomicGetFlags(object) & rpATOMICRENDER )
|
||||
{
|
||||
obj = object;
|
||||
return nullptr;
|
||||
}
|
||||
return object;
|
||||
} );
|
||||
return obj;
|
||||
}
|
||||
|
||||
static RwFrame* GetFrameFromNameCB(RwFrame* pFrame, void* pData)
|
||||
static RwFrame* GetFrameFromName( RwFrame* topFrame, const char* name )
|
||||
{
|
||||
// Is this a frame we want?
|
||||
std::pair<const char*,RwFrame*>* pFindData = static_cast<std::pair<const char*,RwFrame*>*>(pData);
|
||||
if ( !strcmp(pFindData->first, GetFrameNodeName(pFrame)) )
|
||||
class GetFramePredicate
|
||||
{
|
||||
pFindData->second = pFrame;
|
||||
return nullptr;
|
||||
}
|
||||
public:
|
||||
RwFrame* foundFrame = nullptr;
|
||||
|
||||
// Try children
|
||||
RwFrameForAllChildren(pFrame, GetFrameFromNameCB, pData);
|
||||
return !pFindData->second ? pFrame : nullptr;
|
||||
}
|
||||
GetFramePredicate( const char* name )
|
||||
: m_name( name )
|
||||
{
|
||||
}
|
||||
|
||||
static RpMaterial* SetCompAlphaCB(RpMaterial* pMaterial, void* data)
|
||||
{
|
||||
pMaterial->color.alpha = reinterpret_cast<RwUInt8>(data);
|
||||
return pMaterial;
|
||||
RwFrame* operator() ( RwFrame* frame )
|
||||
{
|
||||
if ( strcmp( m_name, GetFrameNodeName(frame) ) == 0 )
|
||||
{
|
||||
foundFrame = frame;
|
||||
return nullptr;
|
||||
}
|
||||
RwFrameForAllChildren( frame, std::ref(*this) );
|
||||
return foundFrame != nullptr ? nullptr : frame;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* const m_name;
|
||||
};
|
||||
|
||||
GetFramePredicate p( name );
|
||||
RwFrameForAllChildren( topFrame, std::ref(p) );
|
||||
return p.foundFrame;
|
||||
}
|
||||
|
||||
void ReadRotorFixExceptions(const wchar_t* pPath)
|
||||
|
@ -73,7 +89,10 @@ void CVehicle::SetComponentAtomicAlpha(RpAtomic* pAtomic, int nAlpha)
|
|||
RpGeometry* pGeometry = RpAtomicGetGeometry(pAtomic);
|
||||
pGeometry->flags |= rpGEOMETRYMODULATEMATERIALCOLOR;
|
||||
|
||||
RpGeometryForAllMaterials(pGeometry, SetCompAlphaCB, reinterpret_cast<void*>(nAlpha));
|
||||
RpGeometryForAllMaterials( pGeometry, [nAlpha] (RpMaterial* material) {
|
||||
material->color.alpha = RwUInt8(nAlpha);
|
||||
return material;
|
||||
} );
|
||||
}
|
||||
|
||||
bool CVehicle::CustomCarPlate_TextureCreate(CVehicleModelInfo* pModelInfo)
|
||||
|
@ -93,7 +112,7 @@ bool CVehicle::CustomCarPlate_TextureCreate(CVehicleModelInfo* pModelInfo)
|
|||
else if ( IsLawEnforcementVehicle() )
|
||||
PlateDesign = CCustomCarPlateMgr::GetMapRegionPlateDesign();
|
||||
else
|
||||
PlateDesign = random(0, 20) == 0 ? random(0, 3) : CCustomCarPlateMgr::GetMapRegionPlateDesign();
|
||||
PlateDesign = random(0, 20) == 0 ? int8_t(random(0, 3)) : CCustomCarPlateMgr::GetMapRegionPlateDesign();
|
||||
|
||||
assert(PlateDesign >= 0 && PlateDesign < 3);
|
||||
|
||||
|
@ -103,53 +122,21 @@ bool CVehicle::CustomCarPlate_TextureCreate(CVehicleModelInfo* pModelInfo)
|
|||
return true;
|
||||
}
|
||||
|
||||
//static RwTexture* pPushedTextures[NUM_MAX_PLATES];
|
||||
|
||||
void CVehicle::CustomCarPlate_BeforeRenderingStart(CVehicleModelInfo* pModelInfo)
|
||||
{
|
||||
//CCustomCarPlateMgr::SetupPlates(reinterpret_cast<RpClump*>(pModelInfo->pRwObject), PlateTexture, PlateDesign);
|
||||
for ( ptrdiff_t i = 0; i < NUM_MAX_PLATES; i++ )
|
||||
for ( ptrdiff_t i = 0; i < CCustomCarPlateMgr::NUM_MAX_PLATES; i++ )
|
||||
{
|
||||
if ( pModelInfo->m_apPlateMaterials[i] )
|
||||
if ( pModelInfo->m_apPlateMaterials[i] != nullptr )
|
||||
{
|
||||
//RwTexture* pPlateTex = RpMaterialGetTexture(pModelInfo->m_apPlateMaterials[i]);
|
||||
|
||||
//RwTextureAddRef(pPlateTex);
|
||||
//pPushedTextures[i] = pPlateTex;
|
||||
|
||||
RpMaterialSetTexture(pModelInfo->m_apPlateMaterials[i], PlateTexture);
|
||||
}
|
||||
|
||||
if ( pModelInfo->m_apPlateMaterials[NUM_MAX_PLATES+i] )
|
||||
CCustomCarPlateMgr::SetupMaterialPlatebackTexture(pModelInfo->m_apPlateMaterials[NUM_MAX_PLATES+i], PlateDesign);
|
||||
//RwTexture* pPlatebackTex = RpMaterialGetTexture(pModelInfo->m_apPlateMaterials[4+i]);
|
||||
|
||||
//RwTextureAddRef(pPlatebackTex);
|
||||
//pPushedTextures[4+i] = pPlateTex;
|
||||
|
||||
//RpMaterialSetTexture(pModelInfo->m_apPlateMaterials[i], PlateTexture);
|
||||
}
|
||||
}
|
||||
|
||||
// This is not needed
|
||||
/*void CVehicle::CustomCarPlate_AfterRenderingStop(CVehicleModelInfo* pModelInfo)
|
||||
{
|
||||
for ( int i = 0; i < NUM_MAX_PLATES; i++ )
|
||||
{
|
||||
if ( pModelInfo->m_apPlateMaterials[i] )
|
||||
if ( pModelInfo->m_apPlateMaterials[CCustomCarPlateMgr::NUM_MAX_PLATES+i] != nullptr )
|
||||
{
|
||||
//RwTexture* pPlateTex = RpMaterialGetTexture(pModelInfo->m_apPlateMaterials[i]);
|
||||
|
||||
//RwTextureAddRef(pPlateTex);
|
||||
//pPushedTextures[i] = pPlateTex;
|
||||
|
||||
//RpMaterialSetTexture(pModelInfo->m_apPlateMaterials[i], pPushedTextures[i]);
|
||||
//RwTextureDestroy(pPushedTextures[i]);
|
||||
//pPushedTextures[i] = nullptr;
|
||||
CCustomCarPlateMgr::SetupMaterialPlatebackTexture(pModelInfo->m_apPlateMaterials[CCustomCarPlateMgr::NUM_MAX_PLATES+i], PlateDesign);
|
||||
}
|
||||
}
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
void CHeli::Render()
|
||||
{
|
||||
|
@ -172,35 +159,31 @@ void CHeli::Render()
|
|||
int nStaticRotorAlpha = static_cast<int>(std::min((1.5-dRotorsSpeed) * 255.0, 255.0));
|
||||
int nMovingRotorAlpha = static_cast<int>(std::min(dMovingRotorSpeed * 175.0, 175.0));
|
||||
|
||||
if ( m_pCarNode[12] )
|
||||
if ( m_pCarNode[12] != nullptr )
|
||||
{
|
||||
RpAtomic* pOutAtomic = nullptr;
|
||||
RwFrameForAllObjects(m_pCarNode[12], GetCurrentAtomicObjectCB, &pOutAtomic);
|
||||
if ( pOutAtomic )
|
||||
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[12] );
|
||||
if ( pOutAtomic != nullptr )
|
||||
SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor ? nStaticRotorAlpha : 255);
|
||||
}
|
||||
|
||||
if ( m_pCarNode[14] )
|
||||
if ( m_pCarNode[14] != nullptr )
|
||||
{
|
||||
RpAtomic* pOutAtomic = nullptr;
|
||||
RwFrameForAllObjects(m_pCarNode[14], GetCurrentAtomicObjectCB, &pOutAtomic);
|
||||
if ( pOutAtomic )
|
||||
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[14] );
|
||||
if ( pOutAtomic != nullptr )
|
||||
SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor2 ? nStaticRotorAlpha : 255);
|
||||
}
|
||||
|
||||
if ( m_pCarNode[13] )
|
||||
if ( m_pCarNode[13] != nullptr )
|
||||
{
|
||||
RpAtomic* pOutAtomic = nullptr;
|
||||
RwFrameForAllObjects(m_pCarNode[13], GetCurrentAtomicObjectCB, &pOutAtomic);
|
||||
if ( pOutAtomic )
|
||||
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[13] );
|
||||
if ( pOutAtomic != nullptr )
|
||||
SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor ? nMovingRotorAlpha : 0);
|
||||
}
|
||||
|
||||
if ( m_pCarNode[15] )
|
||||
if ( m_pCarNode[15] != nullptr )
|
||||
{
|
||||
RpAtomic* pOutAtomic = nullptr;
|
||||
RwFrameForAllObjects(m_pCarNode[15], GetCurrentAtomicObjectCB, &pOutAtomic);
|
||||
if ( pOutAtomic )
|
||||
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[15] );
|
||||
if ( pOutAtomic != nullptr )
|
||||
SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor2 ? nMovingRotorAlpha : 0);
|
||||
}
|
||||
|
||||
|
@ -228,35 +211,31 @@ void CPlane::Render()
|
|||
int nStaticRotorAlpha = static_cast<int>(std::min((1.5-dRotorsSpeed) * 255.0, 255.0));
|
||||
int nMovingRotorAlpha = static_cast<int>(std::min(dMovingRotorSpeed * 175.0, 175.0));
|
||||
|
||||
if ( m_pCarNode[12] )
|
||||
if ( m_pCarNode[12] != nullptr )
|
||||
{
|
||||
RpAtomic* pOutAtomic = nullptr;
|
||||
RwFrameForAllObjects(m_pCarNode[12], GetCurrentAtomicObjectCB, &pOutAtomic);
|
||||
if ( pOutAtomic )
|
||||
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[12] );
|
||||
if ( pOutAtomic != nullptr )
|
||||
SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp ? nStaticRotorAlpha : 255);
|
||||
}
|
||||
|
||||
if ( m_pCarNode[14] )
|
||||
if ( m_pCarNode[14] != nullptr )
|
||||
{
|
||||
RpAtomic* pOutAtomic = nullptr;
|
||||
RwFrameForAllObjects(m_pCarNode[14], GetCurrentAtomicObjectCB, &pOutAtomic);
|
||||
if ( pOutAtomic )
|
||||
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[14] );
|
||||
if ( pOutAtomic != nullptr )
|
||||
SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp2 ? nStaticRotorAlpha : 255);
|
||||
}
|
||||
|
||||
if ( m_pCarNode[13] )
|
||||
if ( m_pCarNode[13] != nullptr )
|
||||
{
|
||||
RpAtomic* pOutAtomic = nullptr;
|
||||
RwFrameForAllObjects(m_pCarNode[13], GetCurrentAtomicObjectCB, &pOutAtomic);
|
||||
if ( pOutAtomic )
|
||||
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[13] );
|
||||
if ( pOutAtomic != nullptr )
|
||||
SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp ? nMovingRotorAlpha : 0);
|
||||
}
|
||||
|
||||
if ( m_pCarNode[15] )
|
||||
if ( m_pCarNode[15] != nullptr )
|
||||
{
|
||||
RpAtomic* pOutAtomic = nullptr;
|
||||
RwFrameForAllObjects(m_pCarNode[15], GetCurrentAtomicObjectCB, &pOutAtomic);
|
||||
if ( pOutAtomic )
|
||||
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[15] );
|
||||
if ( pOutAtomic != nullptr )
|
||||
SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp2 ? nMovingRotorAlpha : 0);
|
||||
}
|
||||
|
||||
|
@ -288,22 +267,19 @@ void CAutomobile::Fix_SilentPatch()
|
|||
void CAutomobile::ResetFrames()
|
||||
{
|
||||
RpClump* pOrigClump = reinterpret_cast<RpClump*>(ms_modelInfoPtrs[m_nModelIndex]->pRwObject);
|
||||
if ( pOrigClump )
|
||||
if ( pOrigClump != nullptr )
|
||||
{
|
||||
// Instead of setting frame rotation to (0,0,0) like R* did, obtain the original frame matrix from CBaseNodelInfo clump
|
||||
for ( ptrdiff_t i = 8; i < 25; i++ )
|
||||
{
|
||||
if ( m_pCarNode[i] )
|
||||
if ( m_pCarNode[i] != nullptr )
|
||||
{
|
||||
// Find a frame in CBaseModelInfo object
|
||||
std::pair<const char*,RwFrame*> FindData = std::make_pair(GetFrameNodeName(m_pCarNode[i]), nullptr);
|
||||
|
||||
RwFrameForAllChildren(RpClumpGetFrame(pOrigClump), GetFrameFromNameCB, &FindData);
|
||||
|
||||
if ( FindData.second )
|
||||
RwFrame* origFrame = GetFrameFromName( RpClumpGetFrame(pOrigClump), GetFrameNodeName(m_pCarNode[i]) );
|
||||
if ( origFrame != nullptr )
|
||||
{
|
||||
// Found a frame, reset it
|
||||
*RwFrameGetMatrix(m_pCarNode[i]) = *RwFrameGetMatrix(FindData.second);
|
||||
*RwFrameGetMatrix(m_pCarNode[i]) = *RwFrameGetMatrix(origFrame);
|
||||
RwMatrixUpdate(RwFrameGetMatrix(m_pCarNode[i]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ protected:
|
|||
CEntity* pDamagingEntity;
|
||||
BYTE __pad3[116];
|
||||
char padpad, padpad2, padpad3;
|
||||
signed char PlateDesign;
|
||||
int8_t PlateDesign;
|
||||
RwTexture* PlateTexture;
|
||||
BYTE __pad5[20];
|
||||
|
||||
|
|
49
SilentPatchSA/rwpred.hpp
Normal file
49
SilentPatchSA/rwpred.hpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include <rwcore.h>
|
||||
#include <rpworld.h>
|
||||
|
||||
template <typename Pred>
|
||||
RwFrame* RwFrameForAllChildren(RwFrame* frame, Pred callback)
|
||||
{
|
||||
for ( RwFrame* curFrame = frame->child; curFrame != nullptr; curFrame = curFrame->next )
|
||||
{
|
||||
if ( callback(curFrame) == nullptr )
|
||||
break;
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
template <typename Pred>
|
||||
RwFrame* RwFrameForAllObjects(RwFrame* frame, Pred callback)
|
||||
{
|
||||
for ( RwLLLink* link = rwLinkListGetFirstLLLink(&frame->objectList); link != rwLinkListGetTerminator(&frame->objectList); link = rwLLLinkGetNext(link) )
|
||||
{
|
||||
if ( callback(&rwLLLinkGetData(link, RwObjectHasFrame, lFrame)->object) == nullptr )
|
||||
break;
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
template <typename Pred>
|
||||
RpClump* RpClumpForAllAtomics(RpClump* clump, Pred callback)
|
||||
{
|
||||
for ( RwLLLink* link = rwLinkListGetFirstLLLink(&clump->atomicList); link != rwLinkListGetTerminator(&clump->atomicList); link = rwLLLinkGetNext(link) )
|
||||
{
|
||||
if ( callback(rwLLLinkGetData(link, RpAtomic, inClumpLink)) == nullptr )
|
||||
break;
|
||||
}
|
||||
return clump;
|
||||
}
|
||||
|
||||
template <typename Pred>
|
||||
RpGeometry* RpGeometryForAllMaterials(RpGeometry* geometry, Pred callback)
|
||||
{
|
||||
for ( RwInt32 i = 0, j = geometry->matList.numMaterials; i < j; i++ )
|
||||
{
|
||||
if ( callback(geometry->matList.materials[i]) == nullptr )
|
||||
break;
|
||||
}
|
||||
return geometry;
|
||||
}
|
|
@ -5,8 +5,8 @@
|
|||
<SILENTPATCH_NAME>SilentPatchSA</SILENTPATCH_NAME>
|
||||
<SILENTPATCH_EXT>.asi</SILENTPATCH_EXT>
|
||||
<SILENTPATCH_FULL_NAME>SilentPatch for San Andreas</SILENTPATCH_FULL_NAME>
|
||||
<SILENTPATCH_REVISION_ID>28</SILENTPATCH_REVISION_ID>
|
||||
<SILENTPATCH_BUILD_ID>5</SILENTPATCH_BUILD_ID>
|
||||
<SILENTPATCH_REVISION_ID>29</SILENTPATCH_REVISION_ID>
|
||||
<SILENTPATCH_BUILD_ID>0</SILENTPATCH_BUILD_ID>
|
||||
<SILENTPATCH_COPYRIGHT>2014-2017</SILENTPATCH_COPYRIGHT>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup />
|
||||
|
|
Loading…
Reference in a new issue