3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
25 #include "util/numeric.h"
26 #include "util/string.h"
27 #include "common/c_converter.h"
28 #include "constants.h"
31 #define CHECK_TYPE(index, name, type) do { \
32 int t = lua_type(L, (index)); \
34 throw LuaError(std::string("Invalid ") + (name) + \
35 " (expected " + lua_typename(L, (type)) + \
36 " got " + lua_typename(L, t) + ")."); \
39 #define CHECK_POS_COORD(name) CHECK_TYPE(-1, "position coordinate '" name "'", LUA_TNUMBER)
40 #define CHECK_POS_TAB(index) CHECK_TYPE(index, "position", LUA_TTABLE)
43 void push_v3f(lua_State *L, v3f p)
46 lua_pushnumber(L, p.X);
47 lua_setfield(L, -2, "x");
48 lua_pushnumber(L, p.Y);
49 lua_setfield(L, -2, "y");
50 lua_pushnumber(L, p.Z);
51 lua_setfield(L, -2, "z");
54 void push_v2f(lua_State *L, v2f p)
57 lua_pushnumber(L, p.X);
58 lua_setfield(L, -2, "x");
59 lua_pushnumber(L, p.Y);
60 lua_setfield(L, -2, "y");
63 v2s16 read_v2s16(lua_State *L, int index)
67 lua_getfield(L, index, "x");
68 p.X = lua_tonumber(L, -1);
70 lua_getfield(L, index, "y");
71 p.Y = lua_tonumber(L, -1);
76 v2s16 check_v2s16(lua_State *L, int index)
80 lua_getfield(L, index, "x");
82 p.X = lua_tonumber(L, -1);
84 lua_getfield(L, index, "y");
86 p.Y = lua_tonumber(L, -1);
91 void push_v2s16(lua_State *L, v2s16 p)
94 lua_pushnumber(L, p.X);
95 lua_setfield(L, -2, "x");
96 lua_pushnumber(L, p.Y);
97 lua_setfield(L, -2, "y");
100 void push_v2s32(lua_State *L, v2s32 p)
103 lua_pushnumber(L, p.X);
104 lua_setfield(L, -2, "x");
105 lua_pushnumber(L, p.Y);
106 lua_setfield(L, -2, "y");
109 v2s32 read_v2s32(lua_State *L, int index)
112 CHECK_POS_TAB(index);
113 lua_getfield(L, index, "x");
114 p.X = lua_tonumber(L, -1);
116 lua_getfield(L, index, "y");
117 p.Y = lua_tonumber(L, -1);
122 v2f read_v2f(lua_State *L, int index)
125 CHECK_POS_TAB(index);
126 lua_getfield(L, index, "x");
127 p.X = lua_tonumber(L, -1);
129 lua_getfield(L, index, "y");
130 p.Y = lua_tonumber(L, -1);
135 v2f check_v2f(lua_State *L, int index)
138 CHECK_POS_TAB(index);
139 lua_getfield(L, index, "x");
140 CHECK_POS_COORD("x");
141 p.X = lua_tonumber(L, -1);
143 lua_getfield(L, index, "y");
144 CHECK_POS_COORD("y");
145 p.Y = lua_tonumber(L, -1);
150 v3f read_v3f(lua_State *L, int index)
153 CHECK_POS_TAB(index);
154 lua_getfield(L, index, "x");
155 pos.X = lua_tonumber(L, -1);
157 lua_getfield(L, index, "y");
158 pos.Y = lua_tonumber(L, -1);
160 lua_getfield(L, index, "z");
161 pos.Z = lua_tonumber(L, -1);
166 v3f check_v3f(lua_State *L, int index)
169 CHECK_POS_TAB(index);
170 lua_getfield(L, index, "x");
171 CHECK_POS_COORD("x");
172 pos.X = lua_tonumber(L, -1);
174 lua_getfield(L, index, "y");
175 CHECK_POS_COORD("y");
176 pos.Y = lua_tonumber(L, -1);
178 lua_getfield(L, index, "z");
179 CHECK_POS_COORD("z");
180 pos.Z = lua_tonumber(L, -1);
185 void push_ARGB8(lua_State *L, video::SColor color)
188 lua_pushnumber(L, color.getAlpha());
189 lua_setfield(L, -2, "a");
190 lua_pushnumber(L, color.getRed());
191 lua_setfield(L, -2, "r");
192 lua_pushnumber(L, color.getGreen());
193 lua_setfield(L, -2, "g");
194 lua_pushnumber(L, color.getBlue());
195 lua_setfield(L, -2, "b");
198 void pushFloatPos(lua_State *L, v3f p)
204 v3f checkFloatPos(lua_State *L, int index)
206 return check_v3f(L, index) * BS;
209 void push_v3s16(lua_State *L, v3s16 p)
212 lua_pushnumber(L, p.X);
213 lua_setfield(L, -2, "x");
214 lua_pushnumber(L, p.Y);
215 lua_setfield(L, -2, "y");
216 lua_pushnumber(L, p.Z);
217 lua_setfield(L, -2, "z");
220 v3s16 read_v3s16(lua_State *L, int index)
222 // Correct rounding at <0
223 v3f pf = read_v3f(L, index);
224 return floatToInt(pf, 1.0);
227 v3s16 check_v3s16(lua_State *L, int index)
229 // Correct rounding at <0
230 v3f pf = check_v3f(L, index);
231 return floatToInt(pf, 1.0);
234 bool read_color(lua_State *L, int index, video::SColor *color)
236 if (lua_istable(L, index)) {
237 *color = read_ARGB8(L, index);
238 } else if (lua_isnumber(L, index)) {
239 color->set(lua_tonumber(L, index));
240 } else if (lua_isstring(L, index)) {
241 video::SColor parsed_color;
242 if (!parseColorString(lua_tostring(L, index), parsed_color, true))
245 *color = parsed_color;
253 video::SColor read_ARGB8(lua_State *L, int index)
255 video::SColor color(0);
256 CHECK_TYPE(index, "ARGB color", LUA_TTABLE);
257 lua_getfield(L, index, "a");
258 color.setAlpha(lua_isnumber(L, -1) ? lua_tonumber(L, -1) : 0xFF);
260 lua_getfield(L, index, "r");
261 color.setRed(lua_tonumber(L, -1));
263 lua_getfield(L, index, "g");
264 color.setGreen(lua_tonumber(L, -1));
266 lua_getfield(L, index, "b");
267 color.setBlue(lua_tonumber(L, -1));
272 aabb3f read_aabb3f(lua_State *L, int index, f32 scale)
275 if(lua_istable(L, index)){
276 lua_rawgeti(L, index, 1);
277 box.MinEdge.X = lua_tonumber(L, -1) * scale;
279 lua_rawgeti(L, index, 2);
280 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
282 lua_rawgeti(L, index, 3);
283 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
285 lua_rawgeti(L, index, 4);
286 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
288 lua_rawgeti(L, index, 5);
289 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
291 lua_rawgeti(L, index, 6);
292 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
298 void push_aabb3f(lua_State *L, aabb3f box)
301 lua_pushnumber(L, box.MinEdge.X);
302 lua_rawseti(L, -2, 1);
303 lua_pushnumber(L, box.MinEdge.Y);
304 lua_rawseti(L, -2, 2);
305 lua_pushnumber(L, box.MinEdge.Z);
306 lua_rawseti(L, -2, 3);
307 lua_pushnumber(L, box.MaxEdge.X);
308 lua_rawseti(L, -2, 4);
309 lua_pushnumber(L, box.MaxEdge.Y);
310 lua_rawseti(L, -2, 5);
311 lua_pushnumber(L, box.MaxEdge.Z);
312 lua_rawseti(L, -2, 6);
315 std::vector<aabb3f> read_aabb3f_vector(lua_State *L, int index, f32 scale)
317 std::vector<aabb3f> boxes;
318 if(lua_istable(L, index)){
319 int n = lua_objlen(L, index);
320 // Check if it's a single box or a list of boxes
321 bool possibly_single_box = (n == 6);
322 for(int i = 1; i <= n && possibly_single_box; i++){
323 lua_rawgeti(L, index, i);
324 if(!lua_isnumber(L, -1))
325 possibly_single_box = false;
328 if(possibly_single_box){
330 boxes.push_back(read_aabb3f(L, index, scale));
332 // Read a list of boxes
333 for(int i = 1; i <= n; i++){
334 lua_rawgeti(L, index, i);
335 boxes.push_back(read_aabb3f(L, -1, scale));
343 size_t read_stringlist(lua_State *L, int index, std::vector<std::string> *result)
346 index = lua_gettop(L) + 1 + index;
348 size_t num_strings = 0;
350 if (lua_istable(L, index)) {
352 while (lua_next(L, index)) {
353 if (lua_isstring(L, -1)) {
354 result->push_back(lua_tostring(L, -1));
359 } else if (lua_isstring(L, index)) {
360 result->push_back(lua_tostring(L, index));
371 bool getstringfield(lua_State *L, int table,
372 const char *fieldname, std::string &result)
374 lua_getfield(L, table, fieldname);
376 if(lua_isstring(L, -1)){
378 const char *ptr = lua_tolstring(L, -1, &len);
380 result.assign(ptr, len);
388 bool getintfield(lua_State *L, int table,
389 const char *fieldname, int &result)
391 lua_getfield(L, table, fieldname);
393 if(lua_isnumber(L, -1)){
394 result = lua_tointeger(L, -1);
401 bool getintfield(lua_State *L, int table,
402 const char *fieldname, u8 &result)
404 lua_getfield(L, table, fieldname);
406 if(lua_isnumber(L, -1)){
407 result = lua_tointeger(L, -1);
414 bool getintfield(lua_State *L, int table,
415 const char *fieldname, u16 &result)
417 lua_getfield(L, table, fieldname);
419 if(lua_isnumber(L, -1)){
420 result = lua_tointeger(L, -1);
427 bool getintfield(lua_State *L, int table,
428 const char *fieldname, u32 &result)
430 lua_getfield(L, table, fieldname);
432 if(lua_isnumber(L, -1)){
433 result = lua_tointeger(L, -1);
440 bool getfloatfield(lua_State *L, int table,
441 const char *fieldname, float &result)
443 lua_getfield(L, table, fieldname);
445 if(lua_isnumber(L, -1)){
446 result = lua_tonumber(L, -1);
453 bool getboolfield(lua_State *L, int table,
454 const char *fieldname, bool &result)
456 lua_getfield(L, table, fieldname);
458 if(lua_isboolean(L, -1)){
459 result = lua_toboolean(L, -1);
466 size_t getstringlistfield(lua_State *L, int table, const char *fieldname,
467 std::vector<std::string> *result)
469 lua_getfield(L, table, fieldname);
471 size_t num_strings_read = read_stringlist(L, -1, result);
474 return num_strings_read;
477 std::string checkstringfield(lua_State *L, int table,
478 const char *fieldname)
480 lua_getfield(L, table, fieldname);
481 CHECK_TYPE(-1, std::string("field \"") + fieldname + '"', LUA_TSTRING);
483 const char *s = lua_tolstring(L, -1, &len);
485 return std::string(s, len);
488 std::string getstringfield_default(lua_State *L, int table,
489 const char *fieldname, const std::string &default_)
491 std::string result = default_;
492 getstringfield(L, table, fieldname, result);
496 int getintfield_default(lua_State *L, int table,
497 const char *fieldname, int default_)
499 int result = default_;
500 getintfield(L, table, fieldname, result);
504 float getfloatfield_default(lua_State *L, int table,
505 const char *fieldname, float default_)
507 float result = default_;
508 getfloatfield(L, table, fieldname, result);
512 bool getboolfield_default(lua_State *L, int table,
513 const char *fieldname, bool default_)
515 bool result = default_;
516 getboolfield(L, table, fieldname, result);
520 void setstringfield(lua_State *L, int table,
521 const char *fieldname, const char *value)
523 lua_pushstring(L, value);
526 lua_setfield(L, table, fieldname);
529 void setintfield(lua_State *L, int table,
530 const char *fieldname, int value)
532 lua_pushinteger(L, value);
535 lua_setfield(L, table, fieldname);
538 void setfloatfield(lua_State *L, int table,
539 const char *fieldname, float value)
541 lua_pushnumber(L, value);
544 lua_setfield(L, table, fieldname);
547 void setboolfield(lua_State *L, int table,
548 const char *fieldname, bool value)
550 lua_pushboolean(L, value);
553 lua_setfield(L, table, fieldname);
558 //// Array table slices
561 size_t write_array_slice_float(
569 v3u16 pmin, pmax(data_size);
571 if (slice_offset.X > 0) {
573 pmin.X = slice_offset.X;
574 pmax.X = MYMIN(slice_offset.X + slice_size.X, data_size.X);
577 if (slice_offset.Y > 0) {
579 pmin.Y = slice_offset.Y;
580 pmax.Y = MYMIN(slice_offset.Y + slice_size.Y, data_size.Y);
583 if (slice_offset.Z > 0) {
585 pmin.Z = slice_offset.Z;
586 pmax.Z = MYMIN(slice_offset.Z + slice_size.Z, data_size.Z);
589 const u32 ystride = data_size.X;
590 const u32 zstride = data_size.X * data_size.Y;
593 for (u32 z = pmin.Z; z != pmax.Z; z++)
594 for (u32 y = pmin.Y; y != pmax.Y; y++)
595 for (u32 x = pmin.X; x != pmax.X; x++) {
596 u32 i = z * zstride + y * ystride + x;
597 lua_pushnumber(L, data[i]);
598 lua_rawseti(L, table_index, elem_index);
602 return elem_index - 1;
606 size_t write_array_slice_u16(
614 v3u16 pmin, pmax(data_size);
616 if (slice_offset.X > 0) {
618 pmin.X = slice_offset.X;
619 pmax.X = MYMIN(slice_offset.X + slice_size.X, data_size.X);
622 if (slice_offset.Y > 0) {
624 pmin.Y = slice_offset.Y;
625 pmax.Y = MYMIN(slice_offset.Y + slice_size.Y, data_size.Y);
628 if (slice_offset.Z > 0) {
630 pmin.Z = slice_offset.Z;
631 pmax.Z = MYMIN(slice_offset.Z + slice_size.Z, data_size.Z);
634 const u32 ystride = data_size.X;
635 const u32 zstride = data_size.X * data_size.Y;
638 for (u32 z = pmin.Z; z != pmax.Z; z++)
639 for (u32 y = pmin.Y; y != pmax.Y; y++)
640 for (u32 x = pmin.X; x != pmax.X; x++) {
641 u32 i = z * zstride + y * ystride + x;
642 lua_pushinteger(L, data[i]);
643 lua_rawseti(L, table_index, elem_index);
647 return elem_index - 1;