Implement a PenArray class for caching parts of rendered screens

develop
lethosor 2015-03-27 22:56:20 -04:00
parent ac2f537bf4
commit 99f4ea4d2b
5 changed files with 156 additions and 0 deletions

@ -1041,6 +1041,88 @@ static void OpenPen(lua_State *state)
lua_pop(state, 1);
}
/******************
* PenArray object *
******************/
static int DFHACK_PENARRAY_TOKEN = 0;
using Screen::PenArray;
static PenArray *check_penarray_native(lua_State *L, int index)
{
lua_rawgetp(L, LUA_REGISTRYINDEX, &DFHACK_PENARRAY_TOKEN);
if (!lua_getmetatable(L, index) || !lua_rawequal(L, -1, -2))
luaL_argerror(L, index, "not a penarray object");
lua_pop(L, 2);
return (PenArray*)lua_touserdata(L, index);
}
static int dfhack_penarray_new(lua_State *L)
{
int bufwidth = luaL_checkint(L, 1);
int bufheight = luaL_checkint(L, 2);
new (L) PenArray(bufwidth, bufheight);
lua_rawgetp(L, LUA_REGISTRYINDEX, &DFHACK_PENARRAY_TOKEN);
lua_setmetatable(L, -2);
return 1;
}
static int dfhack_penarray_clear(lua_State *L)
{
PenArray *parr = check_penarray_native(L, 1);
parr->clear();
return 0;
}
static int dfhack_penarray_set_tile(lua_State *L)
{
PenArray *parr = check_penarray_native(L, 1);
unsigned int x = luaL_checkint(L, 2);
unsigned int y = luaL_checkint(L, 3);
Pen pen;
Lua::CheckPen(L, &pen, 4);
parr->set_tile(x, y, pen);
return 0;
}
static int dfhack_penarray_draw(lua_State *L)
{
PenArray *parr = check_penarray_native(L, 1);
unsigned int x = (unsigned int)luaL_checkint(L, 2);
unsigned int y = (unsigned int)luaL_checkint(L, 3);
unsigned int w = (unsigned int)luaL_checkint(L, 4);
unsigned int h = (unsigned int)luaL_checkint(L, 5);
unsigned int bufx = (unsigned int)luaL_optint(L, 6, 0);
unsigned int bufy = (unsigned int)luaL_optint(L, 7, 0);
parr->draw(x, y, w, h, bufx, bufy);
return 0;
}
static const luaL_Reg dfhack_penarray_funcs[] = {
{ "new", dfhack_penarray_new },
{ "clear", dfhack_penarray_clear },
{ "set_tile", dfhack_penarray_set_tile },
{ "draw", dfhack_penarray_draw },
{ NULL, NULL }
};
static void OpenPenArray(lua_State *state)
{
luaL_getsubtable(state, lua_gettop(state), "penarray");
lua_dup(state);
lua_rawsetp(state, LUA_REGISTRYINDEX, &DFHACK_PENARRAY_TOKEN);
luaL_setfuncs(state, dfhack_penarray_funcs, 0);
lua_pop(state, 1);
}
/********************
* Random generator *
********************/
@ -2516,6 +2598,7 @@ void OpenDFHackApi(lua_State *state)
OpenPersistent(state);
OpenMatinfo(state);
OpenPen(state);
OpenPenArray(state);
OpenRandom(state);
LuaWrapper::SetFunctionWrappers(state, dfhack_module);

@ -48,6 +48,7 @@ namespace DFHack {
}
namespace Screen {
struct Pen;
struct PenArray;
};
}

@ -114,6 +114,19 @@ namespace DFHack
Pen chtile(char ch, int tile) { Pen cp(*this); cp.ch = ch; cp.tile = tile; return cp; }
};
class DFHACK_EXPORT PenArray {
Pen *buffer;
unsigned int dimx;
unsigned int dimy;
public:
PenArray(unsigned int bufwidth, unsigned int bufheight);
~PenArray();
void clear();
void set_tile(unsigned int x, unsigned int y, Screen::Pen pen);
void draw(unsigned int x, unsigned int y, unsigned int width, unsigned int height,
unsigned int bufx = 0, unsigned int bufy = 0);
};
struct DFHACK_EXPORT ViewRect {
rect2d view, clip;

@ -264,6 +264,12 @@ function dfhack.random:__tostring()
return "<random generator>"
end
dfhack.penarray.__index = dfhack.penarray
function dfhack.penarray.__tostring()
return "<penarray>"
end
function dfhack.maps.getSize()
local map = df.global.world.map
return map.x_count_block, map.y_count_block, map.z_count_block

@ -65,6 +65,7 @@ using df::global::gview;
using df::global::enabler;
using Screen::Pen;
using Screen::PenArray;
using std::string;
@ -436,6 +437,58 @@ df::interface_key Screen::charToKey(char code)
return df::interface_key(interface_key::STRING_A128 + (val-128));
}
/*
* Pen array
*/
PenArray::PenArray(unsigned int bufwidth, unsigned int bufheight)
:dimx(bufwidth), dimy(bufheight)
{
buffer = new Pen[bufwidth * bufheight];
clear();
}
PenArray::~PenArray()
{
delete[] buffer;
}
void PenArray::clear()
{
for (unsigned int x = 0; x < dimx; x++)
{
for (unsigned int y = 0; y < dimy; y++)
{
set_tile(x, y, Screen::Pen(0, 0, 0, 0, false));
}
}
}
void PenArray::set_tile(unsigned int x, unsigned int y, Screen::Pen pen)
{
if (x < dimx && y < dimy)
buffer[(y * dimx) + x] = pen;
}
void PenArray::draw(unsigned int x, unsigned int y, unsigned int width, unsigned int height,
unsigned int bufx, unsigned int bufy)
{
if (!gps)
return;
for (unsigned int gridx = x; gridx < x + width; gridx++)
{
for (unsigned int gridy = y; gridy < y + height; gridy++)
{
if (gridx >= gps->dimx ||
gridy >= gps->dimy ||
gridx - x + bufx >= dimx ||
gridy - y + bufy >= dimy)
continue;
Screen::paintTile(buffer[((gridy - y + bufy) * dimx) + (gridx - x + bufx)], gridx, gridy);
}
}
}
/*
* Base DFHack viewscreen.
*/