Move lua-framebuffer to lua namespace
[lsnes.git] / src / lua / gui-rqueue.cpp
blobe2691ffe580957bb8ae0e90cc59dfebe526aeb41
1 #include "core/framebuffer.hpp"
2 #include "lua/internal.hpp"
3 #include "lua/bitmap.hpp"
4 #include "library/framebuffer.hpp"
6 namespace
8 lua::render_context* saved = NULL;
9 lua::render_context* last = NULL;
10 bool redirect = false;
12 struct lua_renderqueue
14 lua_renderqueue(lua::state& L, uint32_t width, uint32_t height) throw();
15 static size_t overcommit(uint32_t width, uint32_t height) { return 0; }
16 ~lua_renderqueue() throw() {}
17 lua::render_context* get() { return &lctx; }
18 std::string print()
20 size_t s = rqueue.get_object_count();
21 return (stringfmt() << s << " " << ((s != 1) ? "objects" : "object")).str();
23 static int create(lua::state& L, lua::parameters& P);
24 static int setnull(lua::state& L, lua::parameters& P);
25 int run(lua::state& L, lua::parameters& P)
27 if(!lua_render_ctx) return 0;
29 lua::render_context* ptr = get();
30 if(ptr->top_gap != std::numeric_limits<uint32_t>::max())
31 lua_render_ctx->top_gap = ptr->top_gap;
32 if(ptr->right_gap != std::numeric_limits<uint32_t>::max())
33 lua_render_ctx->right_gap = ptr->right_gap;
34 if(ptr->bottom_gap != std::numeric_limits<uint32_t>::max())
35 lua_render_ctx->bottom_gap = ptr->bottom_gap;
36 if(ptr->left_gap != std::numeric_limits<uint32_t>::max())
37 lua_render_ctx->left_gap = ptr->left_gap;
38 lua_render_ctx->queue->copy_from(*ptr->queue);
39 return 0;
41 int synchronous_repaint(lua::state& L, lua::parameters& P)
43 lua::objpin<lua_renderqueue> q;
45 P(q);
47 synchronous_paint_ctx = &*q;
48 redraw_framebuffer();
49 synchronous_paint_ctx = NULL;
50 return 0;
52 int clear(lua::state& L, lua::parameters& P)
54 lua::render_context* ptr = get();
55 ptr->top_gap = std::numeric_limits<uint32_t>::max();
56 ptr->right_gap = std::numeric_limits<uint32_t>::max();
57 ptr->bottom_gap = std::numeric_limits<uint32_t>::max();
58 ptr->left_gap = std::numeric_limits<uint32_t>::max();
59 ptr->queue->clear();
60 return 0;
62 int set(lua::state& L, lua::parameters& P)
64 lua::objpin<lua_renderqueue> q;
66 P(q);
68 lua::render_context* ptr = q->get();
69 if(!redirect || last != lua_render_ctx)
70 saved = lua_render_ctx;
71 lua_render_ctx = last = ptr;
72 redirect = true;
73 return 0;
75 int render(lua::state& L, lua::parameters& P)
77 uint32_t rwidth = lctx.width + rdgap(lctx.left_gap) + rdgap(lctx.right_gap);
78 uint32_t rheight = lctx.height + rdgap(lctx.top_gap) + rdgap(lctx.bottom_gap);
79 uint32_t xoff = rdgap(lctx.left_gap);
80 uint32_t yoff = rdgap(lctx.top_gap);
81 framebuffer::fb<false> fb;
82 fb.reallocate(rwidth, rheight);
83 fb.set_origin(xoff, yoff);
84 rqueue.run(fb);
85 lua_dbitmap* b = lua::_class<lua_dbitmap>::create(L, rwidth, rheight);
86 for(auto y = 0U; y < rheight; y++) {
87 const uint32_t* rowp = fb.rowptr(y);
88 auto rowt = &b->pixels[y * rwidth];
89 for(auto x = 0U; x < rwidth; x++) {
90 uint32_t v = rowp[x];
91 uint64_t c = -1;
92 if(v >> 24)
93 c = ((256 - (v >> 24) - (v >> 31)) << 24) + (v & 0xFFFFFF);
94 rowt[x] = c;
97 return 1;
99 private:
100 uint32_t rdgap(uint32_t v)
102 return (v + 1) ? v : 0;
104 framebuffer::queue rqueue;
105 lua::render_context lctx;
108 lua_renderqueue::lua_renderqueue(lua::state& L, uint32_t width, uint32_t height) throw()
110 lctx.left_gap = std::numeric_limits<uint32_t>::max();
111 lctx.right_gap = std::numeric_limits<uint32_t>::max();
112 lctx.bottom_gap = std::numeric_limits<uint32_t>::max();
113 lctx.top_gap = std::numeric_limits<uint32_t>::max();
114 lctx.queue = &rqueue;
115 lctx.width = width;
116 lctx.height = height;
119 int lua_renderqueue::create(lua::state& L, lua::parameters& P)
121 int32_t x, y;
123 P(x, y);
125 lua::_class<lua_renderqueue>::create(L, x, y);
126 return 1;
129 int lua_renderqueue::setnull(lua::state& L, lua::parameters& P)
131 if(redirect && last == lua_render_ctx)
132 //If there is valid redirect, undo it.
133 lua_render_ctx = saved;
134 redirect = false;
135 last = NULL;
136 saved = NULL;
137 return 0;
140 lua::_class<lua_renderqueue> class_lua_renderqueue(lua_class_gui, "RENDERCTX", {
141 {"new", lua_renderqueue::create},
142 {"setnull", lua_renderqueue::setnull},
143 }, {
144 {"run", &lua_renderqueue::run},
145 {"synchronous_repaint", &lua_renderqueue::synchronous_repaint},
146 {"clear", &lua_renderqueue::clear},
147 {"set", &lua_renderqueue::set},
148 {"render", &lua_renderqueue::render},
149 }, &lua_renderqueue::print);
152 void lua_renderq_run(lua::render_context* ctx, void* _sctx)
154 lua_renderqueue* sctx = (lua_renderqueue*)_sctx;
155 lua::render_context* ptr = sctx->get();
156 if(ptr->top_gap != std::numeric_limits<uint32_t>::max())
157 ctx->top_gap = ptr->top_gap;
158 if(ptr->right_gap != std::numeric_limits<uint32_t>::max())
159 ctx->right_gap = ptr->right_gap;
160 if(ptr->bottom_gap != std::numeric_limits<uint32_t>::max())
161 ctx->bottom_gap = ptr->bottom_gap;
162 if(ptr->left_gap != std::numeric_limits<uint32_t>::max())
163 ctx->left_gap = ptr->left_gap;
164 ctx->queue->copy_from(*ptr->queue);