diff options
Diffstat (limited to 'src/script/common/c_converter.cpp')
-rw-r--r-- | src/script/common/c_converter.cpp | 300 |
1 files changed, 275 insertions, 25 deletions
diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp index 66eeec68e..f1d3cc421 100644 --- a/src/script/common/c_converter.cpp +++ b/src/script/common/c_converter.cpp @@ -23,9 +23,23 @@ extern "C" { } #include "util/numeric.h" +#include "util/string.h" #include "common/c_converter.h" #include "constants.h" + +#define CHECK_TYPE(index, name, type) do { \ + int t = lua_type(L, (index)); \ + if (t != (type)) { \ + throw LuaError(std::string("Invalid ") + (name) + \ + " (expected " + lua_typename(L, (type)) + \ + " got " + lua_typename(L, t) + ")."); \ + } \ + } while(0) +#define CHECK_POS_COORD(name) CHECK_TYPE(-1, "position coordinate '" name "'", LUA_TNUMBER) +#define CHECK_POS_TAB(index) CHECK_TYPE(index, "position", LUA_TTABLE) + + void push_v3f(lua_State *L, v3f p) { lua_newtable(L); @@ -49,7 +63,7 @@ void push_v2f(lua_State *L, v2f p) v2s16 read_v2s16(lua_State *L, int index) { v2s16 p; - luaL_checktype(L, index, LUA_TTABLE); + CHECK_POS_TAB(index); lua_getfield(L, index, "x"); p.X = lua_tonumber(L, -1); lua_pop(L, 1); @@ -59,10 +73,43 @@ v2s16 read_v2s16(lua_State *L, int index) return p; } +v2s16 check_v2s16(lua_State *L, int index) +{ + v2s16 p; + CHECK_POS_TAB(index); + lua_getfield(L, index, "x"); + CHECK_POS_COORD("x"); + p.X = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, index, "y"); + CHECK_POS_COORD("y"); + p.Y = lua_tonumber(L, -1); + lua_pop(L, 1); + return p; +} + +void push_v2s16(lua_State *L, v2s16 p) +{ + lua_newtable(L); + lua_pushnumber(L, p.X); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, p.Y); + lua_setfield(L, -2, "y"); +} + +void push_v2s32(lua_State *L, v2s32 p) +{ + lua_newtable(L); + lua_pushnumber(L, p.X); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, p.Y); + lua_setfield(L, -2, "y"); +} + v2s32 read_v2s32(lua_State *L, int index) { v2s32 p; - luaL_checktype(L, index, LUA_TTABLE); + CHECK_POS_TAB(index); lua_getfield(L, index, "x"); p.X = lua_tonumber(L, -1); lua_pop(L, 1); @@ -75,11 +122,26 @@ v2s32 read_v2s32(lua_State *L, int index) v2f read_v2f(lua_State *L, int index) { v2f p; - luaL_checktype(L, index, LUA_TTABLE); + CHECK_POS_TAB(index); + lua_getfield(L, index, "x"); + p.X = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, index, "y"); + p.Y = lua_tonumber(L, -1); + lua_pop(L, 1); + return p; +} + +v2f check_v2f(lua_State *L, int index) +{ + v2f p; + CHECK_POS_TAB(index); lua_getfield(L, index, "x"); + CHECK_POS_COORD("x"); p.X = lua_tonumber(L, -1); lua_pop(L, 1); lua_getfield(L, index, "y"); + CHECK_POS_COORD("y"); p.Y = lua_tonumber(L, -1); lua_pop(L, 1); return p; @@ -88,7 +150,7 @@ v2f read_v2f(lua_State *L, int index) v3f read_v3f(lua_State *L, int index) { v3f pos; - luaL_checktype(L, index, LUA_TTABLE); + CHECK_POS_TAB(index); lua_getfield(L, index, "x"); pos.X = lua_tonumber(L, -1); lua_pop(L, 1); @@ -104,19 +166,35 @@ v3f read_v3f(lua_State *L, int index) v3f check_v3f(lua_State *L, int index) { v3f pos; - luaL_checktype(L, index, LUA_TTABLE); + CHECK_POS_TAB(index); lua_getfield(L, index, "x"); - pos.X = luaL_checknumber(L, -1); + CHECK_POS_COORD("x"); + pos.X = lua_tonumber(L, -1); lua_pop(L, 1); lua_getfield(L, index, "y"); - pos.Y = luaL_checknumber(L, -1); + CHECK_POS_COORD("y"); + pos.Y = lua_tonumber(L, -1); lua_pop(L, 1); lua_getfield(L, index, "z"); - pos.Z = luaL_checknumber(L, -1); + CHECK_POS_COORD("z"); + pos.Z = lua_tonumber(L, -1); lua_pop(L, 1); return pos; } +void push_ARGB8(lua_State *L, video::SColor color) +{ + lua_newtable(L); + lua_pushnumber(L, color.getAlpha()); + lua_setfield(L, -2, "a"); + lua_pushnumber(L, color.getRed()); + lua_setfield(L, -2, "r"); + lua_pushnumber(L, color.getGreen()); + lua_setfield(L, -2, "g"); + lua_pushnumber(L, color.getBlue()); + lua_setfield(L, -2, "b"); +} + void pushFloatPos(lua_State *L, v3f p) { p /= BS; @@ -153,13 +231,31 @@ v3s16 check_v3s16(lua_State *L, int index) return floatToInt(pf, 1.0); } -video::SColor readARGB8(lua_State *L, int index) +bool read_color(lua_State *L, int index, video::SColor *color) +{ + if (lua_istable(L, index)) { + *color = read_ARGB8(L, index); + } else if (lua_isnumber(L, index)) { + color->set(lua_tonumber(L, index)); + } else if (lua_isstring(L, index)) { + video::SColor parsed_color; + if (!parseColorString(lua_tostring(L, index), parsed_color, true)) + return false; + + *color = parsed_color; + } else { + return false; + } + + return true; +} + +video::SColor read_ARGB8(lua_State *L, int index) { video::SColor color(0); - luaL_checktype(L, index, LUA_TTABLE); + CHECK_TYPE(index, "ARGB color", LUA_TTABLE); lua_getfield(L, index, "a"); - if(lua_isnumber(L, -1)) - color.setAlpha(lua_tonumber(L, -1)); + color.setAlpha(lua_isnumber(L, -1) ? lua_tonumber(L, -1) : 0xFF); lua_pop(L, 1); lua_getfield(L, index, "r"); color.setRed(lua_tonumber(L, -1)); @@ -199,6 +295,23 @@ aabb3f read_aabb3f(lua_State *L, int index, f32 scale) return box; } +void push_aabb3f(lua_State *L, aabb3f box) +{ + lua_newtable(L); + lua_pushnumber(L, box.MinEdge.X); + lua_rawseti(L, -2, 1); + lua_pushnumber(L, box.MinEdge.Y); + lua_rawseti(L, -2, 2); + lua_pushnumber(L, box.MinEdge.Z); + lua_rawseti(L, -2, 3); + lua_pushnumber(L, box.MaxEdge.X); + lua_rawseti(L, -2, 4); + lua_pushnumber(L, box.MaxEdge.Y); + lua_rawseti(L, -2, 5); + lua_pushnumber(L, box.MaxEdge.Z); + lua_rawseti(L, -2, 6); +} + std::vector<aabb3f> read_aabb3f_vector(lua_State *L, int index, f32 scale) { std::vector<aabb3f> boxes; @@ -227,24 +340,28 @@ std::vector<aabb3f> read_aabb3f_vector(lua_State *L, int index, f32 scale) return boxes; } -bool read_stringlist(lua_State *L, int index, std::vector<const char *> &result) +size_t read_stringlist(lua_State *L, int index, std::vector<std::string> *result) { if (index < 0) index = lua_gettop(L) + 1 + index; + size_t num_strings = 0; + if (lua_istable(L, index)) { lua_pushnil(L); while (lua_next(L, index)) { - if (lua_isstring(L, -1)) - result.push_back(lua_tostring(L, -1)); + if (lua_isstring(L, -1)) { + result->push_back(lua_tostring(L, -1)); + num_strings++; + } lua_pop(L, 1); } } else if (lua_isstring(L, index)) { - result.push_back(lua_tostring(L, index)); - } else { - return false; + result->push_back(lua_tostring(L, index)); + num_strings++; } - return true; + + return num_strings; } /* @@ -281,6 +398,45 @@ bool getintfield(lua_State *L, int table, return got; } +bool getintfield(lua_State *L, int table, + const char *fieldname, u8 &result) +{ + lua_getfield(L, table, fieldname); + bool got = false; + if(lua_isnumber(L, -1)){ + result = lua_tonumber(L, -1); + got = true; + } + lua_pop(L, 1); + return got; +} + +bool getintfield(lua_State *L, int table, + const char *fieldname, u16 &result) +{ + lua_getfield(L, table, fieldname); + bool got = false; + if(lua_isnumber(L, -1)){ + result = lua_tonumber(L, -1); + got = true; + } + lua_pop(L, 1); + return got; +} + +bool getintfield(lua_State *L, int table, + const char *fieldname, u32 &result) +{ + lua_getfield(L, table, fieldname); + bool got = false; + if(lua_isnumber(L, -1)){ + result = lua_tonumber(L, -1); + got = true; + } + lua_pop(L, 1); + return got; +} + bool getfloatfield(lua_State *L, int table, const char *fieldname, float &result) { @@ -307,24 +463,26 @@ bool getboolfield(lua_State *L, int table, return got; } -bool getstringlistfield(lua_State *L, int table, const char *fieldname, - std::vector<const char *> &result) +size_t getstringlistfield(lua_State *L, int table, const char *fieldname, + std::vector<std::string> *result) { lua_getfield(L, table, fieldname); - bool got = read_stringlist(L, -1, result); + size_t num_strings_read = read_stringlist(L, -1, result); lua_pop(L, 1); - return got; + return num_strings_read; } std::string checkstringfield(lua_State *L, int table, const char *fieldname) { lua_getfield(L, table, fieldname); - std::string s = luaL_checkstring(L, -1); + CHECK_TYPE(-1, std::string("field \"") + fieldname + '"', LUA_TSTRING); + size_t len; + const char *s = lua_tolstring(L, -1, &len); lua_pop(L, 1); - return s; + return std::string(s, len); } std::string getstringfield_default(lua_State *L, int table, @@ -387,3 +545,95 @@ void setboolfield(lua_State *L, int table, } +//// +//// Array table slices +//// + +size_t write_array_slice_float( + lua_State *L, + int table_index, + float *data, + v3u16 data_size, + v3u16 slice_offset, + v3u16 slice_size) +{ + v3u16 pmin, pmax(data_size); + + if (slice_offset.X > 0) { + slice_offset.X--; + pmin.X = slice_offset.X; + pmax.X = MYMIN(slice_offset.X + slice_size.X, data_size.X); + } + + if (slice_offset.Y > 0) { + slice_offset.Y--; + pmin.Y = slice_offset.Y; + pmax.Y = MYMIN(slice_offset.Y + slice_size.Y, data_size.Y); + } + + if (slice_offset.Z > 0) { + slice_offset.Z--; + pmin.Z = slice_offset.Z; + pmax.Z = MYMIN(slice_offset.Z + slice_size.Z, data_size.Z); + } + + const u32 ystride = data_size.X; + const u32 zstride = data_size.X * data_size.Y; + + u32 elem_index = 1; + for (u32 z = pmin.Z; z != pmax.Z; z++) + for (u32 y = pmin.Y; y != pmax.Y; y++) + for (u32 x = pmin.X; x != pmax.X; x++) { + u32 i = z * zstride + y * ystride + x; + lua_pushnumber(L, data[i]); + lua_rawseti(L, table_index, elem_index); + elem_index++; + } + + return elem_index - 1; +} + + +size_t write_array_slice_u16( + lua_State *L, + int table_index, + u16 *data, + v3u16 data_size, + v3u16 slice_offset, + v3u16 slice_size) +{ + v3u16 pmin, pmax(data_size); + + if (slice_offset.X > 0) { + slice_offset.X--; + pmin.X = slice_offset.X; + pmax.X = MYMIN(slice_offset.X + slice_size.X, data_size.X); + } + + if (slice_offset.Y > 0) { + slice_offset.Y--; + pmin.Y = slice_offset.Y; + pmax.Y = MYMIN(slice_offset.Y + slice_size.Y, data_size.Y); + } + + if (slice_offset.Z > 0) { + slice_offset.Z--; + pmin.Z = slice_offset.Z; + pmax.Z = MYMIN(slice_offset.Z + slice_size.Z, data_size.Z); + } + + const u32 ystride = data_size.X; + const u32 zstride = data_size.X * data_size.Y; + + u32 elem_index = 1; + for (u32 z = pmin.Z; z != pmax.Z; z++) + for (u32 y = pmin.Y; y != pmax.Y; y++) + for (u32 x = pmin.X; x != pmax.X; x++) { + u32 i = z * zstride + y * ystride + x; + lua_pushinteger(L, data[i]); + lua_rawseti(L, table_index, elem_index); + elem_index++; + } + + return elem_index - 1; +} |