Refactor movie class to library/
[lsnes.git] / include / library / movie.hpp
blobeee4fe73849155948babff039a0f0fcff3e8e35a
1 #ifndef _library__movie__hpp__included__
2 #define _library__movie__hpp__included__
4 #include <string>
5 #include <cstdint>
6 #include <stdexcept>
8 /**
9 * Movie being played back or recorded
11 class movie
13 public:
14 /**
15 * Construct new empty movie.
17 * throws std::bad_alloc: Not enough memory.
19 movie() throw(std::bad_alloc);
21 /**
22 * Is the movie in readonly mode?
24 * returns: True if in read-only mode, false if in read-write mode.
26 bool readonly_mode() throw();
28 /**
29 * Switches movie to read-only or read-write mode. If switching to read-write mode, the movie is truncated.
31 * parameter enable: If true, switch to read-only mode, else to read-write mode.
32 * throws std::bad_alloc: Not enough memory.
34 void readonly_mode(bool enable) throw(std::bad_alloc);
36 /**
37 * Returns the movie rerecord count (this is not the same thing as global rerecord count).
39 * returns: The movie rerecord count
40 * throws std::bad_alloc: Not enough memory.
42 std::string rerecord_count() throw(std::bad_alloc);
44 /**
45 * Sets the movie rerecord count (this is not the same thing as global rerecord count).
47 * parameter count: The new rerecord count
48 * throws std::bad_alloc: Not enough memory.
50 void rerecord_count(const std::string& count) throw(std::bad_alloc);
52 /**
53 * Read project ID
55 * returns: The project ID
56 * throws std::bad_alloc: Not enough memory.
58 std::string project_id() throw(std::bad_alloc);
60 /**
61 * brief Set project ID
63 * parameter id: New project ID.
64 * throws std::bad_alloc: Not enough memory.
66 void project_id(const std::string& id) throw(std::bad_alloc);
68 /**
69 * Get number of frames in movie
71 * returns: The number of frames.
73 uint64_t get_frame_count() throw();
75 /**
76 * Get number of current frame in movie
78 * The first frame in movie is 1. 0 is "before first frame" value.
80 * returns: The number of frame
82 uint64_t get_current_frame() throw();
84 /**
85 * Get number of lag frames so far
87 * returns: The number of lag frames.
89 uint64_t get_lag_frames() throw();
91 /**
92 * This function advances to next frame in movie, discarding subframes not used. If the frame is lag frame, it is
93 * counted as lag frame and subframe entry for it is made (if in readwrite mode).
95 * throws std::bad_alloc: Not enough memory.
97 void next_frame() throw(std::bad_alloc);
99 /**
100 * Reads the data ready flag. On new frame, all data ready flags are unset. On reading control, its data ready
101 * flag is unset.
103 * parameter pid: Physical controller id.
104 * parameter index: Control ID.
105 * returns: The read value.
106 * throws std::logic_error: Invalid control index.
108 bool get_DRDY(unsigned port, unsigned controller, unsigned index) throw(std::logic_error);
111 * Set all data ready flags
113 void set_all_DRDY() throw();
116 * Poll a control by (port, controller, index) tuple.
118 * parameter pid: Physical controller ID.
119 * parameter index: The index of control in controller (0 to 11)
120 * returns: The read value
121 * throws std::bad_alloc: Not enough memory.
122 * throws std::logic_error: Invalid port, controller or index or before movie start.
124 short next_input(unsigned port, unsigned controller, unsigned index) throw(std::bad_alloc, std::logic_error);
127 * Set current control values. These are read in readwrite mode.
129 * parameter controls: The new controls.
131 void set_controls(controller_frame controls) throw();
134 * Get current control values in effect.
136 * returns: Controls
138 controller_frame get_controls() throw();
141 * Loads a movie plus some other parameters. The playback pointer is positioned to start of movie and readonly
142 * mode is enabled.
144 * parameter rerecs: Movie rerecord count.
145 * parameter project_id: Project ID of movie.
146 * parameter input: The input track.
147 * throws std::bad_alloc: Not enough memory.
148 * throws std::runtime_error: Bad movie data.
150 void load(const std::string& rerecs, const std::string& project_id, controller_frame_vector& input)
151 throw(std::bad_alloc, std::runtime_error);
154 * Saves the movie data.
156 * returns: The movie data.
157 * throws std::bad_alloc: Not enough memory.
159 controller_frame_vector save() throw(std::bad_alloc);
162 * This method serializes the state of movie code.
164 * Parameter proj_id: The project ID is written here.
165 * Parameter curframe: Current frame is written here.
166 * Parameter lagframes: Lag counter is written here.
167 * Parameter pcounters: Poll counters are written here.
168 * throws std::bad_alloc: Not enough memory.
170 void save_state(std::string& proj_id, uint64_t& curframe, uint64_t& lagframes,
171 std::vector<uint32_t>& pcounters) throw(std::bad_alloc);
174 * Given previous serialized state from this movie, restore the state.
176 * Parameter curframe: Current frame.
177 * Parameter lagframe: Lag counter.
178 * Parameter pcounters: Poll counters.
179 * Parameter ro: If true, restore in readonly mode.
180 * Parameter old_movie: Old movie to check for compatiblity against.
181 * Parameter old_projectid: Old project ID to check against.
182 * Returns: ???
183 * Throws std::bad_alloc: Not enough memory.
184 * Throws std::runtime_error: Movie check failure.
186 size_t restore_state(uint64_t curframe, uint64_t lagframe, const std::vector<uint32_t>& pcounters, bool ro,
187 controller_frame_vector* old_movie, const std::string& old_projectid) throw(std::bad_alloc,
188 std::runtime_error);
190 * Reset the state of movie to initial state.
192 void reset_state() throw();
194 * Get reset status for current frame.
196 * returns: -1 if current frame doesn't have a reset. Otherwise number of cycles to wait for delayed reset (0 is
197 * immediate reset).
199 long get_reset_status() throw();
202 * Commit a reset (writes a reset into current frame in readwrite mode).
204 * parameter delay: The number of cycles to delay the reset.
206 void commit_reset(long delay) throw(std::bad_alloc);
209 * Get how manyth poll in the frame next poll would be?
211 * returns: Poll number.
213 unsigned next_poll_number();
215 * Get how many subframes there are in specified frame.
217 * parameter frame: The frame number.
218 * returns: Number of subframes (0 if outside movie).
220 uint64_t frame_subframes(uint64_t frame) throw();
222 * Read controls from specified subframe of specified frame.
224 * parameter frame: The frame number.
225 * parameter subframe: Subframe within frame (first is 0).
226 * returns: The controls for subframe. If subframe is too great, reads last present subframe. If frame is outside
227 * movie, reads all released.
229 controller_frame read_subframe(uint64_t frame, uint64_t subframe) throw();
231 * Fast save.
233 void fast_save(uint64_t& _frame, uint64_t& _ptr, uint64_t& _lagc, std::vector<uint32_t>& counters);
235 * Fast load.
237 void fast_load(uint64_t& _frame, uint64_t& _ptr, uint64_t& _lagc, std::vector<uint32_t>& counters);
239 private:
240 //TRUE if readonly mode is active.
241 bool readonly;
242 //Movie (not global!) rerecord count.
243 std::string rerecords;
244 //Project ID.
245 std::string _project_id;
246 //The actual controller data.
247 controller_frame_vector movie_data;
248 //Current frame + 1 (0 before next_frame() has been called.
249 uint64_t current_frame;
250 //First subframe in current frame (movie_data.size() if no subframes have been stored).
251 uint64_t current_frame_first_subframe;
252 //How many times has each control been polled (bit 31 is data ready bit)?
253 pollcounter_vector pollcounters;
254 //Current state of buttons.
255 controller_frame current_controls;
256 //Number of known lag frames.
257 uint64_t lag_frames;
258 //Number of frames in movie.
259 uint64_t frames_in_movie;
260 //Cached subframes.
261 void clear_caches() throw();
262 uint64_t cached_frame;
263 uint64_t cached_subframe;
264 //Count present subframes in frame starting from first_subframe (returns 0 if out of movie).
265 uint32_t count_changes(uint64_t first_subframe) throw();
268 #endif