summaryrefslogtreecommitdiff
path: root/plugins/devel
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-08-17 22:40:53 +0400
committerAlexander Gavrilov2012-08-17 22:40:53 +0400
commit236ffd578b66805fa45d65df79e099d00156bfff (patch)
treecdbf17b2c1fb3c3cf5135531861ecd0c90061abe /plugins/devel
parentbcc41c081a43a68042c4757a6569cb690098d9b8 (diff)
downloaddfhack-236ffd578b66805fa45d65df79e099d00156bfff.tar.gz
dfhack-236ffd578b66805fa45d65df79e099d00156bfff.tar.bz2
dfhack-236ffd578b66805fa45d65df79e099d00156bfff.tar.xz
Add experimental support for interposing vmethods of known classes.
The hairiest bit is the abuse of compiler-specific pointer-to-member internals in order to provide more or less transparent API.
Diffstat (limited to 'plugins/devel')
-rw-r--r--plugins/devel/CMakeLists.txt1
-rw-r--r--plugins/devel/vshook.cpp61
2 files changed, 62 insertions, 0 deletions
diff --git a/plugins/devel/CMakeLists.txt b/plugins/devel/CMakeLists.txt
index 5d1d585a..8274accf 100644
--- a/plugins/devel/CMakeLists.txt
+++ b/plugins/devel/CMakeLists.txt
@@ -17,3 +17,4 @@ DFHACK_PLUGIN(stockcheck stockcheck.cpp)
DFHACK_PLUGIN(stripcaged stripcaged.cpp)
DFHACK_PLUGIN(rprobe rprobe.cpp)
DFHACK_PLUGIN(nestboxes nestboxes.cpp)
+DFHACK_PLUGIN(vshook vshook.cpp)
diff --git a/plugins/devel/vshook.cpp b/plugins/devel/vshook.cpp
new file mode 100644
index 00000000..28f98362
--- /dev/null
+++ b/plugins/devel/vshook.cpp
@@ -0,0 +1,61 @@
+#include "Core.h"
+#include <Console.h>
+#include <Export.h>
+#include <PluginManager.h>
+#include <modules/Gui.h>
+#include <vector>
+#include <cstdio>
+#include <stack>
+#include <string>
+#include <cmath>
+
+#include <VTableInterpose.h>
+#include "df/graphic.h"
+#include "df/viewscreen_titlest.h"
+
+using std::vector;
+using std::string;
+using std::stack;
+using namespace DFHack;
+
+using df::global::gps;
+
+DFHACK_PLUGIN("vshook");
+
+struct title_hook : df::viewscreen_titlest {
+ typedef df::viewscreen_titlest interpose_base;
+
+ DEFINE_VMETHOD_INTERPOSE(void, render, ())
+ {
+ INTERPOSE_NEXT(render)();
+
+ if (gps) {
+ uint8_t *buf = gps->screen;
+ int32_t *stp = gps->screentexpos;
+
+ for (const char *p = "DFHack " DFHACK_VERSION; *p; p++) {
+ *buf++ = *p; *buf++ = 7; *buf++ = 0; *buf++ = 1;
+ *stp++ = 0;
+ }
+ }
+ }
+};
+
+IMPLEMENT_VMETHOD_INTERPOSE(title_hook, render);
+
+DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
+{
+ if (gps)
+ {
+ if (!title_hook::interpose_render.apply())
+ out.printerr("Could not interpose viewscreen_titlest::render\n");
+ }
+
+ return CR_OK;
+}
+
+DFhackCExport command_result plugin_shutdown ( color_ostream &out )
+{
+ title_hook::interpose_render.remove();
+ return CR_OK;
+}