|
9 | 9 | #include <SDL_stdinc.h> |
10 | 10 | #include <SDL_keycode.h> |
11 | 11 |
|
| 12 | +#include <vector> |
| 13 | + |
12 | 14 | #ifdef WIN32 |
13 | 15 | # include <regex> |
14 | 16 | #endif |
@@ -62,6 +64,9 @@ SDL_Surface* (*g_SDL_CreateRGBSurfaceWithFormat)(uint32_t flags, int width, int |
62 | 64 | int (*g_SDL_ShowSimpleMessageBox)(uint32_t flags, const char *title, const char *message, SDL_Window *window) = nullptr; |
63 | 65 | char* (*g_SDL_GetPrefPath)(const char* org, const char* app) = nullptr; |
64 | 66 | char* (*g_SDL_GetBasePath)() = nullptr; |
| 67 | +uint32_t (*g_SDL_GetMouseState)(int* x, int* y) = nullptr; |
| 68 | +void (*g_SDL_RenderWindowToLogical)(SDL_Renderer* renderer, int windowX, int windowY, float* logicalX, float* logicalY); |
| 69 | +void (*g_SDL_RenderLogicalToWindow)(SDL_Renderer* renderer, float logicalX, float logicalY, int* windowX, int* windowY); |
65 | 70 |
|
66 | 71 | SDL_Keycode (*g_SDL_GetKeyFromName)(const char* name) = nullptr; |
67 | 72 | const char* (*g_SDL_GetKeyName)(SDL_Keycode key) = nullptr; |
@@ -112,6 +117,9 @@ bool DFSDL::init(color_ostream &out) { |
112 | 117 | bind(g_sdl_handle, SDL_GetBasePath); |
113 | 118 | bind(g_sdl_handle, SDL_GetKeyFromName); |
114 | 119 | bind(g_sdl_handle, SDL_GetKeyName); |
| 120 | + bind(g_sdl_handle, SDL_GetMouseState); |
| 121 | + bind(g_sdl_handle, SDL_RenderWindowToLogical); |
| 122 | + bind(g_sdl_handle, SDL_RenderLogicalToWindow); |
115 | 123 | #undef bind |
116 | 124 |
|
117 | 125 | DEBUG(dfsdl,out).print("sdl successfully loaded\n"); |
@@ -196,6 +204,18 @@ char* DFSDL::DFSDL_GetBasePath() |
196 | 204 | return g_SDL_GetBasePath(); |
197 | 205 | } |
198 | 206 |
|
| 207 | +uint32_t DFSDL::DFSDL_GetMouseState(int* x, int* y) { |
| 208 | + return g_SDL_GetMouseState(x, y); |
| 209 | +} |
| 210 | + |
| 211 | +void DFSDL::DFSDL_RenderWindowToLogical(SDL_Renderer *renderer, int windowX, int windowY, float *logicalX, float *logicalY) { |
| 212 | + g_SDL_RenderWindowToLogical(renderer, windowX, windowY, logicalX, logicalY); |
| 213 | +} |
| 214 | + |
| 215 | +void DFSDL::DFSDL_RenderLogicalToWindow(SDL_Renderer *renderer, float logicalX, float logicalY, int *windowX, int *windowY) { |
| 216 | + g_SDL_RenderLogicalToWindow(renderer, logicalX, logicalY, windowX, windowY); |
| 217 | +} |
| 218 | + |
199 | 219 | int DFSDL::DFSDL_ShowSimpleMessageBox(uint32_t flags, const char *title, const char *message, SDL_Window *window) { |
200 | 220 | if (!g_SDL_ShowSimpleMessageBox) |
201 | 221 | return -1; |
@@ -284,3 +304,25 @@ DFHACK_EXPORT bool DFHack::setClipboardTextCp437Multiline(string text) { |
284 | 304 | } |
285 | 305 | return 0 == DFHack::DFSDL::DFSDL_SetClipboardText(str.str().c_str()); |
286 | 306 | } |
| 307 | + |
| 308 | +// Queue to run callbacks on the render thread. |
| 309 | +// Semantics loosely based on SDL3's SDL_RunOnMainThread |
| 310 | +static std::recursive_mutex render_cb_lock; |
| 311 | +static std::vector<std::function<void()>> render_cb_queue; |
| 312 | + |
| 313 | +DFHACK_EXPORT void DFHack::runOnRenderThread(std::function<void()> cb) { |
| 314 | + std::lock_guard<std::recursive_mutex> l(render_cb_lock); |
| 315 | + render_cb_queue.push_back(std::move(cb)); |
| 316 | +} |
| 317 | + |
| 318 | +DFHACK_EXPORT void DFHack::runRenderThreadCallbacks() { |
| 319 | + static decltype(render_cb_queue) local_queue; |
| 320 | + { |
| 321 | + std::lock_guard<std::recursive_mutex> l(render_cb_lock); |
| 322 | + std::swap(local_queue, render_cb_queue); |
| 323 | + } |
| 324 | + for (auto& cb : local_queue) { |
| 325 | + cb(); |
| 326 | + } |
| 327 | + local_queue.clear(); |
| 328 | +} |
0 commit comments