|
|
@@ -21,13 +21,18 @@ WRAPPER void CShadowCamera::InvertRaster() { EAXJMP(0x705660); } |
|
WRAPPER void CRealTimeShadow::Destroy() { EAXJMP(0x705990); }
|
|
WRAPPER void CRealTimeShadow::Destroy() { EAXJMP(0x705990); }
|
|
WRAPPER bool CRealTimeShadow::SetShadowedObject(CPhysical* pObject) { WRAPARG(pObject); EAXJMP(0x706520); }
|
|
WRAPPER bool CRealTimeShadow::SetShadowedObject(CPhysical* pObject) { WRAPARG(pObject); EAXJMP(0x706520); }
|
|
|
|
|
|
CShadowCamera CRealTimeShadowManager::m_BlurCamera_Player;
|
|
RpAtomic* ShadowCameraRenderCB(RpAtomic* pAtomic, void* pData)
|
|
CShadowCamera CRealTimeShadowManager::m_GradientCamera_Player;
|
|
|
|
|
|
|
|
static RpAtomic* ShadowCameraRenderCallback(RpAtomic* pAtomic, void* pData)
|
|
|
|
{
|
|
{
|
|
UNREFERENCED_PARAMETER(pData);
|
|
UNREFERENCED_PARAMETER(pData);
|
|
return AtomicDefaultRenderCallBack(pAtomic);
|
|
|
|
|
|
RpGeometry* pGeometry = RpAtomicGetGeometry(pAtomic);
|
|
|
|
RwUInt32 geometryFlags = RpGeometryGetFlags(pGeometry);
|
|
|
|
RpGeometrySetFlags(pGeometry, geometryFlags & ~(rpGEOMETRYTEXTURED|rpGEOMETRYPRELIT|
|
|
|
|
rpGEOMETRYLIGHT|rpGEOMETRYMODULATEMATERIALCOLOR|rpGEOMETRYTEXTURED2));
|
|
|
|
|
|
|
|
auto* pOut = AtomicDefaultRenderCallBack(pAtomic);
|
|
|
|
RpGeometrySetFlags(pGeometry, geometryFlags);
|
|
|
|
return pOut;
|
|
}
|
|
}
|
|
|
|
|
|
void CShadowCamera::ReInit()
|
|
void CShadowCamera::ReInit()
|
|
|
@@ -42,61 +47,35 @@ void CShadowCamera::ReInit() |
|
RwTextureSetRaster(m_pTexture, pNewRaster);
|
|
RwTextureSetRaster(m_pTexture, pNewRaster);
|
|
}
|
|
}
|
|
|
|
|
|
RwCamera* CShadowCamera::Update(RpClump* pClump, CPed* pPed)
|
|
static RpAtomic* PushGeometryFlags(RpAtomic* pAtomic, void* pData)
|
|
|
|
{
|
|
|
|
std::pair<RwUInt32*, RwUInt32>** pGeometryStack = static_cast<std::pair<RwUInt32*, RwUInt32>**>(pData);
|
|
|
|
RpGeometry* pGeometry = RpAtomicGetGeometry(pAtomic);
|
|
|
|
|
|
|
|
*((*pGeometryStack)++) = std::make_pair(&RpGeometryGetFlags(pGeometry), RpGeometryGetFlags(pGeometry));
|
|
|
|
return pAtomic;
|
|
|
|
}
|
|
|
|
|
|
|
|
RwCamera* CShadowCamera::Update(RpClump* pClump, CPhysical* pEntity)
|
|
{
|
|
{
|
|
RwRGBA ClearColour = { 255, 255, 255, 0 };
|
|
RwRGBA ClearColour = { 255, 255, 255, 0 };
|
|
RwCameraClear(m_pCamera, &ClearColour, rwCAMERACLEARIMAGE|rwCAMERACLEARZ);
|
|
RwCameraClear(m_pCamera, &ClearColour, rwCAMERACLEARIMAGE|rwCAMERACLEARZ);
|
|
|
|
|
|
if ( RwCameraBeginUpdate(m_pCamera ) )
|
|
if ( RwCameraBeginUpdate(m_pCamera ) )
|
|
{
|
|
{
|
|
RpGeometry* pGeometry = RpAtomicGetGeometry(GetFirstAtomic(pClump));
|
|
//std::pair<RwUInt32*, RwUInt32> GeometryFlagsPair[32];
|
|
auto geometryFlags = RpGeometryGetFlags(pGeometry);
|
|
|
|
|
|
|
|
RpGeometrySetFlags(pGeometry, geometryFlags & ~(rpGEOMETRYTEXTURED|rpGEOMETRYPRELIT|
|
|
//RpGeometry* pGeometry = RpAtomicGetGeometry(GetFirstAtomic(pClump));
|
|
rpGEOMETRYLIGHT|rpGEOMETRYMODULATEMATERIALCOLOR|rpGEOMETRYTEXTURED2));
|
|
//RwUInt32 geometryFlags = RpGeometryGetFlags(pGeometry);
|
|
RpClumpForAllAtomics(pClump, ShadowCameraRenderCallback, nullptr);
|
|
|
|
RpGeometrySetFlags(pGeometry, geometryFlags);
|
|
|
|
|
|
|
|
if ( pPed )
|
|
//RpGeometrySetFlags(pGeometry, geometryFlags & ~(rpGEOMETRYTEXTURED|rpGEOMETRYPRELIT|
|
|
|
|
// rpGEOMETRYLIGHT|rpGEOMETRYMODULATEMATERIALCOLOR|rpGEOMETRYTEXTURED2));
|
|
|
|
if ( pEntity )
|
|
{
|
|
{
|
|
if ( pPed->m_pWeaponObject )
|
|
if ( pEntity->nType == 3 )
|
|
{
|
|
static_cast<CPed*>(pEntity)->RenderForShadow(pClump);
|
|
RpHAnimHierarchy* pAnimHierarchy = GetAnimHierarchyFromSkinClump(pClump);
|
|
else if ( pEntity->nType == 2 )
|
|
bool bHasParachute = pPed->weaponSlots[pPed->m_bActiveWeapon].m_eWeaponType == WEAPONTYPE_PARACHUTE;
|
|
static_cast<CVehicle*>(pEntity)->RenderForShadow(pClump);
|
|
|
|
|
|
RwFrame* pFrame = RpClumpGetFrame(reinterpret_cast<RpClump*>(pPed->m_pWeaponObject));
|
|
|
|
*RwFrameGetMatrix(pFrame) = RpHAnimHierarchyGetMatrixArray(pAnimHierarchy)[RpHAnimIDGetIndex(pAnimHierarchy, bHasParachute ? 3 : 24)];
|
|
|
|
|
|
|
|
if ( bHasParachute )
|
|
|
|
{
|
|
|
|
const RwV3d vecParachuteTranslation = { 0.1f, -0.15f, 0.0f };
|
|
|
|
const RwV3d vecParachuteRotation = { 0.0f, 1.0f, 0.0f };
|
|
|
|
RwMatrixTranslate(RwFrameGetMatrix(pFrame), &vecParachuteTranslation, rwCOMBINEPRECONCAT);
|
|
|
|
RwMatrixRotate(RwFrameGetMatrix(pFrame), &vecParachuteRotation, 90.0f, rwCOMBINEPRECONCAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
RwFrameUpdateObjects(pFrame);
|
|
|
|
AtomicDefaultRenderCallBack(GetFirstAtomic(reinterpret_cast<RpClump*>(pPed->m_pWeaponObject)));
|
|
|
|
|
|
|
|
// Dual weapons
|
|
|
|
if ( CWeaponInfo::GetWeaponInfo(pPed->weaponSlots[pPed->m_bActiveWeapon].m_eWeaponType, pPed->GetWeaponSkill())->hexFlags >> 11 & 1 )
|
|
|
|
{
|
|
|
|
*RwFrameGetMatrix(pFrame) = RpHAnimHierarchyGetMatrixArray(pAnimHierarchy)[RpHAnimIDGetIndex(pAnimHierarchy, 34)];
|
|
|
|
|
|
|
|
const RwV3d vecParachuteRotation = { 1.0f, 0.0f, 0.0f };
|
|
|
|
const RwV3d vecParachuteTranslation = { 0.04f, -0.05f, 0.0f };
|
|
|
|
RwMatrixRotate(RwFrameGetMatrix(pFrame), &vecParachuteRotation, 180.0f, rwCOMBINEPRECONCAT);
|
|
|
|
RwMatrixTranslate(RwFrameGetMatrix(pFrame), &vecParachuteTranslation, rwCOMBINEPRECONCAT);
|
|
|
|
|
|
|
|
RwFrameUpdateObjects(pFrame);
|
|
|
|
AtomicDefaultRenderCallBack(GetFirstAtomic(reinterpret_cast<RpClump*>(pPed->m_pWeaponObject)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Render jetpack
|
|
|
|
auto* pJetPackTask = pPed->GetPedIntelligencePtr()->GetTaskJetPack();
|
|
|
|
if ( pJetPackTask )
|
|
|
|
pJetPackTask->RenderJetPack(pPed);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
InvertRaster();
|
|
InvertRaster();
|
|
|
@@ -116,18 +95,18 @@ RwTexture* CRealTimeShadow::Update() |
|
if ( m_nRwObjectType == rpATOMIC )
|
|
if ( m_nRwObjectType == rpATOMIC )
|
|
m_Camera.Update(reinterpret_cast<RpAtomic*>(m_pEntity->m_pRwObject));
|
|
m_Camera.Update(reinterpret_cast<RpAtomic*>(m_pEntity->m_pRwObject));
|
|
else if ( m_nRwObjectType == rpCLUMP )
|
|
else if ( m_nRwObjectType == rpCLUMP )
|
|
m_Camera.Update(reinterpret_cast<RpClump*>(m_pEntity->m_pRwObject), m_pEntity->nType == 3 ? static_cast<CPed*>(m_pEntity) : nullptr);
|
|
m_Camera.Update(reinterpret_cast<RpClump*>(m_pEntity->m_pRwObject), m_pEntity);
|
|
|
|
|
|
RwRaster* pRaster = RwCameraGetRaster(m_Camera.m_pCamera);
|
|
RwRaster* pRaster = RwCameraGetRaster(m_Camera.m_pCamera);
|
|
|
|
|
|
if ( m_bDrawResample )
|
|
if ( m_bDrawResample )
|
|
pRaster = m_ResampledCamera.RasterResample(pRaster);
|
|
pRaster = m_ResampledCamera.RasterResample(pRaster);
|
|
|
|
|
|
if ( m_dwBlurPasses )
|
|
if ( m_dwBlurPasses )
|
|
pRaster = m_bUsePlayerHelperCams ? CRealTimeShadowManager::m_BlurCamera_Player.RasterBlur(pRaster, m_dwBlurPasses) : g_realTimeShadowMan.m_BlurCamera.RasterBlur(pRaster, m_dwBlurPasses);
|
|
pRaster = m_bUsePlayerHelperCams ? g_realTimeShadowMan.m_BlurCamera_Player.RasterBlur(pRaster, m_dwBlurPasses) : g_realTimeShadowMan.m_BlurCamera.RasterBlur(pRaster, m_dwBlurPasses);
|
|
|
|
|
|
if ( m_bDrawGradient )
|
|
if ( m_bDrawGradient )
|
|
pRaster = m_bUsePlayerHelperCams ? CRealTimeShadowManager::m_GradientCamera_Player.RasterGradient(pRaster) : g_realTimeShadowMan.m_GradientCamera.RasterGradient(pRaster);
|
|
pRaster = m_bUsePlayerHelperCams ? g_realTimeShadowMan.m_GradientCamera_Player.RasterGradient(pRaster) : g_realTimeShadowMan.m_GradientCamera.RasterGradient(pRaster);
|
|
|
|
|
|
return m_bDrawResample ? m_ResampledCamera.m_pTexture : m_Camera.m_pTexture;
|
|
return m_bDrawResample ? m_ResampledCamera.m_pTexture : m_Camera.m_pTexture;
|
|
}
|
|
}
|
|
|
@@ -317,9 +296,10 @@ void CRealTimeShadowManager::GetRealTimeShadow(CPhysical* pEntity) |
|
|
|
|
|
if ( pPlayerPed->pedFlags.bInVehicle )
|
|
if ( pPlayerPed->pedFlags.bInVehicle )
|
|
{
|
|
{
|
|
CVehicle* pVehicle = pPlayerPed->pVehicle;
|
|
/*CVehicle* pVehicle = pPlayerPed->pVehicle;
|
|
if ( pVehicle )
|
|
if ( pVehicle )
|
|
bRender = pVehicle->GetLinearVelocity().MagnitudeSqr() <= 0.3f * 0.3f;
|
|
bRender = pVehicle->GetLinearVelocity().MagnitudeSqr() <= 0.3f * 0.3f;*/
|
|
|
|
bIsPlayer = pPlayerPed->pVehicle == pEntity;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -339,14 +319,28 @@ void CRealTimeShadowManager::GetRealTimeShadow(CPhysical* pEntity) |
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Debug
|
|
|
|
#ifdef DEVBUILD
|
|
|
|
if ( !pOutShadow )
|
|
|
|
{
|
|
|
|
static bool bLimitHit = false;
|
|
|
|
|
|
|
|
if ( !bLimitHit )
|
|
|
|
{
|
|
|
|
assert(!"Too many real time shadows at once, consider increasing limits.");
|
|
|
|
bLimitHit = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
if ( pOutShadow )
|
|
if ( pOutShadow )
|
|
{
|
|
{
|
|
pOutShadow->SetShadowedObject(pEntity);
|
|
pOutShadow->SetShadowedObject(pEntity);
|
|
|
|
pOutShadow->ResetIntensity();
|
|
pEntity->SetRealTimeShadow(pOutShadow);
|
|
pEntity->SetRealTimeShadow(pOutShadow);
|
|
pOutShadow->SetRenderedThisFrame();
|
|
pOutShadow->SetRenderedThisFrame();
|
|
pOutShadow->ResetIntensity();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
@@ -387,4 +381,22 @@ static StaticPatcher Patcher([](){ |
|
Memory::InjectHook(0x706BA0, &CRealTimeShadowManager::DoShadowThisFrame, PATCH_JUMP);
|
|
Memory::InjectHook(0x706BA0, &CRealTimeShadowManager::DoShadowThisFrame, PATCH_JUMP);
|
|
Memory::InjectHook(0x706AC2, &CRealTimeShadowManager::ReInit);
|
|
Memory::InjectHook(0x706AC2, &CRealTimeShadowManager::ReInit);
|
|
Memory::InjectHook(0x706B29, &CRealTimeShadow::Update);
|
|
Memory::InjectHook(0x706B29, &CRealTimeShadow::Update);
|
|
|
|
|
|
|
|
// Increased shadows limit
|
|
|
|
Memory::Patch<const void*>(0x45D412, &g_realTimeShadowMan);
|
|
|
|
Memory::Patch<const void*>(0x53BE63, &g_realTimeShadowMan);
|
|
|
|
Memory::Patch<const void*>(0x53C63F, &g_realTimeShadowMan);
|
|
|
|
Memory::Patch<const void*>(0x53C9E5, &g_realTimeShadowMan);
|
|
|
|
Memory::Patch<const void*>(0x53EA09, &g_realTimeShadowMan);
|
|
|
|
Memory::Patch<const void*>(0x542487, &g_realTimeShadowMan);
|
|
|
|
Memory::Patch<const void*>(0x5B1F38, &g_realTimeShadowMan);
|
|
|
|
Memory::Patch<const void*>(0x5BA478, &g_realTimeShadowMan);
|
|
|
|
Memory::Patch<const void*>(0x5E68A4, &g_realTimeShadowMan);
|
|
|
|
//Memory::Patch<const void*>(0x854980, &g_realTimeShadowMan);
|
|
|
|
//Memory::Patch<const void*>(0x856AD0, &g_realTimeShadowMan);
|
|
|
|
|
|
|
|
Memory::Patch<const void*>(0x5BA137, &g_realTimeShadowMan.m_bNeedsReinit);
|
|
|
|
|
|
|
|
Memory::Patch<DWORD>(0x706AD4, NUM_MAX_REALTIME_SHADOWS);
|
|
|
|
Memory::Patch<DWORD>(0x706B80, NUM_MAX_REALTIME_SHADOWS);
|
|
});
|
|
});
|