summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LUA_API.rst5
-rw-r--r--Lua API.html4
-rw-r--r--library/LuaApi.cpp40
-rw-r--r--library/include/modules/Screen.h6
-rw-r--r--library/modules/Screen.cpp39
5 files changed, 92 insertions, 2 deletions
diff --git a/LUA_API.rst b/LUA_API.rst
index d13c1e52..4d9170d6 100644
--- a/LUA_API.rst
+++ b/LUA_API.rst
@@ -1308,6 +1308,11 @@ Basic painting functions:
Returns *false* if coordinates out of bounds, or other error.
+* ``dfhack.screen.readTile(x,y)``
+
+ Retrieves the contents of the specified tile from the screen buffers.
+ Returns a pen, or *nil* if invalid or TrueType.
+
* ``dfhack.screen.paintString(pen,x,y,text)``
Paints the string starting at *x,y*. Uses the string characters
diff --git a/Lua API.html b/Lua API.html
index 546d2740..dc9c8d73 100644
--- a/Lua API.html
+++ b/Lua API.html
@@ -1480,6 +1480,10 @@ Otherwise should be <em>true/false</em>.</p>
</dl>
<p>Returns <em>false</em> if coordinates out of bounds, or other error.</p>
</li>
+<li><p class="first"><tt class="docutils literal">dfhack.screen.readTile(x,y)</tt></p>
+<p>Retrieves the contents of the specified tile from the screen buffers.
+Returns a pen, or <em>nil</em> if invalid or TrueType.</p>
+</li>
<li><p class="first"><tt class="docutils literal">dfhack.screen.paintString(pen,x,y,text)</tt></p>
<p>Paints the string starting at <em>x,y</em>. Uses the string characters
in sequence to override the <tt class="docutils literal">ch</tt> field of pen.</p>
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;