summaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-09-07 11:36:45 +0400
committerAlexander Gavrilov2012-09-07 11:36:45 +0400
commite925d8f4d999817d3ccf7f3180e7abee382e03b4 (patch)
tree5a48c08b6c8a45aa3cf85e7d4b05e79cc2d4e028 /library
parentc971a819def1c5cc29dc926f62456c336a1dfa17 (diff)
downloaddfhack-e925d8f4d999817d3ccf7f3180e7abee382e03b4.tar.gz
dfhack-e925d8f4d999817d3ccf7f3180e7abee382e03b4.tar.bz2
dfhack-e925d8f4d999817d3ccf7f3180e7abee382e03b4.tar.xz
Add an API function for reading tiles from the screen buffers.
Diffstat (limited to 'library')
-rw-r--r--library/LuaApi.cpp40
-rw-r--r--library/include/modules/Screen.h6
-rw-r--r--library/modules/Screen.cpp39
3 files changed, 83 insertions, 2 deletions
diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp
index 63838d35..807cbf53 100644
--- a/library/LuaApi.cpp
+++ b/library/LuaApi.cpp
@@ -1154,6 +1154,45 @@ static int screen_paintTile(lua_State *L)
return 1;
}
+static int screen_readTile(lua_State *L)
+{
+ int x = luaL_checkint(L, 1);
+ int y = luaL_checkint(L, 2);
+ Pen pen = Screen::readTile(x, y);
+
+ if (!pen.valid())
+ {
+ lua_pushnil(L);
+ }
+ else
+ {
+ lua_newtable(L);
+ lua_pushinteger(L, pen.ch); lua_setfield(L, -2, "ch");
+ lua_pushinteger(L, pen.fg); lua_setfield(L, -2, "fg");
+ lua_pushinteger(L, pen.bg); lua_setfield(L, -2, "bg");
+ lua_pushboolean(L, pen.bold); lua_setfield(L, -2, "bold");
+
+ if (pen.tile)
+ {
+ lua_pushinteger(L, pen.tile); lua_setfield(L, -2, "tile");
+
+ switch (pen.tile_mode) {
+ case Pen::CharColor:
+ lua_pushboolean(L, true); lua_setfield(L, -2, "tile_color");
+ break;
+ case Pen::TileColor:
+ lua_pushinteger(L, pen.tile_fg); lua_setfield(L, -2, "tile_fg");
+ lua_pushinteger(L, pen.tile_bg); lua_setfield(L, -2, "tile_bg");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return 1;
+}
+
static int screen_paintString(lua_State *L)
{
Pen pen;
@@ -1258,6 +1297,7 @@ static const luaL_Reg dfhack_screen_funcs[] = {
{ "getMousePos", screen_getMousePos },
{ "getWindowSize", screen_getWindowSize },
{ "paintTile", screen_paintTile },
+ { "readTile", screen_readTile },
{ "paintString", screen_paintString },
{ "fillRect", screen_fillRect },
{ "findGraphicsTile", screen_findGraphicsTile },
diff --git a/library/include/modules/Screen.h b/library/include/modules/Screen.h
index 492e1eec..4f47205f 100644
--- a/library/include/modules/Screen.h
+++ b/library/include/modules/Screen.h
@@ -65,6 +65,9 @@ namespace DFHack
} tile_mode;
int8_t tile_fg, tile_bg;
+ bool valid() const { return tile >= 0; }
+ bool empty() const { return ch == 0 && tile == 0; }
+
Pen(char ch = 0, int8_t fg = 7, int8_t bg = 0, int tile = 0, bool color_tile = false)
: ch(ch), fg(fg&7), bg(bg), bold(!!(fg&8)),
tile(tile), tile_mode(color_tile ? CharColor : AsIs), tile_fg(0), tile_bg(0)
@@ -92,6 +95,9 @@ namespace DFHack
/// Paint one screen tile with the given pen
DFHACK_EXPORT bool paintTile(const Pen &pen, int x, int y);
+ /// Retrieves one screen tile from the buffer
+ DFHACK_EXPORT Pen readTile(int x, int y);
+
/// Paint a string onto the screen. Ignores ch and tile of pen.
DFHACK_EXPORT bool paintString(const Pen &pen, int x, int y, const std::string &text);
diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp
index c2377f2c..9f258fe0 100644
--- a/library/modules/Screen.cpp
+++ b/library/modules/Screen.cpp
@@ -100,7 +100,7 @@ static void doSetTile(const Pen &pen, int index)
bool Screen::paintTile(const Pen &pen, int x, int y)
{
- if (!gps) return false;
+ if (!gps || !pen.valid()) return false;
int dimx = gps->dimx, dimy = gps->dimy;
if (x < 0 || x >= dimx || y < 0 || y >= dimy) return false;
@@ -109,6 +109,41 @@ bool Screen::paintTile(const Pen &pen, int x, int y)
return true;
}
+Pen Screen::readTile(int x, int y)
+{
+ if (!gps) return Pen(0,0,0,-1);
+
+ int dimx = gps->dimx, dimy = gps->dimy;
+ if (x < 0 || x >= dimx || y < 0 || y >= dimy)
+ return Pen(0,0,0,-1);
+
+ int index = x*dimy + y;
+ auto screen = gps->screen + index*4;
+ if (screen[3] & 0x80)
+ return Pen(0,0,0,-1);
+
+ Pen pen(
+ screen[0], screen[1], screen[2], screen[3]?true:false,
+ gps->screentexpos[index]
+ );
+
+ if (pen.tile)
+ {
+ if (gps->screentexpos_grayscale[index])
+ {
+ pen.tile_mode = Screen::Pen::TileColor;
+ pen.tile_fg = gps->screentexpos_cf[index];
+ pen.tile_bg = gps->screentexpos_cbr[index];
+ }
+ else if (gps->screentexpos_addcolor[index])
+ {
+ pen.tile_mode = Screen::Pen::CharColor;
+ }
+ }
+
+ return pen;
+}
+
bool Screen::paintString(const Pen &pen, int x, int y, const std::string &text)
{
if (!gps || y < 0 || y >= gps->dimy) return false;
@@ -132,7 +167,7 @@ bool Screen::paintString(const Pen &pen, int x, int y, const std::string &text)
bool Screen::fillRect(const Pen &pen, int x1, int y1, int x2, int y2)
{
- if (!gps) return false;
+ if (!gps || !pen.valid()) return false;
if (x1 < 0) x1 = 0;
if (y1 < 0) y1 = 0;