|
8 | 8 |
|
9 | 9 | #include <SDL_stdinc.h> |
10 | 10 |
|
| 11 | +#include <vector> |
| 12 | + |
11 | 13 | #ifdef WIN32 |
12 | 14 | # include <regex> |
13 | 15 | #endif |
@@ -61,6 +63,9 @@ SDL_Surface* (*g_SDL_CreateRGBSurfaceWithFormat)(uint32_t flags, int width, int |
61 | 63 | int (*g_SDL_ShowSimpleMessageBox)(uint32_t flags, const char *title, const char *message, SDL_Window *window) = nullptr; |
62 | 64 | char* (*g_SDL_GetPrefPath)(const char* org, const char* app) = nullptr; |
63 | 65 | char* (*g_SDL_GetBasePath)() = nullptr; |
| 66 | +uint32_t (*g_SDL_GetMouseState)(int* x, int* y) = nullptr; |
| 67 | +void (*g_SDL_RenderWindowToLogical)(SDL_Renderer* renderer, int windowX, int windowY, float* logicalX, float* logicalY); |
| 68 | +void (*g_SDL_RenderLogicalToWindow)(SDL_Renderer* renderer, float logicalX, float logicalY, int* windowX, int* windowY); |
64 | 69 |
|
65 | 70 | bool DFSDL::init(color_ostream &out) { |
66 | 71 | for (auto &lib_str : SDL_LIBS) { |
@@ -106,6 +111,9 @@ bool DFSDL::init(color_ostream &out) { |
106 | 111 | bind(g_sdl_handle, SDL_ShowSimpleMessageBox); |
107 | 112 | bind(g_sdl_handle, SDL_GetPrefPath); |
108 | 113 | bind(g_sdl_handle, SDL_GetBasePath); |
| 114 | + bind(g_sdl_handle, SDL_GetMouseState); |
| 115 | + bind(g_sdl_handle, SDL_RenderWindowToLogical); |
| 116 | + bind(g_sdl_handle, SDL_RenderLogicalToWindow); |
109 | 117 | #undef bind |
110 | 118 |
|
111 | 119 | DEBUG(dfsdl,out).print("sdl successfully loaded\n"); |
@@ -190,6 +198,18 @@ char* DFSDL::DFSDL_GetBasePath() |
190 | 198 | return g_SDL_GetBasePath(); |
191 | 199 | } |
192 | 200 |
|
| 201 | +uint32_t DFSDL::DFSDL_GetMouseState(int* x, int* y) { |
| 202 | + return g_SDL_GetMouseState(x, y); |
| 203 | +} |
| 204 | + |
| 205 | +void DFSDL::DFSDL_RenderWindowToLogical(SDL_Renderer *renderer, int windowX, int windowY, float *logicalX, float *logicalY) { |
| 206 | + g_SDL_RenderWindowToLogical(renderer, windowX, windowY, logicalX, logicalY); |
| 207 | +} |
| 208 | + |
| 209 | +void DFSDL::DFSDL_RenderLogicalToWindow(SDL_Renderer *renderer, float logicalX, float logicalY, int *windowX, int *windowY) { |
| 210 | + g_SDL_RenderLogicalToWindow(renderer, logicalX, logicalY, windowX, windowY); |
| 211 | +} |
| 212 | + |
193 | 213 | int DFSDL::DFSDL_ShowSimpleMessageBox(uint32_t flags, const char *title, const char *message, SDL_Window *window) { |
194 | 214 | if (!g_SDL_ShowSimpleMessageBox) |
195 | 215 | return -1; |
@@ -266,3 +286,25 @@ DFHACK_EXPORT bool DFHack::setClipboardTextCp437Multiline(string text) { |
266 | 286 | } |
267 | 287 | return 0 == DFHack::DFSDL::DFSDL_SetClipboardText(str.str().c_str()); |
268 | 288 | } |
| 289 | + |
| 290 | +// Queue to run callbacks on the render thread. |
| 291 | +// Semantics loosely based on SDL3's SDL_RunOnMainThread |
| 292 | +static std::recursive_mutex render_cb_lock; |
| 293 | +static std::vector<std::function<void()>> render_cb_queue; |
| 294 | + |
| 295 | +DFHACK_EXPORT void DFHack::runOnRenderThread(std::function<void()> cb) { |
| 296 | + std::lock_guard<std::recursive_mutex> l(render_cb_lock); |
| 297 | + render_cb_queue.push_back(std::move(cb)); |
| 298 | +} |
| 299 | + |
| 300 | +DFHACK_EXPORT void DFHack::runRenderThreadCallbacks() { |
| 301 | + static decltype(render_cb_queue) local_queue; |
| 302 | + { |
| 303 | + std::lock_guard<std::recursive_mutex> l(render_cb_lock); |
| 304 | + std::swap(local_queue, render_cb_queue); |
| 305 | + } |
| 306 | + for (auto& cb : local_queue) { |
| 307 | + cb(); |
| 308 | + } |
| 309 | + local_queue.clear(); |
| 310 | +} |
0 commit comments