]> git.lizzy.rs Git - minetest.git/blob - src/script/common/c_converter.cpp
Add push_ARGB8 to script/common/c_converter
[minetest.git] / src / script / common / c_converter.cpp
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 extern "C" {
21 #include "lua.h"
22 #include "lauxlib.h"
23 }
24
25 #include "util/numeric.h"
26 #include "common/c_converter.h"
27 #include "constants.h"
28
29
30 #define CHECK_TYPE(index, name, type) do { \
31         int t = lua_type(L, (index)); \
32         if (t != (type)) { \
33                 throw LuaError(std::string("Invalid ") + (name) + \
34                         " (expected " + lua_typename(L, (type)) + \
35                         " got " + lua_typename(L, t) + ")."); \
36         } \
37 } while(0)
38 #define CHECK_POS_COORD(name) CHECK_TYPE(-1, "position coordinate '" name "'", LUA_TNUMBER)
39 #define CHECK_POS_TAB(index) CHECK_TYPE(index, "position", LUA_TTABLE)
40
41
42 void push_ARGB8(lua_State *L, video::SColor color)
43 {
44         lua_newtable(L);
45         lua_pushnumber(L, color.getAlpha());
46         lua_setfield(L, -2, "a");
47         lua_pushnumber(L, color.getRed());
48         lua_setfield(L, -2, "r");
49         lua_pushnumber(L, color.getGreen());
50         lua_setfield(L, -2, "g");
51         lua_pushnumber(L, color.getBlue());
52         lua_setfield(L, -2, "b");
53 }
54
55 void push_v3f(lua_State *L, v3f p)
56 {
57         lua_newtable(L);
58         lua_pushnumber(L, p.X);
59         lua_setfield(L, -2, "x");
60         lua_pushnumber(L, p.Y);
61         lua_setfield(L, -2, "y");
62         lua_pushnumber(L, p.Z);
63         lua_setfield(L, -2, "z");
64 }
65
66 void push_v2f(lua_State *L, v2f p)
67 {
68         lua_newtable(L);
69         lua_pushnumber(L, p.X);
70         lua_setfield(L, -2, "x");
71         lua_pushnumber(L, p.Y);
72         lua_setfield(L, -2, "y");
73 }
74
75 v2s16 read_v2s16(lua_State *L, int index)
76 {
77         v2s16 p;
78         CHECK_POS_TAB(index);
79         lua_getfield(L, index, "x");
80         p.X = lua_tonumber(L, -1);
81         lua_pop(L, 1);
82         lua_getfield(L, index, "y");
83         p.Y = lua_tonumber(L, -1);
84         lua_pop(L, 1);
85         return p;
86 }
87
88 v2s16 check_v2s16(lua_State *L, int index)
89 {
90         v2s16 p;
91         CHECK_POS_TAB(index);
92         lua_getfield(L, index, "x");
93         CHECK_POS_COORD("x");
94         p.X = lua_tonumber(L, -1);
95         lua_pop(L, 1);
96         lua_getfield(L, index, "y");
97         CHECK_POS_COORD("y");
98         p.Y = lua_tonumber(L, -1);
99         lua_pop(L, 1);
100         return p;
101 }
102
103 v2s32 read_v2s32(lua_State *L, int index)
104 {
105         v2s32 p;
106         CHECK_POS_TAB(index);
107         lua_getfield(L, index, "x");
108         p.X = lua_tonumber(L, -1);
109         lua_pop(L, 1);
110         lua_getfield(L, index, "y");
111         p.Y = lua_tonumber(L, -1);
112         lua_pop(L, 1);
113         return p;
114 }
115
116 v2f read_v2f(lua_State *L, int index)
117 {
118         v2f p;
119         CHECK_POS_TAB(index);
120         lua_getfield(L, index, "x");
121         p.X = lua_tonumber(L, -1);
122         lua_pop(L, 1);
123         lua_getfield(L, index, "y");
124         p.Y = lua_tonumber(L, -1);
125         lua_pop(L, 1);
126         return p;
127 }
128
129 v2f check_v2f(lua_State *L, int index)
130 {
131         v2f p;
132         CHECK_POS_TAB(index);
133         lua_getfield(L, index, "x");
134         CHECK_POS_COORD("x");
135         p.X = lua_tonumber(L, -1);
136         lua_pop(L, 1);
137         lua_getfield(L, index, "y");
138         CHECK_POS_COORD("y");
139         p.Y = lua_tonumber(L, -1);
140         lua_pop(L, 1);
141         return p;
142 }
143
144 v3f read_v3f(lua_State *L, int index)
145 {
146         v3f pos;
147         CHECK_POS_TAB(index);
148         lua_getfield(L, index, "x");
149         pos.X = lua_tonumber(L, -1);
150         lua_pop(L, 1);
151         lua_getfield(L, index, "y");
152         pos.Y = lua_tonumber(L, -1);
153         lua_pop(L, 1);
154         lua_getfield(L, index, "z");
155         pos.Z = lua_tonumber(L, -1);
156         lua_pop(L, 1);
157         return pos;
158 }
159
160 v3f check_v3f(lua_State *L, int index)
161 {
162         v3f pos;
163         CHECK_POS_TAB(index);
164         lua_getfield(L, index, "x");
165         CHECK_POS_COORD("x");
166         pos.X = lua_tonumber(L, -1);
167         lua_pop(L, 1);
168         lua_getfield(L, index, "y");
169         CHECK_POS_COORD("y");
170         pos.Y = lua_tonumber(L, -1);
171         lua_pop(L, 1);
172         lua_getfield(L, index, "z");
173         CHECK_POS_COORD("z");
174         pos.Z = lua_tonumber(L, -1);
175         lua_pop(L, 1);
176         return pos;
177 }
178
179 void pushFloatPos(lua_State *L, v3f p)
180 {
181         p /= BS;
182         push_v3f(L, p);
183 }
184
185 v3f checkFloatPos(lua_State *L, int index)
186 {
187         return check_v3f(L, index) * BS;
188 }
189
190 void push_v3s16(lua_State *L, v3s16 p)
191 {
192         lua_newtable(L);
193         lua_pushnumber(L, p.X);
194         lua_setfield(L, -2, "x");
195         lua_pushnumber(L, p.Y);
196         lua_setfield(L, -2, "y");
197         lua_pushnumber(L, p.Z);
198         lua_setfield(L, -2, "z");
199 }
200
201 v3s16 read_v3s16(lua_State *L, int index)
202 {
203         // Correct rounding at <0
204         v3f pf = read_v3f(L, index);
205         return floatToInt(pf, 1.0);
206 }
207
208 v3s16 check_v3s16(lua_State *L, int index)
209 {
210         // Correct rounding at <0
211         v3f pf = check_v3f(L, index);
212         return floatToInt(pf, 1.0);
213 }
214
215 video::SColor readARGB8(lua_State *L, int index)
216 {
217         video::SColor color(0);
218         CHECK_TYPE(index, "ARGB color", LUA_TTABLE);
219         lua_getfield(L, index, "a");
220         if(lua_isnumber(L, -1))
221                 color.setAlpha(lua_tonumber(L, -1));
222         lua_pop(L, 1);
223         lua_getfield(L, index, "r");
224         color.setRed(lua_tonumber(L, -1));
225         lua_pop(L, 1);
226         lua_getfield(L, index, "g");
227         color.setGreen(lua_tonumber(L, -1));
228         lua_pop(L, 1);
229         lua_getfield(L, index, "b");
230         color.setBlue(lua_tonumber(L, -1));
231         lua_pop(L, 1);
232         return color;
233 }
234
235 aabb3f read_aabb3f(lua_State *L, int index, f32 scale)
236 {
237         aabb3f box;
238         if(lua_istable(L, index)){
239                 lua_rawgeti(L, index, 1);
240                 box.MinEdge.X = lua_tonumber(L, -1) * scale;
241                 lua_pop(L, 1);
242                 lua_rawgeti(L, index, 2);
243                 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
244                 lua_pop(L, 1);
245                 lua_rawgeti(L, index, 3);
246                 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
247                 lua_pop(L, 1);
248                 lua_rawgeti(L, index, 4);
249                 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
250                 lua_pop(L, 1);
251                 lua_rawgeti(L, index, 5);
252                 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
253                 lua_pop(L, 1);
254                 lua_rawgeti(L, index, 6);
255                 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
256                 lua_pop(L, 1);
257         }
258         return box;
259 }
260
261 std::vector<aabb3f> read_aabb3f_vector(lua_State *L, int index, f32 scale)
262 {
263         std::vector<aabb3f> boxes;
264         if(lua_istable(L, index)){
265                 int n = lua_objlen(L, index);
266                 // Check if it's a single box or a list of boxes
267                 bool possibly_single_box = (n == 6);
268                 for(int i = 1; i <= n && possibly_single_box; i++){
269                         lua_rawgeti(L, index, i);
270                         if(!lua_isnumber(L, -1))
271                                 possibly_single_box = false;
272                         lua_pop(L, 1);
273                 }
274                 if(possibly_single_box){
275                         // Read a single box
276                         boxes.push_back(read_aabb3f(L, index, scale));
277                 } else {
278                         // Read a list of boxes
279                         for(int i = 1; i <= n; i++){
280                                 lua_rawgeti(L, index, i);
281                                 boxes.push_back(read_aabb3f(L, -1, scale));
282                                 lua_pop(L, 1);
283                         }
284                 }
285         }
286         return boxes;
287 }
288
289 size_t read_stringlist(lua_State *L, int index, std::vector<std::string> *result)
290 {
291         if (index < 0)
292                 index = lua_gettop(L) + 1 + index;
293
294         size_t num_strings = 0;
295
296         if (lua_istable(L, index)) {
297                 lua_pushnil(L);
298                 while (lua_next(L, index)) {
299                         if (lua_isstring(L, -1)) {
300                                 result->push_back(lua_tostring(L, -1));
301                                 num_strings++;
302                         }
303                         lua_pop(L, 1);
304                 }
305         } else if (lua_isstring(L, index)) {
306                 result->push_back(lua_tostring(L, index));
307                 num_strings++;
308         }
309
310         return num_strings;
311 }
312
313 /*
314         Table field getters
315 */
316
317 bool getstringfield(lua_State *L, int table,
318                 const char *fieldname, std::string &result)
319 {
320         lua_getfield(L, table, fieldname);
321         bool got = false;
322         if(lua_isstring(L, -1)){
323                 size_t len = 0;
324                 const char *ptr = lua_tolstring(L, -1, &len);
325                 if (ptr) {
326                         result.assign(ptr, len);
327                         got = true;
328                 }
329         }
330         lua_pop(L, 1);
331         return got;
332 }
333
334 bool getintfield(lua_State *L, int table,
335                 const char *fieldname, int &result)
336 {
337         lua_getfield(L, table, fieldname);
338         bool got = false;
339         if(lua_isnumber(L, -1)){
340                 result = lua_tonumber(L, -1);
341                 got = true;
342         }
343         lua_pop(L, 1);
344         return got;
345 }
346
347 bool getintfield(lua_State *L, int table,
348                 const char *fieldname, u8 &result)
349 {
350         lua_getfield(L, table, fieldname);
351         bool got = false;
352         if(lua_isnumber(L, -1)){
353                 result = lua_tonumber(L, -1);
354                 got = true;
355         }
356         lua_pop(L, 1);
357         return got;
358 }
359
360 bool getintfield(lua_State *L, int table,
361                 const char *fieldname, u16 &result)
362 {
363         lua_getfield(L, table, fieldname);
364         bool got = false;
365         if(lua_isnumber(L, -1)){
366                 result = lua_tonumber(L, -1);
367                 got = true;
368         }
369         lua_pop(L, 1);
370         return got;
371 }
372
373 bool getintfield(lua_State *L, int table,
374                 const char *fieldname, u32 &result)
375 {
376         lua_getfield(L, table, fieldname);
377         bool got = false;
378         if(lua_isnumber(L, -1)){
379                 result = lua_tonumber(L, -1);
380                 got = true;
381         }
382         lua_pop(L, 1);
383         return got;
384 }
385
386 bool getfloatfield(lua_State *L, int table,
387                 const char *fieldname, float &result)
388 {
389         lua_getfield(L, table, fieldname);
390         bool got = false;
391         if(lua_isnumber(L, -1)){
392                 result = lua_tonumber(L, -1);
393                 got = true;
394         }
395         lua_pop(L, 1);
396         return got;
397 }
398
399 bool getboolfield(lua_State *L, int table,
400                 const char *fieldname, bool &result)
401 {
402         lua_getfield(L, table, fieldname);
403         bool got = false;
404         if(lua_isboolean(L, -1)){
405                 result = lua_toboolean(L, -1);
406                 got = true;
407         }
408         lua_pop(L, 1);
409         return got;
410 }
411
412 size_t getstringlistfield(lua_State *L, int table, const char *fieldname,
413                 std::vector<std::string> *result)
414 {
415         lua_getfield(L, table, fieldname);
416
417         size_t num_strings_read = read_stringlist(L, -1, result);
418
419         lua_pop(L, 1);
420         return num_strings_read;
421 }
422
423 std::string checkstringfield(lua_State *L, int table,
424                 const char *fieldname)
425 {
426         lua_getfield(L, table, fieldname);
427         CHECK_TYPE(-1, std::string("field \"") + fieldname + '"', LUA_TSTRING);
428         size_t len;
429         const char *s = lua_tolstring(L, -1, &len);
430         lua_pop(L, 1);
431         return std::string(s, len);
432 }
433
434 std::string getstringfield_default(lua_State *L, int table,
435                 const char *fieldname, const std::string &default_)
436 {
437         std::string result = default_;
438         getstringfield(L, table, fieldname, result);
439         return result;
440 }
441
442 int getintfield_default(lua_State *L, int table,
443                 const char *fieldname, int default_)
444 {
445         int result = default_;
446         getintfield(L, table, fieldname, result);
447         return result;
448 }
449
450 float getfloatfield_default(lua_State *L, int table,
451                 const char *fieldname, float default_)
452 {
453         float result = default_;
454         getfloatfield(L, table, fieldname, result);
455         return result;
456 }
457
458 bool getboolfield_default(lua_State *L, int table,
459                 const char *fieldname, bool default_)
460 {
461         bool result = default_;
462         getboolfield(L, table, fieldname, result);
463         return result;
464 }
465
466 void setintfield(lua_State *L, int table,
467                 const char *fieldname, int value)
468 {
469         lua_pushinteger(L, value);
470         if(table < 0)
471                 table -= 1;
472         lua_setfield(L, table, fieldname);
473 }
474
475 void setfloatfield(lua_State *L, int table,
476                 const char *fieldname, float value)
477 {
478         lua_pushnumber(L, value);
479         if(table < 0)
480                 table -= 1;
481         lua_setfield(L, table, fieldname);
482 }
483
484 void setboolfield(lua_State *L, int table,
485                 const char *fieldname, bool value)
486 {
487         lua_pushboolean(L, value);
488         if(table < 0)
489                 table -= 1;
490         lua_setfield(L, table, fieldname);
491 }
492
493