From 69918d4145b26325473ed608b34e37bee19cfa10 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Sun, 30 Jun 2019 19:22:44 +0300 Subject: More replay functions, also removed pool iteration error --- src/Camera.cpp | 1 + src/Camera.h | 1 + src/control/Replay.cpp | 121 +++++++++++++++++++++++++++++++++++++++++++------ src/control/Replay.h | 2 +- src/entities/Vehicle.h | 2 +- 5 files changed, 112 insertions(+), 15 deletions(-) diff --git a/src/Camera.cpp b/src/Camera.cpp index e2dd12ff..e5e50ef2 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -19,6 +19,7 @@ CCamera &TheCamera = *(CCamera*)0x6FACF8; bool &CCamera::m_bUseMouse3rdPerson = *(bool *)0x5F03D8; WRAPPER void CCamera::DrawBordersForWideScreen(void) { EAXJMP(0x46B430); } +WRAPPER void CCamera::CalculateDerivedValues(void) { EAXJMP(0x46EEA0); } bool CCamera::IsSphereVisible(const CVector ¢er, float radius, const CMatrix *mat) diff --git a/src/Camera.h b/src/Camera.h index 2316fd5d..6d20de72 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -456,6 +456,7 @@ int m_iModeObbeCamIsInForCar; void SetMotionBlur(int r, int g, int b, int a, int type); void SetMotionBlurAlpha(int a); void RenderMotionBlur(void); + void CalculateDerivedValues(void); void DrawBordersForWideScreen(void); diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index b6a7b8c2..09cbf2d2 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -810,11 +810,7 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo TheCamera.GetMatrix() = TheCamera.GetMatrix() * CMatrix(split); *TheCamera.GetMatrix().GetPosition() *= split; TheCamera.GetMatrix() += CMatrix(interpolation) * pg->camera_pos; - RwMatrix* pm = &RpAtomicGetFrame(&TheCamera.m_pRwCamera->object.object)->modelling; - pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition(); - pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward(); - pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp(); - pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight(); + *RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)) = TheCamera.GetMatrix().m_matrix; CameraFocusX = split * CameraFocusX + interpolation * pg->player_pos.x; CameraFocusY = split * CameraFocusY + interpolation * pg->player_pos.y; CameraFocusZ = split * CameraFocusZ + interpolation * pg->player_pos.z; @@ -932,7 +928,41 @@ void CReplay::EmptyReplayBuffer(void) } #endif +#if 0 WRAPPER void CReplay::ProcessReplayCamera(void) { EAXJMP(0x595C40); } +#else +void CReplay::ProcessReplayCamera(void) +{ + switch (CameraMode) { + case REPLAYCAMMODE_TOPDOWN: + *TheCamera.GetMatrix().GetPosition() = CVector(CameraFocusX, CameraFocusY, CameraFocusZ + 15.0f); + *TheCamera.GetMatrix().GetForward() = CVector(0.0f, 0.0f, -1.0f); + *TheCamera.GetMatrix().GetUp() = CVector(0.0f, 1.0f, 0.0f); + *TheCamera.GetMatrix().GetRight() = CVector(1.0f, 0.0f, 0.0f); + *RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)) = TheCamera.GetMatrix().m_matrix; + break; + case REPLAYCAMMODE_FIXED: + *TheCamera.GetMatrix().GetPosition() = CVector(CameraFixedX, CameraFixedY, CameraFixedZ); + CVector forward(CameraFocusX - CameraFixedX, CameraFocusY - CameraFixedY, CameraFocusZ - CameraFixedZ); + forward.Normalise(); + CVector right = CrossProduct(CVector(0.0f, 0.0f, 1.0f), forward); + right.Normalise(); + CVector up = CrossProduct(forward, right); + up.Normalise(); + *TheCamera.GetMatrix().GetForward() = forward; + *TheCamera.GetMatrix().GetUp() = up; + *TheCamera.GetMatrix().GetRight() = right; + *RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)) = TheCamera.GetMatrix().m_matrix; + break; + default: + break; + } + TheCamera.m_vecGameCamPos = *TheCamera.GetMatrix().GetPosition(); + TheCamera.CalculateDerivedValues(); + RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera))); + RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera)); +} +#endif #if 0 WRAPPER void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene) { EAXJMP(0x596030); } @@ -1070,7 +1100,7 @@ void CReplay::RestoreStuffFromMem(void) FindPlayerPed()->m_pWanted = new CWanted(PlayerWanted); /* Nice memory leak */ CWorld::Players[0] = PlayerInfo; int i = CPools::GetPedPool()->GetSize(); - while (--i){ + while (i--){ CPed* ped = CPools::GetPedPool()->GetSlot(i); if (!ped) continue; @@ -1088,7 +1118,7 @@ void CReplay::RestoreStuffFromMem(void) ped->AddWeaponModel(ped->m_wepModelID); } i = CPools::GetVehiclePool()->GetSize(); - while (--i){ + while (i--){ CVehicle* vehicle = CPools::GetVehiclePool()->GetSlot(i); if (!vehicle) continue; @@ -1147,7 +1177,7 @@ void CReplay::RestoreStuffFromMem(void) } PrintElementsInPtrList(); i = CPools::GetObjectPool()->GetSize(); - while (--i){ + while (i--){ CObject* object = CPools::GetObjectPool()->GetSlot(i); if (!object) continue; @@ -1162,7 +1192,7 @@ void CReplay::RestoreStuffFromMem(void) object->GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame(object->m_rwObject)), false); } i = CPools::GetDummyPool()->GetSize(); - while (--i){ + while (i--){ CDummy* dummy = CPools::GetDummyPool()->GetSlot(i); if (!dummy) continue; @@ -1201,9 +1231,77 @@ void CReplay::RestoreStuffFromMem(void) DMAudio.ChangeMusicMode(1); } #endif + +#if 0 WRAPPER void CReplay::EmptyPedsAndVehiclePools(void) { EAXJMP(0x5970E0); } +#else +void CReplay::EmptyPedsAndVehiclePools(void) +{ + int i = CPools::GetVehiclePool()->GetSize(); + while (i--) { + CVehicle* v = CPools::GetVehiclePool()->GetSlot(i); + if (!v) + continue; + CWorld::Remove(v); + delete v; + } + i = CPools::GetPedPool()->GetSize(); + while (i--) { + CPed* p = CPools::GetPedPool()->GetSlot(i); + if (!p) + continue; + CWorld::Remove(p); + delete p; + } +} +#endif + +#if 0 WRAPPER void CReplay::EmptyAllPools(void) { EAXJMP(0x5971B0); } +#else +void CReplay::EmptyAllPools(void) +{ + EmptyPedsAndVehiclePools(); + int i = CPools::GetObjectPool()->GetSize(); + while (i--) { + CObject* o = CPools::GetObjectPool()->GetSlot(i); + if (!o) + continue; + CWorld::Remove(o); + delete o; + } + i = CPools::GetDummyPool()->GetSize(); + while (i--) { + CDummy* d = CPools::GetDummyPool()->GetSlot(i); + if (!d) + continue; + CWorld::Remove(d); + delete d; + } +} +#endif + +#if 0 WRAPPER void CReplay::MarkEverythingAsNew(void) { EAXJMP(0x597280); } +#else +void CReplay::MarkEverythingAsNew(void) +{ + int i = CPools::GetVehiclePool()->GetSize(); + while (i--) { + CVehicle* v = CPools::GetVehiclePool()->GetSlot(i); + if (!v) + continue; + v->bRecordedForReplay = false; + } + i = CPools::GetPedPool()->GetSize(); + while (i--) { + CPed* p = CPools::GetPedPool()->GetSlot(i); + if (!p) + continue; + p->bRecordedForReplay = false; + } +} +#endif WRAPPER void CReplay::SaveReplayToHD(void) { EAXJMP(0x597330); } WRAPPER void PlayReplayFromHD(void) { EAXJMP(0x597420); } WRAPPER void CReplay::StreamAllNecessaryCarsAndPeds(void) { EAXJMP(0x597560); } @@ -1236,9 +1334,6 @@ InjectHook(0x593150, CReplay::DisableReplays, PATCH_JUMP); InjectHook(0x593160, CReplay::EnableReplays, PATCH_JUMP); InjectHook(0x593170, CReplay::Update, PATCH_JUMP); InjectHook(0x595B20, CReplay::FinishPlayback, PATCH_JUMP); -InjectHook(0x594050, CReplay::ProcessPedUpdate, PATCH_JUMP); -InjectHook(0x594D10, CReplay::ProcessCarUpdate, PATCH_JUMP); -InjectHook(0x593BB0, CReplay::StoreDetailedPedAnimation, PATCH_JUMP); -InjectHook(0x5944B0, CReplay::RetrieveDetailedPedAnimation, PATCH_JUMP); +InjectHook(0x595BD0, CReplay::EmptyReplayBuffer, PATCH_JUMP); InjectHook(0x596030, CReplay::TriggerPlayback, PATCH_JUMP); ENDPATCHES diff --git a/src/control/Replay.h b/src/control/Replay.h index 18701293..3a2ecc7f 100644 --- a/src/control/Replay.h +++ b/src/control/Replay.h @@ -261,7 +261,7 @@ public: inline static bool IsPlayingBack() { return Mode == MODE_PLAYBACK; } inline static bool IsPlayingBackFromFile() { return bPlayingBackFromFile; } -//private: +private: static void RecordThisFrame(void); static void StorePedUpdate(CPed *ped, int id); static void StorePedAnimation(CPed *ped, CStoredAnimationState *state); diff --git a/src/entities/Vehicle.h b/src/entities/Vehicle.h index 997720f6..27641e47 100644 --- a/src/entities/Vehicle.h +++ b/src/entities/Vehicle.h @@ -77,7 +77,7 @@ public: uint8 m_veh_flagD2 : 1; uint8 m_veh_flagD4 : 1; uint8 m_veh_flagD8 : 1; - uint8 m_veh_flagD10 : 1; + uint8 bRecordedForReplay : 1; uint8 m_veh_flagD20 : 1; uint8 m_veh_flagD40 : 1; uint8 m_veh_flagD80 : 1; -- cgit v1.2.3 From 4e09f9ee39e003b852471e3016411cc3a3169802 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Sun, 30 Jun 2019 23:29:53 +0300 Subject: Added camera funcs to Replay --- src/control/Replay.cpp | 242 ++++++++++++++++++++++++++++++++++++++++++++++--- src/control/Replay.h | 8 ++ 2 files changed, 239 insertions(+), 11 deletions(-) diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 09cbf2d2..8d59f3ce 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -8,7 +8,9 @@ #include "Clock.h" #include "DMAudio.h" #include "Draw.h" +#include "FileMgr.h" #include "Heli.h" +#include "main.h" #include "math/Matrix.h" #include "ModelIndices.h" #include "ModelInfo.h" @@ -91,6 +93,9 @@ float &CReplay::CameraFocusX = *(float*)0x942F5C; float &CReplay::CameraFocusY = *(float*)0x942F74; float &CReplay::CameraFocusZ = *(float*)0x942F58; bool &CReplay::bPlayerInRCBuggy = *(bool*)0x95CDC3; +float &CReplay::fDistanceLookAroundCam = *(float*)0x885B44; +float &CReplay::fBetaAngleLookAroundCam = *(float*)0x94072C; +float &CReplay::fAlphaAngleLookAroundCam = *(float*)0x8F2A0C; static void(*(&CBArray)[30])(CAnimBlendAssociation*, void*) = *(void(*(*)[30])(CAnimBlendAssociation*, void*))*(uintptr*)0x61052C; static void(*CBArray_RE3[])(CAnimBlendAssociation*, void*) = @@ -810,7 +815,11 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo TheCamera.GetMatrix() = TheCamera.GetMatrix() * CMatrix(split); *TheCamera.GetMatrix().GetPosition() *= split; TheCamera.GetMatrix() += CMatrix(interpolation) * pg->camera_pos; - *RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)) = TheCamera.GetMatrix().m_matrix; + RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); + pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition(); + pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward(); + pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp(); + pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight(); CameraFocusX = split * CameraFocusX + interpolation * pg->player_pos.x; CameraFocusY = split * CameraFocusY + interpolation * pg->player_pos.y; CameraFocusZ = split * CameraFocusZ + interpolation * pg->player_pos.z; @@ -935,13 +944,20 @@ void CReplay::ProcessReplayCamera(void) { switch (CameraMode) { case REPLAYCAMMODE_TOPDOWN: + { *TheCamera.GetMatrix().GetPosition() = CVector(CameraFocusX, CameraFocusY, CameraFocusZ + 15.0f); *TheCamera.GetMatrix().GetForward() = CVector(0.0f, 0.0f, -1.0f); *TheCamera.GetMatrix().GetUp() = CVector(0.0f, 1.0f, 0.0f); *TheCamera.GetMatrix().GetRight() = CVector(1.0f, 0.0f, 0.0f); - *RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)) = TheCamera.GetMatrix().m_matrix; + RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); + pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition(); + pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward(); + pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp(); + pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight(); break; + } case REPLAYCAMMODE_FIXED: + { *TheCamera.GetMatrix().GetPosition() = CVector(CameraFixedX, CameraFixedY, CameraFixedZ); CVector forward(CameraFocusX - CameraFixedX, CameraFocusY - CameraFixedY, CameraFocusZ - CameraFixedZ); forward.Normalise(); @@ -952,8 +968,13 @@ void CReplay::ProcessReplayCamera(void) *TheCamera.GetMatrix().GetForward() = forward; *TheCamera.GetMatrix().GetUp() = up; *TheCamera.GetMatrix().GetRight() = right; - *RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)) = TheCamera.GetMatrix().m_matrix; + RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); + pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition(); + pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward(); + pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp(); + pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight(); break; + } default: break; } @@ -1302,13 +1323,210 @@ void CReplay::MarkEverythingAsNew(void) } } #endif + +#if 0 WRAPPER void CReplay::SaveReplayToHD(void) { EAXJMP(0x597330); } +#else +void CReplay::SaveReplayToHD(void) +{ + CFileMgr::SetDirMyDocuments(); + int fw = CFileMgr::OpenFileForWriting("replay.rep"); + if (fw < 0){ + debug("Couldn't open replay.rep for writing"); + CFileMgr::SetDir(""); + return; + } + CFileMgr::Write(fw, "gta3_7f", sizeof("gta3_7f")); + int current; + for (current = 0; current < 8; current++) + if (BufferStatus[current] == REPLAYBUFFER_RECORD) + break; + int first; + for (first = (current + 1) % 8; ; first = (first + 1) % 8) + if (BufferStatus[first] == REPLAYBUFFER_RECORD || BufferStatus[first] == REPLAYBUFFER_PLAYBACK) + break; + for(int i = first;; i = (i + 1) % 8 ){ + CFileMgr::Write(fw, (char*)Buffers[first], sizeof(Buffers[first])); + if (BufferStatus[i] == REPLAYBUFFER_RECORD) + break; + } + CFileMgr::CloseFile(fw); + CFileMgr::SetDir(""); +} +#endif + +#if 0 WRAPPER void PlayReplayFromHD(void) { EAXJMP(0x597420); } +#else +void PlayReplayFromHD(void) +{ + CFileMgr::SetDirMyDocuments(); + int fr = CFileMgr::OpenFile("replay.rep", "rb"); + if (fr < 0) { + debug("Couldn't open replay.rep for reading"); + /* Forgot to SetDir? */ + return; + } + CFileMgr::Read(fr, gString, 8); + if (strncmp(gString, "gta3_7f", sizeof("gta3_7f"))){ + CFileMgr::CloseFile(fr); + debug("Wrong file type for replay"); + CFileMgr::SetDir(""); + return; + } + int slot; + for (slot = 0; CFileMgr::Read(fr, (char*)CReplay::Buffers[slot], sizeof(CReplay::Buffers[slot])); slot++) + CReplay::BufferStatus[slot] = CReplay::REPLAYBUFFER_PLAYBACK; + CReplay::BufferStatus[slot - 1] = CReplay::REPLAYBUFFER_RECORD; + while (slot < 8) + CReplay::BufferStatus[slot++] = CReplay::REPLAYBUFFER_UNUSED; + CFileMgr::CloseFile(fr); + CFileMgr::SetDir(""); + CReplay::TriggerPlayback(CReplay::REPLAYCAMMODE_ASSTORED, 0.0f, 0.0f, 0.0f, false); + CReplay::bPlayingBackFromFile = true; + CReplay::bAllowLookAroundCam = true; + CReplay::StreamAllNecessaryCarsAndPeds(); +} +#endif + +#if 0 WRAPPER void CReplay::StreamAllNecessaryCarsAndPeds(void) { EAXJMP(0x597560); } +#else +void CReplay::StreamAllNecessaryCarsAndPeds(void) +{ + for (int slot = 0; slot < 8; slot++) { + if (BufferStatus[slot] == REPLAYBUFFER_UNUSED) + continue; + for (int offset = 0; Buffers[slot][offset] != REPLAYPACKET_END; offset += FindSizeOfPacket(Buffers[slot][offset])) { + switch (Buffers[slot][offset]) { + case REPLAYPACKET_VEHICLE: + CStreaming::RequestModel(((tVehicleUpdatePacket*)&Buffers[slot][offset])->mi, 0); + break; + case REPLAYPACKET_PED_HEADER: + CStreaming::RequestModel(((tPedHeaderPacket*)&Buffers[slot][offset])->mi, 0); + break; + default: + break; + } + } + } + CStreaming::LoadAllRequestedModels(false); +} +#endif + +#if 0 WRAPPER void CReplay::FindFirstFocusCoordinate(CVector *coord) { EAXJMP(0x5975E0); } +#else +void CReplay::FindFirstFocusCoordinate(CVector *coord) +{ + *coord = CVector(0.0f, 0.0f, 0.0f); + for (int slot = 0; slot < 8; slot++) { + if (BufferStatus[slot] == REPLAYBUFFER_UNUSED) + continue; + for (int offset = 0; Buffers[slot][offset] != REPLAYPACKET_END; offset += FindSizeOfPacket(Buffers[slot][offset])) { + if (Buffers[slot][offset] == REPLAYPACKET_GENERAL) { + *coord = ((tGeneralPacket*)&Buffers[slot][offset])->player_pos; + return; + } + } + } +} +#endif + +#if 0 WRAPPER bool CReplay::ShouldStandardCameraBeProcessed(void) { EAXJMP(0x597680); } +#else +bool CReplay::ShouldStandardCameraBeProcessed(void) +{ + if (Mode != MODE_PLAYBACK) + return true; + if (FramesActiveLookAroundCam || bPlayerInRCBuggy) + return false; + return FindPlayerVehicle() != nil; +} +#endif + +#if 0 WRAPPER void CReplay::ProcessLookAroundCam(void) { EAXJMP(0x5976C0); } +#else +void CReplay::ProcessLookAroundCam(void) +{ + if (!bAllowLookAroundCam) + return; + float x_moved = CPad::NewMouseControllerState.x / 200.0f; + float y_moved = CPad::NewMouseControllerState.y / 200.0f; + if (x_moved > 0.01f || y_moved > 0.01f) { + if (FramesActiveLookAroundCam == 0) + fDistanceLookAroundCam = 9.0f; + FramesActiveLookAroundCam = 60; + } + if (bPlayerInRCBuggy) + FramesActiveLookAroundCam = 0; + if (!FramesActiveLookAroundCam) + return; + --FramesActiveLookAroundCam; + fBetaAngleLookAroundCam += x_moved; + if (CPad::NewMouseControllerState.LMB && CPad::NewMouseControllerState.RMB) + fDistanceLookAroundCam = max(3.0f, min(15.0f, fDistanceLookAroundCam + 2.0f * y_moved)); + else + fAlphaAngleLookAroundCam = max(0.1f, min(1.5f, fAlphaAngleLookAroundCam + y_moved)); + CVector camera_pt( + fDistanceLookAroundCam * sin(fBetaAngleLookAroundCam) * cos(fAlphaAngleLookAroundCam), + fDistanceLookAroundCam * cos(fBetaAngleLookAroundCam) * cos(fAlphaAngleLookAroundCam), + fDistanceLookAroundCam * sin(fAlphaAngleLookAroundCam) + ); + CVector focus = CVector(CameraFocusX, CameraFocusY, CameraFocusZ); + camera_pt += focus; + CColPoint cp; + CEntity* pe = nil; + if (CWorld::ProcessLineOfSight(focus, camera_pt, cp, pe, true, false, false, false, false, true, true)){ + camera_pt = cp.point; + CVector direction = focus - cp.point; + direction.Normalise(); + camera_pt += direction / 4.0f; + } + CVector forward = focus - camera_pt; + forward.Normalise(); + CVector right = CrossProduct(CVector(0.0f, 0.0f, 1.0f), forward); + right.Normalise(); + CVector up = CrossProduct(forward, right); + up.Normalise(); + *TheCamera.GetMatrix().GetForward() = forward; + *TheCamera.GetMatrix().GetUp() = up; + *TheCamera.GetMatrix().GetRight() = right; + *TheCamera.GetMatrix().GetPosition() = camera_pt; + RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); + pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition(); + pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward(); + pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp(); + pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight(); + TheCamera.CalculateDerivedValues(); + RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera))); + RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera)); +} +#endif + +#if 0 WRAPPER size_t CReplay::FindSizeOfPacket(uint8 type) { EAXJMP(0x597CC0); } +#else +size_t CReplay::FindSizeOfPacket(uint8 type) +{ + switch (type) { + case REPLAYPACKET_END: return 4; + case REPLAYPACKET_VEHICLE: return sizeof(tVehicleUpdatePacket); + case REPLAYPACKET_PED_HEADER: return sizeof(tPedHeaderPacket); + case REPLAYPACKET_PED_UPDATE: return sizeof(tPedUpdatePacket); + case REPLAYPACKET_GENERAL: return sizeof(tGeneralPacket); + case REPLAYPACKET_CLOCK: return sizeof(tClockPacket); + case REPLAYPACKET_WEATHER: return sizeof(tWeatherPacket); + case REPLAYPACKET_ENDOFFRAME: return 4; + case REPLAYPACKET_TIMER: return sizeof(tTimerPacket); + case REPLAYPACKET_BULLET_TRACES:return sizeof(tBulletTracePacket); + default: break; + } + return 0; +} +#endif #if 0 WRAPPER void CReplay::Display(void) { EAXJMP(0x595EE0); } @@ -1328,12 +1546,14 @@ void CReplay::Display() #endif STARTPATCHES -InjectHook(0x592FC0, PrintElementsInPtrList, PATCH_JUMP); -InjectHook(0x592FE0, CReplay::Init, PATCH_JUMP); -InjectHook(0x593150, CReplay::DisableReplays, PATCH_JUMP); -InjectHook(0x593160, CReplay::EnableReplays, PATCH_JUMP); -InjectHook(0x593170, CReplay::Update, PATCH_JUMP); -InjectHook(0x595B20, CReplay::FinishPlayback, PATCH_JUMP); -InjectHook(0x595BD0, CReplay::EmptyReplayBuffer, PATCH_JUMP); -InjectHook(0x596030, CReplay::TriggerPlayback, PATCH_JUMP); +InjectHook(0x592FE0, &CReplay::Init, PATCH_JUMP); +InjectHook(0x593150, &CReplay::DisableReplays, PATCH_JUMP); +InjectHook(0x593160, &CReplay::EnableReplays, PATCH_JUMP); +InjectHook(0x593170, &CReplay::Update, PATCH_JUMP); +InjectHook(0x595B20, &CReplay::FinishPlayback, PATCH_JUMP); +InjectHook(0x595BD0, &CReplay::EmptyReplayBuffer, PATCH_JUMP); +InjectHook(0x595EE0, &CReplay::Display, PATCH_JUMP); +InjectHook(0x596030, &CReplay::TriggerPlayback, PATCH_JUMP); +InjectHook(0x597560, &CReplay::StreamAllNecessaryCarsAndPeds, PATCH_JUMP); +InjectHook(0x597680, &CReplay::ShouldStandardCameraBeProcessed, PATCH_JUMP); ENDPATCHES diff --git a/src/control/Replay.h b/src/control/Replay.h index 3a2ecc7f..d622ce9c 100644 --- a/src/control/Replay.h +++ b/src/control/Replay.h @@ -49,6 +49,8 @@ struct CStoredDetailedAnimationState uint16 aFlags2[6]; }; +void PlayReplayFromHD(void); + class CReplay { enum { @@ -245,6 +247,9 @@ private: static float &CameraFocusY; static float &CameraFocusZ; static bool &bPlayerInRCBuggy; + static float &fDistanceLookAroundCam; + static float &fAlphaAngleLookAroundCam; + static float &fBetaAngleLookAroundCam; public: static void Init(void); @@ -283,4 +288,7 @@ private: static void FindFirstFocusCoordinate(CVector *coord); static void ProcessLookAroundCam(void); static size_t FindSizeOfPacket(uint8); + + /* Absolute nonsense, but how could this function end up being outside of class? */ + friend void PlayReplayFromHD(void); }; -- cgit v1.2.3 From 3a763cc6e703eef5761b964cd495d41585897c9c Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Sun, 30 Jun 2019 23:49:32 +0300 Subject: Changed CReplay::Display slightly --- src/control/Replay.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 8d59f3ce..ce2a9bd4 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -1533,15 +1533,20 @@ WRAPPER void CReplay::Display(void) { EAXJMP(0x595EE0); } #else void CReplay::Display() { - if (CReplay::IsPlayingBack() && CTimer::GetFrameCounter() + 1 & 0x20) { - CFont::SetPropOn(); - CFont::SetBackgroundOff(); - CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f)); - CFont::SetAlignment(ALIGN_LEFT); - CFont::SetColor(CRGBA(255, 255, 200, 200)); - CFont::SetFontStyle(FONT_BANK); + static int counter = 0; + if (Mode == MODE_RECORD) + return; + counter = (counter + 1) % 65536; + if (counter & 0x20 == 0) + return; + CFont::SetPropOn(); + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f)); + CFont::SetAlignment(ALIGN_LEFT); + CFont::SetColor(CRGBA(255, 255, 200, 200)); + CFont::SetFontStyle(FONT_BANK); + if (Mode == MODE_PLAYBACK) CFont::PrintString(SCREEN_SCALE_X(63.5f), SCREEN_SCALE_Y(30.0f), TheText.Get("REPLAY")); - } } #endif -- cgit v1.2.3 From 02c7cbc75f0451e87bff0a9d5469fe057432769c Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Mon, 1 Jul 2019 00:15:34 +0300 Subject: Completed CReplay --- src/DamageManager.h | 25 ++++++++++++++++++++++++- src/control/Replay.cpp | 35 +++++++++++++++++++++++++++++++++++ src/entities/Automobile.cpp | 2 ++ src/entities/Automobile.h | 2 ++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/DamageManager.h b/src/DamageManager.h index 01269a42..4c1e3925 100644 --- a/src/DamageManager.h +++ b/src/DamageManager.h @@ -15,12 +15,35 @@ public: CAR_DOOR_RR }; + enum { + PANEL_FL = 0, + PANEL_FR, + PANEL_RL, + PANEL_RR, + PANEL_WINDSHIELD, + PANEL_FRONT, + PANEL_BACK + }; + + struct PanelStatus { + uint32 m_nPanelFrontLeftStatus : 4; + uint32 m_nPanelFrontRightStatus : 4; + uint32 m_nPanelBackLeftStatus : 4; + uint32 m_nPanelBackRightStatus : 4; + uint32 m_nWindshieldStatus : 4; + uint32 m_nPanelFrontStatus : 4; + uint32 m_nPanelBackStatus : 4; + }; + float field_0; char m_bEngineStatus; char m_bWheelStatus[4]; char m_bDoorStatus[7]; uint32 m_abLightStatus; - uint32 m_abPanelsStatus; + union{ + PanelStatus m_sPanelsStatus; + uint32 m_abPanelsStatus; + }; char field_24; char field_25; char field_26; diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index ce2a9bd4..e49e10bc 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -130,7 +130,42 @@ static void(*FindCBFunction(uint8 id))(CAnimBlendAssociation*, void*) return CBArray_RE3[id]; } +#if 0 WRAPPER static void ApplyPanelDamageToCar(uint32, CAutomobile*, bool) { EAXJMP(0x584EA0); } +#else +static void ApplyPanelDamageToCar(uint32 panels, CAutomobile* vehicle, bool flying) +{ + CDamageManager::PanelStatus rp = *(CDamageManager::PanelStatus*)&panels; + if (vehicle->m_DamageManager.m_sPanelsStatus.m_nPanelFrontLeftStatus != rp.m_nPanelFrontLeftStatus){ + vehicle->m_DamageManager.m_sPanelsStatus.m_nPanelFrontLeftStatus = rp.m_nPanelFrontLeftStatus; + vehicle->SetPanelDamage(13, CDamageManager::PANEL_FL, flying); + } + if (vehicle->m_DamageManager.m_sPanelsStatus.m_nPanelFrontRightStatus != rp.m_nPanelFrontRightStatus) { + vehicle->m_DamageManager.m_sPanelsStatus.m_nPanelFrontRightStatus = rp.m_nPanelFrontRightStatus; + vehicle->SetPanelDamage(9, CDamageManager::PANEL_FR, flying); + } + if (vehicle->m_DamageManager.m_sPanelsStatus.m_nPanelBackLeftStatus != rp.m_nPanelBackLeftStatus) { + vehicle->m_DamageManager.m_sPanelsStatus.m_nPanelBackLeftStatus = rp.m_nPanelBackLeftStatus; + vehicle->SetPanelDamage(14, CDamageManager::PANEL_RL, flying); + } + if (vehicle->m_DamageManager.m_sPanelsStatus.m_nPanelBackRightStatus != rp.m_nPanelBackRightStatus) { + vehicle->m_DamageManager.m_sPanelsStatus.m_nPanelBackRightStatus = rp.m_nPanelBackRightStatus; + vehicle->SetPanelDamage(10, CDamageManager::PANEL_RR, flying); + } + if (vehicle->m_DamageManager.m_sPanelsStatus.m_nWindshieldStatus != rp.m_nWindshieldStatus) { + vehicle->m_DamageManager.m_sPanelsStatus.m_nWindshieldStatus = rp.m_nWindshieldStatus; + vehicle->SetPanelDamage(19, CDamageManager::PANEL_WINDSHIELD, flying); + } + if (vehicle->m_DamageManager.m_sPanelsStatus.m_nPanelFrontStatus != rp.m_nPanelFrontStatus) { + vehicle->m_DamageManager.m_sPanelsStatus.m_nPanelFrontStatus = rp.m_nPanelFrontStatus; + vehicle->SetPanelDamage(7, CDamageManager::PANEL_FRONT, flying); + } + if (vehicle->m_DamageManager.m_sPanelsStatus.m_nPanelBackStatus != rp.m_nPanelBackStatus) { + vehicle->m_DamageManager.m_sPanelsStatus.m_nPanelBackStatus = rp.m_nPanelBackStatus; + vehicle->SetPanelDamage(8, CDamageManager::PANEL_BACK, flying); + } +} +#endif void PrintElementsInPtrList(void) { diff --git a/src/entities/Automobile.cpp b/src/entities/Automobile.cpp index e74013be..54eed17a 100644 --- a/src/entities/Automobile.cpp +++ b/src/entities/Automobile.cpp @@ -10,6 +10,8 @@ CAutomobile::CAutomobile(int mi, uint8 owner) WRAPPER CAutomobile* CAutomobile::ctor(int, uint8) { EAXJMP(0x52C6B0); } WRAPPER void CAutomobile::SetDoorDamage(int32, uint32, bool) { EAXJMP(0x530200); } +WRAPPER void CAutomobile::SetPanelDamage(int32, uint32, bool) { EAXJMP(0x5301A0); } +WRAPPER void CAutomobile::SetBumperDamage(int32, uint32, bool) { EAXJMP(0x530120); } STARTPATCHES InjectHook(0x52D170, &CAutomobile::dtor, PATCH_JUMP); diff --git a/src/entities/Automobile.h b/src/entities/Automobile.h index 246943a7..64e411ce 100644 --- a/src/entities/Automobile.h +++ b/src/entities/Automobile.h @@ -25,6 +25,8 @@ public: CAutomobile(int, uint8); CAutomobile* ctor(int, uint8); void SetDoorDamage(int32, uint32, bool); /* TODO: eDoors */ + void SetPanelDamage(int32, uint32, bool); /* TODO: ePanels */ + void SetBumperDamage(int32, uint32, bool); /* TODO: ePanels */ void dtor() { this->CAutomobile::~CAutomobile(); } }; static_assert(sizeof(CAutomobile) == 0x5A8, "CAutomobile: error"); -- cgit v1.2.3