summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolay Korolev <nickvnuk@gmail.com>2020-04-11 01:03:42 +0200
committerNikolay Korolev <nickvnuk@gmail.com>2020-04-11 01:03:42 +0200
commit92b6d775d67d01aab0706564b2cae3714bcf05b0 (patch)
tree714f32c096807d919f95ff4c2d31990f3e34b08c
parentMerge branch 'master' into garages_dev (diff)
downloadre3-92b6d775d67d01aab0706564b2cae3714bcf05b0.tar
re3-92b6d775d67d01aab0706564b2cae3714bcf05b0.tar.gz
re3-92b6d775d67d01aab0706564b2cae3714bcf05b0.tar.bz2
re3-92b6d775d67d01aab0706564b2cae3714bcf05b0.tar.lz
re3-92b6d775d67d01aab0706564b2cae3714bcf05b0.tar.xz
re3-92b6d775d67d01aab0706564b2cae3714bcf05b0.tar.zst
re3-92b6d775d67d01aab0706564b2cae3714bcf05b0.zip
-rw-r--r--src/control/Record.cpp355
-rw-r--r--src/control/Record.h54
-rw-r--r--src/core/Pad.cpp3
-rw-r--r--src/core/Timer.cpp2
-rw-r--r--src/vehicles/Automobile.cpp2
5 files changed, 394 insertions, 22 deletions
diff --git a/src/control/Record.cpp b/src/control/Record.cpp
index 7a3763be..19fd8969 100644
--- a/src/control/Record.cpp
+++ b/src/control/Record.cpp
@@ -5,7 +5,10 @@
#include "FileMgr.h"
#include "Pad.h"
#include "Pools.h"
+#include "Streaming.h"
#include "Timer.h"
+#include "VehicleModelInfo.h"
+#include "World.h"
uint16 &CRecordDataForGame::RecordingState = *(uint16*)0x95CC24;
uint8*& CRecordDataForGame::pDataBuffer = *(uint8**)0x8F1B70;
@@ -13,8 +16,6 @@ uint8*& CRecordDataForGame::pDataBufferPointer = *(uint8**)0x8F1AB0;
int& CRecordDataForGame::FId = *(int*)0x885BA4;
tGameBuffer& CRecordDataForGame::pDataBufferForFrame = *(tGameBuffer*)0x72CED0;
-uint8 &CRecordDataForChase::Status = *(uint8*)0x95CDCE;
-
#define MEMORY_FOR_GAME_RECORD (150000)
void CRecordDataForGame::Init(void)
@@ -176,16 +177,348 @@ uint16 CRecordDataForGame::CalcGameChecksum(void)
return checksum ^ checksum >> 16;
}
-WRAPPER void CRecordDataForChase::Init(void)
+uint8& CRecordDataForChase::Status = *(uint8*)0x95CDCE;
+int& CRecordDataForChase::PositionChanges = *(int*)0x8F59C8;
+uint8& CRecordDataForChase::CurrentCar = *(uint8*)0x95CDC9;
+CAutomobile* (&CRecordDataForChase::pChaseCars)[NUM_CHASE_CARS] = *(CAutomobile * (*)[NUM_CHASE_CARS])*(uintptr*)0x6F46A8;
+uint32& CRecordDataForChase::AnimStartTime = *(uint32*)0x8F1AEC;
+float& CRecordDataForChase::AnimTime = *(float*)0x880F88;
+CCarStateEachFrame* (&CRecordDataForChase::pBaseMemForCar)[NUM_CHASE_CARS] = *(CCarStateEachFrame * (*)[NUM_CHASE_CARS])*(uintptr*)0x70EA18;
+float& CRecordDataForChase::TimeMultiplier = *(float*)0x8E2A94;
+int& CRecordDataForChase::FId2 = *(int*)0x8E2C18;
+
+#define CHASE_SCENE_LENGTH_IN_SECONDS (80)
+#define CHASE_SCENE_FRAMES_PER_SECOND (15) // skipping every second frame
+#define CHASE_SCENE_FRAMES_IN_RECORDING (CHASE_SCENE_LENGTH_IN_SECONDS * CHASE_SCENE_FRAMES_PER_SECOND)
+#define CHASE_SCENE_LENGTH_IN_FRAMES (CHASE_SCENE_FRAMES_IN_RECORDING * 2)
+
+void CRecordDataForChase::Init(void)
+{
+ Status = STATE_NONE;
+ PositionChanges = 0;
+ CurrentCar = 0;
+ for (int i = 0; i < NUM_CHASE_CARS; i++)
+ pChaseCars[i] = nil;
+ AnimStartTime = 0;
+}
+
+void CRecordDataForChase::SaveOrRetrieveDataForThisFrame(void)
+{
+ switch (Status) {
+ case STATE_NONE:
+ return;
+ case STATE_RECORD:
+ {
+ if ((CTimer::GetFrameCounter() & 1) == 0)
+ StoreInfoForCar(pChaseCars[CurrentCar], &pBaseMemForCar[CurrentCar][CTimer::GetFrameCounter() / 2]);
+ if (CTimer::GetFrameCounter() < CHASE_SCENE_LENGTH_IN_FRAMES * 2)
+ return;
+ CFileMgr::SetDir("data\\paths");
+ sprintf(gString, "chase%d.dat", CurrentCar);
+ int fid = CFileMgr::OpenFileForWriting(gString);
+ uint32 fs = CHASE_SCENE_LENGTH_IN_FRAMES * sizeof(CCarStateEachFrame);
+ printf("FileSize:%d\n", fs);
+ CFileMgr::Write(fid, (char*)pBaseMemForCar[CurrentCar], fs);
+ CFileMgr::CloseFile(fid);
+ CFileMgr::SetDir("");
+ sprintf(gString, "car%d.max", CurrentCar);
+ int fid2 = CFileMgr::OpenFileForWriting(gString);
+ for (int i = 0; i < CHASE_SCENE_FRAMES_IN_RECORDING; i++) {
+ // WTF? Was it ever used?
+#ifdef FIX_BUGS
+ CCarStateEachFrame* pState = pBaseMemForCar[CurrentCar];
+#else
+ CCarStateEachFrame* pState = (CCarStateEachFrame*)pChaseCars[CurrentCar];
+#endif
+ CVector right = CVector(pState->rightX, pState->rightY, pState->rightZ) / (UINT8_MAX / 2);
+ CVector forward = CVector(pState->forwardX, pState->forwardY, pState->forwardZ) / (UINT8_MAX / 2);
+ CVector up = CrossProduct(right, forward);
+ sprintf(gString, "%f %f %f\n", pState->pos.x, pState->pos.y, pState->pos.z);
+ CFileMgr::Write(fid2, gString, strlen(gString) - 1);
+ sprintf(gString, "%f %f %f\n", right.x, right.y, right.z);
+ CFileMgr::Write(fid2, gString, strlen(gString) - 1);
+ sprintf(gString, "%f %f %f\n", forward.x, forward.y, forward.z);
+ CFileMgr::Write(fid2, gString, strlen(gString) - 1);
+ sprintf(gString, "%f %f %f\n", up.x, up.y, up.z);
+ CFileMgr::Write(fid2, gString, strlen(gString) - 1);
+ }
+ CFileMgr::CloseFile(fid2);
+ }
+ case STATE_PLAYBACK:
+ case STATE_PLAYBACK_BEFORE_RECORDING:
+ case STATE_PLAYBACK_INIT:
+ break;
+ }
+}
+
+struct tCoors {
+ CVector pos;
+ float angle;
+};
+
+// I guess developer was filling this with actual data before running the game
+tCoors NewCoorsForRecordedCars[7];
+
+void CRecordDataForChase::SaveOrRetrieveCarPositions(void)
+{
+ switch (Status) {
+ case STATE_NONE:
+ return;
+ case STATE_RECORD:
+ case STATE_PLAYBACK_BEFORE_RECORDING:
+ for (int i = 0; i < NUM_CHASE_CARS; i++) {
+ if (i != CurrentCar && CTimer::GetFrameCounter()) {
+ RestoreInfoForCar(pChaseCars[i], &pBaseMemForCar[i][CTimer::GetFrameCounter() / 2], false);
+ pChaseCars[i]->GetMatrix().UpdateRW();
+ pChaseCars[i]->UpdateRwFrame();
+ }
+ }
+ if (Status == STATE_PLAYBACK_BEFORE_RECORDING && CTimer::GetFrameCounter()) {
+ RestoreInfoForCar(pChaseCars[CurrentCar], &pBaseMemForCar[CurrentCar][CTimer::GetFrameCounter() / 2], false);
+ pChaseCars[CurrentCar]->GetMatrix().UpdateRW();
+ pChaseCars[CurrentCar]->UpdateRwFrame();
+ }
+ if (CPad::GetPad(0)->GetLeftShockJustDown() && CPad::GetPad(0)->GetRightShockJustDown()) {
+ if (!CPad::GetPad(0)->GetRightShockJustDown()) {
+ pChaseCars[CurrentCar]->GetPosition() = NewCoorsForRecordedCars[PositionChanges].pos;
+ pChaseCars[CurrentCar]->SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ pChaseCars[CurrentCar]->GetMatrix().SetRotateZOnly(DEGTORAD(NewCoorsForRecordedCars[PositionChanges].angle));
+ ++PositionChanges;
+ }
+ if (Status == STATE_PLAYBACK_BEFORE_RECORDING) {
+ Status = STATE_RECORD;
+ pChaseCars[CurrentCar]->m_status = STATUS_PLAYER;
+ }
+ }
+ break;
+ case STATE_PLAYBACK_INIT:
+ Status = STATE_PLAYBACK;
+ break;
+ case STATE_PLAYBACK:
+ {
+ TimeMultiplier += CTimer::GetTimeStepNonClippedInSeconds();
+ float EndOfFrameTime = CHASE_SCENE_FRAMES_PER_SECOND * min(CHASE_SCENE_LENGTH_IN_SECONDS, TimeMultiplier);
+ for (int i = 0; i < NUM_CHASE_CARS; i++) {
+ if (!pBaseMemForCar[i])
+ continue;
+ if (!pChaseCars[i])
+ continue;
+ if (EndOfFrameTime < CHASE_SCENE_FRAMES_IN_RECORDING - 1) {
+ int FlooredEOFTime = EndOfFrameTime;
+ RestoreInfoForCar(pChaseCars[i], &pBaseMemForCar[i][FlooredEOFTime], false);
+ CMatrix tmp;
+ float dp = EndOfFrameTime - FlooredEOFTime;
+ RestoreInfoForMatrix(tmp, &pBaseMemForCar[i][FlooredEOFTime + 1]);
+ pChaseCars[i]->GetRight() += (tmp.GetRight() - pChaseCars[i]->GetRight()) * dp;
+ pChaseCars[i]->GetForward() += (tmp.GetForward() - pChaseCars[i]->GetForward()) * dp;
+ pChaseCars[i]->GetUp() += (tmp.GetUp() - pChaseCars[i]->GetUp()) * dp;
+ pChaseCars[i]->GetPosition() += (tmp.GetPosition() - pChaseCars[i]->GetPosition()) * dp;
+ }
+ else{
+ RestoreInfoForCar(pChaseCars[i], &pBaseMemForCar[i][CHASE_SCENE_FRAMES_IN_RECORDING - 1], true);
+ if (i == 0)
+ pChaseCars[i]->GetPosition().z += 0.2f;
+ }
+ pChaseCars[i]->GetMatrix().UpdateRW();
+ pChaseCars[i]->UpdateRwFrame();
+ pChaseCars[i]->RemoveAndAdd();
+ }
+ break;
+ }
+ }
+}
+
+void CRecordDataForChase::StoreInfoForCar(CAutomobile* pCar, CCarStateEachFrame* pState)
+{
+ pState->rightX = UINT8_MAX / 2 * pCar->GetRight().x;
+ pState->rightY = UINT8_MAX / 2 * pCar->GetRight().y;
+ pState->rightZ = UINT8_MAX / 2 * pCar->GetRight().z;
+ pState->forwardX = UINT8_MAX / 2 * pCar->GetForward().x;
+ pState->forwardY = UINT8_MAX / 2 * pCar->GetForward().y;
+ pState->forwardZ = UINT8_MAX / 2 * pCar->GetForward().z;
+ pState->pos = pCar->GetPosition();
+ pState->velX = 1.0f * (UINT16_MAX / 2) * pCar->GetMoveSpeed().x;
+ pState->velY = 1.0f * (UINT16_MAX / 2) * pCar->GetMoveSpeed().y;
+ pState->velZ = 1.0f * (UINT16_MAX / 2) * pCar->GetMoveSpeed().z;
+ pState->wheel = 20 * pCar->m_fSteerAngle;
+ pState->gas = 100 * pCar->m_fGasPedal;
+ pState->brake = 100 * pCar->m_fBrakePedal;
+ pState->handbrake = pCar->bIsHandbrakeOn;
+}
+
+void CRecordDataForChase::RestoreInfoForMatrix(CMatrix& matrix, CCarStateEachFrame* pState)
{
- EAXJMP(0x434780);
+ matrix.GetRight() = CVector(pState->rightX, pState->rightY, pState->rightZ) / (UINT8_MAX / 2);
+ matrix.GetForward() = CVector(pState->forwardX, pState->forwardY, pState->forwardZ) / (UINT8_MAX / 2);
+ matrix.GetUp() = CrossProduct(matrix.GetRight(), matrix.GetForward());
+ matrix.GetPosition() = pState->pos;
}
-WRAPPER void CRecordDataForChase::SaveOrRetrieveDataForThisFrame(void) { EAXJMP(0x4347F0); }
-WRAPPER void CRecordDataForChase::ProcessControlCars(void) { EAXJMP(0x435540); }
-WRAPPER void CRecordDataForChase::SaveOrRetrieveCarPositions(void) { EAXJMP(0x434B20); }
-WRAPPER void CRecordDataForChase::StartChaseScene(float) { EAXJMP(0x435690); }
-WRAPPER void CRecordDataForChase::CleanUpChaseScene() { EAXJMP(0x4357C0); }
-WRAPPER void CRecordDataForChase::RemoveCarFromChase(int32) { EAXJMP(0x435BC0); }
-WRAPPER CVehicle* CRecordDataForChase::TurnChaseCarIntoScriptCar(int32) { EAXJMP(0x435C00); }
+void CRecordDataForChase::RestoreInfoForCar(CAutomobile* pCar, CCarStateEachFrame* pState, bool stop)
+{
+ CVector oldPos = pCar->GetPosition();
+ RestoreInfoForMatrix(pCar->GetMatrix(), pState);
+ pCar->SetMoveSpeed(CVector(pState->velX, pState->velY, pState->velZ) * 1.0f / (UINT16_MAX / 2));
+ pCar->SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ pCar->m_fSteerAngle = pState->wheel / 20.0f;
+ pCar->m_fGasPedal = pState->gas / 100.0f;
+ pCar->m_fBrakePedal = pState->brake / 100.0f;
+ pCar->bIsHandbrakeOn = pState->handbrake;
+ if ((oldPos - pCar->GetPosition()).Magnitude() > 15.0f) {
+ if (pCar == pChaseCars[14]) {
+ pCar->m_currentColour1 = 58;
+ pCar->m_currentColour2 = 1;
+ }
+ else
+ pCar->GetModelInfo()->ChooseVehicleColour(pCar->m_currentColour1, pCar->m_currentColour2);
+ }
+ pCar->m_fHealth = min(pCar->m_fHealth, 500.0f);
+ if (stop) {
+ pCar->m_fGasPedal = 0.0f;
+ pCar->m_fBrakePedal = 0.0f;
+ pCar->SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ pCar->bIsHandbrakeOn = false;
+ }
+}
+
+void CRecordDataForChase::ProcessControlCars(void)
+{
+ if (Status != STATE_PLAYBACK)
+ return;
+ for (int i = 0; i < NUM_CHASE_CARS; i++) {
+ if (pChaseCars[i])
+ pChaseCars[i]->ProcessControl();
+ }
+}
+
+#if (defined(GTA_PS2) || defined(FIX_BUGS))
+bool CRecordDataForChase::ShouldThisPadBeLeftAlone(uint8 pad)
+{
+ // may be wrong
+ if (Status == STATE_NONE || Status == STATE_PLAYBACK)
+ return false;
+ return pad != 0;
+}
+#endif
+
+void CRecordDataForChase::GiveUsACar(int32 mi, CVector pos, float angle, CAutomobile** ppCar, uint8 colour1, uint8 colour2)
+{
+ CStreaming::RequestModel(mi, STREAMFLAGS_DEPENDENCY);
+ CStreaming::LoadAllRequestedModels(false);
+ if (!CStreaming::HasModelLoaded(mi))
+ return;
+ CAutomobile* pCar = new CAutomobile(mi, MISSION_VEHICLE);
+ pCar->GetPosition() = pos;
+ pCar->m_status = STATUS_PLAYER_PLAYBACKFROMBUFFER;
+ pCar->GetMatrix().SetRotateZOnly(DEGTORAD(angle));
+ pCar->pDriver = nil;
+ pCar->m_currentColour1 = colour1;
+ pCar->m_currentColour2 = colour2;
+ CWorld::Add(pCar);
+ *ppCar = pCar;
+}
+
+void RemoveUnusedCollision(void)
+{
+ static const char* dontDeleteArray[] = {
+ "rd_SrRoad2A50", "rd_SrRoad2A20", "rd_CrossRda1w22", "rd_CrossRda1rw22",
+ "road_broadway02", "road_broadway01", "com_21way5", "com_21way50",
+ "cm1waycrosscom", "com_21way20", "com_21way10", "road_broadway04",
+ "com_rvroads52", "com_roadsrv", "com_roadkb23", "com_roadkb22"
+ };
+ for (int i = 0; i < ARRAY_SIZE(dontDeleteArray); i++)
+ CModelInfo::GetModelInfo(dontDeleteArray[i], nil)->GetColModel()->level = LEVEL_NONE;
+ CModelInfo::RemoveColModelsFromOtherLevels(LEVEL_NONE);
+ for (int i = 0; i < ARRAY_SIZE(dontDeleteArray); i++)
+ CModelInfo::GetModelInfo(dontDeleteArray[i], nil)->GetColModel()->level = LEVEL_COMMERCIAL;
+}
+
+void CRecordDataForChase::StartChaseScene(float startTime)
+{
+ char filename[28];
+ SetUpCarsForChaseScene();
+ Status = STATE_PLAYBACK;
+ AnimTime = startTime;
+ AnimStartTime = CTimer::GetTimeInMilliseconds();
+ RemoveUnusedCollision();
+ CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN);
+ CGame::TidyUpMemory(true, true);
+ CStreaming::ImGonnaUseStreamingMemory();
+ CFileMgr::SetDir("data\\paths");
+ for (int i = 0; i < NUM_CHASE_CARS; i++) {
+ if (!pChaseCars[i]) {
+ pBaseMemForCar[i] = nil;
+ continue;
+ }
+ sprintf(filename, "chase%d.dat", i);
+ FId2 = CFileMgr::OpenFile(filename, "rb");
+ if (FId2 <= 0) {
+ pBaseMemForCar[i] = nil;
+ continue;
+ }
+ pBaseMemForCar[i] = new CCarStateEachFrame[CHASE_SCENE_FRAMES_IN_RECORDING];
+ for (int j = 0; j < CHASE_SCENE_FRAMES_IN_RECORDING; j++) {
+ CFileMgr::Read(FId2, (char*)&pBaseMemForCar[i][j], sizeof(CCarStateEachFrame));
+ CFileMgr::Seek(FId2, sizeof(CCarStateEachFrame), 1);
+ }
+ CFileMgr::CloseFile(FId2);
+ }
+ CFileMgr::SetDir("");
+ CStreaming::IHaveUsedStreamingMemory();
+ TimeMultiplier = 0.0f;
+}
+
+void CRecordDataForChase::CleanUpChaseScene(void)
+{
+ if (Status != STATE_PLAYBACK_INIT && Status != STATE_PLAYBACK)
+ return;
+ Status = STATE_NONE;
+ CleanUpCarsForChaseScene();
+ for (int i = 0; i < NUM_CHASE_CARS; i++) {
+ if (pBaseMemForCar[i]) {
+ delete[] pBaseMemForCar[i];
+ pBaseMemForCar[i] = nil;
+ }
+ }
+}
+
+void CRecordDataForChase::SetUpCarsForChaseScene(void)
+{
+ GiveUsACar(MI_POLICE, CVector(273.54221f, -1167.1907f, 24.880601f), 63.0f, &pChaseCars[0], 2, 1);
+ GiveUsACar(MI_ENFORCER, CVector(231.1783f, -1388.8322f, 25.978201f), 90.0f, &pChaseCars[1], 2, 1);
+ GiveUsACar(MI_TAXI, CVector(184.3156f, -1473.251f, 25.978201f), 0.0f, &pChaseCars[4], 6, 6);
+ GiveUsACar(MI_CHEETAH, CVector(173.8868f, -1377.6514f, 25.978201f), 0.0f, &pChaseCars[6], 4, 5);
+ GiveUsACar(MI_STINGER, CVector(102.5946f, -943.93628f, 25.9781f), 270.0f, &pChaseCars[7], 53, 53);
+ GiveUsACar(MI_CHEETAH, CVector(-177.7157f, -862.18652f, 25.978201f), 155.0f, &pChaseCars[10], 41, 1);
+ GiveUsACar(MI_STINGER, CVector(-170.56979f, -889.02362f, 25.978201f), 154.0f, &pChaseCars[11], 10, 10);
+ GiveUsACar(MI_KURUMA, CVector(402.60809f, -917.49628f, 37.381001f), 90.0f, &pChaseCars[14], 34, 1);
+ GiveUsACar(MI_TAXI, CVector(-33.496201f, -938.4563f, 25.9781f), 266.0f, &pChaseCars[16], 6, 6);
+ GiveUsACar(MI_KURUMA, CVector(49.363098f, -987.60498f, 25.9781f), 0.0f, &pChaseCars[18], 51, 1);
+ GiveUsACar(MI_TAXI, CVector(179.0049f, -1154.6686f, 25.9781f), 0.0f, &pChaseCars[19], 6, 76);
+ GiveUsACar(MI_RUMPO, CVector(-28.9762f, -1031.3367f, 25.990601f), 242.0f, &pChaseCars[2], 1, 75);
+ GiveUsACar(MI_PATRIOT, CVector(114.1564f, -796.69379f, 24.978201f), 180.0f, &pChaseCars[3], 0, 0);
+}
+
+void CRecordDataForChase::CleanUpCarsForChaseScene(void)
+{
+ for (int i = 0; i < NUM_CHASE_CARS; i++)
+ RemoveCarFromChase(i);
+}
+
+void CRecordDataForChase::RemoveCarFromChase(int32 i)
+{
+ if (!pChaseCars[i])
+ return;
+ CWorld::Remove(pChaseCars[i]);
+ delete pChaseCars[i];
+ pChaseCars[i] = nil;
+}
+
+CVehicle* CRecordDataForChase::TurnChaseCarIntoScriptCar(int32 i)
+{
+ CVehicle* pVehicle = pChaseCars[i];
+ pChaseCars[i] = nil;
+ pVehicle->m_status = STATUS_PHYSICS;
+ return pVehicle;
+}
diff --git a/src/control/Record.h b/src/control/Record.h
index 3cb09318..4abeb68a 100644
--- a/src/control/Record.h
+++ b/src/control/Record.h
@@ -4,32 +4,70 @@ class CAutomobile;
class CVehicle;
class CControllerState;
-enum {
- RECORDSTATE_0,
- RECORDSTATE_1,
- RECORDSTATE_2,
+class CCarStateEachFrame
+{
+public:
+ int16 velX;
+ int16 velY;
+ int16 velZ;
+ int8 rightX;
+ int8 rightY;
+ int8 rightZ;
+ int8 forwardX;
+ int8 forwardY;
+ int8 forwardZ;
+ int8 wheel;
+ uint8 gas;
+ uint8 brake;
+ bool handbrake;
+ CVector pos;
};
+extern char* gString;
+
class CRecordDataForChase
{
enum {
NUM_CHASE_CARS = 20
};
-public:
+ enum {
+ STATE_NONE = 0,
+ STATE_RECORD = 1,
+ STATE_PLAYBACK_INIT = 2,
+ STATE_PLAYBACK = 3,
+ STATE_PLAYBACK_BEFORE_RECORDING = 4
+ };
static uint8 &Status;
static int &PositionChanges;
static uint8 &CurrentCar;
static CAutomobile*(&pChaseCars)[NUM_CHASE_CARS];
+ static float &AnimTime;
static uint32 &AnimStartTime;
+ static CCarStateEachFrame* (&pBaseMemForCar)[NUM_CHASE_CARS];
+ static float &TimeMultiplier;
+ static int &FId2;
+public:
+
+ static bool IsRecording(void) { return Status == STATE_RECORD; }
+ static void Init(void);
static void SaveOrRetrieveDataForThisFrame(void);
- static void ProcessControlCars(void);
static void SaveOrRetrieveCarPositions(void);
+ static void StoreInfoForCar(CAutomobile*, CCarStateEachFrame*);
+ static void RestoreInfoForMatrix(CMatrix&, CCarStateEachFrame*);
+ static void RestoreInfoForCar(CAutomobile*, CCarStateEachFrame*, bool);
+ static void ProcessControlCars(void);
+#if (defined(GTA_PS2) || defined(FIX_BUGS))
+ static bool ShouldThisPadBeLeftAlone(uint8 pad);
+#endif
+ static void GiveUsACar(int32, CVector, float, CAutomobile**, uint8, uint8);
static void StartChaseScene(float);
- static void CleanUpChaseScene();
+ static void CleanUpChaseScene(void);
+ static void SetUpCarsForChaseScene(void);
+ static void CleanUpCarsForChaseScene(void);
static void RemoveCarFromChase(int32);
static CVehicle* TurnChaseCarIntoScriptCar(int32);
- static void Init(void);
+
};
struct tGameBuffer
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index b03272f9..f83998b8 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -26,6 +26,7 @@
#include "Vehicle.h"
#include "Ped.h"
#include "Population.h"
+#include "Record.h"
#include "Replay.h"
#include "Weather.h"
#include "win.h"
@@ -969,7 +970,7 @@ void CPad::Update(int16 unk)
OldState = NewState;
#if (defined GTA_PS2 || defined FIX_BUGS)
- if (!CRecordDataForGame::IsPlayingBack() /* && !CRecordDataForChase::ShouldThisPadBeLeftAlone(unk) */)
+ if (!CRecordDataForGame::IsPlayingBack() && !CRecordDataForChase::ShouldThisPadBeLeftAlone(unk))
#endif
{
NewState = ReconcileTwoControllersInput(PCTempKeyState, PCTempJoyState);
diff --git a/src/core/Timer.cpp b/src/core/Timer.cpp
index 3cd6862c..d0bb6c8b 100644
--- a/src/core/Timer.cpp
+++ b/src/core/Timer.cpp
@@ -138,7 +138,7 @@ void CTimer::Update(void)
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 60;
}
- if ( CRecordDataForChase::Status == RECORDSTATE_1 )
+ if ( CRecordDataForChase::IsRecording() )
{
ms_fTimeStep = 1.0f;
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 16;
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 1c0d673e..13558920 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -356,7 +356,7 @@ CAutomobile::ProcessControl(void)
PruneReferences();
- if(m_status == STATUS_PLAYER && CRecordDataForChase::Status != RECORDSTATE_1)
+ if(m_status == STATUS_PLAYER && CRecordDataForChase::IsRecording())
DoDriveByShootings();
}
break;