Instancefy lua core stuff
[lsnes.git] / include / core / advdumper.hpp
blobe40b50ad396392a389482afb0a4ba5205501cc58
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 * Add dumper update notifier object.
111 static void add_notifier(notifier& n);
113 * Remove dumper update notifier object.
115 static void drop_notifier(notifier& n);
117 * Notify ctor finished.
119 void ctor_notify();
121 * Notify dumper change.
123 static void run_notify();
124 private:
125 std::string d_id;
128 class master_dumper
130 public:
132 * Information about run.
134 struct gameinfo
136 public:
138 * Construct game info.
140 gameinfo() throw(std::bad_alloc);
142 * Game name.
144 std::string gamename;
146 * Run length in seconds.
148 double length;
150 * Rerecord count (base 10 ASCII)
152 std::string rerecords;
154 * Authors. The first components are real names, the second components are nicknames. Either (but not both) may be
155 * blank.
157 std::vector<std::pair<std::string, std::string>> authors;
159 * Format human-redable representation of the length.
161 * Parameter digits: Number of sub-second digits to use.
162 * Returns: The time formated.
163 * Throws std::bad_alloc: Not enough memory.
165 std::string get_readable_time(unsigned digits) const throw(std::bad_alloc);
167 * Get number of authors.
169 * Returns: Number of authors.
171 size_t get_author_count() const throw();
173 * Get short name of author (nickname if present, otherwise full name).
175 * Parameter idx: Index of author (0-based).
176 * Returns: The short name.
177 * Throws std::bad_alloc: Not enough memory.
179 std::string get_author_short(size_t idx) const throw(std::bad_alloc);
181 * Get long name of author (full name and nickname if present).
183 * Parameter idx: Index of author (0-based).
184 * Returns: The long name.
185 * Throws std::bad_alloc: Not enough memory.
187 std::string get_author_long(size_t idx) const throw(std::bad_alloc);
189 * Get rerecord count as a number. If rerecord count is too high, returns the maximum representatible count.
191 * Returns: The rerecord count.
193 uint64_t get_rerecords() const throw();
196 * Notifier.
198 class notifier
200 public:
201 virtual ~notifier() throw();
202 virtual void dump_status_change() = 0;
205 * Ctor.
207 master_dumper(lua_state& _lua2);
209 * Get instance for specified dumper.
211 dumper_base* get_instance(dumper_factory_base* dumper) throw();
213 * Is dumper busy in this instance?
215 bool busy(dumper_factory_base* dumper) throw()
217 return get_instance(dumper) != NULL;
220 * Call start on dumper.
222 dumper_base* start(dumper_factory_base& factory, const std::string& mode, const std::string& targetname)
223 throw(std::bad_alloc, std::runtime_error);
225 * Add dumper update notifier object.
227 void add_notifier(notifier& n);
229 * Remove dumper update notifier object.
231 void drop_notifier(notifier& n);
233 * Add dumper update notifier object.
235 void add_dumper(dumper_base& n);
237 * Remove dumper update notifier object.
239 void drop_dumper(dumper_base& n);
241 * Get number of active dumpers.
243 unsigned get_dumper_count() throw();
245 * Call all notifiers (on_frame).
247 void on_frame(struct framebuffer::raw& _frame, uint32_t fps_n, uint32_t fps_d);
249 * Call all notifiers (on_sample).
251 void on_sample(short l, short r);
253 * Call all notifiers (on_rate_change)
255 * Also changes builtin rate variables.
257 void on_rate_change(uint32_t n, uint32_t d);
259 * Call all notifiers (on_gameinfo_change)
261 * Also changes builtin gameinfo structure.
263 void on_gameinfo_change(const gameinfo& gi);
265 * Get current sound rate in effect.
267 std::pair<uint32_t, uint32_t> get_rate();
269 * Get current gameinfo in effect.
271 const gameinfo& get_gameinfo();
273 * End all dumps.
275 void end_dumps();
277 * Set output stream.
279 void set_output(std::ostream* _output);
281 * Render Lua HUD on video.
283 * Parameter target: The target screen to render on.
284 * Parameter source: The source screen to read.
285 * Parameter hscl: The horizontal scale factor.
286 * Parameter vscl: The vertical scale factor.
287 * Parameter lgap: Left gap.
288 * Parameter tgap: Top gap.
289 * Parameter rgap: Right gap
290 * Parameter bgap: Bottom gap.
291 * Parameter fn: Function to call between running lua hooks and actually rendering.
292 * Returns: True if frame should be dumped, false if not.
294 template<bool X> bool render_video_hud(struct framebuffer::fb<X>& target, struct framebuffer::raw& source,
295 uint32_t hscl, uint32_t vscl, uint32_t lgap, uint32_t tgap, uint32_t rgap, uint32_t bgap,
296 std::function<void()> fn);
298 * Calculate number of sound samples to drop due to dropped frame.
300 uint64_t killed_audio_length(uint32_t fps_n, uint32_t fps_d, double& fraction);
301 private:
302 void statuschange();
303 friend class dumper_base;
304 std::map<dumper_factory_base*, dumper_base*> dumpers;
305 std::set<notifier*> notifications;
306 std::set<dumper_base*> sdumpers;
307 uint32_t current_rate_n;
308 uint32_t current_rate_d;
309 gameinfo current_gi;
310 std::ostream* output;
311 threads::rlock lock;
312 lua_state& lua2;
315 class dumper_base
317 public:
318 dumper_base();
319 dumper_base(master_dumper& _mdumper, dumper_factory_base& _fbase);
320 virtual ~dumper_base() throw();
322 * New frame available.
324 virtual void on_frame(struct framebuffer::raw& _frame, uint32_t fps_n, uint32_t fps_d) = 0;
326 * New sample available.
328 virtual void on_sample(short l, short r) = 0;
330 * Sample rate is changing.
332 virtual void on_rate_change(uint32_t n, uint32_t d) = 0;
334 * Gameinfo is changing.
336 virtual void on_gameinfo_change(const master_dumper::gameinfo& gi) = 0;
338 * Dump is being forcibly ended.
340 virtual void on_end() = 0;
342 * Render Lua HUD on video. samples_killed is incremented if needed.
344 * Parameter target: The target screen to render on.
345 * Parameter source: The source screen to read.
346 * Parameter fps_n: Fps numerator.
347 * Parameter fps_d: Fps denominator.
348 * Parameter hscl: The horizontal scale factor.
349 * Parameter vscl: The vertical scale factor.
350 * Parameter lgap: Left gap.
351 * Parameter tgap: Top gap.
352 * Parameter rgap: Right gap
353 * Parameter bgap: Bottom gap.
354 * Parameter fn: Function to call between running lua hooks and actually rendering.
355 * Returns: True if frame should be dumped, false if not.
357 template<bool X> bool render_video_hud(struct framebuffer::fb<X>& target, struct framebuffer::raw& source,
358 uint32_t fps_n, uint32_t fps_d, uint32_t hscl, uint32_t vscl, uint32_t lgap, uint32_t tgap,
359 uint32_t rgap, uint32_t bgap, std::function<void()> fn)
361 bool r = mdumper->render_video_hud(target, source, hscl, vscl, lgap, tgap, rgap, bgap, fn);
362 if(!r)
363 samples_killed += mdumper->killed_audio_length(fps_n, fps_d, akillfrac);
364 return r;
366 private:
367 friend class master_dumper;
368 uint64_t samples_killed;
369 master_dumper* mdumper;
370 dumper_factory_base* fbase;
371 double akillfrac;
374 #endif