diff --git a/VCS PC/Building.cpp b/VCS PC/Building.cpp index 57aad77..07bf8a7 100644 --- a/VCS PC/Building.cpp +++ b/VCS PC/Building.cpp @@ -2,6 +2,8 @@ #include "Building.h" #include "Pools.h" +#include "RealTimeShadowMgr.h" +#include "Shadows.h" void* CBuilding::operator new(size_t size) { @@ -12,4 +14,62 @@ void* CBuilding::operator new(size_t size) void CBuilding::operator delete(void* ptr) { CPools::GetBuildingPool()->Delete(static_cast(ptr)); -} \ No newline at end of file +} + +void CBuilding::PreRender() +{ + CEntity::PreRender(); + CShadows::StoreRealTimeShadowForBuilding(this); +} + +void CBuildingAux::Construct(CBuilding* pParent) +{ + CBuildingAux* pSpace = CPools::GetBuildingPoolAux()->GetAtPointer(pParent); + + // ctor + pSpace->m_pShadow = nullptr; +} + +CBuilding* CBuildingAux::Destruct(CBuilding* pParent) +{ + CBuildingAux* pSpace = CPools::GetBuildingPoolAux()->GetAtPointer(pParent); + + // dtor + if ( pSpace->m_pShadow ) + g_realTimeShadowMan.ReturnRealTimeShadow(pSpace->m_pShadow); + + return pParent; +} + +static void __declspec(naked) CtorHack() +{ + _asm + { + mov dword ptr [esi], 8585C8h + push esi + call CBuildingAux::Construct + add esp, 4 + mov eax, esi + pop esi + retn + } +} + +static void __declspec(naked) DtorHack() +{ + _asm + { + push ecx + call CBuildingAux::Destruct + add esp, 4 + mov ecx, eax + push 535E90h + retn + } +} + +static StaticPatcher Patcher([](){ + Memory::InjectHook(0x403E16, &CtorHack, PATCH_JUMP); + Memory::InjectHook(0x404134, &DtorHack); + Memory::Patch(0x85860C, &CBuilding::PreRender_Stub); + }); \ No newline at end of file diff --git a/VCS PC/Building.h b/VCS PC/Building.h index 9f8fa87..e42047d 100644 --- a/VCS PC/Building.h +++ b/VCS PC/Building.h @@ -20,6 +20,11 @@ class NOVMT CBuilding : public CEntity void* operator new(size_t size); void operator delete(void* ptr); + + inline void PreRender_Stub() + { CBuilding::PreRender(); } + + virtual void PreRender() override; }; @@ -34,4 +39,21 @@ class NOVMT CDummy : public CEntity } }; +class CBuildingAux +{ + friend class CBuilding; + +private: + class CRealTimeShadow* m_pShadow; + +public: + inline class CRealTimeShadow* GetShadow() + { return m_pShadow; } + inline void SetShadow(class CRealTimeShadow* pShadow) + { m_pShadow = pShadow; } + + static void Construct(CBuilding* pParent); + static CBuilding* Destruct(CBuilding* pParent); +}; + #endif \ No newline at end of file diff --git a/VCS PC/EmpireMgr.cpp b/VCS PC/EmpireMgr.cpp index bf24863..70495e4 100644 --- a/VCS PC/EmpireMgr.cpp +++ b/VCS PC/EmpireMgr.cpp @@ -227,9 +227,6 @@ void CEmpire::Place() m_pBuilding[0] = pEmpireBuilding; - // Additional models - CBuilding pAdditionalBuilding[2]; - // TODO: Damaged check for ( int i = 0; i < 2; i++ ) { diff --git a/VCS PC/FileMgr.cpp b/VCS PC/FileMgr.cpp index 4203e11..414cde9 100644 --- a/VCS PC/FileMgr.cpp +++ b/VCS PC/FileMgr.cpp @@ -39,7 +39,16 @@ WRAPPER void CFileLoader::LoadCollisionFile(const char* pFileName, unsigned char static WRAPPER void InitPostIDEStuff() { EAXJMP(0x5B924E); } static WRAPPER void InitPostLoadLevelStuff() { EAXJMP(0x5B930F); } -static WRAPPER void SetAtomicModelInfoFlags(CAtomicModelInfo* pInfo, unsigned int dwFlags) { WRAPARG(pInfo); WRAPARG(dwFlags); EAXJMP(0x5B3B20); } +void SetAtomicModelInfoFlags(CAtomicModelInfo* pInfo, unsigned int dwFlags) +{ + ((void(*)(CAtomicModelInfo*,unsigned int))0x5B3B20)(pInfo, dwFlags); + + // VCS PC flags + + // Project realtime shadow? + if ( dwFlags & 0x40000 ) + pInfo->SetCastShadowFlag(); +} std::string CFileLoader::TranslatePath(const char* pFileName, const char* pDLCName) { @@ -407,4 +416,9 @@ bool CFileLoader::ParseLevelFile(const char* pFileName, char* pDLCName) return true; } return false; -} \ No newline at end of file +} + + +static StaticPatcher Patcher([](){ + Memory::InjectHook(0x5B3F7B, SetAtomicModelInfoFlags); + }); \ No newline at end of file diff --git a/VCS PC/Frontend.cpp b/VCS PC/Frontend.cpp index f33a031..ba7c44a 100644 --- a/VCS PC/Frontend.cpp +++ b/VCS PC/Frontend.cpp @@ -473,6 +473,7 @@ void CMenuManager::SaveSettings() const FxQuality_e nEffectsQuality = Fx_c::GetEffectsQuality(); const unsigned char nFilterQuality = Fx_c::GetTextureFilteringQuality(); const eShadowQuality nShadowQuality = CShadows::GetShadowQuality(); + const float fShadowDist = CShadows::GetShadowDistance(); const RwInt32 nSubSystem = RwEngineGetCurrentSubSystem(); //CFileMgr::Write(hFile, &m_bMipMapping, sizeof(m_bMipMapping)); @@ -481,6 +482,7 @@ void CMenuManager::SaveSettings() CFileMgr::Write(hFile, &nEffectsQuality, sizeof(nEffectsQuality)); CFileMgr::Write(hFile, &nFilterQuality, sizeof(nFilterQuality)); CFileMgr::Write(hFile, &nShadowQuality, sizeof(nShadowQuality)); + CFileMgr::Write(hFile, &fShadowDist, sizeof(fShadowDist)); CFileMgr::Write(hFile, &m_fDrawDistance, sizeof(m_fDrawDistance)); CFileMgr::Write(hFile, &m_bAspectRatioMode, sizeof(m_bAspectRatioMode)); CFileMgr::Write(hFile, &m_bFrameLimiterMode, sizeof(m_bFrameLimiterMode)); @@ -544,6 +546,7 @@ void CMenuManager::LoadSettings() // Graphics Setup FxQuality_e /*nFxQuality, */nEffectsQuality; eShadowQuality nShadowQuality; + float fShadowDist; unsigned char nFilterQuality; //CFileMgr::Read(hFile, &m_bMipMapping, sizeof(m_bMipMapping)); @@ -552,6 +555,7 @@ void CMenuManager::LoadSettings() CFileMgr::Read(hFile, &nEffectsQuality, sizeof(nEffectsQuality)); CFileMgr::Read(hFile, &nFilterQuality, sizeof(nFilterQuality)); CFileMgr::Read(hFile, &nShadowQuality, sizeof(nShadowQuality)); + CFileMgr::Read(hFile, &fShadowDist, sizeof(fShadowDist)); CFileMgr::Read(hFile, &m_fDrawDistance, sizeof(m_fDrawDistance)); CFileMgr::Read(hFile, &m_bAspectRatioMode, sizeof(m_bAspectRatioMode)); CFileMgr::Read(hFile, &m_bFrameLimiterMode, sizeof(m_bFrameLimiterMode)); @@ -573,6 +577,8 @@ void CMenuManager::LoadSettings() Fx_c::SetTextureFilteringQuality(nFilterQuality); CShadows::SetShadowQuality(nShadowQuality); + CShadows::SetShadowDistance(fShadowDist); + CShadows::InitialiseChangedSettings(); AudioEngine.SetMusicMasterVolume(m_nRadioVolume); AudioEngine.SetEffectsMasterVolume(m_nSfxVolume); @@ -1021,6 +1027,10 @@ void CMenuManager::DrawStandardMenus(bool bDrawMenu) break; } break; + case MENUACTION_SHADOWS_DISTANCE: + if ( CShadows::GetShadowQuality() == SHADOW_QUALITY_OFF ) + CFont::SetColor(CRGBA(MENU_LOCKED_R, MENU_LOCKED_G, MENU_LOCKED_B)); + break; } float fPosX, fPosY; @@ -1084,7 +1094,7 @@ void CMenuManager::DrawStandardMenus(bool bDrawMenu) case 27: { // Brightness - float nMouseInput = DisplaySlider(_xmiddle(MENU_TEXT_POSITION_RCOLUMN), _ymiddle(-97.0f + MENU_SLIDER_HEIGHT/2 - 1.25f), _height(MENU_SLIDER_HEIGHT), _width(100.0f), m_dwBrightness * (1.0f/192.0f), _width(MENU_SLIDER_WIDTH)); + float nMouseInput = DisplaySlider(_xmiddle(MENU_TEXT_POSITION_RCOLUMN), _ymiddle(-97.0f + MENU_SLIDER_HEIGHT/2 - 1.25f), _height(MENU_SLIDER_HEIGHT), _width(100.0f), m_dwBrightness * (1.0f/192.0f), _width(MENU_SLIDER_WIDTH), false); if ( i == m_dwSelectedMenuItem ) { @@ -1100,7 +1110,7 @@ void CMenuManager::DrawStandardMenus(bool bDrawMenu) case 28: { // Radio volume - float nMouseInput = DisplaySlider(_xmiddle(MENU_TEXT_POSITION_RCOLUMN), _ymiddle(-124.0f + MENU_SLIDER_HEIGHT/2 - 1.25f), _height(MENU_SLIDER_HEIGHT), _width(100.0f), m_nRadioVolume * (1.0f/64.0f), _width(MENU_SLIDER_WIDTH)); + float nMouseInput = DisplaySlider(_xmiddle(MENU_TEXT_POSITION_RCOLUMN), _ymiddle(-124.0f + MENU_SLIDER_HEIGHT/2 - 1.25f), _height(MENU_SLIDER_HEIGHT), _width(100.0f), m_nRadioVolume * (1.0f/64.0f), _width(MENU_SLIDER_WIDTH), false); if ( i == m_dwSelectedMenuItem ) { @@ -1116,7 +1126,7 @@ void CMenuManager::DrawStandardMenus(bool bDrawMenu) case 29: { // SFX volume - float nMouseInput = DisplaySlider(_xmiddle(MENU_TEXT_POSITION_RCOLUMN), _ymiddle(-94.0f + MENU_SLIDER_HEIGHT/2 - 1.25f), _height(MENU_SLIDER_HEIGHT), _width(100.0f), m_nSfxVolume * (1.0f/64.0f), _width(MENU_SLIDER_WIDTH)); + float nMouseInput = DisplaySlider(_xmiddle(MENU_TEXT_POSITION_RCOLUMN), _ymiddle(-94.0f + MENU_SLIDER_HEIGHT/2 - 1.25f), _height(MENU_SLIDER_HEIGHT), _width(100.0f), m_nSfxVolume * (1.0f/64.0f), _width(MENU_SLIDER_WIDTH), false); if ( i == m_dwSelectedMenuItem ) { @@ -1132,7 +1142,7 @@ void CMenuManager::DrawStandardMenus(bool bDrawMenu) case 61: { // Draw Distance - float nMouseInput = DisplaySlider(_xmiddle(MENU_TEXT_POSITION_RCOLUMN), _ymiddle(-124.0f + MENU_SLIDER_HEIGHT/2 - 1.25f), _height(MENU_SLIDER_HEIGHT), _width(100.0f), (m_fDrawDistance-0.925f) * (1.0f/0.875f), _width(MENU_SLIDER_WIDTH)); + float nMouseInput = DisplaySlider(_xmiddle(MENU_TEXT_POSITION_RCOLUMN), _ymiddle(-124.0f + MENU_SLIDER_HEIGHT/2 - 1.25f), _height(MENU_SLIDER_HEIGHT), _width(100.0f), (m_fDrawDistance-0.925f) * (1.0f/0.875f), _width(MENU_SLIDER_WIDTH), false); if ( i == m_dwSelectedMenuItem ) { @@ -1148,7 +1158,7 @@ void CMenuManager::DrawStandardMenus(bool bDrawMenu) case 62: { // Mouse Sensitivity - float nMouseInput = DisplaySlider(_xmiddle(MENU_TEXT_POSITION_RCOLUMN), _ymiddle(-94.0f + MENU_SLIDER_HEIGHT/2 - 1.25f), _height(MENU_SLIDER_HEIGHT), _width(100.0f), (CCamera::m_fMouseAccelHorzntl-0.0003125f)* (1.0f/0.0049f), _width(MENU_SLIDER_WIDTH)); + float nMouseInput = DisplaySlider(_xmiddle(MENU_TEXT_POSITION_RCOLUMN), _ymiddle(-94.0f + MENU_SLIDER_HEIGHT/2 - 1.25f), _height(MENU_SLIDER_HEIGHT), _width(100.0f), (CCamera::m_fMouseAccelHorzntl-0.0003125f)* (1.0f/0.0049f), _width(MENU_SLIDER_WIDTH), false); if ( i == m_dwSelectedMenuItem ) { @@ -1161,6 +1171,27 @@ void CMenuManager::DrawStandardMenus(bool bDrawMenu) } break; } + case MENUACTION_SHADOWS_DISTANCE: + { + // Shadows Distance + bool bLockedSlider = CShadows::GetShadowQuality() == SHADOW_QUALITY_OFF; + float nMouseInput = DisplaySlider(_xmiddle(MENU_TEXT_POSITION_RCOLUMN), _ymiddle(-4.0f + MENU_SLIDER_HEIGHT/2 - 1.25f), _height(MENU_SLIDER_HEIGHT), _width(100.0f), CShadows::GetShadowDistance(), _width(MENU_SLIDER_WIDTH), bLockedSlider); + + if ( !bLockedSlider ) + { + /*if ( i == m_dwSelectedMenuItem ) + { + if ( CheckHover(_xleft(95.0f), nMouseInput - _width(3.0f), _ymiddle(-4.0f + MENU_SLIDER_HEIGHT/2 - 1.25f), _ymiddle(-4.0f + 3*MENU_SLIDER_HEIGHT/2 + 1.25f)) ) + m_nHoverOption = 15; + else if ( CheckHover(nMouseInput + _width(3.0f), _x(95.0f), _ymiddle(-4.0f + MENU_SLIDER_HEIGHT/2 - 1.25f), _ymiddle(-4.0f + 3*MENU_SLIDER_HEIGHT/2 + 1.25f)) ) + m_nHoverOption = 14; + else + m_nHoverOption = 16; + }*/ + } + break; + } + } } } @@ -1815,6 +1846,100 @@ void CMenuManager::ProcessMenuOptions(signed char nArrowsInput, bool* bReturn, b } } +void CMenuManager::CheckSliderMovement(signed char nDirection) +{ + switch ( aScreens[m_bCurrentMenuPage].entryList[m_dwSelectedMenuItem].action ) + { + case 27: + { + float fNewBrightness = m_dwBrightness + (nDirection*12.0f); + + if ( fNewBrightness > 192.0f ) + fNewBrightness = 192.0f; + else if ( fNewBrightness < 0.0f ) + fNewBrightness = 0.0f; + m_dwBrightness = fNewBrightness; + + ((void(__thiscall*)(int,float,bool))0x747200)(0xC92134, fNewBrightness * (1.0f/512.0f), false); + SaveSettings(); + return; + } + case 28: + { + signed char nNewVolume = m_nRadioVolume + (nDirection*4); + + if ( nNewVolume > 64 ) + nNewVolume = 64; + else if ( nNewVolume < 0 ) + nNewVolume = 0; + + m_nRadioVolume = nNewVolume; + AudioEngine.SetMusicMasterVolume(nNewVolume); + SaveSettings(); + return; + } + case 29: + { + signed char nNewVolume = m_nSfxVolume + (nDirection*4); + + if ( nNewVolume > 64 ) + nNewVolume = 64; + else if ( nNewVolume < 0 ) + nNewVolume = 0; + + m_nSfxVolume = nNewVolume; + AudioEngine.SetEffectsMasterVolume(nNewVolume); + SaveSettings(); + return; + } + case 61: + { + float fNewDrawDist = m_fDrawDistance + (nDirection*((1.8f-0.925f)/16.0f)); + + if ( fNewDrawDist > 1.8f ) + fNewDrawDist = 1.8f; + else if ( fNewDrawDist < 0.925f ) + fNewDrawDist = 0.925f; + ms_lodDistScale = m_fDrawDistance = fNewDrawDist; + + CModelInfo::RecalcDrawDistances(); + SaveSettings(); + return; + } + case 62: + { + float fNewSensitivity = CCamera::m_fMouseAccelHorzntl + (nDirection*((0.005f-0.0003125f)/16.0f)); + + if ( fNewSensitivity > 0.005f ) + fNewSensitivity = 0.005f; + else if ( fNewSensitivity < 0.0003125f ) + fNewSensitivity = 0.0003125f; + CCamera::m_fMouseAccelHorzntl = fNewSensitivity; + + SaveSettings(); + return; + } + case MENUACTION_SHADOWS_DISTANCE: + { + if ( CShadows::GetShadowQuality() != SHADOW_QUALITY_OFF ) + { + float fNewDist = CShadows::GetShadowDistance() + (nDirection*(1.0f/16.0f)); + + if ( fNewDist > 1.0f ) + fNewDist = 1.0f; + else if ( fNewDist < 0.0f ) + fNewDist = 0.0f; + CShadows::SetShadowDistance(fNewDist); + CShadows::InitialiseChangedSettings(); + + SaveSettings(); + } + return; + } + + } +} + void CMenuManager::CentreMousePointer() { POINT PointerPos; @@ -1972,7 +2097,7 @@ void CMenuManager::DrawRadioStationIcons() while ( bLoopCounter < 11 ); } -float CMenuManager::DisplaySlider(float posX, float posY, float height, float distBetweenRects, float filledAmount, float width) +float CMenuManager::DisplaySlider(float posX, float posY, float height, float distBetweenRects, float filledAmount, float width, bool bLocked) { BYTE loopCounter = NUM_SLIDERS * 2; BYTE positionCounter = 0; @@ -1987,13 +2112,13 @@ float CMenuManager::DisplaySlider(float posX, float posY, float height, float di CRGBA colour; if ( static_cast(positionCounter) / NUM_SLIDERS + ( 1 / (NUM_SLIDERS * 2) ) >= filledAmount ) - colour = CRGBA(MENU_INACTIVE_R, MENU_INACTIVE_G, MENU_INACTIVE_B, 0xFF); + colour = bLocked ? CRGBA(MENU_LOCKED_R, MENU_LOCKED_G, MENU_LOCKED_B) : CRGBA(MENU_INACTIVE_R, MENU_INACTIVE_G, MENU_INACTIVE_B); else { if ( static_cast(secondPositionCounter) / (NUM_SLIDERS * 2) + ( 1 / (NUM_SLIDERS * 4)) >= filledAmount ) bDrawHalfSlider = true; else - colour = CRGBA(MENU_ACTIVE_R, MENU_ACTIVE_G, MENU_ACTIVE_B, 255); + colour = bLocked ? CRGBA(MENU_ACTIVE_LOCKED_R, MENU_ACTIVE_LOCKED_G, MENU_ACTIVE_LOCKED_B) : CRGBA(MENU_ACTIVE_R, MENU_ACTIVE_G, MENU_ACTIVE_B); fullWidth = mousePosX; } @@ -2707,6 +2832,8 @@ void CMenuManager::SetDefaultPreferences(signed char bScreen) Fx_c::SetEffectsQuality(FXQUALITY_HIGH); Fx_c::SetTextureFilteringQuality(1); // Trilinear CShadows::SetShadowQuality(SHADOW_QUALITY_MEDIUM); + CShadows::SetShadowDistance(6.0f/16.0f); + CShadows::InitialiseChangedSettings(); // Reinit widescreen and framelimit stuff WidescreenSupport::Recalculate(RsGlobal.MaximumWidth, RsGlobal.MaximumHeight, true); @@ -2787,6 +2914,9 @@ void CMenuManager::Inject() Memory::InjectHook(0x57BA58, &DrawStandardMenus); Memory::InjectHook(0x57B66F, &ProcessMenuOptions); Memory::InjectHook(0x57B702, &ProcessMenuOptions); + + Memory::InjectHook(0x57B70A, &CheckSliderMovement); + Memory::InjectHook(0x580215, &CheckSliderMovement); } // TODO: CLoadingScreen diff --git a/VCS PC/Frontend.h b/VCS PC/Frontend.h index d825e7b..d4d1fc3 100644 --- a/VCS PC/Frontend.h +++ b/VCS PC/Frontend.h @@ -62,7 +62,7 @@ #define MENU_RED_B 0x4D #define MAX_AA 8 -#define SET_FILE_VERSION 9 +#define SET_FILE_VERSION 10 #ifdef DEVBUILD #define SET_FILE_NAME "gta_vcsd.set" @@ -379,10 +379,11 @@ class CMenuManager void PrintActivationScreen(); void DrawStandardMenus(bool bDrawMenu); void DrawRadioStationIcons(); - float DisplaySlider(float posX, float posY, float height, float distBetweenRects, float filledAmount, float width); + float DisplaySlider(float posX, float posY, float height, float distBetweenRects, float filledAmount, float width, bool bLocked); void CentreMousePointer(); void ProcessMenuOptions(signed char nArrowsInput, bool* bReturn, bool bEnterInput); + void CheckSliderMovement(signed char nDirection); public: inline BYTE GetHudMode() diff --git a/VCS PC/General.cpp b/VCS PC/General.cpp index ec4d98c..d041f0b 100644 --- a/VCS PC/General.cpp +++ b/VCS PC/General.cpp @@ -1,6 +1,9 @@ #include "stdafx.h" #include "General.h" +#include "Building.h" +#include "Pools.h" + // Wrappers WRAPPER bool CalcScreenCoors(const CVector& vecIn, CVector* vecOut) { WRAPARG(vecIn); WRAPARG(vecOut); EAXJMP(0x71DAB0); } WRAPPER void LoadingScreenLoadingFile(const char* pText) { WRAPARG(pText); EAXJMP(0x5B3680); } @@ -9,31 +12,25 @@ WRAPPER void CEntity::UpdateRW() { EAXJMP(0x446F90); } WRAPPER void CEntity::RegisterReference(CEntity** pAddress) { WRAPARG(pAddress); EAXJMP(0x571B70); } WRAPPER void CEntity::CleanUpOldReference(CEntity** pAddress) { WRAPARG(pAddress); EAXJMP(0x571A00); } WRAPPER void CEntity::Render() { EAXJMP(0x534310); } +WRAPPER void CEntity::PreRender() { EAXJMP(0x535FA0); } WRAPPER unsigned int CKeyGen::GetUppercaseKey(const char* pEntry) { WRAPARG(pEntry); EAXJMP(0x53CF30); } unsigned char& CGame::bMissionPackGame = *(unsigned char*)0xB72910; -/*void CMatrix::UpdateRW() +class CRealTimeShadow* CEntity::GetRealTimeShadow() +{ + if ( nType == 1 ) + return CPools::GetBuildingPoolAux()->GetAtPointer(static_cast(this))->GetShadow(); + + return static_cast(this)->GetRealTimeShadow(); +} + + +void CEntity::SetRealTimeShadow(class CRealTimeShadow* pShadow) { - if ( pMatrix ) - { - pMatrix->right.x = matrix.right.x; - pMatrix->right.y = matrix.right.y; - pMatrix->right.z = matrix.right.z; - - pMatrix->up.x = matrix.up.x; - pMatrix->up.y = matrix.up.y; - pMatrix->up.z = matrix.up.z; - - pMatrix->at.x = matrix.at.x; - pMatrix->at.y = matrix.at.y; - pMatrix->at.z = matrix.at.z; - - pMatrix->pos.x = matrix.pos.x; - pMatrix->pos.y = matrix.pos.y; - pMatrix->pos.z = matrix.pos.z; - - RwMatrixUpdate(pMatrix); - } -}*/ \ No newline at end of file + if ( nType == 1 ) + CPools::GetBuildingPoolAux()->GetAtPointer(static_cast(this))->SetShadow(pShadow); + else + static_cast(this)->SetRealTimeShadow(pShadow); +} \ No newline at end of file diff --git a/VCS PC/General.h b/VCS PC/General.h index c4173aa..64fe93c 100644 --- a/VCS PC/General.h +++ b/VCS PC/General.h @@ -192,6 +192,9 @@ class NOVMT CEntity : public CPlaceable inline short GetModelIndex() { return m_nModelIndex; } + class CRealTimeShadow* GetRealTimeShadow(); + void SetRealTimeShadow(class CRealTimeShadow* pShadow); + void UpdateRW(); void RegisterReference(CEntity** pAddress); void CleanUpOldReference(CEntity** pAddress); diff --git a/VCS PC/MemoryMgr.h b/VCS PC/MemoryMgr.h index 05d68a3..0a64472 100644 --- a/VCS PC/MemoryMgr.h +++ b/VCS PC/MemoryMgr.h @@ -27,6 +27,7 @@ inline void CheckMemoryBanList(AT address) assert(nAddress < 0x5794A0 || nAddress > 0x57B43F); assert(nAddress < 0x576FE0 || nAddress > 0x5773CF); assert(nAddress < 0x57CD50 || nAddress > 0x57D51F); + assert(nAddress < 0x573440 || nAddress > 0x57367F); #endif } diff --git a/VCS PC/ModelInfo.h b/VCS PC/ModelInfo.h index d9caac1..70bae8a 100644 --- a/VCS PC/ModelInfo.h +++ b/VCS PC/ModelInfo.h @@ -485,6 +485,7 @@ class CAtomicModelInfo : public CBaseModelInfo private: // VCS PC class extension (NONSTATIC) CEmpireBuildingData* pEmpireData; + bool m_bCastShadow; public: virtual CAtomicModelInfo* AsAtomicModelInfoPtr() override { return this; } @@ -501,15 +502,20 @@ class CAtomicModelInfo : public CBaseModelInfo inline CEmpireBuildingData* GetEmpireData() { return pEmpireData; } + inline void SetCastShadowFlag() + { m_bCastShadow = true; } + inline bool CastShadow() + { return m_bCastShadow; } + CAtomicModelInfo() - : pEmpireData(nullptr) + : pEmpireData(nullptr), m_bCastShadow(false) {} }; class CDamageAtomicModelInfo : public CAtomicModelInfo { public: - RpAtomic* pAtomic2; + RpAtomic* pAtomic2; public: virtual CDamageAtomicModelInfo* AsDamageAtomicModelInfoPtr() override { return this; } diff --git a/VCS PC/Pools.cpp b/VCS PC/Pools.cpp index 72d854c..3b72de4 100644 --- a/VCS PC/Pools.cpp +++ b/VCS PC/Pools.cpp @@ -10,6 +10,7 @@ CTaskPool*& CPools::ms_pTaskPool = *(CTaskPool**)0xB744A8; CEmpireBuildingDataPool* CPools::ms_pEmpireBuildingDataPool; CPedPoolAux* CPools::ms_pPedPoolAux; +CBuildingPoolAux* CPools::ms_pBuildingPoolAux; void CPools::Initialise() { @@ -21,6 +22,9 @@ void CPools::Initialise() // Initialise children pools if ( ms_pPedPool ) ms_pPedPoolAux = new CPedPoolAux(ms_pPedPool); + + if ( ms_pBuildingPool ) + ms_pBuildingPoolAux = new CBuildingPoolAux(ms_pBuildingPool); } void CPools::ShutDown() @@ -32,4 +36,5 @@ void CPools::ShutDown() // Shutdown children pools delete ms_pPedPoolAux; + delete ms_pBuildingPoolAux; } \ No newline at end of file diff --git a/VCS PC/Pools.h b/VCS PC/Pools.h index 8d25cb3..fb82290 100644 --- a/VCS PC/Pools.h +++ b/VCS PC/Pools.h @@ -206,7 +206,8 @@ typedef CPool> CTaskPool; typedef CPool CEmpireBuildingDataPool; -typedef CChildrenPool CPedPoolAux; +typedef CChildrenPool CPedPoolAux; +typedef CChildrenPool CBuildingPoolAux; class CPools { @@ -221,6 +222,7 @@ class CPools // VCS PC class extension static CEmpireBuildingDataPool* ms_pEmpireBuildingDataPool; static CPedPoolAux* ms_pPedPoolAux; + static CBuildingPoolAux* ms_pBuildingPoolAux; public: static inline CPedPool* GetPedPool() @@ -240,6 +242,8 @@ class CPools { return ms_pEmpireBuildingDataPool; } static inline CPedPoolAux* GetPedPoolAux() { return ms_pPedPoolAux; } + static inline CBuildingPoolAux* GetBuildingPoolAux() + { return ms_pBuildingPoolAux; } static void Initialise(); static void ShutDown(); diff --git a/VCS PC/RealTimeShadowMgr.cpp b/VCS PC/RealTimeShadowMgr.cpp index 9b95eb6..518f109 100644 --- a/VCS PC/RealTimeShadowMgr.cpp +++ b/VCS PC/RealTimeShadowMgr.cpp @@ -19,7 +19,7 @@ WRAPPER RwRaster* CShadowCamera::RasterGradient(RwRaster* pRaster) { WRAPARG(pRa WRAPPER void CShadowCamera::InvertRaster() { EAXJMP(0x705660); } WRAPPER void CRealTimeShadow::Destroy() { EAXJMP(0x705990); } -WRAPPER bool CRealTimeShadow::SetShadowedObject(CPhysical* pObject) { WRAPARG(pObject); EAXJMP(0x706520); } +WRAPPER bool CRealTimeShadow::SetShadowedObject(CEntity* pObject) { WRAPARG(pObject); EAXJMP(0x706520); } RpAtomic* ShadowCameraRenderCB_Vehicle(RpAtomic* pAtomic, void* pData) { @@ -79,39 +79,37 @@ void CShadowCamera::ReInit() RwTextureSetRaster(m_pTexture, pNewRaster); } -static RpAtomic* PushGeometryFlags(RpAtomic* pAtomic, void* pData) +RwCamera* CShadowCamera::Update(RpAtomic* pAtomic, CEntity* pEntity) { - std::pair** pGeometryStack = static_cast**>(pData); - RpGeometry* pGeometry = RpAtomicGetGeometry(pAtomic); - - *((*pGeometryStack)++) = std::make_pair(&RpGeometryGetFlags(pGeometry), RpGeometryGetFlags(pGeometry)); - return pAtomic; -} - -RwCamera* CShadowCamera::Update(RpAtomic* pAtomic) -{ - RwRGBA ClearColour = { 255, 255, 255, 0 }; - RwCameraClear(m_pCamera, &ClearColour, rwCAMERACLEARIMAGE|rwCAMERACLEARZ); - - if ( RwCameraBeginUpdate(m_pCamera ) ) + if ( RpAtomicGetFlags(pAtomic) & rpATOMICRENDER ) { - RpGeometry* pGeometry = RpAtomicGetGeometry(pAtomic); - RwUInt32 geometryFlags = RpGeometryGetFlags(pGeometry); + RwRGBA ClearColour = { 255, 255, 255, 0 }; + RwCameraClear(m_pCamera, &ClearColour, rwCAMERACLEARIMAGE|rwCAMERACLEARZ); - RpGeometrySetFlags(pGeometry, geometryFlags & ~(rpGEOMETRYTEXTURED|/*rpGEOMETRYPRELIT|*/ - rpGEOMETRYLIGHT|rpGEOMETRYMODULATEMATERIALCOLOR|rpGEOMETRYTEXTURED2)); - - AtomicDefaultRenderCallBack(pAtomic); + if ( RwCameraBeginUpdate(m_pCamera ) ) + { + RpGeometry* pGeometry = RpAtomicGetGeometry(pAtomic); + RwUInt32 geometryFlags = RpGeometryGetFlags(pGeometry); - RpGeometrySetFlags(pGeometry, geometryFlags); + // Disable prelighting if it's not CObject + if ( pEntity->nType != 4 ) + RpGeometrySetFlags(pGeometry, geometryFlags & ~(rpGEOMETRYTEXTURED|rpGEOMETRYPRELIT| + rpGEOMETRYLIGHT|rpGEOMETRYMODULATEMATERIALCOLOR|rpGEOMETRYTEXTURED2)); + else + RpGeometrySetFlags(pGeometry, geometryFlags & ~(rpGEOMETRYTEXTURED|/*rpGEOMETRYPRELIT|*/ + rpGEOMETRYLIGHT|rpGEOMETRYMODULATEMATERIALCOLOR|rpGEOMETRYTEXTURED2)); + + AtomicDefaultRenderCallBack(pAtomic); - InvertRaster(); - RwCameraEndUpdate(m_pCamera); + RpGeometrySetFlags(pGeometry, geometryFlags); + InvertRaster(); + RwCameraEndUpdate(m_pCamera); + } } return m_pCamera; } -RwCamera* CShadowCamera::Update(RpClump* pClump, CPhysical* pEntity) +RwCamera* CShadowCamera::Update(RpClump* pClump, CEntity* pEntity) { RwRGBA ClearColour = { 255, 255, 255, 0 }; RwCameraClear(m_pCamera, &ClearColour, rwCAMERACLEARIMAGE|rwCAMERACLEARZ); @@ -146,9 +144,9 @@ RwTexture* CRealTimeShadow::Update() // Close enough to the object? CVector* pObjPos = m_pEntity->GetCoords(); CVector* pCamPos = TheCamera.GetCoords(); - - // TODO: Different distances for different entities - if ( (*pObjPos-*pCamPos).MagnitudeSqr() > MAX_DISTANCE_PED_SHADOWS * MAX_DISTANCE_PED_SHADOWS ) + float fMaxDist = CShadows::GetRealTimeShadowDistances(m_pEntity) * 1.1f; + + if ( (*pObjPos-*pCamPos).MagnitudeSqr() > fMaxDist*fMaxDist ) return nullptr; if ( m_nRwObjectType == rpATOMIC ) @@ -158,7 +156,7 @@ RwTexture* CRealTimeShadow::Update() m_Camera.SetCenter(&m_BaseSphere.center); if ( m_nRwObjectType == rpATOMIC ) - m_Camera.Update(reinterpret_cast(m_pEntity->m_pRwObject)); + m_Camera.Update(reinterpret_cast(m_pEntity->m_pRwObject), m_pEntity); else if ( m_nRwObjectType == rpCLUMP ) m_Camera.Update(reinterpret_cast(m_pEntity->m_pRwObject), m_pEntity); @@ -327,7 +325,7 @@ void CRealTimeShadowManager::Exit() } } -void CRealTimeShadowManager::DoShadowThisFrame(CPhysical* pEntity) +void CRealTimeShadowManager::DoShadowThisFrame(CEntity* pEntity) { if ( m_bNeedsReinit ) return; @@ -350,7 +348,7 @@ void CRealTimeShadowManager::DoShadowThisFrame(CPhysical* pEntity) } } -void CRealTimeShadowManager::GetRealTimeShadow(CPhysical* pEntity) +void CRealTimeShadowManager::GetRealTimeShadow(CEntity* pEntity) { bool bIsPlayer; bool bRender = true; @@ -464,7 +462,7 @@ void CRealTimeShadowManager::ReInit() for ( int i = 0; i < NUM_MAX_REALTIME_SHADOWS; i++ ) { - CPhysical* pOldOwner = m_pShadows[i]->GetOwner(); + CEntity* pOldOwner = m_pShadows[i]->GetOwner(); m_pShadows[i]->Destroy(); if ( !i ) @@ -547,8 +545,22 @@ void CRealTimeShadowManager::ReturnRealTimeShadow(CRealTimeShadow* pShadow) } } +static void __declspec(naked) ReturnShadowHack() +{ + _asm + { + push ecx + mov ecx, edi + call CRealTimeShadowManager::ReturnRealTimeShadow + push 706B70h + retn + } +} + static StaticPatcher Patcher([](){ + Memory::InjectHook(0x706B19, ReturnShadowHack, PATCH_JUMP); + Memory::InjectHook(0x7067C0, &CRealTimeShadowManager::Init, PATCH_JUMP); Memory::InjectHook(0x706A60, &CRealTimeShadowManager::Exit, PATCH_JUMP); Memory::InjectHook(0x706BA0, &CRealTimeShadowManager::DoShadowThisFrame, PATCH_JUMP); @@ -568,6 +580,7 @@ static StaticPatcher Patcher([](){ //Memory::Patch(0x854980, &g_realTimeShadowMan); //Memory::Patch(0x856AD0, &g_realTimeShadowMan); + Memory::Patch(0x5BA12C, &g_realTimeShadowMan.m_bInitialised); Memory::Patch(0x5BA137, &g_realTimeShadowMan.m_bNeedsReinit); Memory::Patch(0x706AD4, NUM_MAX_REALTIME_SHADOWS); diff --git a/VCS PC/RealTimeShadowMgr.h b/VCS PC/RealTimeShadowMgr.h index 58b247e..fb38665 100644 --- a/VCS PC/RealTimeShadowMgr.h +++ b/VCS PC/RealTimeShadowMgr.h @@ -33,15 +33,15 @@ class CShadowCamera RwRaster* RasterGradient(RwRaster* pRaster); void InvertRaster(); - RwCamera* Update(RpAtomic* pAtomic); - RwCamera* Update(RpClump* pClump, CPhysical* pEntity); + RwCamera* Update(RpAtomic* pAtomic, CEntity* pEntity); + RwCamera* Update(RpClump* pClump, CEntity* pEntity); void ReInit(); }; class CRealTimeShadow { private: - CPhysical* m_pEntity; + CEntity* m_pEntity; bool m_bRenderedThisFrame; unsigned char m_nIntensity; bool m_bUsePlayerHelperCams; // VCS PC class extension @@ -56,7 +56,7 @@ class CRealTimeShadow RwSphere m_BaseSphere; public: - inline class CPhysical* GetOwner() + inline class CEntity* GetOwner() { return m_pEntity; } inline void SetRenderedThisFrame() { m_bRenderedThisFrame = true; } @@ -90,7 +90,7 @@ class CRealTimeShadow void Create(int nSize, int nSizeResampled, bool bResample, int nBlurPasses, bool bGradient, bool bUsePlayerCams); RwTexture* Update(); - bool SetShadowedObject(CPhysical* pObject); + bool SetShadowedObject(CEntity* pObject); }; @@ -122,8 +122,8 @@ class CRealTimeShadowManager void ReturnRealTimeShadow(CRealTimeShadow* pShadow); void Init(); void Exit(); - void DoShadowThisFrame(CPhysical* pEntity); - void GetRealTimeShadow(CPhysical* pEntity); + void DoShadowThisFrame(CEntity* pEntity); + void GetRealTimeShadow(CEntity* pEntity); void ReInit(); }; diff --git a/VCS PC/Shadows.cpp b/VCS PC/Shadows.cpp index 44adf43..060b355 100644 --- a/VCS PC/Shadows.cpp +++ b/VCS PC/Shadows.cpp @@ -6,14 +6,25 @@ #include "RealTimeShadowMgr.h" #include "Vehicle.h" #include "Object.h" +#include "Camera.h" +#include "Building.h" -eShadowQuality CShadows::m_bShadowQuality; +eShadowQuality CShadows::m_bShadowQuality; +float CShadows::m_fShadowDistMult; -float& MAX_DISTANCE_PED_SHADOWS = *(float*)0x8D5240; +float& MAX_DISTANCE_REALTIME_SHADOWS = *(float*)0x8D5240; +float& MAX_DISTANCE_REALTIME_SHADOWS_SQR = *(float*)0xC4B6B0; + +float MAX_DISTANCE_PED_SHADOWS, MAX_DISTANCE_PED_SHADOWS_SQR; +float MAX_DISTANCE_CAR_SHADOWS, MAX_DISTANCE_CAR_SHADOWS_SQR; // SHADOW DRAW DISTANCES // Ped -// Min - ??? Max - 45.0 +// Min - 12.5 Max - 45.0 +// Vehicle +// Min - 15.0 Max - 60.0 +// Object +// Min - 12.5 Max - 45.0 void CShadows::RenderIndicatorShadow(unsigned int nIndex, unsigned char, RwTexture*, CVector* pPos, float radiusX, float, float, float radiusY, short) { @@ -22,7 +33,20 @@ void CShadows::RenderIndicatorShadow(unsigned int nIndex, unsigned char, RwTextu void CShadows::InitialiseChangedSettings() { - g_realTimeShadowMan.ResetForChangedSettings(); + static eShadowQuality eOldQuality = SHADOW_QUALITY_UNDEFINED; + + if ( eOldQuality != m_bShadowQuality ) + { + eOldQuality = m_bShadowQuality; + g_realTimeShadowMan.ResetForChangedSettings(); + } + + // Recalculate distances + MAX_DISTANCE_PED_SHADOWS = 12.5f + (m_fShadowDistMult*(45.0f-12.5f)); + MAX_DISTANCE_CAR_SHADOWS = 15.0 + (m_fShadowDistMult*(60.0f-15.0f)); + + MAX_DISTANCE_PED_SHADOWS_SQR = MAX_DISTANCE_PED_SHADOWS*MAX_DISTANCE_PED_SHADOWS; + MAX_DISTANCE_CAR_SHADOWS_SQR = MAX_DISTANCE_CAR_SHADOWS*MAX_DISTANCE_CAR_SHADOWS; } bool CShadows::StoreRealTimeShadowForVehicle(CVehicle* pVehicle) @@ -41,15 +65,59 @@ void CShadows::StoreRealTimeShadowForObject(CObject* pObject) { if ( m_bShadowQuality > SHADOW_QUALITY_MEDIUM && ThisPropCanHaveShadow(pObject) ) g_realTimeShadowMan.DoShadowThisFrame(pObject); +} + +void CShadows::StoreRealTimeShadowForBuilding(CBuilding* pBuilding) +{ + if ( m_bShadowQuality > SHADOW_QUALITY_MEDIUM && ThisPropCanHaveShadow(pBuilding) ) + { + float fMaxDist = GetRealTimeShadowDistances(pBuilding) * 1.1f; + if ( (*pBuilding->GetCoords() - *TheCamera.GetCoords()).MagnitudeSqr() < fMaxDist*fMaxDist ) + { + g_realTimeShadowMan.DoShadowThisFrame(pBuilding); + } + } +} + +bool CShadows::ThisPropCanHaveShadow(CEntity* pEntity) +{ + // Is flying component? + if ( pEntity->m_nModelIndex >= 374 && pEntity->m_nModelIndex <= 379 ) + return true; + + // IDE flag enabled? + CAtomicModelInfo* pModelInfo = CModelInfo::ms_modelInfoPtrs[pEntity->m_nModelIndex]->AsAtomicModelInfoPtr(); + + if ( pModelInfo ) + return pModelInfo->CastShadow(); + return false; } -bool CShadows::ThisPropCanHaveShadow(CPhysical* pPhysical) +void CShadows::SetRealTimeShadowDistances(CEntity* pEntity) { - return pPhysical->m_nModelIndex == MI_PARKBENCH || pPhysical->m_nModelIndex == MI_CANOPY_TEST || pPhysical->m_nModelIndex == MI_CHAIR_TEST - || pPhysical->m_nModelIndex == MI_PAPERMACHINE || pPhysical->m_nModelIndex == MI_HYDRANT - // Flying components - || ( pPhysical->m_nModelIndex >= 374 && pPhysical->m_nModelIndex <= 379 ); + switch ( pEntity->nType ) + { + case 2: + MAX_DISTANCE_REALTIME_SHADOWS = MAX_DISTANCE_CAR_SHADOWS; + MAX_DISTANCE_REALTIME_SHADOWS_SQR = MAX_DISTANCE_CAR_SHADOWS_SQR; + break; + default: + MAX_DISTANCE_REALTIME_SHADOWS = MAX_DISTANCE_PED_SHADOWS; + MAX_DISTANCE_REALTIME_SHADOWS_SQR = MAX_DISTANCE_PED_SHADOWS_SQR; + break; + } +} + +float CShadows::GetRealTimeShadowDistances(CEntity* pEntity) +{ + switch ( pEntity->nType ) + { + case 2: + return MAX_DISTANCE_CAR_SHADOWS; + default: + return MAX_DISTANCE_PED_SHADOWS; + } } static const float f215 = 2.15f; @@ -58,7 +126,7 @@ static const float f115 = 1.15f; //static float gA; static float gB; -static CPhysical *gCurrentEntityStoresShadow; +static CEntity *gCurrentEntityStoresShadow; void * __fastcall SetLightParameters(int shd, int edx0, float a, float b, bool set) { @@ -86,11 +154,11 @@ void CastShadow(void *a1, float a2, float a3, float a4, float a5, void *a6, floa (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); } -void __fastcall SetupShadowBoundSphere(void *sphere, int edx0, float size, CVector const& center, unsigned char material, unsigned char flags, unsigned char lighting) +/*void __fastcall SetupShadowBoundSphere(void *sphere, int edx0, float size, CVector const& center, unsigned char material, unsigned char flags, unsigned char lighting) { ((void (__thiscall *)(void *, float, CVector const&, unsigned char, unsigned char, unsigned char))0x40FD10) - (sphere, 3.0f, center, material, flags, lighting); -} + // (sphere, 7.5f/*3.0f*///, center, material, flags, lighting); +//} #define NightState (*(float *)0x8D12C0) @@ -165,6 +233,21 @@ static void __declspec(naked) StoreRTObjectShadowHack() } } +static void __declspec(naked) GetShadowHack() +{ + _asm + { + push ecx + call CShadows::SetRealTimeShadowDistances + add esp, 4 + mov ecx, ebp + call CEntity::GetRealTimeShadow + mov edi, eax + push 707CB0h + retn + } +} + /*static void __declspec(naked) StoreRTPoleShadowHack() { _asm @@ -187,10 +270,19 @@ void CShadows::Inject() Memory::Nop(0x53C1AB, 5); // Off vehicle shadows - Memory::Patch(0x70F9B0, 0xA1); - Memory::Patch(0x70F9B1, &CShadows::m_bShadowQuality); - Memory::Patch(0x70F9B5, 0x940FC085); - Memory::Patch(0x70F9B9, 0xC3C0); + //Memory::Patch(0x70F9B0, 0xA1); + //Memory::Patch(0x70F9B1, &CShadows::m_bShadowQuality); + //Memory::Patch(0x70F9B5, 0x940FC085); + //Memory::Patch(0x70F9B9, 0xC3C0); + Memory::InjectHook(0x70C753, DontRenderShadowsForPoles); + + // Adjustable shadows draw distance + Memory::Patch(0x707BF3, &MAX_DISTANCE_PED_SHADOWS); + Memory::Patch(0x5E67E0, &MAX_DISTANCE_PED_SHADOWS_SQR); + Memory::Patch(0x707B9E, &MAX_DISTANCE_PED_SHADOWS_SQR); + + Memory::Patch(0x70BEA7, &MAX_DISTANCE_CAR_SHADOWS_SQR); + Memory::Patch(0x70BEB6, &MAX_DISTANCE_CAR_SHADOWS); } static StaticPatcher Patcher([](){ @@ -216,12 +308,15 @@ static StaticPatcher Patcher([](){ // Same as TranslateShdMatrix Memory::Patch(0x70A19D, 0.5f); + // Same as SetupShadowBoundSphere + Memory::Patch(0x70A2AA, 9.75f); + Memory::Patch(0x707D59, 9.75f * 1.5f); //Memory::InjectHook(0x70A1AC, TranlateShdMatrix); Memory::InjectHook(0x707E2B, CompareSunZ, PATCH_JUMP); //Memory::InjectHook(0x70AD0D, CastShadow); - Memory::InjectHook(0x70A2C8, SetupShadowBoundSphere); + //Memory::InjectHook(0x70A2C8, SetupShadowBoundSphere); // matrix rotate Memory::Nop(0x70A0C9, 5); @@ -232,6 +327,7 @@ static StaticPatcher Patcher([](){ //Memory::Patch(0x5E683B, 0xEB); Memory::InjectHook(0x70BDA4, StoreRTVehicleShadowHack); Memory::InjectHook(0x59FEDB, StoreRTObjectShadowHack, PATCH_JUMP); + Memory::InjectHook(0x707CAA, GetShadowHack, PATCH_JUMP); //Memory::InjectHook(0x70C753, StoreRTPoleShadowHack); #endif //Memory::InjectHook(0x705590, &CShadowCamera::SetCenter, PATCH_JUMP); diff --git a/VCS PC/Shadows.h b/VCS PC/Shadows.h index 7966f0c..367d354 100644 --- a/VCS PC/Shadows.h +++ b/VCS PC/Shadows.h @@ -8,7 +8,9 @@ enum eShadowQuality SHADOW_QUALITY_LOW, SHADOW_QUALITY_MEDIUM, SHADOW_QUALITY_HIGH, - SHADOW_QUALITY_HIGHEST + SHADOW_QUALITY_HIGHEST, + + SHADOW_QUALITY_UNDEFINED }; class CShadows @@ -16,6 +18,7 @@ class CShadows private: // VCS PC class extension static eShadowQuality m_bShadowQuality; + static float m_fShadowDistMult; public: static void RenderIndicatorShadow(unsigned int nIndex, unsigned char, RwTexture*, CVector* pPos, float radiusX, float, float, float radiusY, short); @@ -24,14 +27,26 @@ class CShadows { m_bShadowQuality = nQuality; } static inline eShadowQuality GetShadowQuality() { return m_bShadowQuality; } + static inline void SetShadowDistance(float fMult) + { m_fShadowDistMult = fMult; } + static inline float GetShadowDistance() + { return m_fShadowDistMult; } + + static inline bool DontRenderShadowsForPoles() + { return m_bShadowQuality == SHADOW_QUALITY_OFF || m_bShadowQuality > SHADOW_QUALITY_MEDIUM; } static bool StoreRealTimeShadowForVehicle(class CVehicle* pVehicle); static void StoreRealTimeShadowForObject(class CObject* pObject); + static void StoreRealTimeShadowForBuilding(class CBuilding* pBuilding); static void InitialiseChangedSettings(); - static bool ThisPropCanHaveShadow(CPhysical* pPhysical); + static bool ThisPropCanHaveShadow(CEntity* pEntity); + static void SetRealTimeShadowDistances(CEntity* pEntity); + static float GetRealTimeShadowDistances(CEntity* pEntity); static void Inject(); }; -extern float& MAX_DISTANCE_PED_SHADOWS; +//extern float& MAX_DISTANCE_REALTIME_SHADOWS, &MAX_DISTANCE_REALTIME_SHADOWS_SQR; +//extern float MAX_DISTANCE_PED_SHADOWS, MAX_DISTANCE_PED_SHADOWS_SQR; +//extern float MAX_DISTANCE_CAR_SHADOWS, MAX_DISTANCE_CAR_SHADOWS_SQR; #endif \ No newline at end of file diff --git a/VCS PC/VCSPC.cpp b/VCS PC/VCSPC.cpp index 4f6a80a..472e366 100644 --- a/VCS PC/VCSPC.cpp +++ b/VCS PC/VCSPC.cpp @@ -314,7 +314,6 @@ void* RightShockKeyHack_JumpBack; void* NoRadioCommercialsHack_JumpBack; void* VideoPlayerCreate1_JumpBack; void* VideoPlayerPlayNextFrame_JumpBack; -void* VideoPlayerProc_JumpBack; void* VideoPlayerRelease_JumpBack; //void* FrameLimit_StringInject_JumpBack; /*void* LoadFontsHack_JumpBack; @@ -402,8 +401,8 @@ const float fCTSliderRight = 370.0f; const float fRhinoHitStrength = 1000.0f; const float fRefZVal = 1.0f; //const float fBrightnessStep = 1.0f / 192.0f; -const float fBrightnessStep2 = 12.0f; -const float fBrightnessMax = 192.0f; +//const float fBrightnessStep2 = 12.0f; +//const float fBrightnessMax = 192.0f; //const float fBriefTextHeight = 0.7/448.0; const float fNewDrawDistance = MAX_DRAW_DISTANCE; const float fSkyMultFix = 3.5f; @@ -873,7 +872,6 @@ __forceinline void DefineVariables() NoRadioCommercialsHack_JumpBack = (void*)0x4EA675; VideoPlayerCreate1_JumpBack = (void*)0x748B08; VideoPlayerPlayNextFrame_JumpBack = (void*)0x748DA3; - VideoPlayerProc_JumpBack = (void*)0x74817E; VideoPlayerRelease_JumpBack = (void*)0x748C21; //FrameLimit_StringInject_JumpBack = (void*)0x57A168; /*LoadFontsHack_JumpBack = (void*)0x5BA6E5; @@ -3287,12 +3285,12 @@ __forceinline void Main_Patches() //Patch(0x573B8A, 96.0 / 512.0); //Patch(0x573B96, 96); //Patch(0x57A8A9, &fBrightnessStep); - Patch(0x573487, &fBrightnessStep2); - Patch(0x5734AD, &fBrightnessMax); - Patch(0x5734BC, &fBrightnessMax); + //Patch(0x573487, &fBrightnessStep2); + //Patch(0x5734AD, &fBrightnessMax); + //Patch(0x5734BC, &fBrightnessMax); // Tweaked draw distance - InjectHook(0x5735C8, &DrawDistanceRecalc); + //InjectHook(0x5735C8, &DrawDistanceRecalc); // Widescreen Patch(0x745B71, 0x9090687D); @@ -3320,7 +3318,7 @@ __forceinline void Main_Patches() Patch(0x748F0C, &VideoPlayerRelease); // InjectHook(0x748BC9, &VideoPlayerCreate2, PATCH_JUMP); InjectHook(0x748BB9, &VideoPlayerPlayNextFrame); - InjectHook(0x7480D6, &VideoPlayerProc, PATCH_JUMP); + InjectHook(0x7480C5, &VideoPlayerProc, PATCH_JUMP); // Disable re-initialization of DirectInput mouse device by the game Patch(0x576CCC, 0xEB); @@ -3896,7 +3894,7 @@ __forceinline void Main_Patches() //Patch(0x579D52, ACTION_JOYMOUSE); Patch(0x57B6F5, ACTION_CLICKORARROWS); - Patch(0x57344F, sizeof(MenuItem)); + //Patch(0x57344F, sizeof(MenuItem)); Patch(0x5736FD, sizeof(MenuItem)); Patch(0x573703, sizeof(MenuItem)); Patch(0x57371B, sizeof(MenuItem)); @@ -4150,7 +4148,7 @@ __forceinline void PatchMenus() #endif using namespace Memory; - Patch(0x57345A, &MenuEntriesList->entryList->action); + //Patch(0x57345A, &MenuEntriesList->entryList->action); Patch(0x57370A, &MenuEntriesList->startingMenuEntry); Patch(0x573713, &MenuEntriesList->prevMenu); Patch(0x573728, &MenuEntriesList->prevMenu); @@ -6436,16 +6434,6 @@ void __declspec(naked) LookLeftRightHack() } } -void __declspec(naked) DrawDistanceRecalc() -{ - _asm - { - mov eax, 57C660h - call eax - jmp CModelInfo::RecalcDrawDistances - } -} - void __declspec(naked) DriveByKillFix() { _asm @@ -6623,7 +6611,8 @@ void __declspec(naked) VideoPlayerProc() push esi call CVideoPlayer::WindowProc add esp, 4 - jmp VideoPlayerProc_JumpBack + push 74817Eh + retn } } diff --git a/VCS PC/VideoPlayer.cpp b/VCS PC/VideoPlayer.cpp index 741b4ab..6dd0d81 100644 --- a/VCS PC/VideoPlayer.cpp +++ b/VCS PC/VideoPlayer.cpp @@ -5,13 +5,13 @@ #include "Sprite.h" BINK* CVideoPlayer::m_hBinkPlayer; -BINKBUFFER* CVideoPlayer::m_hBinkBuffer; RwRaster* CVideoPlayer::m_pVideoRaster; CRect CVideoPlayer::m_videoFrame; +int CVideoPlayer::m_nRasterPitch; unsigned char CVideoPlayer::m_bSurfaceMask; unsigned char CVideoPlayer::m_bExtraThreadIndex; -void CVideoPlayer::UpdateVideoFrame(const CRect* pVideoFrame) +void CVideoPlayer::UpdateVideoFrame(const CRect* pVideoFrame, const CVector2D& vecScale) { if ( !pVideoFrame ) { @@ -23,10 +23,10 @@ void CVideoPlayer::UpdateVideoFrame(const CRect* pVideoFrame) colour.blue = 0; colour.alpha = 255; - m_videoFrame.x1 = 0.5f * (RsGlobal.MaximumWidth - m_hBinkBuffer->StretchWidth); - m_videoFrame.y1 = 0.5f * (RsGlobal.MaximumHeight + m_hBinkBuffer->StretchHeight); - m_videoFrame.x2 = 0.5f * (RsGlobal.MaximumWidth + m_hBinkBuffer->StretchWidth); - m_videoFrame.y2 = 0.5f * (RsGlobal.MaximumHeight - m_hBinkBuffer->StretchHeight); + m_videoFrame.x1 = 0.5f * (RsGlobal.MaximumWidth - vecScale.x); + m_videoFrame.y1 = 0.5f * (RsGlobal.MaximumHeight + vecScale.y); + m_videoFrame.x2 = 0.5f * (RsGlobal.MaximumWidth + vecScale.x); + m_videoFrame.y2 = 0.5f * (RsGlobal.MaximumHeight - vecScale.y); RwCameraClear(Scene, &colour, rwCAMERACLEARIMAGE); } @@ -70,21 +70,21 @@ void CVideoPlayer::Create(const char* pFileName, const CRect* pVideoFrame, bool if ( m_hBinkPlayer ) { BinkDoFrameAsync(m_hBinkPlayer, 0, m_bExtraThreadIndex); - m_hBinkBuffer = BinkBufferOpen(RsGlobal.ps->window, m_hBinkPlayer->Width, m_hBinkPlayer->Height, BINKBUFFERAUTO /*BINKBUFFERSTRETCHXINT | BINKBUFFERSTRETCHYINT*//*BINKBUFFERSTRETCHY*/); + CVector2D vecOutScale; if ( !pVideoFrame ) + vecOutScale = WidescreenSupport::GetFullscreenImageDimensions(static_cast(m_hBinkPlayer->Width)/m_hBinkPlayer->Height, WidescreenSupport::SetAspectRatio(), true); + else { - CVector2D vecVidScale = WidescreenSupport::GetFullscreenImageDimensions(static_cast(m_hBinkPlayer->Width)/m_hBinkPlayer->Height, WidescreenSupport::SetAspectRatio(), true); - - BinkBufferSetScale(m_hBinkBuffer, static_cast(vecVidScale.x), static_cast(vecVidScale.y)); + vecOutScale.x = abs(pVideoFrame->x2 - pVideoFrame->x1); + vecOutScale.y = abs(pVideoFrame->y2 - pVideoFrame->y1); } - else - BinkBufferSetScale(m_hBinkBuffer, static_cast(abs(pVideoFrame->x2 - pVideoFrame->x1)), static_cast(abs(pVideoFrame->y2 - pVideoFrame->y1))); m_pVideoRaster = RwRasterCreate(m_hBinkPlayer->Width, m_hBinkPlayer->Height, 0, rwRASTERTYPECAMERATEXTURE); m_bSurfaceMask = ( RwRasterGetFormat(m_pVideoRaster) == rwRASTERFORMAT565 ) ? BINKSURFACE565 : BINKSURFACE32; + m_nRasterPitch = RwRasterGetWidth(m_pVideoRaster) * (RwRasterGetDepth(m_pVideoRaster)/8); - UpdateVideoFrame(pVideoFrame); + UpdateVideoFrame(pVideoFrame, vecOutScale); } } @@ -102,7 +102,6 @@ void CVideoPlayer::Release() if ( m_bExtraThreadIndex ) BinkWaitStopAsyncThread(1); - BinkBufferClose(m_hBinkBuffer); RwRasterDestroy(m_pVideoRaster); } } @@ -119,11 +118,7 @@ bool CVideoPlayer::PlayNextFullscreenFrame() { if ( RwRasterLock(m_pVideoRaster, 0, rwRASTERLOCKREADWRITE) ) { - if ( BinkBufferLock(m_hBinkBuffer) ) - { - BinkCopyToBuffer(m_hBinkPlayer, m_pVideoRaster->cpPixels, m_hBinkBuffer->BufferPitch, m_hBinkBuffer->Height, 0, 0, (m_hBinkBuffer->SurfaceType & (~BINKSURFACEMASK)) | m_bSurfaceMask); - BinkBufferUnlock(m_hBinkBuffer); - } + BinkCopyToBuffer(m_hBinkPlayer, m_pVideoRaster->cpPixels, m_nRasterPitch, RwRasterGetHeight(m_pVideoRaster), 0, 0, m_bSurfaceMask); RwRasterUnlock(m_pVideoRaster); } @@ -167,11 +162,7 @@ void CVideoPlayer::PlayNextFrame() { if ( RwRasterLock(m_pVideoRaster, 0, rwRASTERLOCKREADWRITE) ) { - if ( BinkBufferLock(m_hBinkBuffer) ) - { - BinkCopyToBuffer(m_hBinkPlayer, m_pVideoRaster->cpPixels, m_hBinkBuffer->BufferPitch, m_hBinkBuffer->Height, 0, 0, (m_hBinkBuffer->SurfaceType & (~BINKSURFACEMASK)) | m_bSurfaceMask); - BinkBufferUnlock(m_hBinkBuffer); - } + BinkCopyToBuffer(m_hBinkPlayer, m_pVideoRaster->cpPixels, m_nRasterPitch, RwRasterGetHeight(m_pVideoRaster), 0, 0, m_bSurfaceMask); RwRasterUnlock(m_pVideoRaster); } @@ -199,12 +190,9 @@ void CVideoPlayer::WindowProc(WPARAM wParam) { if ( m_hBinkPlayer ) { - if ( m_hBinkPlayer->Paused && wParam ) + if ( wParam ) BinkPause(m_hBinkPlayer, FALSE); else - { - if ( !m_hBinkPlayer->Paused && !wParam ) - BinkPause(m_hBinkPlayer, TRUE); - } + BinkPause(m_hBinkPlayer, TRUE); } } \ No newline at end of file diff --git a/VCS PC/VideoPlayer.h b/VCS PC/VideoPlayer.h index a13dab8..dd58b76 100644 --- a/VCS PC/VideoPlayer.h +++ b/VCS PC/VideoPlayer.h @@ -8,14 +8,14 @@ class CVideoPlayer { private: static BINK* m_hBinkPlayer; - static BINKBUFFER* m_hBinkBuffer; static RwRaster* m_pVideoRaster; static CRect m_videoFrame; + static int m_nRasterPitch; static unsigned char m_bSurfaceMask; static unsigned char m_bExtraThreadIndex; private: - static void UpdateVideoFrame(const CRect* pVideoFrame); + static void UpdateVideoFrame(const CRect* pVideoFrame, const CVector2D& vecScale); public: static void Create(const char* pFileName, const CRect* pVideoFrame = nullptr, bool bAudio = true, bool bBlackWhite = false);