Merge remote-tracking branch 'DFHack/develop' into develop

develop
Rose 2022-12-28 16:06:21 -08:00
commit b8f4da65bb
12 changed files with 163 additions and 71 deletions

@ -258,6 +258,7 @@ if(UNIX)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 -march=i686")
endif()
string(REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
set(CMAKE_INSTALL_RPATH "hack")
elseif(MSVC)
# for msvc, tell it to always use 8-byte pointers to member functions to avoid confusion
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /vmg /vmm /MP")

@ -96,6 +96,7 @@ endif()
set(MAIN_SOURCES_WINDOWS
${CONSOLE_SOURCES}
Hooks-windows.cpp
Hooks.cpp
PlugLoad-windows.cpp
Process-windows.cpp
)
@ -374,6 +375,8 @@ if(WIN32)
else()
set_target_properties(dfhack PROPERTIES COMPILE_FLAGS "-include Export.h" )
set_target_properties(dfhack-client PROPERTIES COMPILE_FLAGS "-include Export.h" )
add_library(dfhooks SHARED Hooks.cpp)
target_link_libraries(dfhooks dfhack)
endif()
# effectively disables debug builds...
@ -422,6 +425,9 @@ if(UNIX)
install(PROGRAMS ${dfhack_SOURCE_DIR}/package/linux/dfhack-run
DESTINATION .)
endif()
install(TARGETS dfhooks
LIBRARY DESTINATION .
RUNTIME DESTINATION .)
else()
# On windows, copy the renamed SDL so DF can still run.
install(PROGRAMS ${dfhack_SOURCE_DIR}/package/windows/win${DFHACK_BUILD_ARCH}/SDLreal.dll

@ -1481,11 +1481,14 @@ bool Core::Init()
// make it obvious what's going on if someone checks the *.txt files.
#ifndef LINUX_BUILD
// Don't do this on Linux because it will break PRINT_MODE:TEXT
// this is handled as appropriate in Console-posix.cpp
fprintf(stdout, "dfhack: redirecting stdout to stdout.log (again)\n");
fprintf(stderr, "dfhack: redirecting stderr to stderr.log (again)\n");
freopen("stdout.log", "w", stdout);
freopen("stderr.log", "w", stderr);
if (!freopen("stdout.log", "w", stdout))
cerr << "Could not redirect stdout to stdout.log" << endl;
#endif
fprintf(stderr, "dfhack: redirecting stderr to stderr.log\n");
if (!freopen("stderr.log", "w", stderr))
cerr << "Could not redirect stderr to stderr.log" << endl;
Filesystem::init();
@ -1760,6 +1763,14 @@ bool Core::Init()
}
cerr << "DFHack is running.\n";
{
auto L = Lua::Core::State;
Lua::StackUnwinder top(L);
Lua::CallLuaModuleFunction(con, L, "script-manager", "reload");
onStateChange(con, SC_CORE_INITIALIZED);
}
return true;
}
/// sets the current hotkey command
@ -1835,17 +1846,10 @@ bool Core::isSuspended(void)
return ownerThread.load() == std::this_thread::get_id();
}
void Core::doUpdate(color_ostream &out, bool first_update)
void Core::doUpdate(color_ostream &out)
{
Lua::Core::Reset(out, "DF code execution");
if (first_update) {
auto L = Lua::Core::State;
Lua::StackUnwinder top(L);
Lua::CallLuaModuleFunction(out, L, "script-manager", "reload");
onStateChange(out, SC_CORE_INITIALIZED);
}
// find the current viewscreen
df::viewscreen *screen = NULL;
if (df::global::gview)
@ -1948,19 +1952,15 @@ int Core::Update()
// Pretend this thread has suspended the core in the usual way,
// and run various processing hooks.
{
// Initialize the core
bool first_update = false;
if(!started)
{
first_update = true;
// Initialize the core
Init();
if(errorstate)
return -1;
Lua::Core::Reset(con, "core init");
}
doUpdate(out, first_update);
doUpdate(out);
}
// Let all commands run that require CoreSuspender
@ -2289,6 +2289,14 @@ bool Core::ncurses_wgetch(int in, int & out)
return true;
}
bool Core::DFH_ncurses_key(int key)
{
if (getenv("DFHACK_HEADLESS"))
return true;
int dummy;
return !ncurses_wgetch(key, dummy);
}
int UnicodeAwareSym(const SDL::KeyboardEvent& ke)
{
// Assume keyboard layouts don't change the order of numbers:

@ -279,9 +279,8 @@ DFhackCExport int DFH_SDL_Init(uint32_t flags)
{
// reroute stderr
fprintf(stderr,"dfhack: attempting to hook in\n");
freopen("stderr.log", "w", stderr);
// we don't reroute stdout until we figure out if this should be done at all
// See: Console-linux.cpp
// See: Console-posix.cpp
// find real functions
fprintf(stderr,"dfhack: saving real SDL functions\n");

@ -117,12 +117,6 @@ DFhackCExport int wgetch(WINDOW *win)
static int (*_SDL_Init)(uint32_t flags) = 0;
DFhackCExport int SDL_Init(uint32_t flags)
{
// reroute stderr
if (!freopen("stderr.log", "w", stderr))
fprintf(stderr, "dfhack: failed to reroute stderr\n");
// we don't reroute stdout until we figure out if this should be done at all
// See: Console-linux.cpp
// find real functions
_SDL_Init = (int (*)( uint32_t )) dlsym(RTLD_NEXT, "SDL_Init");
_SDL_Quit = (void (*)( void )) dlsym(RTLD_NEXT, "SDL_Quit");

@ -0,0 +1,33 @@
#include "Core.h"
#include "Export.h"
// called before main event loop starts
DFhackCExport void dfhooks_init() {
DFHack::Core::getInstance().Init();
}
// called after main event loops exits
DFhackCExport void dfhooks_shutdown() {
DFHack::Core::getInstance().Shutdown();
}
// called in the main event loop
DFhackCExport void dfhooks_update() {
DFHack::Core::getInstance().Update();
}
// called just before adding the macro recording/playback overlay
DFhackCExport void dfhooks_prerender() {
// TODO: render overlay widgets that are not attached to a viewscreen
}
// called for each SDL event, if true is returned, then the event has been
// consumed and further processing shouldn't happen
DFhackCExport bool dfhooks_sdl_event(SDL::Event* event) {
return DFHack::Core::getInstance().DFH_SDL_Event(event);
}
// called for each utf-8 char read from the ncurses input
// key is positive for ncurses keys and negative for everything else
DFhackCExport bool dfhooks_ncurses_key(int key) {
return DFHack::Core::getInstance().DFH_ncurses_key(key);
}

@ -121,6 +121,12 @@ namespace DFHack
friend int ::SDL_Init(uint32_t flags);
friend int ::wgetch(WINDOW * w);
#endif
friend void ::dfhooks_init();
friend void ::dfhooks_shutdown();
friend void ::dfhooks_update();
friend void ::dfhooks_prerender();
friend bool ::dfhooks_sdl_event(SDL::Event* event);
friend bool ::dfhooks_ncurses_key(int key);
public:
/// Get the single Core instance or make one.
static Core& getInstance()
@ -202,8 +208,9 @@ namespace DFHack
int Shutdown (void);
int DFH_SDL_Event(SDL::Event* event);
bool ncurses_wgetch(int in, int & out);
bool DFH_ncurses_key(int key);
void doUpdate(color_ostream &out, bool first_update);
void doUpdate(color_ostream &out);
void onUpdate(color_ostream &out);
void onStateChange(color_ostream &out, state_change_event event);
void handleLoadAndUnloadScripts(color_ostream &out, state_change_event event);

@ -74,3 +74,11 @@ DFhackCExport void * SDL_GetVideoSurface(void);
DFhackCExport int SDL_SemWait(vPtr sem);
DFhackCExport int SDL_SemPost(vPtr sem);
// new Hooks API
DFhackCExport void dfhooks_init();
DFhackCExport void dfhooks_shutdown();
DFhackCExport void dfhooks_update();
DFhackCExport void dfhooks_prerender();
DFhackCExport bool dfhooks_sdl_event(SDL::Event* event);
DFhackCExport bool dfhooks_ncurses_key(int key);

@ -11,7 +11,7 @@ USE_GRAPHICS = dscreen.inGraphicsMode()
local to_pen = dfhack.pen.parse
CLEAR_PEN = to_pen{ch=32,fg=0,bg=0}
CLEAR_PEN = to_pen{tile=909, ch=32, fg=0, bg=0}
local FAKE_INPUT_KEYS = {
_MOUSE_L = true,
@ -624,6 +624,7 @@ function Screen:renderParent()
else
dscreen.clear()
end
df.global.gps.force_full_display_count = 1
end
function Screen:sendInputToParent(...)
@ -693,15 +694,17 @@ BOUNDARY_FRAME = {
}
GREY_LINE_FRAME = {
frame_pen = to_pen{ ch = 206, fg = COLOR_GREY, bg = COLOR_BLACK },
h_frame_pen = to_pen{ ch = 205, fg = COLOR_GREY, bg = COLOR_BLACK },
v_frame_pen = to_pen{ ch = 186, fg = COLOR_GREY, bg = COLOR_BLACK },
lt_frame_pen = to_pen{ ch = 201, fg = COLOR_GREY, bg = COLOR_BLACK },
lb_frame_pen = to_pen{ ch = 200, fg = COLOR_GREY, bg = COLOR_BLACK },
rt_frame_pen = to_pen{ ch = 187, fg = COLOR_GREY, bg = COLOR_BLACK },
rb_frame_pen = to_pen{ ch = 188, fg = COLOR_GREY, bg = COLOR_BLACK },
title_pen = to_pen{ fg = COLOR_BLACK, bg = COLOR_GREY },
signature_pen = to_pen{ fg = COLOR_GREY, bg = COLOR_BLACK },
frame_pen = to_pen{ ch=206, fg=COLOR_GREY, bg=COLOR_BLACK },
t_frame_pen = to_pen{ tile=902, ch=205, fg=COLOR_GREY, bg=COLOR_BLACK },
l_frame_pen = to_pen{ tile=908, ch=186, fg=COLOR_GREY, bg=COLOR_BLACK },
b_frame_pen = to_pen{ tile=916, ch=205, fg=COLOR_GREY, bg=COLOR_BLACK },
r_frame_pen = to_pen{ tile=910, ch=186, fg=COLOR_GREY, bg=COLOR_BLACK },
lt_frame_pen = to_pen{ tile=901, ch=201, fg=COLOR_GREY, bg=COLOR_BLACK },
lb_frame_pen = to_pen{ tile=915, ch=200, fg=COLOR_GREY, bg=COLOR_BLACK },
rt_frame_pen = to_pen{ tile=903, ch=187, fg=COLOR_GREY, bg=COLOR_BLACK },
rb_frame_pen = to_pen{ tile=917, ch=188, fg=COLOR_GREY, bg=COLOR_BLACK },
title_pen = to_pen{ fg=COLOR_BLACK, bg=COLOR_GREY },
signature_pen = to_pen{ fg=COLOR_GREY, bg=COLOR_BLACK },
}
function paint_frame(dc,rect,style,title)

@ -54,7 +54,7 @@ using namespace DFHack;
#include "df/tile_pagest.h"
#include "df/interfacest.h"
#include "df/enabler.h"
#include "df/graphic_map_portst.h"
#include "df/graphic_viewportst.h"
#include "df/unit.h"
#include "df/item.h"
#include "df/job.h"
@ -115,39 +115,72 @@ bool Screen::inGraphicsMode()
return init && init->display.flag.is_set(init_display_flags::USE_GRAPHICS);
}
static bool doSetTile_map(const Pen &pen, int x, int y) {
size_t index = (x * gps->main_viewport->dim_y) + y;
long texpos = pen.tile;
if (texpos == 0) {
texpos = init->font.large_font_texpos[(uint8_t)pen.ch];
}
gps->main_viewport->screentexpos_interface[index] = texpos;
return true;
}
static bool doSetTile_default(const Pen &pen, int x, int y, bool map)
{
// TODO: understand how this changes for v50
size_t index = ((x * gps->dimy) + y);
if (!map) {
// don't let DF overlay interface elements draw over us
gps->screentexpos_anchored[index] = 0;
gps->screentexpos_top[index] = 0;
gps->screentexpos_flag[index] = 0;
bool use_graphics = Screen::inGraphicsMode();
if (map && use_graphics)
return doSetTile_map(pen, x, y);
size_t index = (x * gps->dimy) + y;
uint8_t *screen = &gps->screen[index * 8];
if (screen > gps->screen_limit)
return false;
long *texpos = &gps->screentexpos[index];
long *texpos_lower = &gps->screentexpos_lower[index];
uint32_t *flag = &gps->screentexpos_flag[index];
*screen = 0;
*texpos = 0;
*texpos_lower = 0;
*flag = 4; // remove SCREENTEXPOS_FLAG_ANCHOR_SUBORDINATE
if (gps->top_in_use) {
screen = &gps->screen_top[index * 8];
texpos = &gps->screentexpos_top[index];
texpos_lower = &gps->screentexpos_top_lower[index];
flag = &gps->screentexpos_top_flag[index];
*screen = 0;
*texpos = 0;
*texpos_lower = 0;
*flag = 4; // remove SCREENTEXPOS_FLAG_ANCHOR_SUBORDINATE
}
if (pen.tile_mode == Screen::Pen::CharColor)
*flag |= 2; // SCREENTEXPOS_FLAG_ADDCOLOR
else if (pen.tile_mode == Screen::Pen::TileColor)
*flag |= 1; // SCREENTEXPOS_FLAG_GRAYSCALE
if (pen.tile && use_graphics) {
*texpos = pen.tile;
} else {
screen[0] = uint8_t(pen.ch);
*texpos_lower = 909;
}
//gps->screen1_opt_tile[index] = uint8_t(pen.tile);
// note that pen.bold currently (50.04) has no representation in the DF data
auto fg = &gps->uccolor[pen.fg][0];
auto bg = &gps->uccolor[pen.bg][0];
auto argb = &gps->screen[index * 8];
argb[0] = uint8_t(pen.ch);
argb[1] = fg[0];
argb[2] = fg[1];
argb[3] = fg[2];
argb[4] = bg[0];
argb[5] = bg[1];
argb[6] = bg[2];
/* old code
// auto screen = gps->screen + index*4;
// screen[0] = uint8_t(pen.ch);
// screen[1] = uint8_t(pen.fg) & 15;
// screen[2] = uint8_t(pen.bg) & 15;
// screen[3] = uint8_t(pen.bold) & 1;
// gps->screentexpos[index] = pen.tile;
// gps->screentexpos_addcolor[index] = (pen.tile_mode == Screen::Pen::CharColor);
// gps->screentexpos_grayscale[index] = (pen.tile_mode == Screen::Pen::TileColor);
// gps->screentexpos_cf[index] = pen.tile_fg;
// gps->screentexpos_cbr[index] = pen.tile_bg;
*/
screen[1] = fg[0];
screen[2] = fg[1];
screen[3] = fg[2];
screen[4] = bg[0];
screen[5] = bg[1];
screen[6] = bg[2];
return true;
}

@ -11,15 +11,15 @@ local widgets = require('gui.widgets')
HotspotMenuWidget = defclass(HotspotMenuWidget, overlay.OverlayWidget)
HotspotMenuWidget.ATTRS{
default_pos={x=1,y=3},
default_pos={x=1,y=2},
hotspot=true,
viewscreens={'dwarfmode'},
overlay_onupdate_max_freq_seconds=0,
frame={w=2, h=1}
frame={w=4, h=3}
}
function HotspotMenuWidget:init()
self:addviews{widgets.Label{text='!'}}
self:addviews{widgets.Label{text={'!!!!', NEWLINE, '!!!!', NEWLINE, '!!!!'}}}
self.mouseover = false
end
@ -136,9 +136,9 @@ function MenuScreen:init()
local help_frame = {w=list_frame.w, l=list_frame.l, r=list_frame.r}
if list_frame.t then
help_frame.t = list_frame.t + list_frame.h + 1
help_frame.t = list_frame.t + list_frame.h
else
help_frame.b = list_frame.b + list_frame.h + 1
help_frame.b = list_frame.b + list_frame.h
end
self:addviews{

@ -1 +1 @@
Subproject commit 6f723420adbd3e485167b725ca980e10e6055f96
Subproject commit e64d86728f25f22871e47beb52ad1177aef5e043