Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add paintTileMapPort to support world map tile painting (Develop) #4767

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add paintTileMapPort to support world map tile painting
(no getTileMapPort yet)
  • Loading branch information
Crystalwarrior committed Jun 29, 2024
commit 12ae6dd2b0f292831ef95d9bdb956b31f0c25baf
29 changes: 29 additions & 0 deletions library/LuaApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2861,6 +2861,34 @@ static int screen_readTile(lua_State *L)
return 1;
}

static int screen_paintTileMapPort(lua_State *L)
{
Pen pen;
Lua::CheckPen(L, &pen, 1);
int x = luaL_checkint(L, 2);
int y = luaL_checkint(L, 3);
if (lua_gettop(L) >= 4 && !lua_isnil(L, 4))
{
if (lua_type(L, 4) == LUA_TSTRING)
pen.ch = lua_tostring(L, 4)[0];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if it's a zero-length string?

Copy link
Member

@lethosor lethosor Jul 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will still be safe, since the string is null-terminated, but it will set pen.ch to 0, which may or may not be what you want.

else
pen.ch = luaL_checkint(L, 4);
}
if (lua_gettop(L) >= 5 && !lua_isnil(L, 5))
pen.tile = luaL_checkint(L, 5);
lua_pushboolean(L, Screen::paintTileMapPort(pen, x, y));
return 1;
}

// static int screen_readTileMapPort(lua_State *L)
// {
// int x = luaL_checkint(L, 1);
// int y = luaL_checkint(L, 2);
// Pen pen = Screen::readTileMapPort(x, y);
// Lua::Push(L, pen);
// return 1;
// }

static int screen_paintString(lua_State *L)
{
Pen pen;
Expand Down Expand Up @@ -3048,6 +3076,7 @@ static const luaL_Reg dfhack_screen_funcs[] = {
{ "getWindowSize", screen_getWindowSize },
{ "paintTile", screen_paintTile },
{ "readTile", screen_readTile },
{ "paintTileMapPort", screen_paintTileMapPort },
{ "paintString", screen_paintString },
{ "fillRect", screen_fillRect },
{ "findGraphicsTile", screen_findGraphicsTile },
Expand Down
9 changes: 9 additions & 0 deletions library/include/modules/Screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ distribution.

#include "df/viewscreen.h"
#include "df/graphic_viewportst.h"
#include "df/graphic_map_portst.h"

#include <set>
#include <memory>
Expand Down Expand Up @@ -203,6 +204,12 @@ namespace DFHack
/// Retrieves one screen tile from the buffer
DFHACK_EXPORT Pen readTile(int x, int y, bool map = false, int32_t * df::graphic_viewportst::*texpos_field = NULL);

/// Paint one world map tile with the given pen
DFHACK_EXPORT bool paintTileMapPort(const Pen &pen, int x, int y, int32_t * df::graphic_map_portst::*texpos_field = NULL);

/// Retrieves one world map tile from the buffer
// DFHACK_EXPORT Pen readTile(int x, int y, int32_t * df::graphic_map_portst::*texpos_field = NULL);

/// 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, bool map = false);

Expand Down Expand Up @@ -315,6 +322,8 @@ namespace DFHack
namespace Hooks {
GUI_HOOK_DECLARE(get_tile, Pen, (int x, int y, bool map, int32_t * df::graphic_viewportst::*texpos_field));
GUI_HOOK_DECLARE(set_tile, bool, (const Pen &pen, int x, int y, bool map, int32_t * df::graphic_viewportst::*texpos_field));
// GUI_HOOK_DECLARE(get_tile_map_port, Pen, (int x, int y, int32_t * df::graphic_map_portst::*texpos_field));
GUI_HOOK_DECLARE(set_tile_map_port, bool, (const Pen &pen, int x, int y, int32_t * df::graphic_map_portst::*texpos_field));
}

//! Temporary hide a screen until destructor is called
Expand Down
35 changes: 35 additions & 0 deletions library/modules/Screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,41 @@ Pen Screen::readTile(int x, int y, bool map, int32_t * df::graphic_viewportst::*
return doGetTile(x, y, map, texpos_field);
}

static bool doSetTile_map_port(const Pen &pen, int x, int y, int32_t * df::graphic_map_portst::*texpos_field) {
auto &vp = gps->main_map_port;
if (!texpos_field)
texpos_field = &df::graphic_map_portst::screentexpos_interface;

if (x < 0 || x >= vp->dim_x || y < 0 || y >= vp->dim_y)
return false;

size_t max_index = vp->dim_y * vp->dim_x - 1;
size_t index = (y * vp->dim_x) + x;

if (index > max_index)
return false;

long texpos = pen.tile;
if (!texpos && pen.ch)
texpos = init->font.large_font_texpos[(uint8_t)pen.ch];
(vp->*texpos_field)[index] = texpos;
return true;
}

GUI_HOOK_DEFINE(Screen::Hooks::set_tile_map_port, doSetTile_map_port);
static bool doSetTileMapPort(const Pen &pen, int x, int y, int32_t * df::graphic_map_portst::*texpos_field = NULL)
{
return GUI_HOOK_TOP(Screen::Hooks::set_tile_map_port)(pen, x, y, texpos_field);
}

bool Screen::paintTileMapPort(const Pen &pen, int x, int y, int32_t * df::graphic_map_portst::*texpos_field)
{
if (!gps || !pen.valid()) return false;

doSetTileMapPort(pen, x, y, texpos_field);
return true;
}

bool Screen::paintString(const Pen &pen, int x, int y, const std::string &text, bool map)
{
auto dim = getWindowSize();
Expand Down