Lua: Don't lua_error() out of context with pending dtors
[lsnes.git] / src / lua / gui-core.cpp
blob127bd08926b6cc32f92889c06cced325fc145c95
1 #include "lua/internal.hpp"
2 #include "core/emustatus.hpp"
3 #include "core/instance.hpp"
4 #include "core/window.hpp"
5 #include "library/minmax.hpp"
7 namespace
9 template<uint32_t lua::render_context::*gap, bool delta>
10 int lua_gui_set_gap(lua::state& L, lua::parameters& P)
12 auto& core = CORE();
13 int32_t g;
14 if(!core.lua2->render_ctx)
15 return 0;
17 P(g);
19 if(core.lua2->render_ctx->*gap == std::numeric_limits<uint32_t>::max())
20 core.lua2->render_ctx->*gap = 0; //Handle default gap of render queue.
21 if(delta) g += core.lua2->render_ctx->*gap;
22 if(g < 0 || g > 8192)
23 return 0; //Ignore ridiculous gap.
24 uint32_t old = core.lua2->render_ctx->*gap;
25 core.lua2->render_ctx->*gap = g;
26 L.pushnumber(old);
27 return 1;
30 int resolution(lua::state& L, lua::parameters& P)
32 auto& core = CORE();
33 if(!core.lua2->render_ctx)
34 return 0;
35 L.pushnumber(core.lua2->render_ctx->width);
36 L.pushnumber(core.lua2->render_ctx->height);
37 return 2;
40 int repaint(lua::state& L, lua::parameters& P)
42 CORE().lua2->requests_repaint = true;
43 return 0;
46 int subframe_update(lua::state& L, lua::parameters& P)
48 P(CORE().lua2->requests_subframe_paint);
49 return 0;
52 int color(lua::state& L, lua::parameters& P)
54 int64_t r, g, b, a;
56 if(P.is_string()) {
57 framebuffer::color c(P.arg<std::string>());
58 L.pushnumber(c.asnumber());
59 return 1;
62 P(r, g, b, P.optional(a, 256));
64 if(a > 0)
65 L.pushnumber(((256 - a) << 24) | (r << 16) | (g << 8) | b);
66 else
67 L.pushnumber(-1);
68 return 1;
71 int status(lua::state& L, lua::parameters& P)
73 auto& core = CORE();
74 std::string name, value;
76 P(name, value);
78 if(value == "")
79 core.lua2->watch_vars.erase(name);
80 else
81 core.lua2->watch_vars[name] = utf8::to32(value);
82 core.supdater->update();
83 return 1;
86 int rainbow(lua::state& L, lua::parameters& P)
88 int64_t step, steps;
89 framebuffer::color c;
91 P(step, steps, P.optional(c, 0x00FF0000));
93 auto basecolor = c.asnumber();
94 if(!steps)
95 throw std::runtime_error("Expected nonzero steps for gui.rainbow");
96 basecolor = framebuffer::color_rotate_hue(basecolor, step, steps);
97 L.pushnumber(basecolor);
98 return 1;
101 int kill_frame(lua::state& L, lua::parameters& P)
103 auto& core = CORE();
104 if(core.lua2->kill_frame)
105 *core.lua2->kill_frame = true;
106 return 0;
109 int set_video_scale(lua::state& L, lua::parameters& P)
111 auto& core = CORE();
112 if(core.lua2->hscl && core.lua2->vscl) {
113 uint32_t h, v;
115 P(h, v);
117 *core.lua2->hscl = h;
118 *core.lua2->vscl = v;
120 return 0;
123 lua::functions LUA_guicore_fns(lua_func_misc, "gui", {
124 {"left_gap", lua_gui_set_gap<&lua::render_context::left_gap, false>},
125 {"right_gap", lua_gui_set_gap<&lua::render_context::right_gap, false>},
126 {"top_gap", lua_gui_set_gap<&lua::render_context::top_gap, false>},
127 {"bottom_gap", lua_gui_set_gap<&lua::render_context::bottom_gap, false>},
128 {"delta_left_gap", lua_gui_set_gap<&lua::render_context::left_gap, true>},
129 {"delta_right_gap", lua_gui_set_gap<&lua::render_context::right_gap, true>},
130 {"delta_top_gap", lua_gui_set_gap<&lua::render_context::top_gap, true>},
131 {"delta_bottom_gap", lua_gui_set_gap<&lua::render_context::bottom_gap, true>},
132 {"resolution", resolution},
133 {"repaint", repaint},
134 {"subframe_update", subframe_update},
135 {"color", color},
136 {"status", status},
137 {"rainbow", rainbow},
138 {"kill_frame", kill_frame},
139 {"set_video_scale", set_video_scale},