2019-05-30 15:24:47 -04:00
|
|
|
#pragma once
|
|
|
|
|
2019-06-22 14:16:29 -04:00
|
|
|
#include "Pools.h"
|
|
|
|
#include "World.h"
|
|
|
|
|
2020-03-15 11:47:21 -04:00
|
|
|
#ifdef FIX_BUGS
|
|
|
|
#ifndef DONT_FIX_REPLAY_BUGS
|
|
|
|
#define FIX_REPLAY_BUGS
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2020-03-28 10:47:52 -04:00
|
|
|
class CVehicle;
|
|
|
|
struct CReference;
|
|
|
|
|
2019-06-22 14:16:29 -04:00
|
|
|
struct CAddressInReplayBuffer
|
|
|
|
{
|
2019-06-22 14:42:26 -04:00
|
|
|
uint32 m_nOffset;
|
2019-06-22 14:16:29 -04:00
|
|
|
uint8 *m_pBase;
|
|
|
|
uint8 m_bSlot;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CStoredAnimationState
|
|
|
|
{
|
2019-06-23 06:58:14 -04:00
|
|
|
uint8 animId;
|
|
|
|
uint8 time;
|
|
|
|
uint8 speed;
|
|
|
|
uint8 secAnimId;
|
|
|
|
uint8 secTime;
|
|
|
|
uint8 secSpeed;
|
|
|
|
uint8 blendAmount;
|
|
|
|
uint8 partAnimId;
|
|
|
|
uint8 partAnimTime;
|
|
|
|
uint8 partAnimSpeed;
|
|
|
|
uint8 partBlendAmount;
|
2019-06-22 14:16:29 -04:00
|
|
|
};
|
|
|
|
|
2020-03-15 11:47:21 -04:00
|
|
|
enum {
|
|
|
|
NUM_MAIN_ANIMS_IN_REPLAY = 3,
|
|
|
|
NUM_PARTIAL_ANIMS_IN_REPLAY = 6
|
|
|
|
};
|
|
|
|
|
2019-06-22 14:16:29 -04:00
|
|
|
struct CStoredDetailedAnimationState
|
|
|
|
{
|
2020-03-15 11:47:21 -04:00
|
|
|
uint8 aAnimId[NUM_MAIN_ANIMS_IN_REPLAY];
|
|
|
|
uint8 aCurTime[NUM_MAIN_ANIMS_IN_REPLAY];
|
|
|
|
uint8 aSpeed[NUM_MAIN_ANIMS_IN_REPLAY];
|
|
|
|
uint8 aBlendAmount[NUM_MAIN_ANIMS_IN_REPLAY];
|
|
|
|
#ifdef FIX_REPLAY_BUGS
|
|
|
|
int8 aBlendDelta[NUM_MAIN_ANIMS_IN_REPLAY];
|
|
|
|
#endif
|
|
|
|
uint8 aFunctionCallbackID[NUM_MAIN_ANIMS_IN_REPLAY];
|
|
|
|
uint16 aFlags[NUM_MAIN_ANIMS_IN_REPLAY];
|
|
|
|
uint8 aAnimId2[NUM_PARTIAL_ANIMS_IN_REPLAY];
|
|
|
|
uint8 aCurTime2[NUM_PARTIAL_ANIMS_IN_REPLAY];
|
|
|
|
uint8 aSpeed2[NUM_PARTIAL_ANIMS_IN_REPLAY];
|
|
|
|
uint8 aBlendAmount2[NUM_PARTIAL_ANIMS_IN_REPLAY];
|
|
|
|
#ifdef FIX_REPLAY_BUGS
|
|
|
|
int8 aBlendDelta2[NUM_PARTIAL_ANIMS_IN_REPLAY];
|
|
|
|
#endif
|
|
|
|
uint8 aFunctionCallbackID2[NUM_PARTIAL_ANIMS_IN_REPLAY];
|
|
|
|
uint16 aFlags2[NUM_PARTIAL_ANIMS_IN_REPLAY];
|
2019-06-22 14:16:29 -04:00
|
|
|
};
|
|
|
|
|
2019-06-30 16:29:53 -04:00
|
|
|
void PlayReplayFromHD(void);
|
|
|
|
|
2019-05-30 15:24:47 -04:00
|
|
|
class CReplay
|
|
|
|
{
|
2019-06-12 07:46:02 -04:00
|
|
|
enum {
|
2019-06-22 14:16:29 -04:00
|
|
|
MODE_RECORD = 0,
|
|
|
|
MODE_PLAYBACK = 1
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
REPLAYCAMMODE_ASSTORED = 0,
|
|
|
|
REPLAYCAMMODE_TOPDOWN = 1,
|
|
|
|
REPLAYCAMMODE_FIXED = 2
|
2019-06-12 07:46:02 -04:00
|
|
|
};
|
2019-06-07 16:31:03 -04:00
|
|
|
|
2019-06-22 14:16:29 -04:00
|
|
|
enum {
|
|
|
|
REPLAYPACKET_END = 0,
|
|
|
|
REPLAYPACKET_VEHICLE = 1,
|
|
|
|
REPLAYPACKET_PED_HEADER = 2,
|
2019-06-22 18:34:11 -04:00
|
|
|
REPLAYPACKET_PED_UPDATE = 3,
|
2019-06-22 14:16:29 -04:00
|
|
|
REPLAYPACKET_GENERAL = 4,
|
|
|
|
REPLAYPACKET_CLOCK = 5,
|
|
|
|
REPLAYPACKET_WEATHER = 6,
|
|
|
|
REPLAYPACKET_ENDOFFRAME = 7,
|
|
|
|
REPLAYPACKET_TIMER = 8,
|
2019-06-22 18:34:11 -04:00
|
|
|
REPLAYPACKET_BULLET_TRACES = 9
|
2019-06-22 14:16:29 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
REPLAYBUFFER_UNUSED = 0,
|
|
|
|
REPLAYBUFFER_PLAYBACK = 1,
|
|
|
|
REPLAYBUFFER_RECORD = 2
|
|
|
|
};
|
|
|
|
|
2020-03-15 11:47:21 -04:00
|
|
|
enum {
|
|
|
|
NUM_REPLAYBUFFERS = 8,
|
|
|
|
REPLAYBUFFERSIZE = 100000
|
|
|
|
};
|
|
|
|
|
2019-06-22 14:16:29 -04:00
|
|
|
|
2019-06-22 14:35:23 -04:00
|
|
|
struct tGeneralPacket
|
|
|
|
{
|
|
|
|
uint8 type;
|
|
|
|
bool in_rcvehicle;
|
|
|
|
CMatrix camera_pos;
|
|
|
|
CVector player_pos;
|
|
|
|
};
|
|
|
|
static_assert(sizeof(tGeneralPacket) == 88, "tGeneralPacket: error");
|
|
|
|
|
|
|
|
struct tClockPacket
|
|
|
|
{
|
|
|
|
uint8 type;
|
|
|
|
uint8 hours;
|
|
|
|
uint8 minutes;
|
|
|
|
private:
|
|
|
|
uint8 __align;
|
|
|
|
};
|
|
|
|
static_assert(sizeof(tClockPacket) == 4, "tClockPacket: error");
|
|
|
|
|
|
|
|
struct tWeatherPacket
|
|
|
|
{
|
|
|
|
uint8 type;
|
|
|
|
uint8 old_weather;
|
|
|
|
uint8 new_weather;
|
|
|
|
float interpolation;
|
|
|
|
};
|
|
|
|
static_assert(sizeof(tWeatherPacket) == 8, "tWeatherPacket: error");
|
|
|
|
|
|
|
|
struct tTimerPacket
|
|
|
|
{
|
|
|
|
uint8 type;
|
|
|
|
uint32 timer;
|
|
|
|
};
|
|
|
|
static_assert(sizeof(tTimerPacket) == 8, "tTimerPacket: error");
|
|
|
|
|
|
|
|
struct tPedHeaderPacket
|
|
|
|
{
|
|
|
|
uint8 type;
|
|
|
|
uint8 index;
|
|
|
|
uint16 mi;
|
|
|
|
uint8 pedtype;
|
|
|
|
private:
|
|
|
|
uint8 __align[3];
|
|
|
|
};
|
|
|
|
static_assert(sizeof(tPedHeaderPacket) == 8, "tPedHeaderPacket: error");
|
|
|
|
|
|
|
|
struct tBulletTracePacket
|
|
|
|
{
|
|
|
|
uint8 type;
|
|
|
|
uint8 frames;
|
|
|
|
uint8 lifetime;
|
|
|
|
uint8 index;
|
|
|
|
CVector inf;
|
|
|
|
CVector sup;
|
|
|
|
};
|
|
|
|
static_assert(sizeof(tBulletTracePacket) == 28, "tBulletTracePacket: error");
|
|
|
|
|
|
|
|
struct tEndOfFramePacket
|
|
|
|
{
|
|
|
|
uint8 type;
|
|
|
|
private:
|
|
|
|
uint8 __align[3];
|
|
|
|
};
|
|
|
|
static_assert(sizeof(tEndOfFramePacket) == 4, "tEndOfFramePacket: error");
|
2019-06-22 14:16:29 -04:00
|
|
|
|
2019-06-22 18:34:11 -04:00
|
|
|
struct tPedUpdatePacket
|
|
|
|
{
|
|
|
|
uint8 type;
|
|
|
|
uint8 index;
|
|
|
|
int8 heading;
|
|
|
|
int8 vehicle_index;
|
|
|
|
CStoredAnimationState anim_state;
|
|
|
|
CCompressedMatrixNotAligned matrix;
|
2019-06-29 07:38:37 -04:00
|
|
|
int8 assoc_group_id;
|
2019-06-22 18:34:11 -04:00
|
|
|
uint8 weapon_model;
|
|
|
|
};
|
|
|
|
static_assert(sizeof(tPedUpdatePacket) == 40, "tPedUpdatePacket: error");
|
|
|
|
|
2019-06-24 18:42:23 -04:00
|
|
|
struct tVehicleUpdatePacket
|
|
|
|
{
|
|
|
|
uint8 type;
|
|
|
|
uint8 index;
|
|
|
|
uint8 health;
|
|
|
|
uint8 acceleration;
|
|
|
|
CCompressedMatrixNotAligned matrix;
|
|
|
|
int8 door_angles[2];
|
|
|
|
uint16 mi;
|
|
|
|
uint32 panels;
|
|
|
|
int8 velocityX;
|
|
|
|
int8 velocityY;
|
|
|
|
int8 velocityZ;
|
|
|
|
union{
|
|
|
|
int8 car_gun;
|
2019-07-20 09:18:56 -04:00
|
|
|
int8 wheel_state;
|
2019-06-24 18:42:23 -04:00
|
|
|
};
|
|
|
|
uint8 wheel_susp_dist[4];
|
|
|
|
uint8 wheel_rotation[4];
|
|
|
|
uint8 door_status;
|
|
|
|
uint8 primary_color;
|
|
|
|
uint8 secondary_color;
|
|
|
|
};
|
|
|
|
static_assert(sizeof(tVehicleUpdatePacket) == 48, "tVehicleUpdatePacket: error");
|
|
|
|
|
2019-06-22 14:16:29 -04:00
|
|
|
private:
|
2020-04-17 01:54:14 -04:00
|
|
|
static uint8 Mode;
|
|
|
|
static CAddressInReplayBuffer Record;
|
|
|
|
static CAddressInReplayBuffer Playback;
|
|
|
|
static uint8 *pBuf0;
|
|
|
|
static CAutomobile *pBuf1;
|
|
|
|
static uint8 *pBuf2;
|
|
|
|
static CPlayerPed *pBuf3;
|
|
|
|
static uint8 *pBuf4;
|
|
|
|
static CCutsceneHead *pBuf5;
|
|
|
|
static uint8 *pBuf6;
|
|
|
|
static CPtrNode *pBuf7;
|
|
|
|
static uint8 *pBuf8;
|
|
|
|
static CEntryInfoNode *pBuf9;
|
|
|
|
static uint8 *pBuf10;
|
|
|
|
static CDummyPed *pBuf11;
|
|
|
|
static uint8 *pRadarBlips;
|
|
|
|
static uint8 *pStoredCam;
|
|
|
|
static uint8 *pWorld1;
|
|
|
|
static CReference *pEmptyReferences;
|
|
|
|
static CStoredDetailedAnimationState *pPedAnims;
|
|
|
|
static uint8 *pPickups;
|
|
|
|
static uint8 *pReferences;
|
|
|
|
static uint8 BufferStatus[NUM_REPLAYBUFFERS];
|
|
|
|
static uint8 Buffers[NUM_REPLAYBUFFERS][REPLAYBUFFERSIZE];
|
|
|
|
static bool bPlayingBackFromFile;
|
|
|
|
static bool bReplayEnabled;
|
|
|
|
static uint32 SlowMotion;
|
|
|
|
static uint32 FramesActiveLookAroundCam;
|
|
|
|
static bool bDoLoadSceneWhenDone;
|
|
|
|
static CPtrList WorldPtrList;
|
|
|
|
static CPtrList BigBuildingPtrList;
|
|
|
|
static CWanted PlayerWanted;
|
|
|
|
static CPlayerInfo PlayerInfo;
|
|
|
|
static uint32 Time1;
|
|
|
|
static uint32 Time2;
|
|
|
|
static uint32 Time3;
|
|
|
|
static uint32 Time4;
|
|
|
|
static uint32 Frame;
|
|
|
|
static uint8 ClockHours;
|
|
|
|
static uint8 ClockMinutes;
|
|
|
|
static uint16 OldWeatherType;
|
|
|
|
static uint16 NewWeatherType;
|
|
|
|
static float WeatherInterpolationValue;
|
|
|
|
static float TimeStepNonClipped;
|
|
|
|
static float TimeStep;
|
|
|
|
static float TimeScale;
|
|
|
|
static float CameraFixedX;
|
|
|
|
static float CameraFixedY;
|
|
|
|
static float CameraFixedZ;
|
|
|
|
static int32 OldRadioStation;
|
|
|
|
static int8 CameraMode;
|
|
|
|
static bool bAllowLookAroundCam;
|
|
|
|
static float LoadSceneX;
|
|
|
|
static float LoadSceneY;
|
|
|
|
static float LoadSceneZ;
|
|
|
|
static float CameraFocusX;
|
|
|
|
static float CameraFocusY;
|
|
|
|
static float CameraFocusZ;
|
|
|
|
static bool bPlayerInRCBuggy;
|
|
|
|
static float fDistanceLookAroundCam;
|
|
|
|
static float fAlphaAngleLookAroundCam;
|
|
|
|
static float fBetaAngleLookAroundCam;
|
2019-06-14 19:34:19 -04:00
|
|
|
|
2019-06-22 14:16:29 -04:00
|
|
|
public:
|
|
|
|
static void Init(void);
|
2019-06-22 14:35:23 -04:00
|
|
|
static void DisableReplays(void);
|
|
|
|
static void EnableReplays(void);
|
2019-06-22 14:16:29 -04:00
|
|
|
static void Update(void);
|
|
|
|
static void FinishPlayback(void);
|
2019-06-29 07:38:37 -04:00
|
|
|
static void EmptyReplayBuffer(void);
|
2019-06-14 19:34:19 -04:00
|
|
|
static void Display(void);
|
2019-06-22 14:16:29 -04:00
|
|
|
static void TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene);
|
|
|
|
static void StreamAllNecessaryCarsAndPeds(void);
|
|
|
|
static bool ShouldStandardCameraBeProcessed(void);
|
|
|
|
|
2019-07-07 04:16:16 -04:00
|
|
|
static bool IsPlayingBack() { return Mode == MODE_PLAYBACK; }
|
|
|
|
static bool IsPlayingBackFromFile() { return bPlayingBackFromFile; }
|
2019-06-22 14:16:29 -04:00
|
|
|
|
2019-06-30 12:22:44 -04:00
|
|
|
private:
|
2019-06-22 14:16:29 -04:00
|
|
|
static void RecordThisFrame(void);
|
|
|
|
static void StorePedUpdate(CPed *ped, int id);
|
|
|
|
static void StorePedAnimation(CPed *ped, CStoredAnimationState *state);
|
2019-06-29 14:38:47 -04:00
|
|
|
static void StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState *state);
|
2019-06-22 14:16:29 -04:00
|
|
|
static void ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayBuffer *buffer);
|
|
|
|
static void RetrievePedAnimation(CPed *ped, CStoredAnimationState *state);
|
|
|
|
static void RetrieveDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState *state);
|
|
|
|
static void PlaybackThisFrame(void);
|
2020-03-15 11:47:21 -04:00
|
|
|
static void TriggerPlaybackLastCoupleOfSeconds(uint32, uint8, float, float, float, uint32);
|
|
|
|
static bool FastForwardToTime(uint32);
|
2019-06-22 14:16:29 -04:00
|
|
|
static void StoreCarUpdate(CVehicle *vehicle, int id);
|
|
|
|
static void ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressInReplayBuffer *buffer);
|
|
|
|
static bool PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, float interpolation, uint32 *pTimer);
|
|
|
|
static void ProcessReplayCamera(void);
|
|
|
|
static void StoreStuffInMem(void);
|
|
|
|
static void RestoreStuffFromMem(void);
|
|
|
|
static void EmptyPedsAndVehiclePools(void);
|
|
|
|
static void EmptyAllPools(void);
|
|
|
|
static void MarkEverythingAsNew(void);
|
|
|
|
static void SaveReplayToHD(void);
|
|
|
|
static void FindFirstFocusCoordinate(CVector *coord);
|
|
|
|
static void ProcessLookAroundCam(void);
|
|
|
|
static size_t FindSizeOfPacket(uint8);
|
2019-06-30 16:29:53 -04:00
|
|
|
|
|
|
|
/* Absolute nonsense, but how could this function end up being outside of class? */
|
|
|
|
friend void PlayReplayFromHD(void);
|
2019-05-30 15:24:47 -04:00
|
|
|
};
|