Lua: Fix type confusion between signed and unsigned
[lsnes.git] / include / core / advdumper.hpp
blob5643183ac2c9a244b246cdb28589c6aed8e0bec8
1 #ifndef _advdumper__hpp__included__
2 #define _advdumper__hpp__included__
4 #include <string>
5 #include <set>
6 #include <stdexcept>
7 #include <iostream>
9 #include "library/framebuffer.hpp"
10 #include "library/dispatch.hpp"
11 #include "library/threads.hpp"
13 class master_dumper;
14 class dumper_factory_base;
15 class dumper_base;
16 class lua_state;
18 class dumper_factory_base
20 public:
21 /**
22 * Notifier base.
24 class notifier
26 public:
27 virtual ~notifier() throw();
28 virtual void dumpers_updated() throw() = 0;
30 /**
31 * Detail flags.
33 static const unsigned target_type_mask;
34 static const unsigned target_type_file;
35 static const unsigned target_type_prefix;
36 static const unsigned target_type_special;
37 /**
38 * Register a dumper.
40 * Parameter id: The ID of dumper.
41 * Throws std::bad_alloc: Not enough memory.
43 dumper_factory_base(const std::string& id) throw(std::bad_alloc);
44 /**
45 * Unregister a dumper.
47 ~dumper_factory_base();
48 /**
49 * Get ID of dumper.
51 * Returns: The id.
53 const std::string& id() throw();
54 /**
55 * Get set of all dumpers.
57 * Returns: The set.
58 * Throws std::bad_alloc: Not enough memory.
60 static std::set<dumper_factory_base*> get_dumper_set() throw(std::bad_alloc);
61 /**
62 * List all valid submodes.
64 * Returns: List of all valid submodes. Empty list means this dumper has no submodes.
65 * Throws std::bad_alloc: Not enough memory.
67 virtual std::set<std::string> list_submodes() throw(std::bad_alloc) = 0;
68 /**
69 * Get mode details
71 * parameter mode: The submode.
72 * Returns: Mode details flags
74 virtual unsigned mode_details(const std::string& mode) throw() = 0;
75 /**
76 * Get mode extensions. Only called if mode details specifies that output is a single file.
78 * parameter mode: The submode.
79 * Returns: Mode extension
81 virtual std::string mode_extension(const std::string& mode) throw() = 0;
82 /**
83 * Get human-readable name for this dumper.
85 * Returns: The name.
86 * Throws std::bad_alloc: Not enough memory.
88 virtual std::string name() throw(std::bad_alloc) = 0;
89 /**
90 * Get human-readable name for submode.
92 * Parameter mode: The submode.
93 * Returns: The name.
94 * Throws std::bad_alloc: Not enough memory.
96 virtual std::string modename(const std::string& mode) throw(std::bad_alloc) = 0;
97 /**
98 * Start dump.
100 * parameter mode: The mode to dump using.
101 * parameter targetname: The target filename or prefix.
102 * returns: The dumper object.
103 * Throws std::bad_alloc: Not enough memory.
104 * Throws std::runtime_error: Can't start dump.
106 virtual dumper_base* start(master_dumper& _mdumper, const std::string& mode, const std::string& targetname)
107 throw(std::bad_alloc, std::runtime_error) = 0;
109 * Is hidden?
111 virtual bool hidden() const { return false; }
113 * Add dumper update notifier object.
115 static void add_notifier(notifier& n);
117 * Remove dumper update notifier object.
119 static void drop_notifier(notifier& n);
121 * Notify ctor finished.
123 void ctor_notify();
125 * Notify dumper change.
127 static void run_notify();
128 private:
129 std::string d_id;
132 class master_dumper
134 public:
136 * Information about run.
138 struct gameinfo
140 public:
142 * Construct game info.
144 gameinfo() throw(std::bad_alloc);
146 * Game name.
148 std::string gamename;
150 * Run length in seconds.
152 double length;
154 * Rerecord count (base 10 ASCII)
156 std::string rerecords;
158 * Authors. The first components are real names, the second components are nicknames. Either (but not both) may be
159 * blank.
161 std::vector<std::pair<std::string, std::string>> authors;
163 * Format human-redable representation of the length.
165 * Parameter digits: Number of sub-second digits to use.
166 * Returns: The time formated.
167 * Throws std::bad_alloc: Not enough memory.
169 std::string get_readable_time(unsigned digits) const throw(std::bad_alloc);
171 * Get number of authors.
173 * Returns: Number of authors.
175 size_t get_author_count() const throw();
177 * Get short name of author (nickname if present, otherwise full name).
179 * Parameter idx: Index of author (0-based).
180 * Returns: The short name.
181 * Throws std::bad_alloc: Not enough memory.
183 std::string get_author_short(size_t idx) const throw(std::bad_alloc);
185 * Get long name of author (full name and nickname if present).
187 * Parameter idx: Index of author (0-based).
188 * Returns: The long name.
189 * Throws std::bad_alloc: Not enough memory.
191 std::string get_author_long(size_t idx) const throw(std::bad_alloc);
193 * Get rerecord count as a number. If rerecord count is too high, returns the maximum representatible count.
195 * Returns: The rerecord count.
197 uint64_t get_rerecords() const throw();
200 * Notifier.
202 class notifier
204 public:
205 virtual ~notifier() throw();
206 virtual void dump_status_change() = 0;
209 * Ctor.
211 master_dumper(lua_state& _lua2);
213 * Get instance for specified dumper.
215 dumper_base* get_instance(dumper_factory_base* dumper) throw();
217 * Is dumper busy in this instance?
219 bool busy(dumper_factory_base* dumper) throw()
221 return get_instance(dumper) != NULL;
224 * Call start on dumper.
226 dumper_base* start(dumper_factory_base& factory, const std::string& mode, const std::string& targetname)
227 throw(std::bad_alloc, std::runtime_error);
229 * Add dumper update notifier object.
231 void add_notifier(notifier& n);
233 * Remove dumper update notifier object.
235 void drop_notifier(notifier& n);
237 * Add dumper update notifier object.
239 void add_dumper(dumper_base& n);
241 * Remove dumper update notifier object.
243 void drop_dumper(dumper_base& n);
245 * Get number of active dumpers.
247 unsigned get_dumper_count() throw();
249 * Call all notifiers (on_frame).
251 void on_frame(struct framebuffer::raw& _frame, uint32_t fps_n, uint32_t fps_d);
253 * Call all notifiers (on_sample).
255 void on_sample(short l, short r);
257 * Call all notifiers (on_rate_change)
259 * Also changes builtin rate variables.
261 void on_rate_change(uint32_t n, uint32_t d);
263 * Call all notifiers (on_gameinfo_change)
265 * Also changes builtin gameinfo structure.
267 void on_gameinfo_change(const gameinfo& gi);
269 * Get current sound rate in effect.
271 std::pair<uint32_t, uint32_t> get_rate();
273 * Get current gameinfo in effect.
275 const gameinfo& get_gameinfo();
277 * End all dumps.
279 void end_dumps();
281 * Set output stream.
283 void set_output(std::ostream* _output);
285 * Render Lua HUD on video.
287 * Parameter target: The target screen to render on.
288 * Parameter source: The source screen to read.
289 * Parameter hscl: The horizontal scale factor.
290 * Parameter vscl: The vertical scale factor.
291 * Parameter lgap: Left gap.
292 * Parameter tgap: Top gap.
293 * Parameter rgap: Right gap
294 * Parameter bgap: Bottom gap.
295 * Parameter fn: Function to call between running lua hooks and actually rendering.
296 * Returns: True if frame should be dumped, false if not.
298 template<bool X> bool render_video_hud(struct framebuffer::fb<X>& target, struct framebuffer::raw& source,
299 uint32_t hscl, uint32_t vscl, uint32_t lgap, uint32_t tgap, uint32_t rgap, uint32_t bgap,
300 std::function<void()> fn);
302 * Calculate number of sound samples to drop due to dropped frame.
304 uint64_t killed_audio_length(uint32_t fps_n, uint32_t fps_d, double& fraction);
305 private:
306 void statuschange();
307 friend class dumper_base;
308 std::map<dumper_factory_base*, dumper_base*> dumpers;
309 std::set<notifier*> notifications;
310 std::set<dumper_base*> sdumpers;
311 uint32_t current_rate_n;
312 uint32_t current_rate_d;
313 gameinfo current_gi;
314 std::ostream* output;
315 threads::rlock lock;
316 lua_state& lua2;
319 class dumper_base
321 public:
322 dumper_base();
323 dumper_base(master_dumper& _mdumper, dumper_factory_base& _fbase);
324 virtual ~dumper_base() throw();
326 * New frame available.
328 virtual void on_frame(struct framebuffer::raw& _frame, uint32_t fps_n, uint32_t fps_d) = 0;
330 * New sample available.
332 virtual void on_sample(short l, short r) = 0;
334 * Sample rate is changing.
336 virtual void on_rate_change(uint32_t n, uint32_t d) = 0;
338 * Gameinfo is changing.
340 virtual void on_gameinfo_change(const master_dumper::gameinfo& gi) = 0;
342 * Dump is being forcibly ended.
344 virtual void on_end() = 0;
346 * Render Lua HUD on video. samples_killed is incremented if needed.
348 * Parameter target: The target screen to render on.
349 * Parameter source: The source screen to read.
350 * Parameter fps_n: Fps numerator.
351 * Parameter fps_d: Fps denominator.
352 * Parameter hscl: The horizontal scale factor.
353 * Parameter vscl: The vertical scale factor.
354 * Parameter lgap: Left gap.
355 * Parameter tgap: Top gap.
356 * Parameter rgap: Right gap
357 * Parameter bgap: Bottom gap.
358 * Parameter fn: Function to call between running lua hooks and actually rendering.
359 * Returns: True if frame should be dumped, false if not.
361 template<bool X> bool render_video_hud(struct framebuffer::fb<X>& target, struct framebuffer::raw& source,
362 uint32_t fps_n, uint32_t fps_d, uint32_t hscl, uint32_t vscl, uint32_t lgap, uint32_t tgap,
363 uint32_t rgap, uint32_t bgap, std::function<void()> fn)
365 bool r = mdumper->render_video_hud(target, source, hscl, vscl, lgap, tgap, rgap, bgap, fn);
366 if(!r)
367 samples_killed += mdumper->killed_audio_length(fps_n, fps_d, akillfrac);
368 return r;
370 private:
371 friend class master_dumper;
372 uint64_t samples_killed;
373 master_dumper* mdumper;
374 dumper_factory_base* fbase;
375 double akillfrac;
378 #endif