From 47896376253061416ee636f7a8ab1ab3eb04d53b Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Fri, 23 Dec 2022 19:05:00 -0800 Subject: [PATCH 1/2] implement new dfhooks API --- CMakeLists.txt | 1 + library/CMakeLists.txt | 6 ++++++ library/Core.cpp | 38 ++++++++++++++++++++++---------------- library/Hooks-darwin.cpp | 3 +-- library/Hooks-linux.cpp | 6 ------ library/Hooks.cpp | 33 +++++++++++++++++++++++++++++++++ library/include/Core.h | 9 ++++++++- library/include/Hooks.h | 8 ++++++++ 8 files changed, 79 insertions(+), 25 deletions(-) create mode 100644 library/Hooks.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 96b925221..5877f69c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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") diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index aee5184c8..8c0992a79 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -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 diff --git a/library/Core.cpp b/library/Core.cpp index 9f4707a02..e5fe61771 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1481,11 +1481,12 @@ 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); #endif + fprintf(stderr, "dfhack: redirecting stderr to stderr.log\n"); + freopen("stderr.log", "w", stderr); Filesystem::init(); @@ -1760,6 +1761,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 +1844,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 +1950,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 +2287,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: diff --git a/library/Hooks-darwin.cpp b/library/Hooks-darwin.cpp index 723d97970..418cf5472 100644 --- a/library/Hooks-darwin.cpp +++ b/library/Hooks-darwin.cpp @@ -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"); diff --git a/library/Hooks-linux.cpp b/library/Hooks-linux.cpp index cb8ba20db..7a0cdf947 100644 --- a/library/Hooks-linux.cpp +++ b/library/Hooks-linux.cpp @@ -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"); diff --git a/library/Hooks.cpp b/library/Hooks.cpp new file mode 100644 index 000000000..36af2617c --- /dev/null +++ b/library/Hooks.cpp @@ -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); +} diff --git a/library/include/Core.h b/library/include/Core.h index 531d1b581..6c99e62be 100644 --- a/library/include/Core.h +++ b/library/include/Core.h @@ -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); diff --git a/library/include/Hooks.h b/library/include/Hooks.h index d17b96acf..5856fb44f 100644 --- a/library/include/Hooks.h +++ b/library/include/Hooks.h @@ -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); From 4f9f8ebcf6369a3bd7737ed40ff77a4bb1abee51 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 26 Dec 2022 10:26:22 -0800 Subject: [PATCH 2/2] fix unused return value warning --- library/Core.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/Core.cpp b/library/Core.cpp index e5fe61771..5b53db98f 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1483,10 +1483,12 @@ bool Core::Init() // 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"); - freopen("stdout.log", "w", stdout); + 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"); - freopen("stderr.log", "w", stderr); + if (!freopen("stderr.log", "w", stderr)) + cerr << "Could not redirect stderr to stderr.log" << endl; Filesystem::init();