1 /******************************************************************************
2 * irrlamb - https://github.com/jazztickets/irrlamb
3 * Copyright (C) 2019  Alan Witkowski
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 *******************************************************************************/
18 #pragma once
19 
20 // Libraries
21 #include <fstream>
22 
23 // Constants
24 const int REPLAY_VERSION = 4;
25 
26 // Event packet structure
27 struct _ReplayEvent {
28 	uint8_t Type;
29 	float Timestamp;
30 };
31 
32 // Classes
33 class _Replay {
34 
35 	public:
36 
37 		enum PacketType {
38 
39 			// Header
40 			PACKET_REPLAYVERSION,
41 			PACKET_LEVELVERSION,
42 			PACKET_LEVELFILE,
43 			PACKET_DESCRIPTION,
44 			PACKET_DATE,
45 			PACKET_FINISHTIME,
46 			PACKET_TIMESTEP,
47 			PACKET_AUTOSAVE,
48 			PACKET_WON,
49 			PACKET_PLATFORM,
50 
51 			// Object updates
52 			PACKET_OBJECTDATA = 127,
53 			PACKET_CAMERA,
54 			PACKET_MOVEMENT,
55 			PACKET_CREATE,
56 			PACKET_DELETE,
57 			PACKET_ORBDEACTIVATE,
58 			PACKET_INPUT,
59 			PACKET_PLAYERSPEED,
60 		};
61 
62 		enum StateType {
63 			STATE_NONE,
64 			STATE_RECORDING,
65 			STATE_REPLAYING,
66 		};
67 
68 		// Recording functions
69 		void StartRecording();
70 		void StopRecording();
71 		bool SaveReplay(const std::string &PlayerDescription, bool Autosave=false, bool Won=false);
72 
73 		// Playback functions
74 		bool LoadReplay(const std::string &ReplayFile, bool HeaderOnly=false);
StartReplay()75 		void StartReplay() { State = STATE_REPLAYING; }
76 		void StopReplay();
77 		bool ReplayStopped();
78 
79 		void Update(float FrameTime);
80 
IsRecording()81 		bool IsRecording() const { return State == STATE_RECORDING; }
IsReplaying()82 		bool IsReplaying() const { return State == STATE_REPLAYING; }
83 		bool NeedsPacket();
84 
GetFile()85 		std::fstream &GetFile() { return File; }
86 		void WriteEvent(uint8_t Type);
87 		void ReadEvent(_ReplayEvent &Packet);
88 
GetLevelName()89 		const std::string &GetLevelName() { return LevelName; }
GetDescription()90 		const std::string &GetDescription() { return Description; }
GetVersion()91 		int32_t GetVersion() { return ReplayVersion; }
GetLevelVersion()92 		int32_t GetLevelVersion() { return LevelVersion; }
GetTimeStep()93 		float GetTimeStep() { return TimeStep; }
GetFinishTime()94 		float GetFinishTime() { return FinishTime; }
GetTimestamp()95 		time_t &GetTimestamp() { return Timestamp; }
GetPlatform()96 		char GetPlatform() { return Platform; }
GetAutosave()97 		bool GetAutosave() { return Autosave; }
GetWon()98 		bool GetWon() { return Won; }
99 
100 	private:
101 
102 		void LoadHeader();
103 		void WriteChunk(std::fstream &OutFile, char Type, const char *Data, uint32_t Size);
104 
105 		// Header
106 		int32_t ReplayVersion;
107 		int32_t LevelVersion;
108 		std::string LevelName;
109 		std::string Description;
110 		time_t Timestamp;
111 		float FinishTime;
112 		float TimeStep;
113 		char Platform;
114 		bool Autosave;
115 		bool Won;
116 
117 		// Replay data file name
118 		std::string ReplayDataFile;
119 
120 		// File stream
121 		std::fstream File;
122 
123 		// Time management
124 		float Time;
125 
126 		// State
127 		StateType State;
128 
129 };
130 
131 // Singletons
132 extern _Replay Replay;
133