Merge branch 'rr1-maint'
[lsnes.git] / src / core / advdumper.cpp
blob41f7048de0c1ef75c400cda8750e925816e06b03
1 #include "core/advdumper.hpp"
2 #include "core/command.hpp"
3 #include "core/dispatch.hpp"
4 #include "core/globalwrap.hpp"
5 #include "lua/lua.hpp"
6 #include "library/string.hpp"
8 #include <map>
9 #include <string>
11 namespace
13 globalwrap<std::map<std::string, adv_dumper*>> dumpers;
15 adv_dumper& find_by_name(const std::string& dname)
17 auto i = adv_dumper::get_dumper_set();
18 for(auto j : i)
19 if(j->id() == dname)
20 return *j;
21 throw std::runtime_error("Unknown dumper");
24 function_ptr_command<const std::string&> start_dump("start-dump", "Start dumping",
25 "Syntax: start-dump <dumper> <prefix/filename>\nSyntax: start-dump <dumper> <mode> <prefix/filename>\n"
26 "Start dumping using <dumper> in mode <mode> to <prefix/filename>\n",
27 [](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
28 std::string t2 = t;
29 std::string dumper;
30 extract_token(t2, dumper, " \t", true);
31 adv_dumper& d = find_by_name(dumper);
32 auto modes = d.list_submodes();
33 std::string mode;
34 if(!modes.empty()) {
35 extract_token(t2, mode, " \t", true);
36 mode = std::string(t);
37 if(!modes.count(mode))
38 throw std::runtime_error("Bad mode for dumper");
40 if(t2 == "")
41 throw std::runtime_error("Command syntax error");
42 d.start(mode, t2);
43 });
45 function_ptr_command<const std::string&> end_dump("end-dump", "End dumping",
46 "Syntax: end-dump <dumper>\nEnd dumping using dumper <dumper>\n",
47 [](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
48 auto r = regex("([^ \t]+)[ \t]*", t, "Command syntax error");
49 adv_dumper& d = find_by_name(r[1]);
50 d.end();
51 });
53 function_ptr_command<const std::string&> dumpersc("show-dumpers", "Show dumpers",
54 "Syntax: show-dumpers\nSyntax: show-dumpers <dumper>\nShow dumpers or dumper modes for <dumper>\n",
55 [](const std::string& x) throw(std::bad_alloc, std::runtime_error) {
56 auto a = adv_dumper::get_dumper_set();
57 if(x == "") {
58 for(auto i : a)
59 messages << i->id() << "\t" << i->name() << std::endl;
60 } else {
61 for(auto i : a) {
62 if(i->id() == x) {
63 //This dumper.
64 auto b = i->list_submodes();
65 if(b.empty()) {
66 messages << "No submodes for '" << x << "'" << std::endl;
67 return;
69 for(auto j : b) {
70 if(i->wants_prefix(j))
71 messages << "P " << x << "\t" << j << "\t"
72 << i->modename(j) << std::endl;
73 else
74 messages << "F " << x << "\t" << j << "\t"
75 << i->modename(j) << std::endl;
77 return;
80 messages << "No such dumper '" << x << "'" << std::endl;
82 });
85 const std::string& adv_dumper::id() throw()
87 return d_id;
90 adv_dumper::~adv_dumper()
92 dumpers().erase(d_id);
93 information_dispatch::do_dumper_update();
96 std::set<adv_dumper*> adv_dumper::get_dumper_set() throw(std::bad_alloc)
98 std::set<adv_dumper*> d;
99 for(auto i : dumpers())
100 d.insert(i.second);
101 return d;
104 adv_dumper::adv_dumper(const std::string& id) throw(std::bad_alloc)
106 d_id = id;
107 dumpers()[d_id] = this;
110 template<bool X> void render_video_hud(struct screen<X>& target, struct lcscreen& source, uint32_t hscl, uint32_t vscl,
111 uint32_t roffset, uint32_t goffset, uint32_t boffset, uint32_t lgap, uint32_t tgap, uint32_t rgap,
112 uint32_t bgap, void(*fn)())
114 struct lua_render_context lrc;
115 render_queue rq;
116 lrc.left_gap = lgap;
117 lrc.right_gap = rgap;
118 lrc.bottom_gap = bgap;
119 lrc.top_gap = tgap;
120 lrc.queue = &rq;
121 lrc.width = source.width;
122 lrc.height = source.height;
123 lua_callback_do_video(&lrc);
124 if(fn)
125 fn();
126 target.set_palette(roffset, goffset, boffset);
127 target.reallocate(lrc.left_gap + source.width * hscl + lrc.right_gap, lrc.top_gap +
128 source.height * vscl + lrc.bottom_gap, false);
129 target.set_origin(lrc.left_gap, lrc.top_gap);
130 target.copy_from(source, hscl, vscl);
131 rq.run(target);
134 template void render_video_hud(struct screen<false>& target, struct lcscreen& source, uint32_t hscl, uint32_t vscl,
135 uint32_t roffset, uint32_t goffset, uint32_t boffset, uint32_t lgap, uint32_t tgap, uint32_t rgap,
136 uint32_t bgap, void(*fn)());
137 template void render_video_hud(struct screen<true>& target, struct lcscreen& source, uint32_t hscl, uint32_t vscl,
138 uint32_t roffset, uint32_t goffset, uint32_t boffset, uint32_t lgap, uint32_t tgap, uint32_t rgap,
139 uint32_t bgap, void(*fn)());