1 #pragma once 2 #include "../vdrift/mathvector.h" 3 #include "../vdrift/quaternion.h" 4 #include <OgreVector3.h> 5 #include "half.hpp" 6 #include <OgrePrerequisites.h> // 7 using Ogre::uchar; 8 using Ogre::ushort; 9 class CAR; 10 using half_float::half; 11 12 // replay load log and check 13 #define LOG_RPL 14 15 16 // NEW replays since 2.6 17 // variable header and frame sizes 18 //---------------------------------------------------------------------------------------- 19 20 /// size of ReplayFrame2 21 //= 202 Bytes per frame (minimal,approx) 22 // 202 * 80 fps = 16.1 kB/s 23 // 1 min = 970 kB, 10 min = 9.7 MB 24 25 struct ReplayHeader2 26 { 27 char head[5]; // "SR/^ " 28 short ver; 29 float time; // total time 30 31 std::string track; // track name 32 char track_user; // user/original 33 34 char numPlayers; 35 std::vector<std::string> cars; // car names eg. ES 36 std::vector<uchar> numWh; //wheels count for all cars 37 38 float trees; // trees multipler 39 char num_laps; 40 char networked; // if 1, was networked, so use nicks when playing 41 std::string sim_mode; // easy, normal, etc 42 43 std::vector<std::string> nicks; // multiplayer nicks 44 //std::vector<float> hue,sat,val,gloss,refl; // cars colors? 45 46 ReplayHeader2(); 47 void Default(), SetHead(); 48 void FromOld(const struct ReplayHeader& hdr); 49 }; 50 51 // car data, for each simulation frame 52 //-------------------------------------------- 53 enum eFlags { b_braking=0, b_scrap, b_hit, b_fluid, b_hov }; // max 8 54 55 // wheel 56 struct RWheel 57 { 58 MATHVECTOR<float,3> pos; 59 QUATERNION<half> rot; 60 61 // trails, particles, snd 62 char surfType, whTerMtr; //TRACKSURFACE::TYPE 63 char whRoadMtr, whP; //particle type 64 65 // tire 66 half squeal, slide, whVel; 67 half suspVel, suspDisp; 68 69 // fluids 70 uchar whH; // /var - submerge 71 half whAngVel; 72 half whSteerAng; // 38B 73 }; 74 75 struct RScrap 76 { 77 half fScrap, fScreech; // 4B 78 }; 79 80 struct RHit 81 { 82 half fHitForce, fParIntens, fParVel; 83 Ogre::Vector3 vHitPos, vHitNorm; // world hit data 84 }; // 30B 85 86 struct ReplayFrame2 87 { 88 //dont use int, not portable 89 90 // time since game start 91 float time; 92 93 // car 94 MATHVECTOR<float,3> pos; 95 QUATERNION<float> rot; 96 // 32B (size in Bytes so far) 97 98 // cant use bit fields, not portable 99 uchar fl; // flags, bool 1bit setReplayFrame2100 void set(eFlags e, bool b) { if (b) fl |= 1 << e; else fl &= ~(1 << e); } getReplayFrame2101 bool get(eFlags e) const { return ((fl >> e) & 1u) > 0; } 102 // 35B 103 104 // hud 105 char gear; 106 half rpm,vel; 107 uchar damage, clutch; 108 uchar percent; // track % val 109 // 41B 110 111 // sound, input 112 uchar throttle, fboost; char steer; 113 half speed, dynVel; 114 // 48B 115 116 // ext 117 half whMudSpin; //-2 /var - may not be saved, check flags 118 half hov_roll; //-2 /var - V1 roll_ang or sph_yaw for O 119 120 121 // wheel 122 std::vector<RWheel> wheels; // 38B vec-24B 123 124 // hit continuous 125 std::vector<RScrap> scrap; // 4B 126 127 // hit impact, sparks 128 half fHitTime; 129 std::vector<RHit> hit; // 30B saved on hit only 130 // 50B 131 132 133 ReplayFrame2(); 134 void FromCar(const CAR* pCar, half prevHitTime); 135 void FromOld(const struct ReplayFrame& fr, uchar numWh, half prevHitTime); 136 137 //total: 50B + 4*38B = 202B min 138 }; 139 140 // Replay 141 //-------------------------------------------- 142 class Replay2 143 { 144 public: 145 Replay2(); 146 147 bool LoadFile(std::string file, bool onlyHdr=false); 148 bool SaveFile(std::string file); 149 150 void AddFrame(const ReplayFrame2& frame, int carNum); // record 151 bool GetFrame(float time, ReplayFrame2* fr, int carNum); // play GetFrame0(int id)152 const ReplayFrame2& GetFrame0(int id){ return frames[0][id]; } 153 154 const float GetTimeLength() const; // total time in seconds GetNumFrames()155 const int GetNumFrames() const { return frames.empty() ? 0 : frames[0].size(); } 156 157 bool GetLastFrame(ReplayFrame2* pFr, int carNum); 158 half GetLastHitTime(int carNum); 159 160 // inits only basic header data, fill the rest after 161 void InitHeader(const char* track, bool trk_user, bool bClear); 162 void Clear(bool time=true); // call this after header.numPlayers change 163 void ClearCars(); 164 165 void CopyFrom(const Replay2& rpl); 166 void DeleteFrames(int carNum, float fromTime); 167 168 static bool fixOldTrkName(std::string& trk); // old 169 170 ReplayHeader2 header; 171 private: 172 typedef std::vector<ReplayFrame2> Frames; // 1 player 173 std::vector<Frames> frames; // all plrs 174 int idLast; // last index from GetFrame 175 }; 176 177 178 // OLD replays, const size 179 //----------------------------------------------------------------------------------------------------------- 180 181 const static int ciRplHdrSize = 1024; 182 const static int cDefSize = 8*1024; 183 184 185 // note: add new vars always at end of 186 // ReplayHeader or ReplayFrame structs (backward compatibility) 187 188 /// size of ReplayFrame Old 189 //= 400 Bytes per frame 190 // 400 * 160 fps = 64 kB/s 191 // 1 min = 3.84 MB, 10 min = 38.4 MB 192 193 194 // Replay whole replay/ghost data - max 4 players, max 4 wheels 195 //-------------------------------------------- 196 struct ReplayHeader 197 { 198 char head[5]; // "SR\_ " 199 typedef char ChName[32]; 200 201 char track[63]; // track name (hmap crc? diff-) 202 char track_user; // user/original 203 ChName car; // car name (eg. ES, .car file crc?, settings diff-) 204 205 int ver, frameSize; // bin data format - sizeof(ReplayFrame) 206 float whR[4][4]; // cars wheels radius (not used now) 207 208 int numPlayers; 209 float hue[4],sat[4],val[4]; // cars colors 210 ChName cars[3]; // car names (when numPlayers > 1) 211 212 ChName nicks[4]; // multiplayer nicks 213 char descr[128]; // description - user text (wasnt used) 214 float trees; // trees multipler 215 char num_laps; 216 char networked; // if 1, was networked, so use nicks when playing 217 char sim_mode[32];// easy, normal, etc 218 219 ReplayHeader(); 220 void Default(), SafeEnd0(); 221 }; 222 223 // Replay car data, for each simulation frame 224 //-------------------------------------------- 225 struct ReplayFrame 226 { 227 // time since game start 228 double time; 229 // car & wheels 230 MATHVECTOR<float,3> pos, whPos[4]; 231 QUATERNION<float> rot, whRot[4]; 232 233 // hud 234 float rpm,vel, clutch; int gear; //char 235 236 // sound, input 237 float throttle, steer; 238 MATHVECTOR<float,3> posEngn; //snd engine pos -- 239 float speed, dynVel; 240 241 // wheel trails, particles, snd 242 char surfType[4], whTerMtr[4]; //TRACKSURFACE::TYPE 243 float squeal[4], slide[4], whVel[4]; 244 float suspVel[4], suspDisp[4]; 245 246 float fboost; // input, particles 247 char whRoadMtr[4]; 248 249 // fluids 250 float whH[4], whAngVel[4]; // submerge height 251 char whP[4]; //particle type 252 float whSteerAng[2]; 253 254 float percent; // track % val 255 char braking; // for rear car lights (bool) 256 257 // hit sparks 258 float fHitTime, fParIntens,fParVel; 259 Ogre::Vector3 vHitPos,vHitNorm; // world hit data 260 float whMudSpin, fHitForce, fCarScrap, fCarScreech; 261 float hov_roll; //=sph_yaw for O 262 263 //uchar damage; //todo.. 264 265 ReplayFrame(); 266 void FromCar(const CAR* pCar); 267 }; 268 269 // Replay 270 //-------------------------------------------- 271 class Replay 272 { 273 public: 274 Replay(); 275 276 bool LoadFile(std::string file, bool onlyHdr=false); 277 bool SaveFile(std::string file); 278 279 void AddFrame(const ReplayFrame& frame, int carNum); // record 280 bool GetFrame(double time, ReplayFrame* fr, int carNum); // play GetFrame0(int id)281 const ReplayFrame& GetFrame0(int id){ return frames[0][id]; } 282 283 const double GetTimeLength(int carNum=0) const; // total time in seconds GetNumFrames()284 const int GetNumFrames() const { return frames[0].size(); } 285 286 // inits only basic header data, fill the rest after 287 void InitHeader(const char* track, bool trk_user, const char* car, bool bClear); 288 void Clear(); // call this after header.numPlayers change 289 void CopyFrom(const Replay& rpl); 290 void DeleteFrames(int carNum, double fromTime); 291 292 static bool fixOldTrkName(std::string& trk); // old 293 294 ReplayHeader header; 295 //ReplayHeader2 header; 296 private: 297 friend class Replay2; 298 typedef std::vector<ReplayFrame> Frames; // 1 player 299 std::vector<Frames> frames; // all plrs 300 int idLast; // last index from GetFrame 301 }; 302 303 304 305 // Rewind only data for car sim, to rewind back 306 //----------------------------------------------------------------------------------------------------------- 307 struct RewindFrame 308 { 309 // time since game start 310 double time; 311 // car 312 MATHVECTOR<float,3> pos, vel, angvel; 313 QUATERNION<float> rot; 314 float fDamage, hov_roll; 315 //engine rpm?.. 316 }; 317 318 319 /// Rewind 320 // to move car back in time, not saved in file, can have less frames than replay 321 //-------------------------------------------- 322 class Rewind 323 { 324 public: 325 Rewind(); 326 327 void AddFrame(const RewindFrame& frame, int carNum); 328 bool GetFrame(double time, RewindFrame* fr, int carNum); 329 330 const double GetTimeLength(int carNum=0) const; // total time in seconds 331 332 void Clear(); 333 private: 334 std::vector<RewindFrame> frames[4]; // 4 players max (split screen) 335 int idLast[4]; // last index from GetFrame (optimisation) 336 }; 337