Save bitmaps as PNG
[lsnes.git] / include / library / movie.hpp
blob2491e927b50509859066df422efc587789721347
1 #ifndef _library__movie__hpp__included__
2 #define _library__movie__hpp__included__
4 #include <string>
5 #include <cstdint>
6 #include <stdexcept>
7 #include "controller-data.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 pid: Physical controller id.
105 * parameter index: Control ID.
106 * returns: The read value.
107 * throws std::logic_error: Invalid control index.
109 bool get_DRDY(unsigned port, unsigned controller, unsigned index) throw(std::logic_error);
112 * Set all data ready flags
114 void set_all_DRDY() throw();
117 * Poll a control by (port, controller, index) tuple.
119 * parameter pid: Physical controller ID.
120 * parameter index: The index of control in controller (0 to 11)
121 * returns: The read value
122 * throws std::bad_alloc: Not enough memory.
123 * throws std::logic_error: Invalid port, controller or index or before movie start.
125 short next_input(unsigned port, unsigned controller, unsigned index) throw(std::bad_alloc, std::logic_error);
128 * Set current control values. These are read in readwrite mode.
130 * parameter controls: The new controls.
132 void set_controls(controller_frame controls) throw();
135 * Get current control values in effect.
137 * returns: Controls
139 controller_frame get_controls() throw();
142 * Loads a movie plus some other parameters. The playback pointer is positioned to start of movie and readonly
143 * mode is enabled.
145 * parameter rerecs: Movie rerecord count.
146 * parameter project_id: Project ID of movie.
147 * parameter input: The input track.
148 * throws std::bad_alloc: Not enough memory.
149 * throws std::runtime_error: Bad movie data.
151 void load(const std::string& rerecs, const std::string& project_id, controller_frame_vector& input)
152 throw(std::bad_alloc, std::runtime_error);
155 * Saves the movie data.
157 * returns: The movie data.
158 * throws std::bad_alloc: Not enough memory.
160 controller_frame_vector save() throw(std::bad_alloc);
163 * This method serializes the state of movie code.
165 * Parameter proj_id: The project ID is written here.
166 * Parameter curframe: Current frame is written here.
167 * Parameter lagframes: Lag counter is written here.
168 * Parameter pcounters: Poll counters are written here.
169 * throws std::bad_alloc: Not enough memory.
171 void save_state(std::string& proj_id, uint64_t& curframe, uint64_t& lagframes,
172 std::vector<uint32_t>& pcounters) throw(std::bad_alloc);
175 * Given previous serialized state from this movie, restore the state.
177 * Parameter curframe: Current frame.
178 * Parameter lagframe: Lag counter.
179 * Parameter pcounters: Poll counters.
180 * Parameter ro: If true, restore in readonly mode.
181 * Parameter old_movie: Old movie to check for compatiblity against.
182 * Parameter old_projectid: Old project ID to check against.
183 * Returns: ???
184 * Throws std::bad_alloc: Not enough memory.
185 * Throws std::runtime_error: Movie check failure.
187 size_t restore_state(uint64_t curframe, uint64_t lagframe, const std::vector<uint32_t>& pcounters, bool ro,
188 controller_frame_vector* old_movie, const std::string& old_projectid) throw(std::bad_alloc,
189 std::runtime_error);
191 * Reset the state of movie to initial state.
193 void reset_state() throw();
195 * Get how manyth poll in the frame next poll would be?
197 * returns: Poll number.
199 unsigned next_poll_number();
201 * Get how many subframes there are in specified frame.
203 * parameter frame: The frame number.
204 * returns: Number of subframes (0 if outside movie).
206 uint64_t frame_subframes(uint64_t frame) throw();
208 * Read controls from specified subframe of specified frame.
210 * parameter frame: The frame number.
211 * parameter subframe: Subframe within frame (first is 0).
212 * returns: The controls for subframe. If subframe is too great, reads last present subframe. If frame is outside
213 * movie, reads all released.
215 controller_frame read_subframe(uint64_t frame, uint64_t subframe) throw();
217 * Fast save.
219 void fast_save(uint64_t& _frame, uint64_t& _ptr, uint64_t& _lagc, std::vector<uint32_t>& counters);
221 * Fast load.
223 void fast_load(uint64_t& _frame, uint64_t& _ptr, uint64_t& _lagc, std::vector<uint32_t>& counters);
225 * Poll flag handling.
227 class poll_flag
229 public:
230 virtual ~poll_flag();
232 * Get the poll flag.
234 virtual int get_pflag() = 0;
236 * Set the poll flag.
238 virtual void set_pflag(int flag) = 0;
241 * Set the poll flag handler.
243 void set_pflag_handler(poll_flag* handler);
245 * Get the internal controller frame vector.
247 controller_frame_vector& get_frame_vector() throw() { return movie_data; }
249 * Flush caches.
251 void clear_caches() throw();
253 * Get sequence number (increments by 1 each time whole data is reloaded).
255 uint64_t get_seqno() throw() { return seqno; }
257 * Assignment.
259 movie& operator=(const movie& m);
261 * Get pollcounter vector.
263 pollcounter_vector& get_pollcounters() { return pollcounters; }
265 * Get first subframe of this frame.
267 uint64_t get_current_frame_first_subframe() { return current_frame_first_subframe; }
269 * Recount frames.
271 void recount_frames() { adjust_frame_count(movie_data.count_frames() - frames_in_movie); }
273 * Adjust frame count.
275 void adjust_frame_count(int64_t adjust);
277 * Read specified triple at specified subframe of current frame. Only works in readonly mode.
279 int16_t read_subframe_at_index(uint32_t subframe, unsigned port, unsigned controller, unsigned index);
281 * Write specified triple at specified subframe of current frame (if possible). Only works in readonly mode.
283 void write_subframe_at_index(uint32_t subframe, unsigned port, unsigned controller, unsigned index,
284 int16_t x);
285 private:
286 //Sequence number.
287 uint64_t seqno;
288 //The poll flag handling.
289 poll_flag* pflag_handler;
290 //TRUE if readonly mode is active.
291 bool readonly;
292 //Movie (not global!) rerecord count.
293 std::string rerecords;
294 //Project ID.
295 std::string _project_id;
296 //The actual controller data.
297 controller_frame_vector movie_data;
298 //Current frame + 1 (0 before next_frame() has been called.
299 uint64_t current_frame;
300 //First subframe in current frame (movie_data.size() if no subframes have been stored).
301 uint64_t current_frame_first_subframe;
302 //How many times has each control been polled (bit 31 is data ready bit)?
303 pollcounter_vector pollcounters;
304 //Current state of buttons.
305 controller_frame current_controls;
306 //Number of known lag frames.
307 uint64_t lag_frames;
308 //Number of frames in movie.
309 uint64_t frames_in_movie;
310 //Cached subframes.
311 uint64_t cached_frame;
312 uint64_t cached_subframe;
313 //Count present subframes in frame starting from first_subframe (returns 0 if out of movie).
314 uint32_t count_changes(uint64_t first_subframe) throw();
317 #endif