Lua: Fix type confusion between signed and unsigned
[lsnes.git] / include / library / movie.hpp
blob59f2ca7c1fa60d98f9d913578393b105625f41cc
1 #ifndef _library__movie__hpp__included__
2 #define _library__movie__hpp__included__
4 #include <string>
5 #include <cstdint>
6 #include <stdexcept>
7 #include "portctrl-data.hpp"
8 #include "memtracker.hpp"
10 /**
11 * Movie being played back or recorded
13 class movie
15 public:
16 /**
17 * Construct new empty movie.
19 * throws std::bad_alloc: Not enough memory.
21 movie() throw(std::bad_alloc);
23 /**
24 * Dtor.
26 ~movie();
28 /**
29 * Is the movie in readonly mode?
31 * returns: True if in read-only mode, false if in read-write mode.
33 bool readonly_mode() throw();
35 /**
36 * Switches movie to read-only or read-write mode. If switching to read-write mode, the movie is truncated.
38 * parameter enable: If true, switch to read-only mode, else to read-write mode.
39 * throws std::bad_alloc: Not enough memory.
41 void readonly_mode(bool enable) throw(std::bad_alloc);
43 /**
44 * Returns the movie rerecord count (this is not the same thing as global rerecord count).
46 * returns: The movie rerecord count
47 * throws std::bad_alloc: Not enough memory.
49 std::string rerecord_count() throw(std::bad_alloc);
51 /**
52 * Sets the movie rerecord count (this is not the same thing as global rerecord count).
54 * parameter count: The new rerecord count
55 * throws std::bad_alloc: Not enough memory.
57 void rerecord_count(const std::string& count) throw(std::bad_alloc);
59 /**
60 * Read project ID
62 * returns: The project ID
63 * throws std::bad_alloc: Not enough memory.
65 std::string project_id() throw(std::bad_alloc);
67 /**
68 * brief Set project ID
70 * parameter id: New project ID.
71 * throws std::bad_alloc: Not enough memory.
73 void project_id(const std::string& id) throw(std::bad_alloc);
75 /**
76 * Get number of frames in movie
78 * returns: The number of frames.
80 uint64_t get_frame_count() throw() { return movie_data->count_frames(); }
82 /**
83 * Get number of current frame in movie
85 * The first frame in movie is 1. 0 is "before first frame" value.
87 * returns: The number of frame
89 uint64_t get_current_frame() throw();
91 /**
92 * Get number of lag frames so far
94 * returns: The number of lag frames.
96 uint64_t get_lag_frames() throw();
98 /**
99 * This function advances to next frame in movie, discarding subframes not used. If the frame is lag frame, it is
100 * counted as lag frame and subframe entry for it is made (if in readwrite mode).
102 * throws std::bad_alloc: Not enough memory.
104 void next_frame() throw(std::bad_alloc);
107 * Reads the data ready flag. On new frame, all data ready flags are unset. On reading control, its data ready
108 * flag is unset.
110 * parameter pid: Physical controller id.
111 * parameter index: Control ID.
112 * returns: The read value.
113 * throws std::logic_error: Invalid control index.
115 bool get_DRDY(unsigned port, unsigned controller, unsigned index) throw(std::logic_error);
118 * Set all data ready flags
120 void set_all_DRDY() throw();
123 * Poll a control by (port, controller, index) tuple.
125 * parameter pid: Physical controller ID.
126 * parameter index: The index of control in controller (0 to 11)
127 * returns: The read value
128 * throws std::bad_alloc: Not enough memory.
129 * throws std::logic_error: Invalid port, controller or index or before movie start.
131 short next_input(unsigned port, unsigned controller, unsigned index) throw(std::bad_alloc, std::logic_error);
134 * Set current control values. These are read in readwrite mode.
136 * parameter controls: The new controls.
138 void set_controls(portctrl::frame controls) throw();
141 * Get current control values in effect.
143 * returns: Controls
145 portctrl::frame get_controls() throw();
148 * Loads a movie plus some other parameters. The playback pointer is positioned to start of movie and readonly
149 * mode is enabled.
151 * parameter rerecs: Movie rerecord count.
152 * parameter project_id: Project ID of movie.
153 * parameter input: The input track.
154 * throws std::bad_alloc: Not enough memory.
155 * throws std::runtime_error: Bad movie data.
157 void load(const std::string& rerecs, const std::string& project_id, portctrl::frame_vector& input)
158 throw(std::bad_alloc, std::runtime_error);
161 * This method serializes the state of movie code.
163 * Parameter proj_id: The project ID is written here.
164 * Parameter curframe: Current frame is written here.
165 * Parameter lagframes: Lag counter is written here.
166 * Parameter pcounters: Poll counters are written here.
167 * throws std::bad_alloc: Not enough memory.
169 void save_state(std::string& proj_id, uint64_t& curframe, uint64_t& lagframes,
170 std::vector<uint32_t>& pcounters) throw(std::bad_alloc);
173 * Given previous serialized state from this movie, restore the state.
175 * Parameter curframe: Current frame.
176 * Parameter lagframe: Lag counter.
177 * Parameter pcounters: Poll counters.
178 * Parameter ro: If true, restore in readonly mode.
179 * Parameter old_movie: Old movie to check for compatiblity against.
180 * Parameter old_projectid: Old project ID to check against.
181 * Returns: ???
182 * Throws std::bad_alloc: Not enough memory.
183 * Throws std::runtime_error: Movie check failure.
185 size_t restore_state(uint64_t curframe, uint64_t lagframe, const std::vector<uint32_t>& pcounters, bool ro,
186 portctrl::frame_vector* old_movie, const std::string& old_projectid) throw(std::bad_alloc,
187 std::runtime_error);
189 * Reset the state of movie to initial state.
191 void reset_state() throw();
193 * Get how manyth poll in the frame next poll would be?
195 * returns: Poll number.
197 unsigned next_poll_number();
199 * Get how many subframes there are in specified frame.
201 * parameter frame: The frame number.
202 * returns: Number of subframes (0 if outside movie).
204 uint64_t frame_subframes(uint64_t frame) throw();
206 * Read controls from specified subframe of specified frame.
208 * parameter frame: The frame number.
209 * parameter subframe: Subframe within frame (first is 0).
210 * returns: The controls for subframe. If subframe is too great, reads last present subframe. If frame is outside
211 * movie, reads all released.
213 portctrl::frame read_subframe(uint64_t frame, uint64_t subframe) throw();
215 * Fast save.
217 void fast_save(uint64_t& _frame, uint64_t& _ptr, uint64_t& _lagc, std::vector<uint32_t>& counters);
219 * Fast load.
221 void fast_load(uint64_t& _frame, uint64_t& _ptr, uint64_t& _lagc, std::vector<uint32_t>& counters);
223 * Poll flag handling.
225 class poll_flag
227 public:
228 virtual ~poll_flag();
230 * Get the poll flag.
232 virtual int get_pflag() = 0;
234 * Set the poll flag.
236 virtual void set_pflag(int flag) = 0;
239 * Set the poll flag handler.
241 void set_pflag_handler(poll_flag* handler);
243 * Flush caches.
245 void clear_caches() throw();
247 * Get sequence number (increments by 1 each time whole data is reloaded).
249 uint64_t get_seqno() throw() { return seqno; }
251 * Get pollcounter vector.
253 portctrl::counters& get_pollcounters() { return pollcounters; }
255 * Get first subframe of this frame.
257 uint64_t get_current_frame_first_subframe() { return current_frame_first_subframe; }
259 * Read specified triple at specified subframe of current frame. Only works in readonly mode.
261 int16_t read_subframe_at_index(uint32_t subframe, unsigned port, unsigned controller, unsigned index);
263 * Write specified triple at specified subframe of current frame (if possible). Only works in readonly mode.
265 void write_subframe_at_index(uint32_t subframe, unsigned port, unsigned controller, unsigned index,
266 int16_t x);
268 * Call portctrl::frame_vector::compatible() with correct frame and pollcounters.
270 * Parameter with: The second vector.
271 * Returns: True if compatible, false if not.
273 bool compatible(portctrl::frame_vector& with)
275 return movie_data->compatible(with, current_frame, pollcounters.rawdata());
278 * Set external movie data.
280 * Parameter data: New movie data.
282 void set_movie_data(portctrl::frame_vector* data);
283 private:
284 class fchange_listener : public portctrl::frame_vector::fchange_listener
286 public:
287 fchange_listener(movie& m);
288 ~fchange_listener();
289 void notify(portctrl::frame_vector& src, uint64_t old);
290 private:
291 movie& mov;
292 } _listener;
293 movie(const movie& mov);
294 movie& operator=(const movie& m);
295 //Sequence number.
296 uint64_t seqno;
297 //The poll flag handling.
298 poll_flag* pflag_handler;
299 //TRUE if readonly mode is active.
300 bool readonly;
301 //TRUE if movie is latched to end.
302 bool latch_end;
303 //Movie (not global!) rerecord count.
304 std::string rerecords;
305 //Project ID.
306 std::string _project_id;
307 //The actual controller data.
308 portctrl::frame_vector* movie_data;
309 //Current frame + 1 (0 before next_frame() has been called.
310 uint64_t current_frame;
311 //First subframe in current frame (movie_data.size() if no subframes have been stored).
312 uint64_t current_frame_first_subframe;
313 //How many times has each control been polled (bit 31 is data ready bit)?
314 portctrl::counters pollcounters;
315 //Current state of buttons.
316 portctrl::frame current_controls;
317 //Number of known lag frames.
318 uint64_t lag_frames;
319 //Cached subframes.
320 uint64_t cached_frame;
321 uint64_t cached_subframe;
322 //Count present subframes in frame starting from first_subframe (returns 0 if out of movie).
323 uint32_t count_changes(uint64_t first_subframe) throw();
324 //Tracker.
325 memtracker::autorelease tracker;
328 #endif