Lua: Multi-argument parsing and unify color parsing
[lsnes.git] / src / lua / gui-arrow.cpp
bloba74f42021305100640c444dcebffa8d7aaedad64
1 #include "lua/internal.hpp"
2 #include "library/framebuffer.hpp"
3 #include "library/lua-framebuffer.hpp"
4 #include "library/minmax.hpp"
6 namespace
8 int _dx[8] = {-1,-1, 0, 1, 1, 1, 0,-1};
9 int _dy[8] = { 0, 1, 1, 1, 0,-1,-1,-1};
10 int _dxn[8] = { 0, 0, 1, 1, 0, 0,-1,-1};
11 int _dyn[8] = { 1, 1, 0, 0,-1,-1, 0, 0};
12 int _dxp[8] = { 0, 1, 1, 0, 0,-1,-1, 0};
13 int _dyp[8] = { 1, 0, 0,-1,-1, 0, 0, 1};
14 struct render_object_arrow : public framebuffer::object
16 render_object_arrow(int32_t _x, int32_t _y, uint32_t _length, uint32_t _width,
17 uint32_t _headwidth, uint32_t _headthickness, int _direction, bool _fill,
18 framebuffer::color _color) throw()
19 : x(_x), y(_y), length(_length), width(_width), headwidth(_headwidth),
20 headthickness(_headthickness), direction(_direction), fill(_fill), color(_color) {}
21 ~render_object_arrow() throw() {}
22 template<bool X> void op(struct framebuffer::fb<X>& scr) throw()
24 color.set_palette(scr);
25 uint32_t originx = scr.get_origin_x();
26 uint32_t originy = scr.get_origin_y();
27 auto orange = offsetrange();
28 for(int32_t o = orange.first; o < orange.second; o++) {
29 int32_t bpx, bpy;
30 bpx = x + originx + ((o < 0) ? _dxn[direction & 7] : _dxp[direction & 7]) * o;
31 bpy = y + originy + ((o < 0) ? _dyn[direction & 7] : _dyp[direction & 7]) * o;
32 int dx = _dx[direction & 7];
33 int dy = _dy[direction & 7];
34 auto drange = drawrange(o);
35 for(unsigned d = drange.first; d < drange.second; d++) {
36 int32_t xc = bpx + dx * d;
37 int32_t yc = bpy + dy * d;
38 if(xc < 0 || xc >= scr.get_width())
39 continue;
40 if(yc < 0 || yc >= scr.get_height())
41 continue;
42 color.apply(scr.rowptr(yc)[xc]);
46 void operator()(struct framebuffer::fb<true>& scr) throw() { op(scr); }
47 void operator()(struct framebuffer::fb<false>& scr) throw() { op(scr); }
48 void clone(framebuffer::queue& q) const throw(std::bad_alloc) { q.clone_helper(this); }
49 private:
50 std::pair<int32_t, int32_t> offsetrange()
52 int32_t cmin = -static_cast<int32_t>(width / 2);
53 int32_t cmax = static_cast<int32_t>((width + 1) / 2);
54 int32_t hmin = -static_cast<int32_t>(headwidth / 2);
55 int32_t hmax = static_cast<int32_t>((headwidth + 1) / 2);
56 return std::make_pair(min(cmin, hmin), max(cmax, hmax));
58 std::pair<int32_t, int32_t> drawrange(int32_t offset)
60 int32_t cmin = -static_cast<int32_t>(width / 2);
61 int32_t cmax = static_cast<int32_t>((width + 1) / 2);
62 int32_t hmin = -static_cast<int32_t>(headwidth / 2);
63 int32_t hmax = static_cast<int32_t>((headwidth + 1) / 2);
64 bool in_center = (offset >= cmin && offset < cmax);
65 bool in_head = (offset >= hmin && offset < hmax);
66 int32_t minc = std::abs(offset); //Works for head&tail.
67 int32_t maxc = 0;
68 if(in_center) maxc = max(maxc, static_cast<int32_t>(length));
69 if(in_head) {
70 if(fill) {
71 if(direction & 1) {
72 int32_t fedge = hmax - minc;
73 maxc = max(maxc, minc + fedge / 2 + 1);
74 } else
75 maxc = max(maxc, hmax);
76 } else
77 maxc = max(maxc, static_cast<int32_t>(minc + headthickness));
79 return std::make_pair(minc, maxc);
81 int32_t x;
82 int32_t y;
83 uint32_t length;
84 uint32_t width;
85 uint32_t headwidth;
86 uint32_t headthickness;
87 int direction;
88 bool fill;
89 framebuffer::color color;
92 lua::fnptr2 gui_box(lua_func_misc, "gui.arrow", [](lua::state& L, lua::parameters& P) -> int {
93 int32_t x, y;
94 uint32_t length, headwidth, width, headthickness;
95 int direction;
96 bool fill;
97 framebuffer::color color;
99 if(!lua_render_ctx)
100 return 0;
102 P(x, y, length, headwidth, direction, P.optional(fill, false), P.optional(color, 0xFFFFFF),
103 P.optional(width, 1), P.optional2(headthickness, width));
105 lua_render_ctx->queue->create_add<render_object_arrow>(x, y, length, width, headwidth, headthickness,
106 direction, fill, color);
107 return 0;