bsnes: redump sprite/palette functions
[lsnes.git] / src / library / memorywatch-fb.cpp
blob553979d60511da99f728e807b2b98debb9096187
1 #include "memorywatch-fb.hpp"
2 #include "utf8.hpp"
3 #include "minmax.hpp"
5 namespace
7 struct memorywatch_fb_object : public framebuffer::object
9 struct params
11 int64_t x;
12 int64_t y;
13 bool cliprange_x;
14 bool cliprange_y;
15 bool alt_origin_x;
16 bool alt_origin_y;
17 framebuffer::font2* font;
18 framebuffer::color fg;
19 framebuffer::color bg;
20 framebuffer::color halo;
22 memorywatch_fb_object(const params& _p, const std::string& _msg);
23 ~memorywatch_fb_object() throw();
24 void operator()(struct framebuffer::fb<false>& scr) throw();
25 void operator()(struct framebuffer::fb<true>& scr) throw();
26 void clone(framebuffer::queue& q) const throw(std::bad_alloc);
27 private:
28 template<bool ext> void draw(struct framebuffer::fb<ext>& scr) throw();
29 params p;
30 std::u32string msg;
33 memorywatch_fb_object::memorywatch_fb_object(const memorywatch_fb_object::params& _p, const std::string& _msg)
34 : p(_p)
36 msg = utf8::to32(_msg);
39 memorywatch_fb_object::~memorywatch_fb_object() throw() {}
40 void memorywatch_fb_object::operator()(struct framebuffer::fb<false>& scr) throw() { draw(scr); }
41 void memorywatch_fb_object::operator()(struct framebuffer::fb<true>& scr) throw() { draw(scr); }
43 void memorywatch_fb_object::clone(framebuffer::queue& q) const throw(std::bad_alloc) { q.clone_helper(this); }
45 template<bool ext> void memorywatch_fb_object::draw(struct framebuffer::fb<ext>& scr) throw()
47 p.x += scr.get_origin_x();
48 p.y += scr.get_origin_y();
49 if(p.alt_origin_x)
50 p.x += scr.get_last_blit_width();
51 if(p.alt_origin_y)
52 p.y += scr.get_last_blit_height();
53 p.fg.set_palette(scr);
54 p.bg.set_palette(scr);
55 p.halo.set_palette(scr);
57 bool has_halo = p.halo;
58 //Layout the text.
59 int64_t orig_x = p.x;
60 int64_t drawx = p.x;
61 int64_t drawy = p.y;
62 int64_t max_drawx = p.x;
63 for(size_t i = 0; i < msg.size();) {
64 uint32_t cp = msg[i];
65 std::u32string k = p.font->best_ligature_match(msg, i);
66 const framebuffer::font2::glyph& glyph = p.font->lookup_glyph(k);
67 if(k.length())
68 i += k.length();
69 else
70 i++;
71 if(cp == 9) {
72 drawx = (drawx + 64) >> 6 << 6;
73 } else if(cp == 10) {
74 drawx = orig_x;
75 drawy += p.font->get_rowadvance();
76 } else {
77 drawx += glyph.width;
78 max_drawx = max(max_drawx, drawx);
81 uint64_t width = max_drawx - p.x;
82 uint64_t height = drawy - p.y;
83 if(has_halo) {
84 width += 2;
85 height += 2;
87 drawx = p.x;
88 drawy = p.y;
89 orig_x = p.x;
90 if(p.cliprange_x) {
91 if(drawx < 0)
92 drawx = 0;
93 else if(drawx + width > scr.get_width())
94 drawx = scr.get_width() - width;
96 if(p.cliprange_y) {
97 if(drawy < 0)
98 drawy = 0;
99 else if(drawy + height > scr.get_height())
100 drawy = scr.get_height() - height;
102 if(has_halo) {
103 orig_x++;
104 drawx++;
105 drawy++;
107 for(size_t i = 0; i < msg.size();) {
108 uint32_t cp = msg[i];
109 std::u32string k = p.font->best_ligature_match(msg, i);
110 const framebuffer::font2::glyph& glyph = p.font->lookup_glyph(k);
111 if(k.length())
112 i += k.length();
113 else
114 i++;
115 if(cp == 9) {
116 drawx = (drawx + 64) >> 6 << 6;
117 } else if(cp == 10) {
118 drawx = orig_x;
119 drawy += p.font->get_rowadvance();
120 } else {
121 glyph.render(scr, drawx, drawy, p.fg, p.bg, p.halo);
122 drawx += glyph.width;
128 memorywatch_output_fb::memorywatch_output_fb()
130 font = NULL;
133 memorywatch_output_fb::~memorywatch_output_fb()
135 if(dtor_cb)
136 dtor_cb(*this);
139 void memorywatch_output_fb::set_rqueue(framebuffer::queue& rqueue)
141 queue = &rqueue;
144 void memorywatch_output_fb::set_dtor_cb(std::function<void(memorywatch_output_fb&)> cb)
146 dtor_cb = cb;
149 void memorywatch_output_fb::show(const std::string& iname, const std::string& val)
151 memorywatch_fb_object::params p;
152 try {
153 if(cond_enable) {
154 enabled->reset();
155 auto e = enabled->evaluate();
156 if(!e.type->toboolean(e.value))
157 return;
159 pos_x->reset();
160 pos_y->reset();
161 auto x = pos_x->evaluate();
162 auto y = pos_y->evaluate();
163 p.x = x.type->tosigned(x.value);
164 p.y = y.type->tosigned(y.value);
165 p.alt_origin_x = alt_origin_x;
166 p.alt_origin_y = alt_origin_y;
167 p.cliprange_x = cliprange_x;
168 p.cliprange_y = cliprange_y;
169 p.font = font;
170 p.fg = fg;
171 p.bg = bg;
172 p.halo = halo;
173 queue->create_add<memorywatch_fb_object>(p, val);
174 } catch(...) {
178 void memorywatch_output_fb::reset()
180 enabled->reset();
181 pos_x->reset();
182 pos_y->reset();