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_v3f(lua_State *L, v3f p)
45 lua_pushnumber(L, p.X);
46 lua_setfield(L, -2, "x");
47 lua_pushnumber(L, p.Y);
48 lua_setfield(L, -2, "y");
49 lua_pushnumber(L, p.Z);
50 lua_setfield(L, -2, "z");
53 void push_v2f(lua_State *L, v2f p)
56 lua_pushnumber(L, p.X);
57 lua_setfield(L, -2, "x");
58 lua_pushnumber(L, p.Y);
59 lua_setfield(L, -2, "y");
62 v2s16 read_v2s16(lua_State *L, int index)
66 lua_getfield(L, index, "x");
67 p.X = lua_tonumber(L, -1);
69 lua_getfield(L, index, "y");
70 p.Y = lua_tonumber(L, -1);
75 v2s16 check_v2s16(lua_State *L, int index)
79 lua_getfield(L, index, "x");
81 p.X = lua_tonumber(L, -1);
83 lua_getfield(L, index, "y");
85 p.Y = lua_tonumber(L, -1);
90 v2s32 read_v2s32(lua_State *L, int index)
94 lua_getfield(L, index, "x");
95 p.X = lua_tonumber(L, -1);
97 lua_getfield(L, index, "y");
98 p.Y = lua_tonumber(L, -1);
103 v2f read_v2f(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 check_v2f(lua_State *L, int index)
119 CHECK_POS_TAB(index);
120 lua_getfield(L, index, "x");
121 CHECK_POS_COORD("x");
122 p.X = lua_tonumber(L, -1);
124 lua_getfield(L, index, "y");
125 CHECK_POS_COORD("y");
126 p.Y = lua_tonumber(L, -1);
131 v3f read_v3f(lua_State *L, int index)
134 CHECK_POS_TAB(index);
135 lua_getfield(L, index, "x");
136 pos.X = lua_tonumber(L, -1);
138 lua_getfield(L, index, "y");
139 pos.Y = lua_tonumber(L, -1);
141 lua_getfield(L, index, "z");
142 pos.Z = lua_tonumber(L, -1);
147 v3f check_v3f(lua_State *L, int index)
150 CHECK_POS_TAB(index);
151 lua_getfield(L, index, "x");
152 CHECK_POS_COORD("x");
153 pos.X = lua_tonumber(L, -1);
155 lua_getfield(L, index, "y");
156 CHECK_POS_COORD("y");
157 pos.Z = lua_tonumber(L, -1);
159 lua_getfield(L, index, "z");
160 CHECK_POS_COORD("z");
161 pos.Z = lua_tonumber(L, -1);
166 void pushFloatPos(lua_State *L, v3f p)
172 v3f checkFloatPos(lua_State *L, int index)
174 return check_v3f(L, index) * BS;
177 void push_v3s16(lua_State *L, v3s16 p)
180 lua_pushnumber(L, p.X);
181 lua_setfield(L, -2, "x");
182 lua_pushnumber(L, p.Y);
183 lua_setfield(L, -2, "y");
184 lua_pushnumber(L, p.Z);
185 lua_setfield(L, -2, "z");
188 v3s16 read_v3s16(lua_State *L, int index)
190 // Correct rounding at <0
191 v3f pf = read_v3f(L, index);
192 return floatToInt(pf, 1.0);
195 v3s16 check_v3s16(lua_State *L, int index)
197 // Correct rounding at <0
198 v3f pf = check_v3f(L, index);
199 return floatToInt(pf, 1.0);
202 video::SColor readARGB8(lua_State *L, int index)
204 video::SColor color(0);
205 CHECK_TYPE(index, "ARGB color", LUA_TTABLE);
206 lua_getfield(L, index, "a");
207 if(lua_isnumber(L, -1))
208 color.setAlpha(lua_tonumber(L, -1));
210 lua_getfield(L, index, "r");
211 color.setRed(lua_tonumber(L, -1));
213 lua_getfield(L, index, "g");
214 color.setGreen(lua_tonumber(L, -1));
216 lua_getfield(L, index, "b");
217 color.setBlue(lua_tonumber(L, -1));
222 aabb3f read_aabb3f(lua_State *L, int index, f32 scale)
225 if(lua_istable(L, index)){
226 lua_rawgeti(L, index, 1);
227 box.MinEdge.X = lua_tonumber(L, -1) * scale;
229 lua_rawgeti(L, index, 2);
230 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
232 lua_rawgeti(L, index, 3);
233 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
235 lua_rawgeti(L, index, 4);
236 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
238 lua_rawgeti(L, index, 5);
239 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
241 lua_rawgeti(L, index, 6);
242 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
248 std::vector<aabb3f> read_aabb3f_vector(lua_State *L, int index, f32 scale)
250 std::vector<aabb3f> boxes;
251 if(lua_istable(L, index)){
252 int n = lua_objlen(L, index);
253 // Check if it's a single box or a list of boxes
254 bool possibly_single_box = (n == 6);
255 for(int i = 1; i <= n && possibly_single_box; i++){
256 lua_rawgeti(L, index, i);
257 if(!lua_isnumber(L, -1))
258 possibly_single_box = false;
261 if(possibly_single_box){
263 boxes.push_back(read_aabb3f(L, index, scale));
265 // Read a list of boxes
266 for(int i = 1; i <= n; i++){
267 lua_rawgeti(L, index, i);
268 boxes.push_back(read_aabb3f(L, -1, scale));
276 size_t read_stringlist(lua_State *L, int index, std::vector<std::string> *result)
279 index = lua_gettop(L) + 1 + index;
281 size_t num_strings = 0;
283 if (lua_istable(L, index)) {
285 while (lua_next(L, index)) {
286 if (lua_isstring(L, -1)) {
287 result->push_back(lua_tostring(L, -1));
292 } else if (lua_isstring(L, index)) {
293 result->push_back(lua_tostring(L, index));
304 bool getstringfield(lua_State *L, int table,
305 const char *fieldname, std::string &result)
307 lua_getfield(L, table, fieldname);
309 if(lua_isstring(L, -1)){
311 const char *ptr = lua_tolstring(L, -1, &len);
313 result.assign(ptr, len);
321 bool getintfield(lua_State *L, int table,
322 const char *fieldname, int &result)
324 lua_getfield(L, table, fieldname);
326 if(lua_isnumber(L, -1)){
327 result = lua_tonumber(L, -1);
334 bool getintfield(lua_State *L, int table,
335 const char *fieldname, u16 &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, u32 &result)
350 lua_getfield(L, table, fieldname);
352 if(lua_isnumber(L, -1)){
353 result = lua_tonumber(L, -1);
360 bool getfloatfield(lua_State *L, int table,
361 const char *fieldname, float &result)
363 lua_getfield(L, table, fieldname);
365 if(lua_isnumber(L, -1)){
366 result = lua_tonumber(L, -1);
373 bool getboolfield(lua_State *L, int table,
374 const char *fieldname, bool &result)
376 lua_getfield(L, table, fieldname);
378 if(lua_isboolean(L, -1)){
379 result = lua_toboolean(L, -1);
386 size_t getstringlistfield(lua_State *L, int table, const char *fieldname,
387 std::vector<std::string> *result)
389 lua_getfield(L, table, fieldname);
391 size_t num_strings_read = read_stringlist(L, -1, result);
394 return num_strings_read;
397 std::string checkstringfield(lua_State *L, int table,
398 const char *fieldname)
400 lua_getfield(L, table, fieldname);
401 CHECK_TYPE(-1, std::string("field \"") + fieldname + '"', LUA_TSTRING);
403 const char *s = lua_tolstring(L, -1, &len);
405 return std::string(s, len);
408 std::string getstringfield_default(lua_State *L, int table,
409 const char *fieldname, const std::string &default_)
411 std::string result = default_;
412 getstringfield(L, table, fieldname, result);
416 int getintfield_default(lua_State *L, int table,
417 const char *fieldname, int default_)
419 int result = default_;
420 getintfield(L, table, fieldname, result);
424 float getfloatfield_default(lua_State *L, int table,
425 const char *fieldname, float default_)
427 float result = default_;
428 getfloatfield(L, table, fieldname, result);
432 bool getboolfield_default(lua_State *L, int table,
433 const char *fieldname, bool default_)
435 bool result = default_;
436 getboolfield(L, table, fieldname, result);
440 void setintfield(lua_State *L, int table,
441 const char *fieldname, int value)
443 lua_pushinteger(L, value);
446 lua_setfield(L, table, fieldname);
449 void setfloatfield(lua_State *L, int table,
450 const char *fieldname, float value)
452 lua_pushnumber(L, value);
455 lua_setfield(L, table, fieldname);
458 void setboolfield(lua_State *L, int table,
459 const char *fieldname, bool value)
461 lua_pushboolean(L, value);
464 lua_setfield(L, table, fieldname);