Split cases for prefix and special for dumper targets
[lsnes.git] / src / core / advdumper.cpp
blob90c7446e54e8fcd89707e5f35af8e7b487deddf1
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 if(!modes.count(mode))
37 throw std::runtime_error("Bad mode for dumper");
39 if(t2 == "")
40 throw std::runtime_error("Command syntax error");
41 d.start(mode, t2);
42 });
44 function_ptr_command<const std::string&> end_dump("end-dump", "End dumping",
45 "Syntax: end-dump <dumper>\nEnd dumping using dumper <dumper>\n",
46 [](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
47 auto r = regex("([^ \t]+)[ \t]*", t, "Command syntax error");
48 adv_dumper& d = find_by_name(r[1]);
49 d.end();
50 });
52 function_ptr_command<const std::string&> dumpersc("show-dumpers", "Show dumpers",
53 "Syntax: show-dumpers\nSyntax: show-dumpers <dumper>\nShow dumpers or dumper modes for <dumper>\n",
54 [](const std::string& x) throw(std::bad_alloc, std::runtime_error) {
55 auto a = adv_dumper::get_dumper_set();
56 if(x == "") {
57 for(auto i : a)
58 messages << i->id() << "\t" << i->name() << std::endl;
59 } else {
60 for(auto i : a) {
61 if(i->id() == x) {
62 //This dumper.
63 auto b = i->list_submodes();
64 if(b.empty()) {
65 messages << "No submodes for '" << x << "'" << std::endl;
66 return;
68 for(auto j : b) {
69 unsigned d = i->mode_details(j);
70 if((d & adv_dumper::target_type_mask) ==
71 adv_dumper::target_type_prefix)
72 messages << "P " << x << "\t" << j << "\t"
73 << i->modename(j) << std::endl;
74 else if((d & adv_dumper::target_type_mask) ==
75 adv_dumper::target_type_file)
76 messages << "F " << x << "\t" << j << "\t"
77 << i->modename(j) << std::endl;
78 else if((d & adv_dumper::target_type_mask) ==
79 adv_dumper::target_type_special)
80 messages << "S " << x << "\t" << j << "\t"
81 << i->modename(j) << std::endl;
82 else
83 messages << "U " << x << "\t" << j << "\t"
84 << i->modename(j) << std::endl;
86 return;
89 messages << "No such dumper '" << x << "'" << std::endl;
91 });
94 const std::string& adv_dumper::id() throw()
96 return d_id;
99 adv_dumper::~adv_dumper()
101 dumpers().erase(d_id);
102 information_dispatch::do_dumper_update();
105 std::set<adv_dumper*> adv_dumper::get_dumper_set() throw(std::bad_alloc)
107 std::set<adv_dumper*> d;
108 for(auto i : dumpers())
109 d.insert(i.second);
110 return d;
113 adv_dumper::adv_dumper(const std::string& id) throw(std::bad_alloc)
115 d_id = id;
116 dumpers()[d_id] = this;
119 unsigned adv_dumper::target_type_mask = 3;
120 unsigned adv_dumper::target_type_file = 0;
121 unsigned adv_dumper::target_type_prefix = 1;
122 unsigned adv_dumper::target_type_special = 2;
124 template<bool X> void render_video_hud(struct screen<X>& target, struct lcscreen& source, uint32_t hscl, uint32_t vscl,
125 uint32_t roffset, uint32_t goffset, uint32_t boffset, uint32_t lgap, uint32_t tgap, uint32_t rgap,
126 uint32_t bgap, void(*fn)())
128 struct lua_render_context lrc;
129 render_queue rq;
130 lrc.left_gap = lgap;
131 lrc.right_gap = rgap;
132 lrc.bottom_gap = bgap;
133 lrc.top_gap = tgap;
134 lrc.queue = &rq;
135 lrc.width = source.width;
136 lrc.height = source.height;
137 lua_callback_do_video(&lrc);
138 if(fn)
139 fn();
140 target.set_palette(roffset, goffset, boffset);
141 target.reallocate(lrc.left_gap + source.width * hscl + lrc.right_gap, lrc.top_gap +
142 source.height * vscl + lrc.bottom_gap, false);
143 target.set_origin(lrc.left_gap, lrc.top_gap);
144 target.copy_from(source, hscl, vscl);
145 rq.run(target);
148 template void render_video_hud(struct screen<false>& target, struct lcscreen& source, uint32_t hscl, uint32_t vscl,
149 uint32_t roffset, uint32_t goffset, uint32_t boffset, uint32_t lgap, uint32_t tgap, uint32_t rgap,
150 uint32_t bgap, void(*fn)());
151 template void render_video_hud(struct screen<true>& target, struct lcscreen& source, uint32_t hscl, uint32_t vscl,
152 uint32_t roffset, uint32_t goffset, uint32_t boffset, uint32_t lgap, uint32_t tgap, uint32_t rgap,
153 uint32_t bgap, void(*fn)());