#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 &commands) { auto addr =reinterpret_cast(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; }