Fix crash on invalid Lua function arguments
[lsnes.git] / movie.hpp
blob2745986d6456be38d2f6eee0a4c6cf7bd6643e36
1 #ifndef _movie__hpp__included__
2 #define _movie__hpp__included__
4 #include <string>
5 #include <cstdint>
6 #include <stdexcept>
7 #include "controllerdata.hpp"
9 /**
10 * Movie being played back or recorded
12 class movie
14 public:
15 /**
16 * Construct new empty movie.
18 * throws std::bad_alloc: Not enough memory.
20 movie() throw(std::bad_alloc);
22 /**
23 * Is the movie in readonly mode?
25 * returns: True if in read-only mode, false if in read-write mode.
27 bool readonly_mode() throw();
29 /**
30 * Switches movie to read-only or read-write mode. If switching to read-write mode, the movie is truncated.
32 * parameter enable: If true, switch to read-only mode, else to read-write mode.
33 * throws std::bad_alloc: Not enough memory.
35 void readonly_mode(bool enable) throw(std::bad_alloc);
37 /**
38 * Returns the movie rerecord count (this is not the same thing as global rerecord count).
40 * returns: The movie rerecord count
41 * throws std::bad_alloc: Not enough memory.
43 std::string rerecord_count() throw(std::bad_alloc);
45 /**
46 * Sets the movie rerecord count (this is not the same thing as global rerecord count).
48 * parameter count: The new rerecord count
49 * throws std::bad_alloc: Not enough memory.
51 void rerecord_count(const std::string& count) throw(std::bad_alloc);
53 /**
54 * Read project ID
56 * returns: The project ID
57 * throws std::bad_alloc: Not enough memory.
59 std::string project_id() throw(std::bad_alloc);
61 /**
62 * brief Set project ID
64 * parameter id: New project ID.
65 * throws std::bad_alloc: Not enough memory.
67 void project_id(const std::string& id) throw(std::bad_alloc);
69 /**
70 * Get number of frames in movie
72 * returns: The number of frames.
74 uint64_t get_frame_count() throw();
76 /**
77 * Get number of current frame in movie
79 * The first frame in movie is 1. 0 is "before first frame" value.
81 * returns: The number of frame
83 uint64_t get_current_frame() throw();
85 /**
86 * Get number of lag frames so far
88 * returns: The number of lag frames.
90 uint64_t get_lag_frames() throw();
92 /**
93 * This function advances to next frame in movie, discarding subframes not used. If the frame is lag frame, it is
94 * counted as lag frame and subframe entry for it is made (if in readwrite mode).
96 * throws std::bad_alloc: Not enough memory.
98 void next_frame() throw(std::bad_alloc);
101 * Reads the data ready flag. On new frame, all data ready flags are unset. On reading control, its data ready
102 * flag is unset.
104 * parameter controlindex: The index of control to read it for.
105 * returns: The read value.
106 * throws std::logic_error: Invalid control index.
108 bool get_DRDY(unsigned controlindex) throw(std::logic_error);
111 * Reads the data ready flag. On new frame, all data ready flags are unset. On reading control, its data ready
112 * flag is unset.
114 * This differs from get_DRDY(unsigned) in that this takes (port, controller,index) tuple.
116 * parameter port: The port controller is connected to (0 or 1)
117 * parameter controller: The controller number within port (0 to 3)
118 * parameter index: The index of control in controller (0 to 11)
119 * returns: The read value.
120 * throws std::logic_error: Invalid control index.
122 bool get_DRDY(unsigned port, unsigned controller, unsigned index) throw(std::logic_error);
125 * Set all data ready flags
127 void set_all_DRDY() throw();
130 * Poll a control. Note that index 0 (sync flag) always reads as released.
132 * parameter controlindex: The index
133 * returns: The read value
134 * throws std::bad_alloc: Not enough memory.
135 * throws std::logic_error: Invalid control index or before movie start.
137 short next_input(unsigned controlindex) throw(std::bad_alloc, std::logic_error);
140 * Poll a control by (port, controller, index) tuple.
142 * parameter port: The port controller is connected to (0 or 1)
143 * parameter controller: The controller number within port (0 to 3)
144 * parameter index: The index of control in controller (0 to 11)
145 * returns: The read value
146 * throws std::bad_alloc: Not enough memory.
147 * throws std::logic_error: Invalid port, controller or index or before movie start.
149 short next_input(unsigned port, unsigned controller, unsigned index) throw(std::bad_alloc, std::logic_error);
152 * Set current control values. These are read in readwrite mode.
154 * parameter controls: The new controls.
156 void set_controls(controls_t controls) throw();
159 * Get current control values in effect.
161 * returns: Controls
163 controls_t get_controls() throw();
166 * Loads a movie plus some other parameters. The playback pointer is positioned to start of movie and readonly
167 * mode is enabled.
169 * parameter rerecs: Movie rerecord count.
170 * parameter project_id: Project ID of movie.
171 * parameter input: The input track.
172 * throws std::bad_alloc: Not enough memory.
173 * throws std::runtime_error: Bad movie data.
175 void load(const std::string& rerecs, const std::string& project_id, const std::vector<controls_t>& input)
176 throw(std::bad_alloc, std::runtime_error);
179 * Saves the movie data.
181 * returns: The movie data.
182 * throws std::bad_alloc: Not enough memory.
184 std::vector<controls_t> save() throw(std::bad_alloc);
187 * This method serializes the state of movie code.
189 * returns: The serialized state.
190 * throws std::bad_alloc: Not enough memory.
192 std::vector<uint8_t> save_state() throw(std::bad_alloc);
195 * Given previous serialized state from this movie, restore the state.
197 * parameter state: The state to restore.
198 * parameter ro: If true, restore in readonly mode, otherwise in readwrite mode.
199 * throw std::bad_alloc: Not enough memory.
200 * throw std::runtime_error: State is not from this movie or states is corrupt.
202 size_t restore_state(const std::vector<uint8_t>& state, bool ro) throw(std::bad_alloc, std::runtime_error);
205 * Get reset status for current frame.
207 * returns: -1 if current frame doesn't have a reset. Otherwise number of cycles to wait for delayed reset (0 is
208 * immediate reset).
210 long get_reset_status() throw();
213 * Commit a reset (writes a reset into current frame in readwrite mode).
215 * parameter delay: The number of cycles to delay the reset.
217 void commit_reset(long delay) throw(std::bad_alloc);
220 * Get how manyth poll in the frame next poll would be?
222 * returns: Poll number.
224 unsigned next_poll_number();
226 * Get how many subframes there are in specified frame.
228 * parameter frame: The frame number.
229 * returns: Number of subframes (0 if outside movie).
231 uint64_t frame_subframes(uint64_t frame) throw();
233 * Read controls from specified subframe of specified frame.
235 * parameter frame: The frame number.
236 * parameter subframe: Subframe within frame (first is 0).
237 * returns: The controls for subframe. If subframe is too great, reads last present subframe. If frame is outside
238 * movie, reads all released.
240 controls_t read_subframe(uint64_t frame, uint64_t subframe) throw();
241 private:
242 //TRUE if readonly mode is active.
243 bool readonly;
244 //Movie (not global!) rerecord count.
245 std::string rerecords;
246 //Project ID.
247 std::string _project_id;
248 //The actual controller data.
249 std::vector<controls_t> movie_data;
250 //Current frame + 1 (0 before next_frame() has been called.
251 uint64_t current_frame;
252 //First subframe in current frame (movie_data.size() if no subframes have been stored).
253 uint64_t current_frame_first_subframe;
254 //How many times has each control been polled (bit 31 is data ready bit)?
255 uint32_t pollcounters[TOTAL_CONTROLS];
256 //Current state of buttons.
257 controls_t current_controls;
258 //Number of known lag frames.
259 uint64_t lag_frames;
260 //Number of frames in movie.
261 uint64_t frames_in_movie;
262 //Cached subframes.
263 void clear_caches() throw();
264 uint64_t cached_frame;
265 uint64_t cached_subframe;
266 //Count present subframes in frame starting from first_subframe (returns 0 if out of movie).
267 uint32_t count_changes(uint64_t first_subframe) throw();
271 * Class encapsulating bridge logic between bsnes interface and movie code.
273 class movie_logic
275 public:
277 * Create new bridge.
279 movie_logic() throw();
282 * Get the movie instance associated.
284 * returns: The movie instance.
286 movie& get_movie() throw();
289 * Notify about new frame starting.
291 * returns: Reset status for the new frame.
293 long new_frame_starting(bool dont_poll) throw(std::bad_alloc, std::runtime_error);
296 * Poll for input.
298 * parameter port: The port number.
299 * parameter dev: The controller index.
300 * parameter id: Control id.
301 * returns: Value for polled input.
302 * throws std::bad_alloc: Not enough memory.
303 * throws std::runtime_error: Error polling for input.
305 short input_poll(bool port, unsigned dev, unsigned id) throw(std::bad_alloc, std::runtime_error);
308 * Called when movie code needs new controls snapshot.
310 * parameter subframe: True if this is for subframe update, false if for frame update.
312 controls_t update_controls(bool subframe) throw(std::bad_alloc, std::runtime_error);
313 private:
314 movie mov;
317 #endif