lsnes rr2-β24
[lsnes.git] / src / lua / gui-circle.cpp
blob5d5ca623f6ee0c8a5a01975c2ce0d937a37bd7c3
1 #include "core/instance.hpp"
2 #include "lua/internal.hpp"
3 #include "library/framebuffer.hpp"
4 #include "library/range.hpp"
5 #include "library/lua-framebuffer.hpp"
7 namespace
9 struct render_object_circle : public framebuffer::object
11 render_object_circle(int32_t _x, int32_t _y, uint32_t _radius,
12 framebuffer::color _outline, framebuffer::color _fill, uint32_t _thickness) throw()
13 : x(_x), y(_y), outline(_outline), fill(_fill)
15 radius = _radius;
16 radius2 = static_cast<uint64_t>(_radius) * _radius;
17 if(_thickness > _radius)
18 iradius2 = 0;
19 else
20 iradius2 = static_cast<uint64_t>(_radius - _thickness) *
21 (_radius - _thickness);
23 ~render_object_circle() throw() {}
24 template<bool X> void op(struct framebuffer::fb<X>& scr) throw()
26 uint32_t oX = x + scr.get_origin_x();
27 uint32_t oY = y + scr.get_origin_y();
28 range bX = (range::make_w(scr.get_width()) - oX) & range::make_b(-radius, radius + 1);
29 range bY = (range::make_w(scr.get_height()) - oY) & range::make_b(-radius, radius + 1);
30 for(int32_t r = bY.low(); r != (int32_t)bY.high(); r++) {
31 uint64_t pd2 = static_cast<int64_t>(r) * r;
32 typename framebuffer::fb<X>::element_t* rptr = scr.rowptr(oY + r);
33 size_t eptr = oX + bX.low();
34 for(int32_t c = bX.low(); c != (int32_t)bX.high(); c++, eptr++) {
35 uint64_t fd2 = pd2 + static_cast<int64_t>(c) * c;
36 if(fd2 > radius2)
37 continue;
38 else if(fd2 >= iradius2)
39 outline.apply(rptr[eptr]);
40 else
41 fill.apply(rptr[eptr]);
45 void operator()(struct framebuffer::fb<true>& scr) throw() { op(scr); }
46 void operator()(struct framebuffer::fb<false>& scr) throw() { op(scr); }
47 void clone(framebuffer::queue& q) const throw(std::bad_alloc) { q.clone_helper(this); }
48 private:
49 int32_t x;
50 int32_t y;
51 int32_t radius;
52 uint64_t radius2;
53 uint64_t iradius2;
54 framebuffer::color outline;
55 framebuffer::color fill;
58 int circle(lua::state& L, lua::parameters& P)
60 auto& core = CORE();
61 int32_t x, y;
62 uint32_t radius, thickness;
63 framebuffer::color poutline, pfill;
65 if(!core.lua2->render_ctx) return 0;
67 P(x, y, radius, P.optional(thickness, 1), P.optional(poutline, 0xFFFFFFU), P.optional(pfill, -1));
69 core.lua2->render_ctx->queue->create_add<render_object_circle>(x, y, radius, poutline, pfill,
70 thickness);
71 return 0;
74 lua::functions LUA_circle_fns(lua_func_misc, "gui", {
75 {"circle", circle},
76 });