Actually call on_reset callback
[lsnes.git] / src / lua / gui-arrow.cpp
blobf20670a5e59b1382be820c3c9b3aaf88226e6bc1
1 #include "core/instance.hpp"
2 #include "lua/internal.hpp"
3 #include "library/framebuffer.hpp"
4 #include "library/lua-framebuffer.hpp"
5 #include "library/minmax.hpp"
7 namespace
9 const int _dx[8] = {-1,-1, 0, 1, 1, 1, 0,-1};
10 const int _dy[8] = { 0, 1, 1, 1, 0,-1,-1,-1};
11 const int _dxn[8] = { 0, 0, 1, 1, 0, 0,-1,-1};
12 const int _dyn[8] = { 1, 1, 0, 0,-1,-1, 0, 0};
13 const int _dxp[8] = { 0, 1, 1, 0, 0,-1,-1, 0};
14 const int _dyp[8] = { 1, 0, 0,-1,-1, 0, 0, 1};
15 struct render_object_arrow : public framebuffer::object
17 render_object_arrow(int32_t _x, int32_t _y, uint32_t _length, uint32_t _width,
18 uint32_t _headwidth, uint32_t _headthickness, int _direction, bool _fill,
19 framebuffer::color _color) throw()
20 : x(_x), y(_y), length(_length), width(_width), headwidth(_headwidth),
21 headthickness(_headthickness), direction(_direction), fill(_fill), color(_color) {}
22 ~render_object_arrow() throw() {}
23 template<bool X> void op(struct framebuffer::fb<X>& scr) throw()
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(signed 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 >= (ssize_t)scr.get_width())
39 continue;
40 if(yc < 0 || yc >= (ssize_t)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 { 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 int arrow(lua::state& L, lua::parameters& P)
94 auto& core = CORE();
95 int32_t x, y;
96 uint32_t length, headwidth, width, headthickness;
97 int direction;
98 bool fill;
99 framebuffer::color color;
101 if(!core.lua2->render_ctx) return 0;
103 P(x, y, length, headwidth, direction, P.optional(fill, false), P.optional(color, 0xFFFFFF),
104 P.optional(width, 1), P.optional2(headthickness, width));
106 core.lua2->render_ctx->queue->create_add<render_object_arrow>(x, y, length, width, headwidth,
107 headthickness, direction, fill, color);
108 return 0;
111 lua::functions LUA_arrow_fns(lua_func_misc, "gui", {
112 {"arrow", arrow},