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 "common/c_converter.h"
27 #include "constants.h"
30 #define CHECK_TYPE(index, name, type) do { \
31 int t = lua_type(L, (index)); \
33 throw LuaError(std::string("Invalid ") + (name) + \
34 " (expected " + lua_typename(L, (type)) + \
35 " got " + lua_typename(L, t) + ")."); \
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)
42 void push_ARGB8(lua_State *L, video::SColor color)
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");
55 void push_v3f(lua_State *L, v3f p)
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");
66 void push_v2f(lua_State *L, v2f p)
69 lua_pushnumber(L, p.X);
70 lua_setfield(L, -2, "x");
71 lua_pushnumber(L, p.Y);
72 lua_setfield(L, -2, "y");
75 v2s16 read_v2s16(lua_State *L, int index)
79 lua_getfield(L, index, "x");
80 p.X = lua_tonumber(L, -1);
82 lua_getfield(L, index, "y");
83 p.Y = lua_tonumber(L, -1);
88 v2s16 check_v2s16(lua_State *L, int index)
92 lua_getfield(L, index, "x");
94 p.X = lua_tonumber(L, -1);
96 lua_getfield(L, index, "y");
98 p.Y = lua_tonumber(L, -1);
103 v2s32 read_v2s32(lua_State *L, int index)
106 CHECK_POS_TAB(index);
107 lua_getfield(L, index, "x");
108 p.X = lua_tonumber(L, -1);
110 lua_getfield(L, index, "y");
111 p.Y = lua_tonumber(L, -1);
116 v2f read_v2f(lua_State *L, int index)
119 CHECK_POS_TAB(index);
120 lua_getfield(L, index, "x");
121 p.X = lua_tonumber(L, -1);
123 lua_getfield(L, index, "y");
124 p.Y = lua_tonumber(L, -1);
129 v2f check_v2f(lua_State *L, int index)
132 CHECK_POS_TAB(index);
133 lua_getfield(L, index, "x");
134 CHECK_POS_COORD("x");
135 p.X = lua_tonumber(L, -1);
137 lua_getfield(L, index, "y");
138 CHECK_POS_COORD("y");
139 p.Y = lua_tonumber(L, -1);
144 v3f read_v3f(lua_State *L, int index)
147 CHECK_POS_TAB(index);
148 lua_getfield(L, index, "x");
149 pos.X = lua_tonumber(L, -1);
151 lua_getfield(L, index, "y");
152 pos.Y = lua_tonumber(L, -1);
154 lua_getfield(L, index, "z");
155 pos.Z = lua_tonumber(L, -1);
160 v3f check_v3f(lua_State *L, int index)
163 CHECK_POS_TAB(index);
164 lua_getfield(L, index, "x");
165 CHECK_POS_COORD("x");
166 pos.X = lua_tonumber(L, -1);
168 lua_getfield(L, index, "y");
169 CHECK_POS_COORD("y");
170 pos.Y = lua_tonumber(L, -1);
172 lua_getfield(L, index, "z");
173 CHECK_POS_COORD("z");
174 pos.Z = lua_tonumber(L, -1);
179 void pushFloatPos(lua_State *L, v3f p)
185 v3f checkFloatPos(lua_State *L, int index)
187 return check_v3f(L, index) * BS;
190 void push_v3s16(lua_State *L, v3s16 p)
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");
201 v3s16 read_v3s16(lua_State *L, int index)
203 // Correct rounding at <0
204 v3f pf = read_v3f(L, index);
205 return floatToInt(pf, 1.0);
208 v3s16 check_v3s16(lua_State *L, int index)
210 // Correct rounding at <0
211 v3f pf = check_v3f(L, index);
212 return floatToInt(pf, 1.0);
215 video::SColor readARGB8(lua_State *L, int index)
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));
223 lua_getfield(L, index, "r");
224 color.setRed(lua_tonumber(L, -1));
226 lua_getfield(L, index, "g");
227 color.setGreen(lua_tonumber(L, -1));
229 lua_getfield(L, index, "b");
230 color.setBlue(lua_tonumber(L, -1));
235 aabb3f read_aabb3f(lua_State *L, int index, f32 scale)
238 if(lua_istable(L, index)){
239 lua_rawgeti(L, index, 1);
240 box.MinEdge.X = lua_tonumber(L, -1) * scale;
242 lua_rawgeti(L, index, 2);
243 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
245 lua_rawgeti(L, index, 3);
246 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
248 lua_rawgeti(L, index, 4);
249 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
251 lua_rawgeti(L, index, 5);
252 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
254 lua_rawgeti(L, index, 6);
255 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
261 std::vector<aabb3f> read_aabb3f_vector(lua_State *L, int index, f32 scale)
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;
274 if(possibly_single_box){
276 boxes.push_back(read_aabb3f(L, index, scale));
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));
289 size_t read_stringlist(lua_State *L, int index, std::vector<std::string> *result)
292 index = lua_gettop(L) + 1 + index;
294 size_t num_strings = 0;
296 if (lua_istable(L, index)) {
298 while (lua_next(L, index)) {
299 if (lua_isstring(L, -1)) {
300 result->push_back(lua_tostring(L, -1));
305 } else if (lua_isstring(L, index)) {
306 result->push_back(lua_tostring(L, index));
317 bool getstringfield(lua_State *L, int table,
318 const char *fieldname, std::string &result)
320 lua_getfield(L, table, fieldname);
322 if(lua_isstring(L, -1)){
324 const char *ptr = lua_tolstring(L, -1, &len);
326 result.assign(ptr, len);
334 bool getintfield(lua_State *L, int table,
335 const char *fieldname, int &result)
337 lua_getfield(L, table, fieldname);
339 if(lua_isnumber(L, -1)){
340 result = lua_tonumber(L, -1);
347 bool getintfield(lua_State *L, int table,
348 const char *fieldname, u8 &result)
350 lua_getfield(L, table, fieldname);
352 if(lua_isnumber(L, -1)){
353 result = lua_tonumber(L, -1);
360 bool getintfield(lua_State *L, int table,
361 const char *fieldname, u16 &result)
363 lua_getfield(L, table, fieldname);
365 if(lua_isnumber(L, -1)){
366 result = lua_tonumber(L, -1);
373 bool getintfield(lua_State *L, int table,
374 const char *fieldname, u32 &result)
376 lua_getfield(L, table, fieldname);
378 if(lua_isnumber(L, -1)){
379 result = lua_tonumber(L, -1);
386 bool getfloatfield(lua_State *L, int table,
387 const char *fieldname, float &result)
389 lua_getfield(L, table, fieldname);
391 if(lua_isnumber(L, -1)){
392 result = lua_tonumber(L, -1);
399 bool getboolfield(lua_State *L, int table,
400 const char *fieldname, bool &result)
402 lua_getfield(L, table, fieldname);
404 if(lua_isboolean(L, -1)){
405 result = lua_toboolean(L, -1);
412 size_t getstringlistfield(lua_State *L, int table, const char *fieldname,
413 std::vector<std::string> *result)
415 lua_getfield(L, table, fieldname);
417 size_t num_strings_read = read_stringlist(L, -1, result);
420 return num_strings_read;
423 std::string checkstringfield(lua_State *L, int table,
424 const char *fieldname)
426 lua_getfield(L, table, fieldname);
427 CHECK_TYPE(-1, std::string("field \"") + fieldname + '"', LUA_TSTRING);
429 const char *s = lua_tolstring(L, -1, &len);
431 return std::string(s, len);
434 std::string getstringfield_default(lua_State *L, int table,
435 const char *fieldname, const std::string &default_)
437 std::string result = default_;
438 getstringfield(L, table, fieldname, result);
442 int getintfield_default(lua_State *L, int table,
443 const char *fieldname, int default_)
445 int result = default_;
446 getintfield(L, table, fieldname, result);
450 float getfloatfield_default(lua_State *L, int table,
451 const char *fieldname, float default_)
453 float result = default_;
454 getfloatfield(L, table, fieldname, result);
458 bool getboolfield_default(lua_State *L, int table,
459 const char *fieldname, bool default_)
461 bool result = default_;
462 getboolfield(L, table, fieldname, result);
466 void setintfield(lua_State *L, int table,
467 const char *fieldname, int value)
469 lua_pushinteger(L, value);
472 lua_setfield(L, table, fieldname);
475 void setfloatfield(lua_State *L, int table,
476 const char *fieldname, float value)
478 lua_pushnumber(L, value);
481 lua_setfield(L, table, fieldname);
484 void setboolfield(lua_State *L, int table,
485 const char *fieldname, bool value)
487 lua_pushboolean(L, value);
490 lua_setfield(L, table, fieldname);