Merge pull request #1181 from warmist/twbt_experiments

map-render plugin
develop
Alan 2019-08-21 09:33:45 -04:00 committed by GitHub
commit 2344e60101
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 154 additions and 0 deletions

@ -3920,6 +3920,22 @@ A class with all the tcp functionality.
Tries connecting to that address and port. Returns ``client`` object.
.. _map-render:
map-render
==========
A way to ask df to render a slice of map. This uses native df rendering function so it's highly dependant on
df settings (e.g. used tileset, colors, if using graphics or not and so on...)
Functions
---------
- ``render_map_rect(x,y,z,w,h)``
returns a table with w*h*4 entries of rendered tiles. The format is same as ``df.global.gps.screen`` (tile,foreground,bright,background).
.. _cxxrandom:
cxxrandom

@ -2848,4 +2848,5 @@ in the `lua-api` file under `lua-plugins`:
* `eventful`
* `building-hacks`
* `luasocket`
* `map-render`
* `cxxrandom`

@ -136,6 +136,7 @@ if (BUILD_SUPPORTED)
DFHACK_PLUGIN(liquids liquids.cpp Brushes.h LINK_LIBRARIES lua)
DFHACK_PLUGIN(luasocket luasocket.cpp LINK_LIBRARIES clsocket lua dfhack-tinythread)
DFHACK_PLUGIN(manipulator manipulator.cpp)
DFHACK_PLUGIN(map-render map-render.cpp LINK_LIBRARIES lua)
DFHACK_PLUGIN(misery misery.cpp)
DFHACK_PLUGIN(mode mode.cpp)
DFHACK_PLUGIN(mousequery mousequery.cpp)

@ -0,0 +1,11 @@
local _ENV = mkmodule('plugins.map-render')
--[[
Native functions:
* render_map_rect(x,y,z,w,h)
--]]
return _ENV

@ -0,0 +1,125 @@
#include "Core.h"
#include "Console.h"
#include "Export.h"
#include "PluginManager.h"
#include "VersionInfo.h"
#include "VTableInterpose.h"
#include "LuaTools.h"
#include "DataDefs.h"
#include "df/viewscreen_dwarfmodest.h"
#include "df/init.h"
#include "df/renderer.h"
#include "df/graphic.h"
#include "df/enabler.h"
#include "df/map_renderer.h"
using std::string;
using std::vector;
using namespace DFHack;
using namespace df::enums;
DFHACK_PLUGIN("map-render");
REQUIRE_GLOBAL(window_x)
REQUIRE_GLOBAL(window_y)
REQUIRE_GLOBAL(window_z)
REQUIRE_GLOBAL_NO_USE(gps)
REQUIRE_GLOBAL_NO_USE(enabler)
REQUIRE_GLOBAL_NO_USE(twbt_render_map)
REQUIRE_GLOBAL(init)
#ifdef WIN32
// On Windows there's no parameter pointing to the map_renderer structure
typedef void(_stdcall *RENDER_MAP)(int);
RENDER_MAP _render_map;
void render_map(){ _render_map(0); }
#else
REQUIRE_GLOBAL(map_renderer)
typedef void(*RENDER_MAP)(void*, int);
RENDER_MAP _render_map;
void render_map(){ _render_map(map_renderer,0); }
#endif
static int render_map_rect(lua_State* L)
{
CoreSuspender suspender;
int x = luaL_checkint(L, 1);
int y = luaL_checkint(L, 2);
int z = luaL_checkint(L, 3);
int w = luaL_checkint(L, 4);
int h = luaL_checkint(L, 5);
uint8_t *s = df::global::gps->screen;
//backup state
//TODO: figure out if we can replace screen with other pointer. That way it could be a bit more tidy
int32_t win_h = df::global::gps->dimy;
int32_t was_x = *window_x;
int32_t was_y = *window_y;
int32_t was_z = *window_z;
int32_t gx = init->display.grid_x;
int32_t gy = init->display.grid_y;
init->display.grid_x = w+1;
init->display.grid_y = h+1;
*window_x = x;
*window_y = y;
*window_z = z;
//force full redraw
df::global::gps->force_full_display_count = 1;
//this modifies screen so it REALLY wants to redraw stuff
for (int ty = 0; ty < h; ty++)
for (int tx = 0; tx < w; tx++)
{
for (int i = 0; i < 4; i++)
{
int t = (tx + 1)*win_h + ty + 1;
s[t * 4 + i] = 0;
}
}
render_map();
//restore state
*window_x = was_x;
*window_y = was_y;
*window_z = was_z;
init->display.grid_x = gx;
init->display.grid_y = gy;
lua_createtable(L,w*h*4,0);
int counter = 0;
for (int ty = 0; ty < h; ty++)
for (int tx = 0; tx < w; tx++)
{
for (int i = 0; i < 4;i++)
{
int t = (tx + 1)*win_h + ty + 1;
lua_pushnumber(L, s[t*4+i]);
lua_rawseti(L, -2, counter);
counter++;
}
}
return 1;
}
DFHACK_PLUGIN_LUA_COMMANDS{
DFHACK_LUA_COMMAND(render_map_rect),
DFHACK_LUA_END
};
DFhackCExport command_result plugin_init(color_ostream &out, std::vector<PluginCommand> &commands)
{
auto addr =reinterpret_cast<RENDER_MAP>(Core::getInstance().vinfo->getAddress("twbt_render_map"));
if (addr == nullptr)
return CR_FAILURE;
_render_map = addr;
return CR_OK;
}
DFhackCExport command_result plugin_shutdown(color_ostream &out)
{
return CR_OK;
}