Make opus_packet_tick_count a common function
[lsnes.git] / src / lua / gui-core.cpp
blobc16151a43b8ae2ede45de35a343c2ecc63cd717e
1 #include "lua/internal.hpp"
2 #include "core/window.hpp"
3 #include "library/minmax.hpp"
5 namespace
7 class lua_gui_resolution : public lua_function
9 public:
10 lua_gui_resolution() : lua_function(LS, "gui.resolution") {}
11 int invoke(lua_state& L)
13 if(!lua_render_ctx)
14 return 0;
15 L.pushnumber(lua_render_ctx->width);
16 L.pushnumber(lua_render_ctx->height);
17 return 2;
19 } gui_resolution;
21 template<uint32_t lua_render_context::*gap>
22 class lua_gui_set_gap : public lua_function
24 public:
25 lua_gui_set_gap(const std::string& name) : lua_function(LS, name) {}
26 int invoke(lua_state& L)
28 if(!lua_render_ctx)
29 return 0;
30 uint32_t g = L.get_numeric_argument<uint32_t>(1, fname.c_str());
31 if(g > 8192)
32 return 0; //Ignore ridiculous gap.
33 lua_render_ctx->*gap = g;
34 return 0;
38 lua_gui_set_gap<&lua_render_context::left_gap> lg("gui.left_gap");
39 lua_gui_set_gap<&lua_render_context::right_gap> rg("gui.right_gap");
40 lua_gui_set_gap<&lua_render_context::top_gap> tg("gui.top_gap");
41 lua_gui_set_gap<&lua_render_context::bottom_gap> bg("gui.bottom_gap");
43 function_ptr_luafun gui_repaint(LS, "gui.repaint", [](lua_state& L, const std::string& fname) -> int {
44 lua_requests_repaint = true;
45 return 0;
46 });
48 function_ptr_luafun gui_sfupd(LS, "gui.subframe_update", [](lua_state& L, const std::string& fname) -> int {
49 lua_requests_subframe_paint = L.get_bool(1, fname.c_str());
50 return 0;
51 });
53 function_ptr_luafun gui_color(LS, "gui.color", [](lua_state& L, const std::string& fname) -> int {
54 int64_t a = 256;
55 int64_t r = L.get_numeric_argument<uint32_t>(1, fname.c_str());
56 int64_t g = L.get_numeric_argument<uint32_t>(2, fname.c_str());
57 int64_t b = L.get_numeric_argument<uint32_t>(3, fname.c_str());
58 L.get_numeric_argument<int64_t>(4, a, fname.c_str());
59 if(a > 0)
60 L.pushnumber(((256 - a) << 24) | (r << 16) | (g << 8) | b);
61 else
62 L.pushnumber(-1);
63 return 1;
64 });
66 function_ptr_luafun gui_status(LS, "gui.status", [](lua_state& L, const std::string& fname) -> int {
67 std::string name = L.get_string(1, fname.c_str());
68 std::string value = L.get_string(2, fname.c_str());
69 auto& w = platform::get_emustatus();
70 if(value == "")
71 w.erase("L[" + name + "]");
72 else
73 w.set("L[" + name + "]", value);
74 return 1;
75 });
78 //0: m
79 //1: M
80 //2: m + phue
81 //3: M - phue
82 uint8_t hsl2rgb_flags[] = {24, 52, 6, 13, 33, 19};
84 uint32_t shifthue(uint32_t color, double shift)
86 int16_t R = (color >> 16) & 0xFF;
87 int16_t G = (color >> 8) & 0xFF;
88 int16_t B = color & 0xFF;
89 int16_t m = min(R, min(G, B));
90 int16_t M = max(R, max(G, B));
91 int16_t S = M - m;
92 if(!S)
93 return color; //Grey.
94 int16_t hue;
95 if(R == M)
96 hue = G - B + 6 * S;
97 else if(G == M)
98 hue = B - R + 2 * S;
99 else
100 hue = R - G + 4 * S;
101 hue = (hue + static_cast<uint32_t>(shift * S)) % (6 * S);
102 uint32_t V[4];
103 V[0] = m;
104 V[1] = M;
105 V[2] = m + hue % S;
106 V[3] = M - hue % S;
107 uint8_t flag = hsl2rgb_flags[hue / S];
108 return (V[(flag >> 4) & 3] << 16) | (V[(flag >> 2) & 3] << 8) | (V[flag & 3]);
111 function_ptr_luafun gui_rainbow(LS, "gui.rainbow", [](lua_state& L, const std::string& fname) -> int {
112 int64_t basecolor = 0x00FF0000;
113 uint64_t step = L.get_numeric_argument<uint64_t>(1, fname.c_str());
114 int32_t steps = L.get_numeric_argument<int32_t>(2, fname.c_str());
115 L.get_numeric_argument<int64_t>(3, basecolor, fname.c_str());
116 if(!steps) {
117 L.pushstring("Expected nonzero steps for gui.rainbow");
118 L.error();
120 if(basecolor < 0) {
121 //Special: Any rotation of transparent is transparent.
122 L.pushnumber(-1);
123 return 1;
125 uint32_t asteps = std::abs(steps);
126 if(steps < 0)
127 step = asteps - step % asteps; //Reverse order.
128 double hueshift = 6.0 * (step % asteps) / asteps;
129 basecolor = shifthue(basecolor & 0xFFFFFF, hueshift) | (basecolor & 0xFF000000);
130 L.pushnumber(basecolor);
131 return 1;