1 //-----------------------------------------------------------------------------
2 // Demo Header
3 //-----------------------------------------------------------------------------
4 
5 #ifndef __DEMO_H__
6 #define __DEMO_H__
7 
8 #include "client.h"
9 
10 // Demo file structures -------------------------------------------------------
11 
12 /**
13  * Structure of a demo header.
14  */
15 typedef struct
16 {
17   char map[32];       /**< map to load for demo rendering */
18   int num_frames;       /**< number of frames */
19   char version[8];      /**< demo version */
20   float capture_interval;   /**< time interval used for demo recording */
21 } DemoHeader;
22 
23 /**
24  * Structure of a demo frame.
25  */
26 typedef struct
27 {
28   float timing;       /**< frame time */
29   vec3_t campos;        /**< client camera position in frame */
30   vec3_t camrot;        /**< client camera rotation in frame */
31 } DemoFrame;
32 
33 typedef enum
34 {
35   AUTO_INTERPOLATION,     /**< cake decides automatically what interpolation mode to use */
36   LINEAR_INTERPOLATION,   /**< linear interpolation mode */
37   SPLINE_INTERPOLATION    /**< cubic spline interpolaiton mode */
38 } enum_InterpolationMode;
39 
40 /**
41  * The demo class stores and plays demos in cake.
42  * It can be used to save a demo into a file or to play an existing
43  * demo from a file.
44  */
45 class Demo
46 {
47   public:
48 
49     Demo(void);       /**< Default constructor */
50     ~Demo(void);      /**< Default destructor */
51 
52     /**
53      * Starts a demo recording for a client.
54      * The function has no effect if another recording is already running.
55      * @param client The client that is recorded.
56      * @param mapname The name of map used while recording the demo.
57      * @param framesinterval The minimum interval in seconds between 2 frame
58      *        captures.
59      * @return A non null value if recording could start, 0 if not.
60      */
61     int StartDemoRecording(Client *client, const char *mapname, float framesinterval = 0);
62 
63     /**
64      * Stops the recording and write destination file.
65      * @param destfile The destination file for demo saving.
66      * @return A non null value if saving is successfull, 0 if it fails
67      */
68     int StopDemoRecording(const char* destfile);
69 
70     /**
71      * Load a demo in a client view.
72      * The function loads the demo file and create frames buffer.
73      * @param demofile The file that contains demo.
74      * @param mode Mode of interpolation used for camera position
75      *        and rotation interpolation values. Linear interpolation
76      *        is fast and looks well for demos with lot of keyframes,
77      *        but can produce abrupt direction variation at keyframes.
78      *        If demos has few keyframes, splnne interpolation mode
79      *        should be used to avoid this effect. The auto interpolation
80      *        mode chooses the adequate interpolation mode depending on
81      *        capture keyframe rate.
82      * @return The required map name for demo, or an empty string if demo file
83      *         couldn't be loaded.
84      */
85     char* LoadDemo(const char* demofile,
86              enum_InterpolationMode mode = AUTO_INTERPOLATION);
87 
88     /**
89      * Start playing a demo.
90      * The function has no effect if no demo file is loaded.
91      * @param client The client that will be used to view demo
92      * @param loop Define if the demo must loop automatically
93      */
94     void StartDemoPlaying(Client *client, bool loop = false);
95 
96     /**
97      * Stops playing a demo.
98      * The function has no effect if no demo is playing.
99      */
100     void StopDemoPlaying(void);
101 
102     /**
103      * Inform the demo class that a new frame is trigged
104      * This function must be used to inform that a new frame has been done. The
105      * function is used both for demo recording and playing. If recording, the
106      * function checks if a frame must be recorded (depending on framespersecond
107      * value). The function returns without doing anything is no new frame record
108      * is needed.
109      * If playing, the function interpolate camera position in function of framerate.
110      * @return A null value if there is currently no recording or playing, the current
111                position in demo (between 0 to 1).
112      */
113     float NewFrame(void);
114 
115     /**
116      * Dump demo file content (for debug purpose only)
117      * @param demofile The demo file to analyse.
118      * @param n Number of frames to show (all = -1)
119      */
120     void DemoDump(char *demofile, int n = 0);
121 
122     bool isRecording;                 /**< A demo is currently being recorded */
123     bool isPlaying;                   /**< A demo is currently being played */
124 
125   private:
126     char currmapname[32];               /**< Map name used for demo (recording) */
127     Client *currclient;                 /**< Current client (playing or recording) */
128     float frame_interval;               /**< Interval between to captures (recording only) */
129     float last_frame_time;                /**< Time of last capture (recording only) */
130     float start_demo_time;                /**< Time of demo start (playing or recording) */
131     int currframenum;                 /**< Current frame number (playing only) */
132     enum_InterpolationMode interpolationmode;     /**< Interpolation mode (playing only) */
133     bool isLooping;                   /**< Demo is looping (playing only) */
134 
135     int numframes;                    /**< Number of frames */
136     int numframesAllocated;               /**< Number of allocated frames */
137     DemoFrame *frames;                  /**< Demo frames (recording only) */
138 
139     vec3_t *cam_positions;                /**< Camera positions array */
140     vec3_t *cam_positions_tangents;           /**< Tangents to camera positions (required by spline interpolation) */
141     vec3_t *cam_rotations;                /**< Camera rotations array */
142     vec3_t *cam_rotations_tangents;           /**< Tangents to camera rotations (required by spline interpolation) */
143     float *timings;                   /**< Timings array */
144 
145     bool noclipstate;                 /**< Used to store noclip state */
146 
147     void AddFrame(void);                /**< Register the frame */
148 };
149 
150 #endif  /* __DEMO_H__ */
151