diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/control/Garages.cpp | 2 | ||||
-rw-r--r-- | src/control/Pickups.cpp | 1 | ||||
-rw-r--r-- | src/control/Record.cpp | 13 | ||||
-rw-r--r-- | src/control/RoadBlocks.cpp | 200 | ||||
-rw-r--r-- | src/control/RoadBlocks.h | 2 | ||||
-rw-r--r-- | src/core/Frontend.cpp | 51 | ||||
-rw-r--r-- | src/core/Frontend.h | 48 | ||||
-rw-r--r-- | src/core/Pools.cpp | 345 | ||||
-rw-r--r-- | src/core/Profile.cpp | 71 | ||||
-rw-r--r-- | src/core/Profile.h | 28 | ||||
-rw-r--r-- | src/core/Timer.h | 3 | ||||
-rw-r--r-- | src/entities/Entity.h | 1 | ||||
-rw-r--r-- | src/modelinfo/BaseModelInfo.h | 4 | ||||
-rw-r--r-- | src/peds/Gangs.cpp (renamed from src/control/Gangs.cpp) | 2 | ||||
-rw-r--r-- | src/peds/Gangs.h (renamed from src/control/Gangs.h) | 0 | ||||
-rw-r--r-- | src/peds/Population.cpp | 81 | ||||
-rw-r--r-- | src/peds/Population.h | 54 | ||||
-rw-r--r-- | src/rw/RwHelper.cpp | 53 | ||||
-rw-r--r-- | src/rw/RwHelper.h | 1 | ||||
-rw-r--r-- | src/save/GenericGameStorage.cpp | 184 | ||||
-rw-r--r-- | src/vehicles/CarGen.cpp (renamed from src/control/CarGen.cpp) | 86 | ||||
-rw-r--r-- | src/vehicles/CarGen.h (renamed from src/control/CarGen.h) | 12 | ||||
-rw-r--r-- | src/vehicles/Cranes.cpp (renamed from src/control/Cranes.cpp) | 94 | ||||
-rw-r--r-- | src/vehicles/Cranes.h (renamed from src/control/Cranes.h) | 9 | ||||
-rw-r--r-- | src/vehicles/Vehicle.h | 3 |
25 files changed, 1023 insertions, 325 deletions
diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp index 84d49bee..d971d453 100644 --- a/src/control/Garages.cpp +++ b/src/control/Garages.cpp @@ -2108,7 +2108,7 @@ void CGarages::CloseHideOutGaragesBeforeSave() aGarages[i].m_eGarageType != GARAGE_HIDEOUT_THREE) continue; if (aGarages[i].m_eGarageState != GS_FULLYCLOSED && - aGarages[i].m_eGarageType != GARAGE_HIDEOUT_ONE || !aGarages[i].IsAnyCarBlockingDoor()) { + (aGarages[i].m_eGarageType != GARAGE_HIDEOUT_ONE || !aGarages[i].IsAnyCarBlockingDoor())) { aGarages[i].m_eGarageState = GS_FULLYCLOSED; switch (aGarages[i].m_eGarageType) { case GARAGE_HIDEOUT_ONE: diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index 80e89ee8..eb561670 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -1016,6 +1016,7 @@ CPacManPickup::Update() FindPlayerPed()->m_pWanted->m_nChaos += 10; FindPlayerPed()->m_pWanted->UpdateWantedLevel(); DMAudio.PlayFrontEndSound(SOUND_PICKUP_PACMAN_PACKAGE, 0); + break; } case PACMAN_RACE: CPacManPickups::PillsEatenInRace++; diff --git a/src/control/Record.cpp b/src/control/Record.cpp index aead1720..ca4128e3 100644 --- a/src/control/Record.cpp +++ b/src/control/Record.cpp @@ -21,8 +21,7 @@ tGameBuffer& CRecordDataForGame::pDataBufferForFrame = *(tGameBuffer*)0x72CED0; void CRecordDataForGame::Init(void) { RecordingState = STATE_NONE; - if (pDataBuffer) - delete[] pDataBuffer; + delete[] pDataBuffer; pDataBufferPointer = nil; pDataBuffer = nil; #ifndef GTA_PS2 // this stuff is not present on PS2 @@ -42,7 +41,7 @@ void CRecordDataForGame::Init(void) if (RecordingState == STATE_PLAYBACK) { pDataBufferPointer = new uint8[MEMORY_FOR_GAME_RECORD]; pDataBuffer = pDataBufferPointer; - pDataBuffer[CFileMgr::Read(FId, (char*)pDataBufferPointer, MEMORY_FOR_GAME_RECORD) + 8] = -1; + pDataBuffer[CFileMgr::Read(FId, (char*)pDataBufferPointer, MEMORY_FOR_GAME_RECORD) + 8] = (uint8)-1; CFileMgr::CloseFile(FId); } #else @@ -71,7 +70,7 @@ void CRecordDataForGame::SaveOrRetrieveDataForThisFrame(void) break; } case STATE_PLAYBACK: - if (pDataBufferPointer[8] == -1) + if (pDataBufferPointer[8] == (uint8)-1) CPad::GetPad(0)->NewState.Clear(); else { tGameBuffer* pData = (tGameBuffer*)pDataBufferPointer; @@ -92,7 +91,7 @@ void CRecordDataForGame::SaveOrRetrieveDataForThisFrame(void) #define PROCESS_BUTTON_STATE_STORE(buf, os, ns, field, id) \ do { \ - if (os->field != os->field){ \ + if (os->field != ns->field){ \ *buf++ = id; \ *buf++ = ns->field; \ } \ @@ -102,7 +101,7 @@ uint8* CRecordDataForGame::PackCurrentPadValues(uint8* buf, CControllerState* os { PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftStickX, 0); PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftStickY, 1); - PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftShoulder1, 2); + PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightStickX, 2); PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightStickY, 3); PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftShoulder1, 4); PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftShoulder2, 5); @@ -132,7 +131,7 @@ uint8* CRecordDataForGame::UnPackCurrentPadValues(uint8* buf, uint8 total, CCont switch (*buf++) { PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftStickX, 0); PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftStickY, 1); - PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftShoulder1, 2); + PROCESS_BUTTON_STATE_RESTORE(buf, state, RightStickX, 2); PROCESS_BUTTON_STATE_RESTORE(buf, state, RightStickY, 3); PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftShoulder1, 4); PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftShoulder2, 5); diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp index e39fe481..9548bc0a 100644 --- a/src/control/RoadBlocks.cpp +++ b/src/control/RoadBlocks.cpp @@ -2,36 +2,202 @@ #include "patcher.h" #include "RoadBlocks.h" #include "PathFind.h" +#include "ModelIndices.h" +#include "Streaming.h" +#include "World.h" +#include "PedPlacement.h" +#include "Automobile.h" +#include "CopPed.h" +#include "VisibilityPlugins.h" +#include "PlayerPed.h" +#include "Wanted.h" +#include "Camera.h" +#include "CarCtrl.h" +#include "General.h" int16 &CRoadBlocks::NumRoadBlocks = *(int16*)0x95CC34; int16 (&CRoadBlocks::RoadBlockObjects)[NUMROADBLOCKS] = *(int16(*)[NUMROADBLOCKS]) * (uintptr*)0x72B3A8; bool (&CRoadBlocks::InOrOut)[NUMROADBLOCKS] = *(bool(*)[NUMROADBLOCKS]) * (uintptr*)0x733810; -WRAPPER void CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle*, int32, int16) { EAXJMP(0x4376A0); } -WRAPPER void CRoadBlocks::GenerateRoadBlocks(void) { EAXJMP(0x436FA0); } - void CRoadBlocks::Init(void) { - NumRoadBlocks = 0; - for (int objId = 0; objId < ThePaths.m_numMapObjects; objId++) { - if (ThePaths.m_objectFlags[objId] & UseInRoadBlock) { - if (NumRoadBlocks < 600) { - InOrOut[NumRoadBlocks] = true; - RoadBlockObjects[NumRoadBlocks] = objId; - NumRoadBlocks++; - } else { + NumRoadBlocks = 0; + for (int objId = 0; objId < ThePaths.m_numMapObjects; objId++) { + if (ThePaths.m_objectFlags[objId] & UseInRoadBlock) { + if (NumRoadBlocks < NUMROADBLOCKS) { + InOrOut[NumRoadBlocks] = true; + RoadBlockObjects[NumRoadBlocks] = objId; + NumRoadBlocks++; + } else { #ifndef MASTER - printf("Not enough room for the potential roadblocks\n"); + printf("Not enough room for the potential roadblocks\n"); #endif - // FIX: Don't iterate loop after NUMROADBLOCKS - return; - } - } - } + // FIX: Don't iterate loop after NUMROADBLOCKS + return; + } + } + } + +} + +void +CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType, int16 roadBlockNode) +{ + static const CVector vecRoadBlockOffets[6] = { {-1.5, 1.8f, 0.0f}, {-1.5f, -1.8f, 0.0f}, {1.5f, 1.8f, 0.0f}, + {1.5f, -1.8f, 0.0f}, {-1.5f, 0.0f, 0.0f}, {1.5, 0.0, 0.0} }; + CEntity* pEntityToAttack = (CEntity*)FindPlayerVehicle(); + if (!pEntityToAttack) + pEntityToAttack = (CEntity*)FindPlayerPed(); + CColModel* pPoliceColModel = CModelInfo::GetModelInfo(MI_POLICE)->GetColModel(); + float fRadius = pVehicle->GetBoundRadius() / pPoliceColModel->boundingSphere.radius; + for (int32 i = 0; i < 2; i++) { + const int32 roadBlockIndex = i + 2 * roadBlockType; + CVector posForZ = pVehicle->m_matrix * (fRadius * vecRoadBlockOffets[roadBlockIndex]); + int32 modelInfoId = MI_COP; + eCopType copType = COP_STREET; + switch (pVehicle->GetModelIndex()) + { + case MI_FBICAR: + modelInfoId = MI_FBI; + copType = COP_FBI; + break; + case MI_ENFORCER: + modelInfoId = MI_SWAT; + copType = COP_SWAT; + break; + case MI_BARRACKS: + modelInfoId = MI_ARMY; + copType = COP_ARMY; + break; + } + if (!CStreaming::HasModelLoaded(modelInfoId)) + copType = COP_STREET; + CCopPed* pCopPed = new CCopPed(copType); + if (copType == COP_STREET) + pCopPed->SetCurrentWeapon(WEAPONTYPE_COLT45); + CPedPlacement::FindZCoorForPed(&posForZ); + pCopPed->m_matrix.GetPosition() = posForZ; + CVector vecSavedPos = pCopPed->m_matrix.GetPosition(); + pCopPed->m_matrix.SetRotate(0.0f, 0.0f, -HALFPI); + pCopPed->m_matrix.GetPosition() += vecSavedPos; + pCopPed->m_bIsDisabledCop = true; + pCopPed->SetIdle(); + pCopPed->bKindaStayInSamePlace = true; + pCopPed->bNotAllowedToDuck = false; + pCopPed->m_wRoadblockNode = roadBlockNode; + pCopPed->bCrouchWhenShooting = roadBlockType != 2; + if (pEntityToAttack) { + pCopPed->m_pPointGunAt = pEntityToAttack; + pEntityToAttack->RegisterReference(&pCopPed->m_pPointGunAt); + pCopPed->SetAttack(pEntityToAttack); + } + pCopPed->m_pMyVehicle = pVehicle; + pVehicle->RegisterReference((CEntity**)&pCopPed->m_pMyVehicle); + pCopPed->bCullExtraFarAway = true; + CVisibilityPlugins::SetClumpAlpha(pCopPed->GetClump(), 0); + CWorld::Add(pCopPed); + } +} +void +CRoadBlocks::GenerateRoadBlocks(void) +{ + CMatrix offsetMatrix; + uint32 frame = CTimer::GetFrameCounter() & 0xF; + int16 nRoadblockNode = (int16)(NUMROADBLOCKS * frame) / 16; + const int16 maxRoadBlocks = (int16)(NUMROADBLOCKS * (frame + 1)) / 16; + int16 numRoadBlocks = CRoadBlocks::NumRoadBlocks; + if (CRoadBlocks::NumRoadBlocks >= maxRoadBlocks) + numRoadBlocks = maxRoadBlocks; + for (; nRoadblockNode < numRoadBlocks; nRoadblockNode++) { + CTreadable *mapObject = ThePaths.m_mapObjects[CRoadBlocks::RoadBlockObjects[nRoadblockNode]]; + CVector2D vecDistance = FindPlayerCoors() - mapObject->GetPosition(); + if (vecDistance.x > -80.0f && vecDistance.x < 80.0f && + vecDistance.y > -80.0f && vecDistance.y < 80.0f && + vecDistance.Magnitude() < 80.0f) { + if (!CRoadBlocks::InOrOut[nRoadblockNode]) { + CRoadBlocks::InOrOut[nRoadblockNode] = true; + if (FindPlayerVehicle() && (CGeneral::GetRandomNumber() & 0x7F) < FindPlayerPed()->m_pWanted->m_RoadblockDensity) { + CWanted *pPlayerWanted = FindPlayerPed()->m_pWanted; + float fMapObjectRadius = 2.0f * mapObject->GetColModel()->boundingBox.max.x; + int32 vehicleId = MI_POLICE; + if (pPlayerWanted->AreArmyRequired()) + vehicleId = MI_BARRACKS; + else if (pPlayerWanted->AreFbiRequired()) + vehicleId = MI_FBICAR; + else if (pPlayerWanted->AreSwatRequired()) + vehicleId = MI_ENFORCER; + if (!CStreaming::HasModelLoaded(vehicleId)) + vehicleId = MI_POLICE; + CColModel *pVehicleColModel = CModelInfo::GetModelInfo(vehicleId)->GetColModel(); + float fModelRadius = 2.0f * pVehicleColModel->boundingSphere.radius + 0.25f; + int16 radius = (int16)(fMapObjectRadius / fModelRadius); + if (radius > 0 && radius < 6) { + CVector2D vecDistanceToCamera = TheCamera.GetPosition() - mapObject->m_matrix.GetPosition(); + float fDotProduct = DotProduct2D(vecDistanceToCamera, mapObject->m_matrix.GetUp()); + float fOffset = 0.5f * fModelRadius * (float)(radius - 1); + for (int16 i = 0; i < radius; i++) { + uint8 nRoadblockType = fDotProduct < 0.0f; + if (CGeneral::GetRandomNumber() & 1) { + offsetMatrix.SetRotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f + HALFPI); + } + else { + nRoadblockType = !nRoadblockType; + offsetMatrix.SetRotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f - HALFPI); + } + if (ThePaths.m_objectFlags[CRoadBlocks::RoadBlockObjects[nRoadblockNode]] & ObjectEastWest) + offsetMatrix.GetPosition() = CVector(0.0f, -fOffset, 0.6f); + else + offsetMatrix.GetPosition() = CVector(-fOffset, 0.0f, 0.6f); + CMatrix vehicleMatrix = mapObject->m_matrix * offsetMatrix; + float fModelRadius = CModelInfo::GetModelInfo(vehicleId)->GetColModel()->boundingSphere.radius - 0.25f; + int16 colliding = 0; + CWorld::FindObjectsKindaColliding(vehicleMatrix.GetPosition(), fModelRadius, 0, &colliding, 2, nil, false, true, true, false, false); + if (!colliding) { + CAutomobile *pVehicle = new CAutomobile(vehicleId, RANDOM_VEHICLE); + pVehicle->m_status = STATUS_ABANDONED; + // pVehicle->GetHeightAboveRoad(); // called but return value is ignored? + vehicleMatrix.GetPosition().z += fModelRadius - 0.6f; + pVehicle->m_matrix = vehicleMatrix; + pVehicle->PlaceOnRoadProperly(); + pVehicle->bIsStatic = false; + pVehicle->m_matrix.UpdateRW(); + pVehicle->m_nDoorLock = CARLOCK_UNLOCKED; + CCarCtrl::JoinCarWithRoadSystem(pVehicle); + pVehicle->bIsLocked = false; + pVehicle->AutoPilot.m_nCarMission = MISSION_NONE; + pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE; + pVehicle->AutoPilot.m_nCurrentLane = 0; + pVehicle->AutoPilot.m_nNextLane = 0; + pVehicle->AutoPilot.m_fMaxTrafficSpeed = 0.0f; + pVehicle->AutoPilot.m_nCruiseSpeed = 0.0f; + pVehicle->bExtendedRange = true; + if (pVehicle->UsesSiren(pVehicle->GetModelIndex()) && CGeneral::GetRandomNumber() & 1) + pVehicle->m_bSirenOrAlarm = true; + if (pVehicle->m_matrix.GetForward().z > 0.94f) { + CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0); + CWorld::Add(pVehicle); + pVehicle->bCreateRoadBlockPeds = true; + pVehicle->m_nRoadblockType = nRoadblockType; + pVehicle->m_nRoadblockNode = nRoadblockNode; + } + else { + delete pVehicle; + } + } + } + } + } + } + } else { + CRoadBlocks::InOrOut[nRoadblockNode] = false; + } + } } STARTPATCHES InjectHook(0x436F50, &CRoadBlocks::Init, PATCH_JUMP); + InjectHook(0x4376A0, &CRoadBlocks::GenerateRoadBlockCopsForCar, PATCH_JUMP); + InjectHook(0x436FA0, &CRoadBlocks::GenerateRoadBlocks, PATCH_JUMP); ENDPATCHES
\ No newline at end of file diff --git a/src/control/RoadBlocks.h b/src/control/RoadBlocks.h index 3f5868e7..16e3a362 100644 --- a/src/control/RoadBlocks.h +++ b/src/control/RoadBlocks.h @@ -11,6 +11,6 @@ public: static bool (&InOrOut)[NUMROADBLOCKS]; static void Init(void); - static void GenerateRoadBlockCopsForCar(CVehicle*, int32, int16); + static void GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType, int16 roadBlockNode); static void GenerateRoadBlocks(void); }; diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 643c450f..48683abc 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -82,34 +82,34 @@ int curBottomBarOption = -1; int hoveredBottomBarOption = -1; #endif -int32 &CMenuManager::OS_Language = *(int32*)0x5F2F78; // 9 -int8 &CMenuManager::m_PrefsUseVibration = *(int8*)0x95CD92; -int8 &CMenuManager::m_DisplayControllerOnFoot = *(int8*)0x95CD8D; -int8 &CMenuManager::m_PrefsVsync = *(int8*)0x5F2E58; // 1 -int8 &CMenuManager::m_PrefsVsyncDisp = *(int8*)0x5F2E5C; // 1 -int8 &CMenuManager::m_PrefsFrameLimiter = *(int8*)0x5F2E60; // 1 -int8 &CMenuManager::m_PrefsShowSubtitles = *(int8*)0x5F2E54; // 1 -int8 &CMenuManager::m_PrefsSpeakers = *(int8*)0x95CD7E; -int32 &CMenuManager::m_ControlMethod = *(int32*)0x8F5F7C; -int8 &CMenuManager::m_PrefsDMA = *(int8*)0x5F2F74; // 1 -int32 &CMenuManager::m_PrefsLanguage = *(int32*)0x941238; +int32 CMenuManager::OS_Language = LANG_ENGLISH; // *(int32*)0x5F2F78; +int8 CMenuManager::m_PrefsUseVibration; // = *(int8*)0x95CD92; +int8 CMenuManager::m_DisplayControllerOnFoot; // = *(int8*)0x95CD8D; +int8 CMenuManager::m_PrefsVsync = 1; // *(int8*)0x5F2E58; +int8 CMenuManager::m_PrefsVsyncDisp = 1; // *(int8*)0x5F2E5C; +int8 CMenuManager::m_PrefsFrameLimiter = 1; // *(int8*)0x5F2E60; +int8 CMenuManager::m_PrefsShowSubtitles = 1; // *(int8*)0x5F2E54; +int8 CMenuManager::m_PrefsSpeakers; // = *(int8*)0x95CD7E; +int32 CMenuManager::m_ControlMethod; // = *(int32*)0x8F5F7C; +int8 CMenuManager::m_PrefsDMA = 1; // *(int8*)0x5F2F74; +int32 CMenuManager::m_PrefsLanguage; // = *(int32*)0x941238; uint8 CMenuManager::m_PrefsStereoMono; // *(bool*)0x95CDB5; // unused except restore settings -bool &CMenuManager::m_PrefsAllowNastyGame = *(bool*)0x5F2E64; // true -bool &CMenuManager::m_bStartUpFrontEndRequested = *(bool*)0x95CCF4; -bool &CMenuManager::m_bShutDownFrontEndRequested = *(bool*)0x95CD6A; +bool CMenuManager::m_PrefsAllowNastyGame = true; // *(bool*)0x5F2E64; +bool CMenuManager::m_bStartUpFrontEndRequested; // = *(bool*)0x95CCF4; +bool CMenuManager::m_bShutDownFrontEndRequested; // = *(bool*)0x95CD6A; -int8 &CMenuManager::m_PrefsUseWideScreen = *(int8*)0x95CD23; -int8 &CMenuManager::m_PrefsRadioStation = *(int8*)0x95CDA4; -int32 &CMenuManager::m_PrefsBrightness = *(int32*)0x5F2E50; // 256 -float &CMenuManager::m_PrefsLOD = *(float*)0x8F42C4; -int8 &CMenuManager::m_bFrontEnd_ReloadObrTxtGxt = *(int8*)0x628CFC; -int32 &CMenuManager::m_PrefsMusicVolume = *(int32*)0x5F2E4C; // 102 -int32 &CMenuManager::m_PrefsSfxVolume = *(int32*)0x5F2E48; // 102 +int8 CMenuManager::m_PrefsUseWideScreen; // = *(int8*)0x95CD23; +int8 CMenuManager::m_PrefsRadioStation; // = *(int8*)0x95CDA4; +int32 CMenuManager::m_PrefsBrightness = 256; // = *(int32*)0x5F2E50; +float CMenuManager::m_PrefsLOD; // = *(float*)0x8F42C4; +int8 CMenuManager::m_bFrontEnd_ReloadObrTxtGxt; // = *(int8*)0x628CFC; +int32 CMenuManager::m_PrefsMusicVolume = 102; // = *(int32*)0x5F2E4C; +int32 CMenuManager::m_PrefsSfxVolume = 102; // = *(int32*)0x5F2E48; -char *CMenuManager::m_PrefsSkinFile = (char*)0x5F2E74; //[256] "$$\"\"" +char CMenuManager::m_PrefsSkinFile[256] = "$$\"\""; // = (char*)0x5F2E74; -int32 &CMenuManager::m_KeyPressedCode = *(int32*)0x5F2E70; // -1 +int32 CMenuManager::m_KeyPressedCode = -1; // = *(int32*)0x5F2E70; // Originally that was PS2 option color, they forget it here and used in PrintBriefs once(but didn't use the output anyway) #ifdef PS2_LIKE_MENU @@ -1655,7 +1655,6 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 } } -// TODO: Complete aScreens and test that void CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeight) { @@ -2463,7 +2462,7 @@ CMenuManager::DrawPlayerSetupScreen() m_pSelectedSkin->skinNameDisplayed[oldLength - 4] = '\0'; m_pSelectedSkin->skinNameOriginal[oldLength - 4] = '\0'; - // Truncate to 40 bytes-39 chars, idk why. This is done in sepearate function in game. + // Fill to 40 bytes-39 chars, idk why. This is done in sepearate function in game. strncpy(nameTemp, m_pSelectedSkin->skinNameDisplayed, 39); // game doesn't do that, but in our day strncpy to same string is forbidden strncpy(m_pSelectedSkin->skinNameDisplayed, nameTemp, 39); if (oldLength - 4 > 39) @@ -4875,7 +4874,7 @@ float CMenuManager::StretchY(float y) void CMenuManager::SwitchMenuOnAndOff() { - bool menuWasActive = !!m_bMenuActive; + bool menuWasActive = GetIsMenuActive(); // Reminder: You need REGISTER_START_BUTTON defined to make it work. if (CPad::GetPad(0)->GetStartJustDown() diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 81765af9..9064cf4e 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -530,30 +530,30 @@ public: bool GetIsMenuActive() {return !!m_bMenuActive;} public: - static int32 &OS_Language; - static int8 &m_PrefsUseVibration; - static int8 &m_DisplayControllerOnFoot; - static int8 &m_PrefsUseWideScreen; - static int8 &m_PrefsRadioStation; - static int8 &m_PrefsVsync; - static int8 &m_PrefsVsyncDisp; - static int8 &m_PrefsFrameLimiter; - static int8 &m_PrefsShowSubtitles; - static int8 &m_PrefsSpeakers; - static int32 &m_ControlMethod; - static int8 &m_PrefsDMA; - static int32 &m_PrefsLanguage; - static int32 &m_PrefsBrightness; - static float &m_PrefsLOD; - static int8 &m_bFrontEnd_ReloadObrTxtGxt; - static int32 &m_PrefsMusicVolume; - static int32 &m_PrefsSfxVolume; - static char *m_PrefsSkinFile; - static int32 &m_KeyPressedCode; - - static bool &m_bStartUpFrontEndRequested; - static bool &m_bShutDownFrontEndRequested; - static bool &m_PrefsAllowNastyGame; + static int32 OS_Language; + static int8 m_PrefsUseVibration; + static int8 m_DisplayControllerOnFoot; + static int8 m_PrefsUseWideScreen; + static int8 m_PrefsRadioStation; + static int8 m_PrefsVsync; + static int8 m_PrefsVsyncDisp; + static int8 m_PrefsFrameLimiter; + static int8 m_PrefsShowSubtitles; + static int8 m_PrefsSpeakers; + static int32 m_ControlMethod; + static int8 m_PrefsDMA; + static int32 m_PrefsLanguage; + static int32 m_PrefsBrightness; + static float m_PrefsLOD; + static int8 m_bFrontEnd_ReloadObrTxtGxt; + static int32 m_PrefsMusicVolume; + static int32 m_PrefsSfxVolume; + static char m_PrefsSkinFile[256]; + static int32 m_KeyPressedCode; + + static bool m_bStartUpFrontEndRequested; + static bool m_bShutDownFrontEndRequested; + static bool m_PrefsAllowNastyGame; static uint8 m_PrefsStereoMono; static int32 m_SelectedMap; diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp index 75536b88..6add9e0c 100644 --- a/src/core/Pools.cpp +++ b/src/core/Pools.cpp @@ -1,8 +1,14 @@ #include "common.h" #include "patcher.h" #include "Pools.h" -#include "World.h" + +#include "Boat.h" +#include "CarCtrl.h" +#include "Population.h" #include "ProjectileInfo.h" +#include "Streaming.h" +#include "Wanted.h" +#include "World.h" CCPtrNodePool *&CPools::ms_pPtrNodePool = *(CCPtrNodePool**)0x943044; CEntryInfoNodePool *&CPools::ms_pEntryInfoNodePool = *(CEntryInfoNodePool**)0x941448; @@ -14,13 +20,6 @@ CObjectPool *&CPools::ms_pObjectPool = *(CObjectPool**)0x880E28; CDummyPool *&CPools::ms_pDummyPool = *(CDummyPool**)0x8F2C18; CAudioScriptObjectPool *&CPools::ms_pAudioScriptObjectPool = *(CAudioScriptObjectPool**)0x8F1B6C; -WRAPPER void CPools::LoadObjectPool(uint8* buf, uint32 size) { EAXJMP(0x4a2550); } -WRAPPER void CPools::LoadPedPool(uint8* buf, uint32 size) { EAXJMP(0x4a2b50); } -WRAPPER void CPools::LoadVehiclePool(uint8* buf, uint32 size) { EAXJMP(0x4a1b40); } -WRAPPER void CPools::SaveObjectPool(uint8* buf, uint32 *size) { EAXJMP(0x4a22d0); } -WRAPPER void CPools::SavePedPool(uint8* buf, uint32 *size) { EAXJMP(0x4a29b0); } -WRAPPER void CPools::SaveVehiclePool(uint8* buf, uint32 *size) { EAXJMP(0x4a2080); } - void CPools::Initialise(void) { @@ -99,6 +98,333 @@ CPools::MakeSureSlotInObjectPoolIsEmpty(int32 slot) } } +void CPools::LoadVehiclePool(uint8* buf, uint32 size) +{ +INITSAVEBUF + int nNumCars = ReadSaveBuf<int>(buf); + int nNumBoats = ReadSaveBuf<int>(buf); + for (int i = 0; i < nNumCars + nNumBoats; i++) { + uint32 type = ReadSaveBuf<uint32>(buf); + int16 model = ReadSaveBuf<int16>(buf); + CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY); + CStreaming::LoadAllRequestedModels(false); + int32 slot = ReadSaveBuf<int32>(buf); + CVehicle* pVehicle; + char* vbuf = new char[max(sizeof(CAutomobile), sizeof(CBoat))]; + if (type == VEHICLE_TYPE_BOAT) { + memcpy(vbuf, buf, sizeof(CBoat)); + SkipSaveBuf(buf, sizeof(CBoat)); + CBoat* pBoat = new(slot) CBoat(model, RANDOM_VEHICLE); + pVehicle = pBoat; + --CCarCtrl::NumRandomCars; // why? + } + else if (type == VEHICLE_TYPE_CAR) { + memcpy(vbuf, buf, sizeof(CAutomobile)); + SkipSaveBuf(buf, sizeof(CAutomobile)); + CStreaming::RequestModel(model, 0); // is it needed? + CStreaming::LoadAllRequestedModels(false); + CAutomobile* pAutomobile = new(slot) CAutomobile(model, RANDOM_VEHICLE); + pVehicle = pAutomobile; + CCarCtrl::NumRandomCars--; // why? + pAutomobile->Damage = ((CAutomobile*)vbuf)->Damage; + pAutomobile->SetupDamageAfterLoad(); + } + else + assert(0); + CVehicle* pBufferVehicle = (CVehicle*)vbuf; + pVehicle->GetMatrix() = pBufferVehicle->GetMatrix(); + pVehicle->VehicleCreatedBy = pBufferVehicle->VehicleCreatedBy; + pVehicle->m_currentColour1 = pBufferVehicle->m_currentColour1; + pVehicle->m_currentColour2 = pBufferVehicle->m_currentColour2; + pVehicle->m_nAlarmState = pBufferVehicle->m_nAlarmState; + pVehicle->m_nNumMaxPassengers = pBufferVehicle->m_nNumMaxPassengers; + pVehicle->field_1D0[0] = pBufferVehicle->field_1D0[0]; + pVehicle->field_1D0[1] = pBufferVehicle->field_1D0[1]; + pVehicle->field_1D0[2] = pBufferVehicle->field_1D0[2]; + pVehicle->field_1D0[3] = pBufferVehicle->field_1D0[3]; + pVehicle->m_fSteerAngle = pBufferVehicle->m_fSteerAngle; + pVehicle->m_fGasPedal = pBufferVehicle->m_fGasPedal; + pVehicle->m_fBrakePedal = pBufferVehicle->m_fBrakePedal; + pVehicle->bIsLawEnforcer = pBufferVehicle->bIsLawEnforcer; + pVehicle->bIsLocked = pBufferVehicle->bIsLocked; + pVehicle->bEngineOn = pBufferVehicle->bEngineOn; + pVehicle->bIsHandbrakeOn = pBufferVehicle->bIsHandbrakeOn; + pVehicle->bLightsOn = pBufferVehicle->bLightsOn; + pVehicle->bFreebies = pBufferVehicle->bFreebies; + pVehicle->m_fHealth = pBufferVehicle->m_fHealth; + pVehicle->m_nCurrentGear = pBufferVehicle->m_nCurrentGear; + pVehicle->m_fChangeGearTime = pBufferVehicle->m_fChangeGearTime; + pVehicle->m_nTimeOfDeath = pBufferVehicle->m_nTimeOfDeath; +#ifdef FIX_BUGS //must be copypaste + pVehicle->m_nBombTimer = pBufferVehicle->m_nBombTimer; +#else + pVehicle->m_nTimeOfDeath = pBufferVehicle->m_nTimeOfDeath; +#endif + pVehicle->m_nDoorLock = pBufferVehicle->m_nDoorLock; + pVehicle->m_status = pBufferVehicle->m_status; + pVehicle->m_type = pBufferVehicle->m_type; + (pVehicle->GetAddressOfEntityProperties())[0] = (pBufferVehicle->GetAddressOfEntityProperties())[0]; + (pVehicle->GetAddressOfEntityProperties())[1] = (pBufferVehicle->GetAddressOfEntityProperties())[1]; + pVehicle->AutoPilot = pBufferVehicle->AutoPilot; + CWorld::Add(pVehicle); + delete[] vbuf; + } +VALIDATESAVEBUF(size) +} + +void CPools::SaveVehiclePool(uint8* buf, uint32* size) +{ +INITSAVEBUF + int nNumCars = 0; + int nNumBoats = 0; + int nPoolSize = GetVehiclePool()->GetSize(); + for (int i = 0; i < nPoolSize; i++) { + CVehicle* pVehicle = GetVehiclePool()->GetSlot(i); + if (!pVehicle) + continue; + bool bHasPassenger = false; + for (int j = 0; j < ARRAY_SIZE(pVehicle->pPassengers); j++) { + if (pVehicle->pPassengers[i]) + bHasPassenger = true; + } + if (!pVehicle->pDriver && !bHasPassenger) { + if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) + ++nNumCars; + if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) + ++nNumBoats; + } + } + *size = nNumCars * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + sizeof(CAutomobile)) + sizeof(int) + + nNumBoats * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + sizeof(CBoat)) + sizeof(int); + WriteSaveBuf(buf, nNumCars); + WriteSaveBuf(buf, nNumBoats); + for (int i = 0; i < nPoolSize; i++) { + CVehicle* pVehicle = GetVehiclePool()->GetSlot(i); + if (!pVehicle) + continue; + bool bHasPassenger = false; + for (int j = 0; j < ARRAY_SIZE(pVehicle->pPassengers); j++) { + if (pVehicle->pPassengers[j]) + bHasPassenger = true; + } + if (!pVehicle->pDriver && !bHasPassenger) { + if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { + WriteSaveBuf(buf, (uint32)pVehicle->m_vehType); + WriteSaveBuf(buf, pVehicle->m_modelIndex); + WriteSaveBuf(buf, GetVehicleRef(pVehicle)); + memcpy(buf, pVehicle, sizeof(CAutomobile)); + SkipSaveBuf(buf, sizeof(CAutomobile)); + } + if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { + WriteSaveBuf(buf, (uint32)pVehicle->m_vehType); + WriteSaveBuf(buf, pVehicle->m_modelIndex); + WriteSaveBuf(buf, GetVehicleRef(pVehicle)); + memcpy(buf, pVehicle, sizeof(CBoat)); + SkipSaveBuf(buf, sizeof(CBoat)); + } + } + } +VALIDATESAVEBUF(*size) +} + +void CPools::SaveObjectPool(uint8* buf, uint32* size) +{ +INITSAVEBUF + CProjectileInfo::RemoveAllProjectiles(); + CObject::DeleteAllTempObjects(); + int nObjects = 0; + int nPoolSize = GetObjectPool()->GetSize(); + for (int i = 0; i < nPoolSize; i++) { + CObject* pObject = GetObjectPool()->GetSlot(i); + if (!pObject) + continue; + if (pObject->ObjectCreatedBy == MISSION_OBJECT) + ++nObjects; + } + *size = nObjects * (sizeof(int16) + sizeof(int) + sizeof(CCompressedMatrixNotAligned) + sizeof(uint32) + + sizeof(float) + sizeof(CCompressedMatrixNotAligned) + sizeof(uint32) + sizeof(int8) + 7 * sizeof(bool) + sizeof(float) + + sizeof(int8) + sizeof(int8) + sizeof(uint32) + 2 * sizeof(uint32)) + sizeof(int); + WriteSaveBuf(buf, nObjects); + for (int i = 0; i < nPoolSize; i++) { + CObject* pObject = GetObjectPool()->GetSlot(i); + if (!pObject) + continue; + if (pObject->ObjectCreatedBy == MISSION_OBJECT) { + bool bIsPickup = pObject->bIsPickup; + bool bFlag2 = pObject->m_obj_flag2; + bool bOutOfStock = pObject->bOutOfStock; + bool bGlassCracked = pObject->bGlassCracked; + bool bGlassBroken = pObject->bGlassBroken; + bool bHasBeenDamaged = pObject->bHasBeenDamaged; + bool bUseVehicleColours = pObject->bUseVehicleColours; + CCompressedMatrixNotAligned tmp; + WriteSaveBuf(buf, pObject->m_modelIndex); + WriteSaveBuf(buf, GetObjectRef(pObject)); + tmp.CompressFromFullMatrix(pObject->GetMatrix()); + WriteSaveBuf(buf, tmp); + WriteSaveBuf(buf, (uint32)0); // game writes ununitialized data here + WriteSaveBuf(buf, pObject->m_fUprootLimit); + tmp.CompressFromFullMatrix(pObject->m_objectMatrix); + WriteSaveBuf(buf, tmp); + WriteSaveBuf(buf, (uint32)0); // same + WriteSaveBuf(buf, pObject->ObjectCreatedBy); + WriteSaveBuf(buf, bIsPickup); + WriteSaveBuf(buf, bFlag2); + WriteSaveBuf(buf, bOutOfStock); + WriteSaveBuf(buf, bGlassCracked); + WriteSaveBuf(buf, bGlassBroken); + WriteSaveBuf(buf, bHasBeenDamaged); + WriteSaveBuf(buf, bUseVehicleColours); + WriteSaveBuf(buf, pObject->m_fCollisionDamageMultiplier); + WriteSaveBuf(buf, pObject->m_nCollisionDamageEffect); + WriteSaveBuf(buf, pObject->m_nSpecialCollisionResponseCases); + WriteSaveBuf(buf, pObject->m_nEndOfLifeTime); + WriteSaveBuf(buf, (pObject->GetAddressOfEntityProperties())[0]); + WriteSaveBuf(buf, (pObject->GetAddressOfEntityProperties())[1]); + } + } +VALIDATESAVEBUF(*size) +} + +void CPools::LoadObjectPool(uint8* buf, uint32 size) +{ +INITSAVEBUF + int nObjects = ReadSaveBuf<int>(buf); + for (int i = 0; i < nObjects; i++) { + int16 mi = ReadSaveBuf<int16>(buf); + int ref = ReadSaveBuf<int>(buf); + char* obuf = new char[sizeof(CObject)]; + CObject* pBufferObject = (CObject*)obuf; + CCompressedMatrixNotAligned tmp; + tmp = ReadSaveBuf<CCompressedMatrixNotAligned>(buf); + tmp.DecompressIntoFullMatrix(pBufferObject->GetMatrix()); + ReadSaveBuf<uint32>(buf); + pBufferObject->m_fUprootLimit = ReadSaveBuf<float>(buf); + tmp = ReadSaveBuf<CCompressedMatrixNotAligned>(buf); + tmp.DecompressIntoFullMatrix(pBufferObject->m_objectMatrix); + ReadSaveBuf<uint32>(buf); + pBufferObject->ObjectCreatedBy = ReadSaveBuf<int8>(buf); + pBufferObject->bIsPickup = ReadSaveBuf<bool>(buf); + pBufferObject->m_flagE2 = ReadSaveBuf<bool>(buf); + pBufferObject->bOutOfStock = ReadSaveBuf<bool>(buf); + pBufferObject->bGlassCracked = ReadSaveBuf<bool>(buf); + pBufferObject->bGlassBroken = ReadSaveBuf<bool>(buf); + pBufferObject->bHasBeenDamaged = ReadSaveBuf<bool>(buf); + pBufferObject->bUseVehicleColours = ReadSaveBuf<bool>(buf); + pBufferObject->m_fCollisionDamageMultiplier = ReadSaveBuf<float>(buf); + pBufferObject->m_nCollisionDamageEffect = ReadSaveBuf<uint8>(buf); + pBufferObject->m_nSpecialCollisionResponseCases = ReadSaveBuf<uint8>(buf); + pBufferObject->m_nEndOfLifeTime = ReadSaveBuf<uint32>(buf); + (pBufferObject->GetAddressOfEntityProperties())[0] = ReadSaveBuf<uint32>(buf); + (pBufferObject->GetAddressOfEntityProperties())[1] = ReadSaveBuf<uint32>(buf); + if (GetObjectPool()->GetSlot(ref >> 8)) + CPopulation::ConvertToDummyObject(GetObjectPool()->GetSlot(ref >> 8)); + CObject* pObject = new(ref) CObject(mi, false); + pObject->GetMatrix() = pBufferObject->GetMatrix(); + pObject->m_fUprootLimit = pBufferObject->m_fUprootLimit; + pObject->m_objectMatrix = pBufferObject->m_objectMatrix; + pObject->ObjectCreatedBy = pBufferObject->ObjectCreatedBy; + pObject->bIsPickup = pBufferObject->bIsPickup; + pObject->m_flagE2 = pBufferObject->m_flagE2; + pObject->bOutOfStock = pBufferObject->bOutOfStock; + pObject->bGlassCracked = pBufferObject->bGlassCracked; + pObject->bGlassBroken = pBufferObject->bGlassBroken; + pObject->bHasBeenDamaged = pBufferObject->bHasBeenDamaged; + pObject->bUseVehicleColours = pBufferObject->bUseVehicleColours; + pObject->m_fCollisionDamageMultiplier = pBufferObject->m_fCollisionDamageMultiplier; + pObject->m_nCollisionDamageEffect = pBufferObject->m_nCollisionDamageEffect; + pObject->m_nSpecialCollisionResponseCases = pBufferObject->m_nSpecialCollisionResponseCases; + pObject->m_nEndOfLifeTime = pBufferObject->m_nEndOfLifeTime; + (pObject->GetAddressOfEntityProperties())[0] = (pBufferObject->GetAddressOfEntityProperties())[0]; + (pObject->GetAddressOfEntityProperties())[1] = (pBufferObject->GetAddressOfEntityProperties())[1]; + pObject->bHasCollided = false; + CWorld::Add(pObject); + delete[] obuf; + } +VALIDATESAVEBUF(size) +} + +void CPools::SavePedPool(uint8* buf, uint32* size) +{ +INITSAVEBUF + int nNumPeds = 0; + int nPoolSize = GetPedPool()->GetSize(); + for (int i = 0; i < nPoolSize; i++) { + CPed* pPed = GetPedPool()->GetSlot(i); + if (!pPed) + continue; + if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1) + nNumPeds++; + } + *size = sizeof(int) + nNumPeds * (sizeof(uint32) + sizeof(int16) + sizeof(int) + sizeof(CPlayerPed) + + sizeof(CWanted::MaximumWantedLevel) + sizeof(CWanted::nMaximumWantedLevel) + MAX_MODEL_NAME); + WriteSaveBuf(buf, nNumPeds); + for (int i = 0; i < nPoolSize; i++) { + CPed* pPed = GetPedPool()->GetSlot(i); + if (!pPed) + continue; + if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1) { + WriteSaveBuf(buf, pPed->m_nPedType); + WriteSaveBuf(buf, pPed->m_modelIndex); + WriteSaveBuf(buf, GetPedRef(pPed)); + memcpy(buf, pPed, sizeof(CPlayerPed)); + SkipSaveBuf(buf, sizeof(CPlayerPed)); + WriteSaveBuf(buf, CWanted::MaximumWantedLevel); + WriteSaveBuf(buf, CWanted::nMaximumWantedLevel); + memcpy(buf, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetName(), MAX_MODEL_NAME); + SkipSaveBuf(buf, MAX_MODEL_NAME); + } + } +VALIDATESAVEBUF(*size); +} + +void CPools::LoadPedPool(uint8* buf, uint32 size) +{ +INITSAVEBUF + int nPeds = ReadSaveBuf<int>(buf); + for (int i = 0; i < nPeds; i++) { + uint32 pedtype = ReadSaveBuf<uint32>(buf); + int16 model = ReadSaveBuf<int16>(buf); + int ref = ReadSaveBuf<int>(buf); + char* pbuf = new char[sizeof(CPlayerPed)]; + CPlayerPed* pBufferPlayer = (CPlayerPed*)pbuf; + CPed* pPed; + char name[MAX_MODEL_NAME]; + // the code implies that there was idea to load non-player ped + if (pedtype == PEDTYPE_PLAYER1) { // always true + memcpy(pbuf, buf, sizeof(CPlayerPed)); + SkipSaveBuf(buf, sizeof(CPlayerPed)); + CWanted::MaximumWantedLevel = ReadSaveBuf<int32>(buf); + CWanted::nMaximumWantedLevel = ReadSaveBuf<int32>(buf); + memcpy(name, buf, MAX_MODEL_NAME); + SkipSaveBuf(buf, MAX_MODEL_NAME); + } + CStreaming::RequestSpecialModel(model, name, STREAMFLAGS_DONT_REMOVE); + CStreaming::LoadAllRequestedModels(false); + if (pedtype == PEDTYPE_PLAYER1) { + CPlayerPed* pPlayerPed = new(ref) CPlayerPed(); + for (int i = 0; i < ARRAY_SIZE(pPlayerPed->m_nTargettableObjects); i++) + pPlayerPed->m_nTargettableObjects[i] = pBufferPlayer->m_nTargettableObjects[i]; + pPlayerPed->m_fMaxStamina = pBufferPlayer->m_fMaxStamina; + pPed = pPlayerPed; + } + pPed->GetPosition() = pBufferPlayer->GetPosition(); + pPed->m_fHealth = pBufferPlayer->m_fHealth; + pPed->m_fArmour = pBufferPlayer->m_fArmour; + pPed->CharCreatedBy = pBufferPlayer->CharCreatedBy; + pPed->m_currentWeapon = 0; + pPed->m_maxWeaponTypeAllowed = pBufferPlayer->m_maxWeaponTypeAllowed; + for (int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) + pPed->m_weapons[i] = pBufferPlayer->m_weapons[i]; + if (pedtype == PEDTYPE_PLAYER1) { + pPed->m_wepAccuracy = 100; + CWorld::Players[0].m_pPed = (CPlayerPed*)pPed; + } + CWorld::Add(pPed); + delete[] pbuf; + } +VALIDATESAVEBUF(size) +} STARTPATCHES InjectHook(0x4A1770, CPools::Initialise, PATCH_JUMP); @@ -111,4 +437,7 @@ STARTPATCHES InjectHook(0x4A1B00, CPools::GetObjectRef, PATCH_JUMP); InjectHook(0x4A1B20, CPools::GetObject, PATCH_JUMP); InjectHook(0x4A2DB0, CPools::MakeSureSlotInObjectPoolIsEmpty, PATCH_JUMP); + InjectHook(0x4A1B40, CPools::LoadVehiclePool, PATCH_JUMP); + InjectHook(0x4A2550, CPools::LoadObjectPool, PATCH_JUMP); + InjectHook(0x4A2B50, CPools::LoadPedPool, PATCH_JUMP); ENDPATCHES diff --git a/src/core/Profile.cpp b/src/core/Profile.cpp new file mode 100644 index 00000000..56584d12 --- /dev/null +++ b/src/core/Profile.cpp @@ -0,0 +1,71 @@ +#include "common.h" +#include "Profile.h" + +#ifndef MASTER +float CProfile::ms_afStartTime[NUM_PROFILES]; +float CProfile::ms_afCumulativeTime[NUM_PROFILES]; +float CProfile::ms_afEndTime[NUM_PROFILES]; +float CProfile::ms_afMaxEndTime[NUM_PROFILES]; +float CProfile::ms_afMaxCumulativeTime[NUM_PROFILES]; +char *CProfile::ms_pProfileString[NUM_PROFILES]; +RwRGBA CProfile::ms_aBarColours[NUM_PROFILES]; + +void CProfile::Initialise() +{ + ms_afMaxEndTime[PROFILE_FRAME_RATE] = 0.0f; + ms_afMaxEndTime[PROFILE_PHYSICS] = 0.0f; + ms_afMaxEndTime[PROFILE_COLLISION] = 0.0f; + ms_afMaxEndTime[PROFILE_PED_AI] = 0.0f; + ms_afMaxEndTime[PROFILE_PROCESSING_TIME] = 0.0f; + ms_afMaxEndTime[PROFILE_RENDERING_TIME] = 0.0f; + ms_afMaxEndTime[PROFILE_TOTAL] = 0.0f; + + ms_pProfileString[PROFILE_FRAME_RATE] = "Frame rate"; + ms_pProfileString[PROFILE_PHYSICS] = "Physics"; + ms_pProfileString[PROFILE_COLLISION] = "Collision"; + ms_pProfileString[PROFILE_PED_AI] = "Ped AI"; + ms_pProfileString[PROFILE_PROCESSING_TIME] = "Processing time"; + ms_pProfileString[PROFILE_RENDERING_TIME] = "Rendering time"; + ms_pProfileString[PROFILE_TOTAL] = "Total"; + + ms_afMaxCumulativeTime[PROFILE_FRAME_RATE] = 0.0f; + ms_afMaxCumulativeTime[PROFILE_PHYSICS] = 0.0f; + ms_afMaxCumulativeTime[PROFILE_COLLISION] = 0.0f; + ms_afMaxCumulativeTime[PROFILE_PED_AI] = 0.0f; + ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME] = 0.0f; + ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME] = 0.0f; + ms_afMaxCumulativeTime[PROFILE_TOTAL] = 0.0f; + + ms_aBarColours[PROFILE_PHYSICS] = { 0, 127, 255, 255 }; + ms_aBarColours[PROFILE_COLLISION] = { 0, 255, 255, 255 }; + ms_aBarColours[PROFILE_PED_AI] = { 255, 0, 0, 255 }; + ms_aBarColours[PROFILE_PROCESSING_TIME] = { 0, 255, 0, 255 }; + ms_aBarColours[PROFILE_RENDERING_TIME] = { 0, 0, 255, 255 }; + ms_aBarColours[PROFILE_TOTAL] = { 255, 255, 255, 255 }; +} + +void CProfile::SuspendProfile(eProfile profile) +{ + ms_afEndTime[profile] = -ms_afStartTime[profile]; + ms_afCumulativeTime[profile] -= ms_afStartTime[profile]; +} + +void CProfile::ShowResults() +{ + ms_afMaxEndTime[PROFILE_FRAME_RATE] = max(ms_afMaxEndTime[PROFILE_FRAME_RATE], ms_afEndTime[PROFILE_FRAME_RATE]); + ms_afMaxEndTime[PROFILE_PHYSICS] = max(ms_afMaxEndTime[PROFILE_PHYSICS], ms_afEndTime[PROFILE_PHYSICS]); + ms_afMaxEndTime[PROFILE_COLLISION] = max(ms_afMaxEndTime[PROFILE_COLLISION], ms_afEndTime[PROFILE_COLLISION]); + ms_afMaxEndTime[PROFILE_PED_AI] = max(ms_afMaxEndTime[PROFILE_PED_AI], ms_afEndTime[PROFILE_PED_AI]); + ms_afMaxEndTime[PROFILE_PROCESSING_TIME] = max(ms_afMaxEndTime[PROFILE_PROCESSING_TIME], ms_afEndTime[PROFILE_PROCESSING_TIME]); + ms_afMaxEndTime[PROFILE_RENDERING_TIME] = max(ms_afMaxEndTime[PROFILE_RENDERING_TIME], ms_afEndTime[PROFILE_RENDERING_TIME]); + ms_afMaxEndTime[PROFILE_TOTAL] = max(ms_afMaxEndTime[PROFILE_TOTAL], ms_afEndTime[PROFILE_TOTAL]); + + ms_afMaxCumulativeTime[PROFILE_FRAME_RATE] = max(ms_afMaxCumulativeTime[PROFILE_FRAME_RATE], ms_afCumulativeTime[PROFILE_FRAME_RATE]); + ms_afMaxCumulativeTime[PROFILE_PHYSICS] = max(ms_afMaxCumulativeTime[PROFILE_PHYSICS], ms_afCumulativeTime[PROFILE_PHYSICS]); + ms_afMaxCumulativeTime[PROFILE_COLLISION] = max(ms_afMaxCumulativeTime[PROFILE_COLLISION], ms_afCumulativeTime[PROFILE_COLLISION]); + ms_afMaxCumulativeTime[PROFILE_PED_AI] = max(ms_afMaxCumulativeTime[PROFILE_PED_AI], ms_afCumulativeTime[PROFILE_PED_AI]); + ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME] = max(ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME], ms_afCumulativeTime[PROFILE_PROCESSING_TIME]); + ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME] = max(ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME], ms_afCumulativeTime[PROFILE_RENDERING_TIME]); + ms_afMaxCumulativeTime[PROFILE_TOTAL] = max(ms_afMaxCumulativeTime[PROFILE_TOTAL], ms_afCumulativeTime[PROFILE_TOTAL]); +} +#endif
\ No newline at end of file diff --git a/src/core/Profile.h b/src/core/Profile.h new file mode 100644 index 00000000..d2e8054b --- /dev/null +++ b/src/core/Profile.h @@ -0,0 +1,28 @@ +#pragma once + +enum eProfile +{ + PROFILE_FRAME_RATE, + PROFILE_PHYSICS, + PROFILE_COLLISION, + PROFILE_PED_AI, + PROFILE_PROCESSING_TIME, + PROFILE_RENDERING_TIME, + PROFILE_TOTAL, + NUM_PROFILES, +}; + +class CProfile +{ + static float ms_afStartTime[NUM_PROFILES]; + static float ms_afCumulativeTime[NUM_PROFILES]; + static float ms_afEndTime[NUM_PROFILES]; + static float ms_afMaxEndTime[NUM_PROFILES]; + static float ms_afMaxCumulativeTime[NUM_PROFILES]; + static char *ms_pProfileString[NUM_PROFILES]; + static RwRGBA ms_aBarColours[NUM_PROFILES]; +public: + static void Initialise(); + static void SuspendProfile(eProfile profile); + static void ShowResults(); +};
\ No newline at end of file diff --git a/src/core/Timer.h b/src/core/Timer.h index b119bfb2..a4d674da 100644 --- a/src/core/Timer.h +++ b/src/core/Timer.h @@ -53,6 +53,9 @@ public: static void Stop(void); static void StartUserPause(void); static void EndUserPause(void); + + friend bool GenericLoad(void); + friend bool GenericSave(int file); }; #ifdef FIX_BUGS diff --git a/src/entities/Entity.h b/src/entities/Entity.h index 17a219c3..ca501ba4 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -90,6 +90,7 @@ public: CReference *m_pFirstReference; CColModel *GetColModel(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); } + uint32* GetAddressOfEntityProperties() { /* AWFUL */ return (uint32*)((char*)&m_rwObject + sizeof(m_rwObject)); } CEntity(void); ~CEntity(void); diff --git a/src/modelinfo/BaseModelInfo.h b/src/modelinfo/BaseModelInfo.h index a9bafb64..0c4bf934 100644 --- a/src/modelinfo/BaseModelInfo.h +++ b/src/modelinfo/BaseModelInfo.h @@ -2,6 +2,8 @@ #include "Collision.h" +#define MAX_MODEL_NAME (24) + enum ModeInfoType : uint8 { MITYPE_NA = 0, @@ -21,7 +23,7 @@ class CBaseModelInfo { protected: // TODO?: make more things protected - char m_name[24]; + char m_name[MAX_MODEL_NAME]; CColModel *m_colModel; C2dEffect *m_twodEffects; int16 m_objectId; diff --git a/src/control/Gangs.cpp b/src/peds/Gangs.cpp index 57d9c67e..c67fe599 100644 --- a/src/control/Gangs.cpp +++ b/src/peds/Gangs.cpp @@ -4,7 +4,6 @@ #include "Gangs.h" #include "Weapon.h" -//CGangInfo(&CGangs::Gang)[NUM_GANGS] = *(CGangInfo(*)[NUM_GANGS])*(uintptr*)0x6EDF78; CGangInfo CGangs::Gang[NUM_GANGS]; CGangInfo::CGangInfo() : @@ -70,7 +69,6 @@ void CGangs::LoadAllGangData(uint8 *buf, uint32 size) Initialise(); INITSAVEBUF - // original: SkipSaveBuf(buf, SAVE_HEADER_SIZE); CheckSaveHeader(buf, 'G','N','G','\0', size - SAVE_HEADER_SIZE); for (int i = 0; i < NUM_GANGS; i++) diff --git a/src/control/Gangs.h b/src/peds/Gangs.h index dd7a7f93..dd7a7f93 100644 --- a/src/control/Gangs.h +++ b/src/peds/Gangs.h diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp index dfa61584..6959487f 100644 --- a/src/peds/Population.cpp +++ b/src/peds/Population.cpp @@ -29,39 +29,54 @@ #define PED_REMOVE_DIST (MIN_CREATION_DIST + CREATION_RANGE + 1.0f) #define PED_REMOVE_DIST_SPECIAL (MIN_CREATION_DIST + CREATION_RANGE + 15.0f) // for peds with bCullExtraFarAway flag -// TO-DO: These are hard-coded, reverse them. -// More clearly they're transition areas between zones. -RegenerationPoint (&aSafeZones)[8] = *(RegenerationPoint(*)[8]) * (uintptr*)0x5FA578; - -//PedGroup (&CPopulation::ms_pPedGroups)[NUMPEDGROUPS] = *(PedGroup(*)[NUMPEDGROUPS]) * (uintptr*)0x6E9248; -PedGroup CPopulation::ms_pPedGroups[NUMPEDGROUPS]; -bool &CPopulation::ms_bGivePedsWeapons = *(bool*)0x95CCF6; -int32 &CPopulation::m_AllRandomPedsThisType = *(int32*)0x5FA570; -float &CPopulation::PedDensityMultiplier = *(float*)0x5FA56C; -uint32 &CPopulation::ms_nTotalMissionPeds = *(uint32*)0x8F5F70; -int32 &CPopulation::MaxNumberOfPedsInUse = *(int32*)0x5FA574; -uint32& CPopulation::ms_nNumCivMale = *(uint32*)0x8F2548; -uint32& CPopulation::ms_nNumCivFemale = *(uint32*)0x8F5F44; -uint32& CPopulation::ms_nNumCop = *(uint32*)0x885AFC; -bool& CPopulation::bZoneChangeHasHappened = *(bool*)0x95CD79; -uint32& CPopulation::ms_nNumEmergency = *(uint32*)0x94071C; -int8& CPopulation::m_CountDownToPedsAtStart = *(int8*)0x95CD4F; -uint32& CPopulation::ms_nNumGang1 = *(uint32*)0x8F1B1C; -uint32& CPopulation::ms_nNumGang2 = *(uint32*)0x8F1B14; -uint32& CPopulation::ms_nTotalPeds = *(uint32*)0x95CB50; -uint32& CPopulation::ms_nNumGang3 = *(uint32*)0x8F2548; -uint32& CPopulation::ms_nTotalGangPeds = *(uint32*)0x885AF0; -uint32& CPopulation::ms_nNumGang4 = *(uint32*)0x8F1B2C; -uint32& CPopulation::ms_nTotalCivPeds = *(uint32*)0x8F2C3C; -uint32& CPopulation::ms_nNumGang5 = *(uint32*)0x8F1B30; -uint32& CPopulation::ms_nNumDummy = *(uint32*)0x8F1A98; -uint32& CPopulation::ms_nNumGang6 = *(uint32*)0x8F1B20; -uint32& CPopulation::ms_nNumGang9 = *(uint32*)0x8F1B10; -uint32& CPopulation::ms_nNumGang7 = *(uint32*)0x8F1B28; -uint32& CPopulation::ms_nNumGang8 = *(uint32*)0x8F1B0C; -CVector &CPopulation::RegenerationPoint_a = *(CVector*)0x8E2AA4; -CVector &CPopulation::RegenerationPoint_b = *(CVector*)0x8E2A98; -CVector &CPopulation::RegenerationForward = *(CVector*)0x8F1AD4; +// Transition areas between zones +const RegenerationPoint aSafeZones[] = { + { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 400.0f, 814.0f, -954.0f, -903.0f, 30.0f, 100.0f, + CVector(790.0f, -917.0f, 39.0f), CVector(775.0f, -921.0f, 39.0f), CVector(424.0f, -942.0f, 38.0f), CVector(439.0f, -938.0f, 38.0f) }, + { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 555.0f, 711.0f, 118.0f, 186.0f, -30.0f, -10.0f, + CVector(698.0f, 182.0f, -20.0f), CVector(681.0f, 178.0f, -20.0f), CVector(586.0f, 144.0f, -20.0f), CVector(577.0f, 135.0f, -20.0f) }, + { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 26.0f, 44.0f, 124.0f, 87.0f, 20.0f, 6.0f, + CVector(736.0f, -117.0f, -13.0f), CVector(730.0f, -115.0f, -13.0f), CVector(635.0f, -93.0f, -12.5f), CVector(650.0f, -89.0f, -12.5f) }, + { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 45.0f, 34.0f, 780.0f, 750.0f, 25.0f, 6.0f, + CVector(729.0f, -764.0f, -18.0f), CVector(720.0f, -769.0f, -17.0f), CVector(652.0f, -774.0f, -10.5f), CVector(659.0f, -770.0f, -10.5f) }, + { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 532.0f, 136.0f, 668.0f, 599.0f, 4.0f, 0.0f, + CVector(-172.0f, -619.0f, 44.0f), CVector(-183.0f, -623.0f, 44.0f), CVector(-511.0f, -645.0f, 41.0f), CVector(-493.0f, -639.0f, 41.5f) }, + { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 325.0f, 175.0f, 7.0f, 5.0f, 30.0f, 10.0f, + CVector(-185.0f, 40.8f, -20.5f), CVector(-202.0f, 37.0f, -20.5f), CVector(-315.0f, 65.5f, -20.5f), CVector(-306.0f, 62.4f, -20.5f) }, + { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 410.0f, 310.0f, 1055.0f, 1030.0f, 20.0f, 6.0f, + CVector(-321.0f, -1043.0f, -13.2f), CVector(-328.0f, -1045.0f, -13.2f), CVector(-398.0f, -1044.0f, -13.5f), CVector(-390.0f, -1040.5f, -13.5f) }, + { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 425.0f, 280.0f, 471.0f, 447.0f, 20.0f, 5.0f, + CVector(-292.0f, -457.0f, -11.6f), CVector(-310.0f, -461.0f, -11.6f), CVector(-413.0f, -461.0f, -11.5f), CVector(-399.0f, -457.0f, -11.3f) } +}; // *(RegenerationPoint(*)[8]) * (uintptr*)0x5FA578; + +PedGroup CPopulation::ms_pPedGroups[NUMPEDGROUPS]; // = *(PedGroup(*)[NUMPEDGROUPS]) * (uintptr*)0x6E9248; +bool CPopulation::ms_bGivePedsWeapons; // = *(bool*)0x95CCF6; +int32 CPopulation::m_AllRandomPedsThisType = -1; // = *(int32*)0x5FA570; +float CPopulation::PedDensityMultiplier = 1.0f; // = *(float*)0x5FA56C; +uint32 CPopulation::ms_nTotalMissionPeds; // = *(uint32*)0x8F5F70; +int32 CPopulation::MaxNumberOfPedsInUse = 25; // *(int32*)0x5FA574; +uint32 CPopulation::ms_nNumCivMale; // = *(uint32*)0x8F2548; +uint32 CPopulation::ms_nNumCivFemale; // = *(uint32*)0x8F5F44; +uint32 CPopulation::ms_nNumCop; // = *(uint32*)0x885AFC; +bool CPopulation::bZoneChangeHasHappened; // = *(bool*)0x95CD79; +uint32 CPopulation::ms_nNumEmergency; // = *(uint32*)0x94071C; +int8 CPopulation::m_CountDownToPedsAtStart; // = *(int8*)0x95CD4F; +uint32 CPopulation::ms_nNumGang1; // = *(uint32*)0x8F1B1C; +uint32 CPopulation::ms_nNumGang2; // = *(uint32*)0x8F1B14; +uint32 CPopulation::ms_nTotalPeds; // = *(uint32*)0x95CB50; +uint32 CPopulation::ms_nNumGang3; // = *(uint32*)0x8F2548; +uint32 CPopulation::ms_nTotalGangPeds; // = *(uint32*)0x885AF0; +uint32 CPopulation::ms_nNumGang4; // = *(uint32*)0x8F1B2C; +uint32 CPopulation::ms_nTotalCivPeds; // = *(uint32*)0x8F2C3C; +uint32 CPopulation::ms_nNumGang5; // = *(uint32*)0x8F1B30; +uint32 CPopulation::ms_nNumDummy; // = *(uint32*)0x8F1A98; +uint32 CPopulation::ms_nNumGang6; // = *(uint32*)0x8F1B20; +uint32 CPopulation::ms_nNumGang9; // = *(uint32*)0x8F1B10; +uint32 CPopulation::ms_nNumGang7; // = *(uint32*)0x8F1B28; +uint32 CPopulation::ms_nNumGang8; // = *(uint32*)0x8F1B0C; +CVector CPopulation::RegenerationPoint_a; // = *(CVector*)0x8E2AA4; +CVector CPopulation::RegenerationPoint_b; // = *(CVector*)0x8E2A98; +CVector CPopulation::RegenerationForward; // = *(CVector*)0x8F1AD4; void CPopulation::Initialise() diff --git a/src/peds/Population.h b/src/peds/Population.h index f9e6c3b7..aa8129c0 100644 --- a/src/peds/Population.h +++ b/src/peds/Population.h @@ -34,33 +34,33 @@ class CPopulation { public: static PedGroup ms_pPedGroups[NUMPEDGROUPS]; - static bool &ms_bGivePedsWeapons; - static int32 &m_AllRandomPedsThisType; - static float &PedDensityMultiplier; - static uint32 &ms_nTotalMissionPeds; - static int32 &MaxNumberOfPedsInUse; - static uint32& ms_nNumCivMale; - static uint32 &ms_nNumCivFemale; - static uint32 &ms_nNumCop; - static bool &bZoneChangeHasHappened; - static uint32 &ms_nNumEmergency; - static int8& m_CountDownToPedsAtStart; - static uint32& ms_nNumGang1; - static uint32& ms_nNumGang2; - static uint32& ms_nTotalPeds; - static uint32& ms_nNumGang3; - static uint32& ms_nTotalGangPeds; - static uint32& ms_nNumGang4; - static uint32& ms_nTotalCivPeds; - static uint32& ms_nNumGang5; - static uint32& ms_nNumDummy; - static uint32& ms_nNumGang6; - static uint32& ms_nNumGang9; - static uint32& ms_nNumGang7; - static uint32& ms_nNumGang8; - static CVector& RegenerationPoint_a; - static CVector& RegenerationPoint_b; - static CVector& RegenerationForward; + static bool ms_bGivePedsWeapons; + static int32 m_AllRandomPedsThisType; + static float PedDensityMultiplier; + static uint32 ms_nTotalMissionPeds; + static int32 MaxNumberOfPedsInUse; + static uint32 ms_nNumCivMale; + static uint32 ms_nNumCivFemale; + static uint32 ms_nNumCop; + static bool bZoneChangeHasHappened; + static uint32 ms_nNumEmergency; + static int8 m_CountDownToPedsAtStart; + static uint32 ms_nNumGang1; + static uint32 ms_nNumGang2; + static uint32 ms_nTotalPeds; + static uint32 ms_nNumGang3; + static uint32 ms_nTotalGangPeds; + static uint32 ms_nNumGang4; + static uint32 ms_nTotalCivPeds; + static uint32 ms_nNumGang5; + static uint32 ms_nNumDummy; + static uint32 ms_nNumGang6; + static uint32 ms_nNumGang9; + static uint32 ms_nNumGang7; + static uint32 ms_nNumGang8; + static CVector RegenerationPoint_a; + static CVector RegenerationPoint_b; + static CVector RegenerationForward; static void Initialise(); static void Update(void); diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index 44866f4f..44ca3a0a 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -3,6 +3,44 @@ #include "patcher.h" #include "Timecycle.h" #include "skeleton.h" +#if defined(RWLIBS) && !defined(FINAL) +#include "rtcharse.h" +#pragma comment( lib, "rtcharse.lib" ) + +RtCharset *debugCharset; +#endif + +void CreateDebugFont() +{ +#if defined(RWLIBS) && !defined(FINAL) + RwRGBA color = { 255, 255, 128, 255 }; + RwRGBA colorbg = { 0, 0, 0, 0 }; + RtCharsetOpen(); + debugCharset = RtCharsetCreate(&color, &colorbg); +#endif +} + +void DestroyDebugFont() +{ +#if defined(RWLIBS) && !defined(FINAL) + RtCharsetDestroy(debugCharset); + RtCharsetClose(); +#endif +} + +void ObrsPrintfString(const char *str, short x, short y) +{ +#if defined(RWLIBS) && !defined(FINAL) + RtCharsetPrintBuffered(debugCharset, str, x, y, true); +#endif +} + +void FlushObrsPrintfs() +{ +#if defined(RWLIBS) && !defined(FINAL) + RtCharsetBufferFlush(); +#endif +} void * RwMallocAlign(RwUInt32 size, RwUInt32 align) @@ -347,21 +385,6 @@ CameraCreate(RwInt32 width, RwInt32 height, RwBool zBuffer) return (nil); } -void CreateDebugFont() -{ - ; -} - -void DestroyDebugFont() -{ - ; -} - -void FlushObrsPrintfs() -{ - ; -} - WRAPPER void _TexturePoolsInitialise() { EAXJMP(0x598B10); } WRAPPER void _TexturePoolsShutdown() { EAXJMP(0x598B30); } diff --git a/src/rw/RwHelper.h b/src/rw/RwHelper.h index a9f0bdf4..5b47cb6f 100644 --- a/src/rw/RwHelper.h +++ b/src/rw/RwHelper.h @@ -5,6 +5,7 @@ void RwFreeAlign(void *mem); void CreateDebugFont(); void DestroyDebugFont(); +void ObrsPrintfString(const char *str, short x, short y); void FlushObrsPrintfs(); void DefinedState(void); RwFrame *GetFirstChild(RwFrame *frame); diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp index 2545b9ab..0ec0b117 100644 --- a/src/save/GenericGameStorage.cpp +++ b/src/save/GenericGameStorage.cpp @@ -9,17 +9,20 @@ #include "Clock.h" #include "Date.h" #include "FileMgr.h" +#include "Frontend.h" #include "GameLogic.h" #include "Gangs.h" #include "Garages.h" #include "GenericGameStorage.h" #include "Pad.h" +#include "Particle.h" #include "ParticleObject.h" #include "PathFind.h" #include "PCSave.h" #include "Phones.h" #include "Pickups.h" #include "PlayerPed.h" +#include "ProjectileInfo.h" #include "Pools.h" #include "Radar.h" #include "Restart.h" @@ -48,7 +51,6 @@ char SaveFileNameJustSaved[260]; int (&Slots)[SLOT_COUNT+1] = *(int(*)[SLOT_COUNT+1])*(uintptr*)0x72803C; CDate &CompileDateAndTime = *(CDate*)0x72BCB8; - bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8; bool &JustLoadedDontFadeInYet = *(bool*)0x95CDB4; bool &StillToFadeOut = *(bool*)0x95CD99; @@ -58,10 +60,26 @@ uint32 &TimeToStayFadedBeforeFadeOut = *(uint32*)0x611564; #define ReadDataFromBufferPointer(buf, to) memcpy(&to, buf, sizeof(to)); buf += align4bytes(sizeof(to)); #define WriteDataToBufferPointer(buf, from) memcpy(buf, &from, sizeof(from)); buf += align4bytes(sizeof(from)); -WRAPPER bool GenericLoad() { EAXJMP(0x590A00); } +#define LoadSaveDataBlock()\ +do {\ + if (!ReadDataFromFile(file, (uint8 *) &size, 4))\ + return false;\ + size = align4bytes(size);\ + if (!ReadDataFromFile(file, work_buff, size))\ + return false;\ + buf = work_buff;\ +} while (0) +#define ReadDataFromBlock(msg,load_func)\ +do {\ + debug(msg);\ + ReadDataFromBufferPointer(buf, size);\ + load_func(buf, size);\ + size = align4bytes(size);\ + buf += size;\ +} while (0) -#define WRITE_BLOCK(save_func)\ +#define WriteSaveDataBlock(save_func)\ do {\ buf = work_buff;\ reserved = 0;\ @@ -117,11 +135,11 @@ GenericSave(int file) WriteDataToBufferPointer(buf, CClock::ms_nGameClockMinutes); currPad = CPad::GetPad(0); WriteDataToBufferPointer(buf, currPad->Mode); - WriteDataToBufferPointer(buf, CTimer::GetTimeInMilliseconds()); - WriteDataToBufferPointer(buf, CTimer::GetTimeScale()); - WriteDataToBufferPointer(buf, CTimer::GetTimeStep()); - WriteDataToBufferPointer(buf, CTimer::GetTimeStepNonClipped()); - WriteDataToBufferPointer(buf, CTimer::GetFrameCounter()); + WriteDataToBufferPointer(buf, CTimer::m_snTimeInMilliseconds); + WriteDataToBufferPointer(buf, CTimer::ms_fTimeScale); + WriteDataToBufferPointer(buf, CTimer::ms_fTimeStep); + WriteDataToBufferPointer(buf, CTimer::ms_fTimeStepNonClipped); + WriteDataToBufferPointer(buf, CTimer::m_FrameCounter); WriteDataToBufferPointer(buf, CTimeStep::ms_fTimeStep); WriteDataToBufferPointer(buf, CTimeStep::ms_fFramesPerUpdate); WriteDataToBufferPointer(buf, CTimeStep::ms_fTimeScale); @@ -138,7 +156,6 @@ GenericSave(int file) WriteDataToBufferPointer(buf, CWeather::WeatherTypeInList); WriteDataToBufferPointer(buf, TheCamera.CarZoomIndicator); WriteDataToBufferPointer(buf, TheCamera.PedZoomIndicator); - assert(buf - work_buff == SIZE_OF_SIMPLEVARS); // Save scripts, block is nested within the same block as simple vars for some reason @@ -153,25 +170,25 @@ GenericSave(int file) totalSize = buf - work_buff; // Save the rest - WRITE_BLOCK(CPools::SavePedPool); - WRITE_BLOCK(CGarages::Save); - WRITE_BLOCK(CPools::SaveVehiclePool); - WRITE_BLOCK(CPools::SaveObjectPool); - WRITE_BLOCK(ThePaths.Save); - WRITE_BLOCK(CCranes::Save); - WRITE_BLOCK(CPickups::Save); - WRITE_BLOCK(gPhoneInfo.Save); - WRITE_BLOCK(CRestart::SaveAllRestartPoints); - WRITE_BLOCK(CRadar::SaveAllRadarBlips); - WRITE_BLOCK(CTheZones::SaveAllZones); - WRITE_BLOCK(CGangs::SaveAllGangData); - WRITE_BLOCK(CTheCarGenerators::SaveAllCarGenerators); - WRITE_BLOCK(CParticleObject::SaveParticle); - WRITE_BLOCK(cAudioScriptObject::SaveAllAudioScriptObjects); - WRITE_BLOCK(CWorld::Players[CWorld::PlayerInFocus].SavePlayerInfo); - WRITE_BLOCK(CStats::SaveStats); - WRITE_BLOCK(CStreaming::MemoryCardSave); - WRITE_BLOCK(CPedType::Save); + WriteSaveDataBlock(CPools::SavePedPool); + WriteSaveDataBlock(CGarages::Save); + WriteSaveDataBlock(CPools::SaveVehiclePool); + WriteSaveDataBlock(CPools::SaveObjectPool); + WriteSaveDataBlock(ThePaths.Save); + WriteSaveDataBlock(CCranes::Save); + WriteSaveDataBlock(CPickups::Save); + WriteSaveDataBlock(gPhoneInfo.Save); + WriteSaveDataBlock(CRestart::SaveAllRestartPoints); + WriteSaveDataBlock(CRadar::SaveAllRadarBlips); + WriteSaveDataBlock(CTheZones::SaveAllZones); + WriteSaveDataBlock(CGangs::SaveAllGangData); + WriteSaveDataBlock(CTheCarGenerators::SaveAllCarGenerators); + WriteSaveDataBlock(CParticleObject::SaveParticle); + WriteSaveDataBlock(cAudioScriptObject::SaveAllAudioScriptObjects); + WriteSaveDataBlock(CWorld::Players[CWorld::PlayerInFocus].SavePlayerInfo); + WriteSaveDataBlock(CStats::SaveStats); + WriteSaveDataBlock(CStreaming::MemoryCardSave); + WriteSaveDataBlock(CPedType::Save); // Write padding for (int i = 0; i < 4; i++) { @@ -199,6 +216,115 @@ GenericSave(int file) } bool +GenericLoad() +{ + uint8 *buf; + int32 file; + uint32 size; + + int32 saveSize; + CPad *currPad; + + // Load SimpleVars and Scripts + CheckSum = 0; + CDate(CompileDateAndTime); + CPad::ResetCheats(); + if (!ReadInSizeofSaveFileBuffer(file, size)) + return false; + size = align4bytes(size); + ReadDataFromFile(file, work_buff, size); + buf = (work_buff + 0x40); + ReadDataFromBufferPointer(buf, saveSize); + ReadDataFromBufferPointer(buf, CGame::currLevel); + ReadDataFromBufferPointer(buf, TheCamera.GetPosition().x); + ReadDataFromBufferPointer(buf, TheCamera.GetPosition().y); + ReadDataFromBufferPointer(buf, TheCamera.GetPosition().z); + ReadDataFromBufferPointer(buf, CClock::ms_nMillisecondsPerGameMinute); + ReadDataFromBufferPointer(buf, CClock::ms_nLastClockTick); + ReadDataFromBufferPointer(buf, CClock::ms_nGameClockHours); + ReadDataFromBufferPointer(buf, CClock::ms_nGameClockMinutes); + currPad = CPad::GetPad(0); + ReadDataFromBufferPointer(buf, currPad->Mode); + ReadDataFromBufferPointer(buf, CTimer::m_snTimeInMilliseconds); + ReadDataFromBufferPointer(buf, CTimer::ms_fTimeScale); + ReadDataFromBufferPointer(buf, CTimer::ms_fTimeStep); + ReadDataFromBufferPointer(buf, CTimer::ms_fTimeStepNonClipped); + ReadDataFromBufferPointer(buf, CTimer::m_FrameCounter); + ReadDataFromBufferPointer(buf, CTimeStep::ms_fTimeStep); + ReadDataFromBufferPointer(buf, CTimeStep::ms_fFramesPerUpdate); + ReadDataFromBufferPointer(buf, CTimeStep::ms_fTimeScale); + ReadDataFromBufferPointer(buf, CWeather::OldWeatherType); + ReadDataFromBufferPointer(buf, CWeather::NewWeatherType); + ReadDataFromBufferPointer(buf, CWeather::ForcedWeatherType); + ReadDataFromBufferPointer(buf, CWeather::InterpolationValue); + ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nSecond); + ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nMinute); + ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nHour); + ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nDay); + ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nMonth); + ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nYear); + ReadDataFromBufferPointer(buf, CWeather::WeatherTypeInList); + ReadDataFromBufferPointer(buf, TheCamera.CarZoomIndicator); + ReadDataFromBufferPointer(buf, TheCamera.PedZoomIndicator); + assert(buf - work_buff == SIZE_OF_SIMPLEVARS); + ReadDataFromBlock("Loading Scripts \n", CTheScripts::LoadAllScripts); + + // Load the rest + LoadSaveDataBlock(); + ReadDataFromBlock("Loading PedPool \n", CPools::LoadPedPool); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Garages \n", CGarages::Load); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Vehicles \n", CPools::LoadVehiclePool); + LoadSaveDataBlock(); + CProjectileInfo::RemoveAllProjectiles(); + CObject::DeleteAllTempObjects(); + ReadDataFromBlock("Loading Objects \n", CPools::LoadObjectPool); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Paths \n", ThePaths.Load); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Cranes \n", CCranes::Load); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Pickups \n", CPickups::Load); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Phoneinfo \n", gPhoneInfo.Load); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Restart \n", CRestart::LoadAllRestartPoints); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Radar Blips \n", CRadar::LoadAllRadarBlips); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Zones \n", CTheZones::LoadAllZones); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Gang Data \n", CGangs::LoadAllGangData); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Car Generators \n", CTheCarGenerators::LoadAllCarGenerators); + CParticle::ReloadConfig(); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Particles \n", CParticleObject::LoadParticle); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading AudioScript Objects \n", cAudioScriptObject::LoadAllAudioScriptObjects); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Player Info \n", CWorld::Players[CWorld::PlayerInFocus].LoadPlayerInfo); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Stats \n", CStats::LoadStats); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading Streaming Stuff \n", CStreaming::MemoryCardLoad); + LoadSaveDataBlock(); + ReadDataFromBlock("Loading PedType Stuff \n", CPedType::Load); + + DMAudio.SetMusicMasterVolume(CMenuManager::m_PrefsMusicVolume); + DMAudio.SetEffectsMasterVolume(CMenuManager::m_PrefsSfxVolume); + if (!CloseFile(file)) { + PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_CLOSE; + return false; + } + + DoGameSpecificStuffAfterSucessLoad(); + debug("Game successfully loaded \n"); + return true; +} + +bool ReadInSizeofSaveFileBuffer(int32 &file, uint32 &size) { file = CFileMgr::OpenFile(LoadFileName, "rb"); @@ -411,7 +537,7 @@ align4bytes(int32 size) STARTPATCHES InjectHook(0x58F8D0, GenericSave, PATCH_JUMP); - //InjectHook(0x590A00, GenericLoad, PATCH_JUMP); + InjectHook(0x590A00, GenericLoad, PATCH_JUMP); InjectHook(0x591910, ReadInSizeofSaveFileBuffer, PATCH_JUMP); InjectHook(0x591990, ReadDataFromFile, PATCH_JUMP); InjectHook(0x591A00, CloseFile, PATCH_JUMP); diff --git a/src/control/CarGen.cpp b/src/vehicles/CarGen.cpp index 721ac35a..43f77fb7 100644 --- a/src/control/CarGen.cpp +++ b/src/vehicles/CarGen.cpp @@ -14,11 +14,11 @@ #include "Vehicle.h" #include "World.h" -uint8 &CTheCarGenerators::ProcessCounter = *(uint8*)0x95CDAF; -uint32 &CTheCarGenerators::NumOfCarGenerators = *(uint32*)0x8E2C1C; -CCarGenerator (&CTheCarGenerators::CarGeneratorArray)[NUM_CARGENS] = *(CCarGenerator(*)[NUM_CARGENS])*(uintptr*)0x87CB18; -uint8 &CTheCarGenerators::GenerateEvenIfPlayerIsCloseCounter = *(uint8*)0x95CDC6; -uint32 &CTheCarGenerators::CurrentActiveCount = *(uint32*)0x8F2C5C; +uint8 CTheCarGenerators::ProcessCounter; +uint32 CTheCarGenerators::NumOfCarGenerators; +CCarGenerator CTheCarGenerators::CarGeneratorArray[NUM_CARGENS]; +uint8 CTheCarGenerators::GenerateEvenIfPlayerIsCloseCounter; +uint32 CTheCarGenerators::CurrentActiveCount; void CCarGenerator::SwitchOff() { @@ -187,59 +187,6 @@ bool CCarGenerator::CheckIfWithinRangeOfAnyPlayer() return DotProduct2D(direction, FindPlayerSpeed()) <= 0; } -void CCarGenerator::Save(uint8 *&buffer) -{ - WriteSaveBuf(buffer, m_nModelIndex); - WriteSaveBuf(buffer, m_vecPos); - WriteSaveBuf(buffer, m_fAngle); - WriteSaveBuf(buffer, m_nColor1); - WriteSaveBuf(buffer, m_nColor2); - WriteSaveBuf(buffer, m_bForceSpawn); - WriteSaveBuf(buffer, m_nAlarm); - WriteSaveBuf(buffer, m_nDoorlock); - WriteSaveBuf(buffer, (uint8)0); - WriteSaveBuf(buffer, m_nMinDelay); - WriteSaveBuf(buffer, m_nMaxDelay); - WriteSaveBuf(buffer, m_nTimer); - WriteSaveBuf(buffer, m_nVehicleHandle); - WriteSaveBuf(buffer, m_nUsesRemaining); - WriteSaveBuf(buffer, m_bIsBlocking); - WriteSaveBuf(buffer, (uint8)0); - WriteSaveBuf(buffer, m_vecInf); - WriteSaveBuf(buffer, m_vecSup); - WriteSaveBuf(buffer, m_fSize); - - // or - //WriteSaveBuf(buffer, *this); - -} - -void CCarGenerator::Load(uint8 *&buffer) -{ - m_nModelIndex = ReadSaveBuf<uint32>(buffer); - m_vecPos = ReadSaveBuf<CVector>(buffer); - m_fAngle = ReadSaveBuf<float>(buffer); - m_nColor1 = ReadSaveBuf<int16>(buffer); - m_nColor2 = ReadSaveBuf<int16>(buffer); - m_bForceSpawn = ReadSaveBuf<uint8>(buffer); - m_nAlarm = ReadSaveBuf<uint8>(buffer); - m_nDoorlock = ReadSaveBuf<uint8>(buffer); - ReadSaveBuf<uint8>(buffer); - m_nMinDelay = ReadSaveBuf<uint16>(buffer); - m_nMaxDelay = ReadSaveBuf<uint16>(buffer); - m_nTimer = ReadSaveBuf<uint32>(buffer); - m_nVehicleHandle = ReadSaveBuf<int32>(buffer); - m_nUsesRemaining = ReadSaveBuf<uint16>(buffer); - m_bIsBlocking = ReadSaveBuf<bool>(buffer); - ReadSaveBuf<uint8>(buffer); - m_vecInf = ReadSaveBuf<CVector>(buffer); - m_vecSup = ReadSaveBuf<CVector>(buffer); - m_fSize = ReadSaveBuf<float>(buffer); - - // or - //*this = ReadSaveBuf<CCarGenerator>(buffer); -} - void CTheCarGenerators::Process() { if (FindPlayerTrain() || CCutsceneMgr::IsCutsceneProcessing()) @@ -268,39 +215,38 @@ void CTheCarGenerators::Init() void CTheCarGenerators::SaveAllCarGenerators(uint8 *buffer, uint32 *size) { - *size = 20 + sizeof(CarGeneratorArray) + SAVE_HEADER_SIZE; + const uint32 nGeneralDataSize = sizeof(NumOfCarGenerators) + sizeof(CurrentActiveCount) + sizeof(ProcessCounter) + sizeof(GenerateEvenIfPlayerIsCloseCounter) + sizeof(int16); + *size = sizeof(int) + nGeneralDataSize + sizeof(CarGeneratorArray) + SAVE_HEADER_SIZE; INITSAVEBUF WriteSaveHeader(buffer, 'C','G','N','\0', *size - SAVE_HEADER_SIZE); - WriteSaveBuf(buffer, 12); /* what is this? */ + WriteSaveBuf(buffer, nGeneralDataSize); WriteSaveBuf(buffer, NumOfCarGenerators); WriteSaveBuf(buffer, CurrentActiveCount); WriteSaveBuf(buffer, ProcessCounter); WriteSaveBuf(buffer, GenerateEvenIfPlayerIsCloseCounter); - WriteSaveBuf(buffer, (int16)0); + WriteSaveBuf(buffer, (int16)0); // alignment WriteSaveBuf(buffer, sizeof(CarGeneratorArray)); - for (int i = 0; i < NUM_CARGENS; i++){ - CarGeneratorArray[i].Save(buffer); - } + for (int i = 0; i < NUM_CARGENS; i++) + WriteSaveBuf(buffer, CarGeneratorArray[i]); VALIDATESAVEBUF(*size) } void CTheCarGenerators::LoadAllCarGenerators(uint8* buffer, uint32 size) { + const int32 nGeneralDataSize = sizeof(NumOfCarGenerators) + sizeof(CurrentActiveCount) + sizeof(ProcessCounter) + sizeof(GenerateEvenIfPlayerIsCloseCounter) + sizeof(int16); Init(); INITSAVEBUF - assert(size == 20 + sizeof(CarGeneratorArray) + SAVE_HEADER_SIZE); CheckSaveHeader(buffer, 'C','G','N','\0', size - SAVE_HEADER_SIZE); - ReadSaveBuf<uint32>(buffer); + assert(ReadSaveBuf<uint32>(buffer) == nGeneralDataSize); NumOfCarGenerators = ReadSaveBuf<uint32>(buffer); CurrentActiveCount = ReadSaveBuf<uint32>(buffer); ProcessCounter = ReadSaveBuf<uint8>(buffer); GenerateEvenIfPlayerIsCloseCounter = ReadSaveBuf<uint8>(buffer); - ReadSaveBuf<int16>(buffer); + ReadSaveBuf<int16>(buffer); // alignment assert(ReadSaveBuf<uint32>(buffer) == sizeof(CarGeneratorArray)); - for (int i = 0; i < NUM_CARGENS; i++) { - CarGeneratorArray[i].Load(buffer); - } + for (int i = 0; i < NUM_CARGENS; i++) + CarGeneratorArray[i] = ReadSaveBuf<CCarGenerator>(buffer); VALIDATESAVEBUF(size) } diff --git a/src/control/CarGen.h b/src/vehicles/CarGen.h index 75acdd56..9d645318 100644 --- a/src/control/CarGen.h +++ b/src/vehicles/CarGen.h @@ -34,19 +34,17 @@ public: void Setup(float x, float y, float z, float angle, int32 mi, int16 color1, int16 color2, uint8 force, uint8 alarm, uint8 lock, uint16 min_delay, uint16 max_delay); bool CheckForBlockage(); bool CheckIfWithinRangeOfAnyPlayer(); - void Save(uint8*&); - void Load(uint8*&); void SetUsesRemaining(uint16 uses) { m_nUsesRemaining = uses; } }; class CTheCarGenerators { public: - static uint8 &ProcessCounter; - static uint32 &NumOfCarGenerators; - static CCarGenerator (&CarGeneratorArray)[NUM_CARGENS]; - static uint8 &GenerateEvenIfPlayerIsCloseCounter; - static uint32 &CurrentActiveCount; + static uint8 ProcessCounter; + static uint32 NumOfCarGenerators; + static CCarGenerator CarGeneratorArray[NUM_CARGENS]; + static uint8 GenerateEvenIfPlayerIsCloseCounter; + static uint32 CurrentActiveCount; static void Process(); static int32 CreateCarGenerator(float x, float y, float z, float angle, int32 mi, int16 color1, int16 color2, uint8 force, uint8 alarm, uint8 lock, uint16 min_delay, uint16 max_delay); diff --git a/src/control/Cranes.cpp b/src/vehicles/Cranes.cpp index 33385dae..dbc3c340 100644 --- a/src/control/Cranes.cpp +++ b/src/vehicles/Cranes.cpp @@ -38,9 +38,9 @@ uint32 TimerForCamInterpolation; -uint32& CCranes::CarsCollectedMilitaryCrane = *(uint32*)0x8F6248; -int32& CCranes::NumCranes = *(int32*)0x8E28AC; -CCrane(&CCranes::aCranes)[NUM_CRANES] = *(CCrane(*)[NUM_CRANES])*(uintptr*)0x6FA4E0; +uint32 CCranes::CarsCollectedMilitaryCrane; +int32 CCranes::NumCranes; +CCrane CCranes::aCranes[NUM_CRANES]; void CCranes::InitCranes(void) { @@ -466,13 +466,13 @@ bool CCrane::DoesCranePickUpThisCarType(uint32 mi) bool CCranes::DoesMilitaryCraneHaveThisOneAlready(uint32 mi) { switch (mi) { - case MI_FIRETRUCK: return (CCranes::CarsCollectedMilitaryCrane & 1); - case MI_AMBULAN: return (CCranes::CarsCollectedMilitaryCrane & 2); - case MI_ENFORCER: return (CCranes::CarsCollectedMilitaryCrane & 4); - case MI_FBICAR: return (CCranes::CarsCollectedMilitaryCrane & 8); - case MI_RHINO: return (CCranes::CarsCollectedMilitaryCrane & 0x10); - case MI_BARRACKS: return (CCranes::CarsCollectedMilitaryCrane & 0x20); - case MI_POLICE: return (CCranes::CarsCollectedMilitaryCrane & 0x40); + case MI_FIRETRUCK: return (CarsCollectedMilitaryCrane & 1); + case MI_AMBULAN: return (CarsCollectedMilitaryCrane & 2); + case MI_ENFORCER: return (CarsCollectedMilitaryCrane & 4); + case MI_FBICAR: return (CarsCollectedMilitaryCrane & 8); + case MI_RHINO: return (CarsCollectedMilitaryCrane & 0x10); + case MI_BARRACKS: return (CarsCollectedMilitaryCrane & 0x20); + case MI_POLICE: return (CarsCollectedMilitaryCrane & 0x40); default: break; } return false; @@ -481,20 +481,20 @@ bool CCranes::DoesMilitaryCraneHaveThisOneAlready(uint32 mi) void CCranes::RegisterCarForMilitaryCrane(uint32 mi) { switch (mi) { - case MI_FIRETRUCK: CCranes::CarsCollectedMilitaryCrane |= 1; break; - case MI_AMBULAN: CCranes::CarsCollectedMilitaryCrane |= 2; break; - case MI_ENFORCER: CCranes::CarsCollectedMilitaryCrane |= 4; break; - case MI_FBICAR: CCranes::CarsCollectedMilitaryCrane |= 8; break; - case MI_RHINO: CCranes::CarsCollectedMilitaryCrane |= 0x10; break; - case MI_BARRACKS: CCranes::CarsCollectedMilitaryCrane |= 0x20; break; - case MI_POLICE: CCranes::CarsCollectedMilitaryCrane |= 0x40; break; + case MI_FIRETRUCK: CarsCollectedMilitaryCrane |= 1; break; + case MI_AMBULAN: CarsCollectedMilitaryCrane |= 2; break; + case MI_ENFORCER: CarsCollectedMilitaryCrane |= 4; break; + case MI_FBICAR: CarsCollectedMilitaryCrane |= 8; break; + case MI_RHINO: CarsCollectedMilitaryCrane |= 0x10; break; + case MI_BARRACKS: CarsCollectedMilitaryCrane |= 0x20; break; + case MI_POLICE: CarsCollectedMilitaryCrane |= 0x40; break; default: break; } } bool CCranes::HaveAllCarsBeenCollectedByMilitaryCrane() { - return (CCranes::CarsCollectedMilitaryCrane & 0x7F) == 0x7F; + return (CarsCollectedMilitaryCrane & 0x7F) == 0x7F; } bool CCrane::GoTowardsTarget(float fAngleToTarget, float fDistanceToTarget, float fTargetHeight, float fSpeedMultiplier) @@ -509,8 +509,7 @@ bool CCrane::GoTowardsTarget(float fAngleToTarget, float fDistanceToTarget, floa if (Abs(fHookAngleDelta) < fHookAngleChangeThisFrame) { m_fHookAngle = fAngleToTarget; bAngleMovementFinished = true; - } - else { + } else { if (fHookAngleDelta < 0.0f) { m_fHookAngle -= fHookAngleChangeThisFrame; if (m_fHookAngle < 0.0f) @@ -528,8 +527,7 @@ bool CCrane::GoTowardsTarget(float fAngleToTarget, float fDistanceToTarget, floa if (Abs(fHookOffsetDelta) < fHookOffsetChangeThisFrame) { m_fHookOffset = fDistanceToTarget; bOffsetMovementFinished = true; - } - else { + } else { if (fHookOffsetDelta < 0.0f) m_fHookOffset -= fHookOffsetChangeThisFrame; else @@ -541,8 +539,7 @@ bool CCrane::GoTowardsTarget(float fAngleToTarget, float fDistanceToTarget, floa if (Abs(fHookHeightDelta) < fHookHeightChangeThisFrame) { m_fHookHeight = fTargetHeight; bHeightMovementFinished = true; - } - else { + } else { if (fHookHeightDelta < 0.0f) m_fHookHeight -= fHookHeightChangeThisFrame; else @@ -560,8 +557,7 @@ bool CCrane::GoTowardsHeightTarget(float fTargetHeight, float fSpeedMultiplier) if (Abs(fHookHeightDelta) < fHookHeightChangeThisFrame) { m_fHookHeight = fTargetHeight; bHeightMovementFinished = true; - } - else { + } else { if (fHookHeightDelta < 0.0f) m_fHookHeight -= fHookHeightChangeThisFrame; else @@ -587,7 +583,7 @@ void CCrane::CalcHookCoordinates(float* pX, float* pY, float* pZ) void CCrane::SetHookMatrix() { - if (!m_pHook) + if (m_pHook == nil) return; m_pHook->GetPosition() = m_vecHookCurPos; CVector up(m_vecHookInitPos.x - m_vecHookCurPos.x, m_vecHookInitPos.y - m_vecHookCurPos.y, 20.0f); @@ -632,48 +628,44 @@ void CCranes::Save(uint8* buf, uint32* size) { INITSAVEBUF - *size = 2 * sizeof(uint32) + NUM_CRANES * sizeof(CCrane); + *size = 2 * sizeof(uint32) + sizeof(aCranes); WriteSaveBuf(buf, NumCranes); WriteSaveBuf(buf, CarsCollectedMilitaryCrane); for (int i = 0; i < NUM_CRANES; i++) { - CCrane* pCrane = WriteSaveBuf(buf, aCranes[i]); - if (pCrane->m_pCraneEntity) - pCrane->m_pCraneEntity = (CBuilding*)(CPools::GetBuildingPool()->GetJustIndex((CBuilding*)pCrane->m_pCraneEntity) + 1); - if (pCrane->m_pHook) - pCrane->m_pHook = (CObject*)(CPools::GetObjectPool()->GetJustIndex((CObject*)pCrane->m_pHook) + 1); - if (pCrane->m_pVehiclePickedUp) - pCrane->m_pVehiclePickedUp = (CVehicle*)(CPools::GetVehiclePool()->GetJustIndex((CVehicle*)pCrane->m_pVehiclePickedUp) + 1); + CCrane *pCrane = WriteSaveBuf(buf, aCranes[i]); + if (pCrane->m_pCraneEntity != nil) + pCrane->m_pCraneEntity = (CBuilding*)(CPools::GetBuildingPool()->GetJustIndex(pCrane->m_pCraneEntity) + 1); + if (pCrane->m_pHook != nil) + pCrane->m_pHook = (CObject*)(CPools::GetObjectPool()->GetJustIndex(pCrane->m_pHook) + 1); + if (pCrane->m_pVehiclePickedUp != nil) + pCrane->m_pVehiclePickedUp = (CVehicle*)(CPools::GetVehiclePool()->GetJustIndex(pCrane->m_pVehiclePickedUp) + 1); } VALIDATESAVEBUF(*size); } -void CranesLoad(uint8* buf, uint32 size) +void CCranes::Load(uint8* buf, uint32 size) { INITSAVEBUF - CCranes::NumCranes = ReadSaveBuf<int32>(buf); - CCranes::CarsCollectedMilitaryCrane = ReadSaveBuf<uint32>(buf); + NumCranes = ReadSaveBuf<int32>(buf); + CarsCollectedMilitaryCrane = ReadSaveBuf<uint32>(buf); for (int i = 0; i < NUM_CRANES; i++) - CCranes::aCranes[i] = ReadSaveBuf<CCrane>(buf); + aCranes[i] = ReadSaveBuf<CCrane>(buf); for (int i = 0; i < NUM_CRANES; i++) { - CCrane* pCrane = &CCranes::aCranes[i]; - if (pCrane->m_pCraneEntity) + CCrane *pCrane = &aCranes[i]; + if (pCrane->m_pCraneEntity != nil) pCrane->m_pCraneEntity = CPools::GetBuildingPool()->GetSlot((uint32)pCrane->m_pCraneEntity - 1); - if (pCrane->m_pHook) + if (pCrane->m_pHook != nil) pCrane->m_pHook = CPools::GetObjectPool()->GetSlot((uint32)pCrane->m_pHook - 1); - if (pCrane->m_pVehiclePickedUp) - pCrane->m_pVehiclePickedUp = CPools::GetVehiclePool()->GetSlot((uint32)pCrane->m_pVehiclePickedUp + 1); + if (pCrane->m_pVehiclePickedUp != nil) + pCrane->m_pVehiclePickedUp = CPools::GetVehiclePool()->GetSlot((uint32)pCrane->m_pVehiclePickedUp - 1); } for (int i = 0; i < NUM_CRANES; i++) { - CCranes::aCranes[i].m_nAudioEntity = DMAudio.CreateEntity(AUDIOTYPE_CRANE, &CCranes::aCranes[i]); - if (CCranes::aCranes[i].m_nAudioEntity) - DMAudio.SetEntityStatus(CCranes::aCranes[i].m_nAudioEntity, 1); + aCranes[i].m_nAudioEntity = DMAudio.CreateEntity(AUDIOTYPE_CRANE, &aCranes[i]); + if (aCranes[i].m_nAudioEntity != 0) + DMAudio.SetEntityStatus(aCranes[i].m_nAudioEntity, 1); } VALIDATESAVEBUF(size); } - -STARTPATCHES - InjectHook(0x5454D0, CranesLoad, PATCH_JUMP); // GenericLoad -ENDPATCHES diff --git a/src/control/Cranes.h b/src/vehicles/Cranes.h index d9817282..c0502638 100644 --- a/src/control/Cranes.h +++ b/src/vehicles/Cranes.h @@ -89,10 +89,9 @@ public: static bool IsThisCarBeingCarriedByAnyCrane(CVehicle* pVehicle); static bool IsThisCarBeingTargettedByAnyCrane(CVehicle* pVehicle); static void Save(uint8* buf, uint32* size); + static void Load(uint8* buf, uint32 size); // on mobile it's CranesLoad outside of the class - static uint32& CarsCollectedMilitaryCrane; - static int32& NumCranes; - static CCrane(&aCranes)[NUM_CRANES]; + static uint32 CarsCollectedMilitaryCrane; + static int32 NumCranes; + static CCrane aCranes[NUM_CRANES]; }; - -void CranesLoad(uint8*, uint32); // is this really outside CCranes? diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index ede9f8fe..f9becda0 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -130,7 +130,8 @@ public: int8 m_nGettingInFlags; int8 m_nGettingOutFlags; uint8 m_nNumMaxPassengers; - char field_1CD[19]; + char field_1CD[3]; + float field_1D0[4]; CEntity *m_pCurGroundEntity; CFire *m_pCarFire; float m_fSteerAngle; |