diff options
| author | Alexander Gavrilov | 2012-08-19 14:27:44 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-08-19 14:27:44 +0400 |
| commit | 30f71ff5106d271d04bfa26b976441cfa9b2abf6 (patch) | |
| tree | ced0b058f615b90a75c495be1f4db6045100b972 /library/LuaApi.cpp | |
| parent | b8ee52131bccd174f06c9124980bbcb8df7c80e4 (diff) | |
| download | dfhack-30f71ff5106d271d04bfa26b976441cfa9b2abf6.tar.gz dfhack-30f71ff5106d271d04bfa26b976441cfa9b2abf6.tar.bz2 dfhack-30f71ff5106d271d04bfa26b976441cfa9b2abf6.tar.xz | |
Implement support for lua-backed viewscreens.
Diffstat (limited to 'library/LuaApi.cpp')
| -rw-r--r-- | library/LuaApi.cpp | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 108dba88..d296a2e5 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -39,6 +39,7 @@ distribution. #include "modules/World.h" #include "modules/Gui.h" +#include "modules/Screen.h" #include "modules/Job.h" #include "modules/Translation.h" #include "modules/Units.h" @@ -84,6 +85,8 @@ distribution. using namespace DFHack; using namespace DFHack::LuaWrapper; +using Screen::Pen; + void dfhack_printerr(lua_State *S, const std::string &str); void Lua::Push(lua_State *state, const Units::NoblePosition &pos) @@ -179,6 +182,48 @@ static df::coord CheckCoordXYZ(lua_State *state, int base, bool vararg = false) return p; } +template<class T> +static bool get_int_field(lua_State *L, T *pf, int idx, const char *name, int defval) +{ + lua_getfield(L, idx, name); + bool nil = lua_isnil(L, -1); + if (nil) *pf = T(defval); + else if (lua_isnumber(L, -1)) *pf = T(lua_tointeger(L, -1)); + else luaL_error(L, "Field %s is not a number.", name); + lua_pop(L, 1); + return !nil; +} + +static void decode_pen(lua_State *L, Pen &pen, int idx) +{ + get_int_field(L, &pen.ch, idx, "ch", 0); + get_int_field(L, &pen.fg, idx, "fg", 7); + get_int_field(L, &pen.bg, idx, "bg", 0); + + lua_getfield(L, idx, "bold"); + if (lua_isnil(L, -1)) + { + pen.bold = (pen.fg & 8) != 0; + pen.fg &= 7; + } + else pen.bold = lua_toboolean(L, -1); + lua_pop(L, 1); + + get_int_field(L, &pen.tile, idx, "tile", 0); + + bool tcolor = get_int_field(L, &pen.tile_fg, idx, "tile_fg", 7); + tcolor = get_int_field(L, &pen.tile_bg, idx, "tile_bg", 0) || tcolor; + + if (tcolor) + pen.tile_mode = Pen::TileColor; + else + { + lua_getfield(L, idx, "tile_color"); + pen.tile_mode = (lua_toboolean(L, -1) ? Pen::CharColor : Pen::AsIs); + lua_pop(L, 1); + } +} + /************************************************** * Per-world persistent configuration storage API * **************************************************/ @@ -1019,6 +1064,108 @@ static const luaL_Reg dfhack_constructions_funcs[] = { { NULL, NULL } }; +/***** Screen module *****/ + +static const LuaWrapper::FunctionReg dfhack_screen_module[] = { + WRAPM(Screen, clear), + WRAPM(Screen, invalidate), + { NULL, NULL } +}; + +static int screen_getMousePos(lua_State *L) +{ + auto pos = Screen::getMousePos(); + lua_pushinteger(L, pos.x); + lua_pushinteger(L, pos.y); + return 2; +} + +static int screen_getWindowSize(lua_State *L) +{ + auto pos = Screen::getWindowSize(); + lua_pushinteger(L, pos.x); + lua_pushinteger(L, pos.y); + return 2; +} + +static int screen_paintTile(lua_State *L) +{ + Pen pen; + decode_pen(L, pen, 1); + int x = luaL_checkint(L, 2); + int y = luaL_checkint(L, 3); + if (lua_gettop(L) >= 4 && !lua_isnil(L, 4)) + pen.ch = luaL_checkint(L, 4); + if (lua_gettop(L) >= 5 && !lua_isnil(L, 5)) + pen.tile = luaL_checkint(L, 5); + lua_pushboolean(L, Screen::paintTile(pen, x, y)); + return 1; +} + +static int screen_paintString(lua_State *L) +{ + Pen pen; + decode_pen(L, pen, 1); + int x = luaL_checkint(L, 2); + int y = luaL_checkint(L, 3); + const char *text = luaL_checkstring(L, 4); + lua_pushboolean(L, Screen::paintString(pen, x, y, text)); + return 1; +} + +static int screen_fillRect(lua_State *L) +{ + Pen pen; + decode_pen(L, pen, 1); + int x1 = luaL_checkint(L, 2); + int y1 = luaL_checkint(L, 3); + int x2 = luaL_checkint(L, 4); + int y2 = luaL_checkint(L, 5); + lua_pushboolean(L, Screen::fillRect(pen, x1, y1, x2, y2)); + return 1; +} + +namespace { + +int screen_show(lua_State *L) +{ + df::viewscreen *before = NULL; + if (lua_gettop(L) >= 2) + before = Lua::CheckDFObject<df::viewscreen>(L, 2); + + df::viewscreen *screen = dfhack_lua_viewscreen::get_pointer(L, 1, true); + lua_pushboolean(L, Screen::show(screen, before)); + return 1; +} + +static int screen_dismiss(lua_State *L) +{ + df::viewscreen *screen = dfhack_lua_viewscreen::get_pointer(L, 1, false); + Screen::dismiss(screen); + return 0; +} + +static int screen_isDismissed(lua_State *L) +{ + df::viewscreen *screen = dfhack_lua_viewscreen::get_pointer(L, 1, false); + lua_pushboolean(L, Screen::isDismissed(screen)); + return 1; +} + +} + +static const luaL_Reg dfhack_screen_funcs[] = { + { "getMousePos", screen_getMousePos }, + { "getWindowSize", screen_getWindowSize }, + { "paintTile", screen_paintTile }, + { "paintString", screen_paintString }, + { "fillRect", screen_fillRect }, + { "show", &Lua::CallWithCatchWrapper<screen_show> }, + { "dismiss", screen_dismiss }, + { "isDismissed", screen_isDismissed }, + { NULL, NULL } +}; + /***** Internal module *****/ static void *checkaddr(lua_State *L, int idx, bool allow_null = false) @@ -1252,5 +1399,6 @@ void OpenDFHackApi(lua_State *state) OpenModule(state, "burrows", dfhack_burrows_module, dfhack_burrows_funcs); OpenModule(state, "buildings", dfhack_buildings_module, dfhack_buildings_funcs); OpenModule(state, "constructions", dfhack_constructions_module); + OpenModule(state, "screen", dfhack_screen_module, dfhack_screen_funcs); OpenModule(state, "internal", dfhack_internal_module, dfhack_internal_funcs); } |
