diff --git a/binaries/data/mods/public/gui/credits/texts/programming.json b/binaries/data/mods/public/gui/credits/texts/programming.json
index 87f5cf2b..ce1d5042 100644
a
|
b
|
|
53 | 53 | {"name": "Daniel Trevitz"}, |
54 | 54 | {"nick": "DanCar", "name": "Daniel Cardenas"}, |
55 | 55 | {"nick": "danger89", "name": "Melroy van den Berg"}, |
| 56 | {"nick": "Dariost", "name": "Dario Ostuni"}, |
56 | 57 | {"nick": "Dave", "name": "David Protasowski"}, |
57 | 58 | {"nick": "dax", "name": "Dacian Fiordean"}, |
58 | 59 | {"nick": "deebee", "name": "Deepak Anthony"}, |
diff --git a/source/lib/res/graphics/cursor.cpp b/source/lib/res/graphics/cursor.cpp
index c02ca42e..4d0ad944 100644
a
|
b
|
class SDLCursor
|
52 | 52 | SDL_Cursor* cursor; |
53 | 53 | |
54 | 54 | public: |
55 | | Status create(const PIVFS& vfs, const VfsPath& pathname, int hotspotx_, int hotspoty_) |
| 55 | Status create(const PIVFS& vfs, const VfsPath& pathname, int hotspotx_, int hotspoty_, double scale) |
56 | 56 | { |
57 | 57 | shared_ptr<u8> file; size_t fileSize; |
58 | 58 | RETURN_STATUS_IF_ERR(vfs->LoadFile(pathname, file, fileSize)); |
… |
… |
public:
|
70 | 70 | surface = SDL_CreateRGBSurfaceFrom(bgra_img, (int)t.m_Width, (int)t.m_Height, 32, (int)t.m_Width*4, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); |
71 | 71 | if (!surface) |
72 | 72 | return ERR::FAIL; |
| 73 | if (scale != 1.0) |
| 74 | { |
| 75 | SDL_Surface* scaled_surface = SDL_CreateRGBSurface(0, surface->w * scale, surface->h * scale, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); |
| 76 | if (!scaled_surface) |
| 77 | return ERR::FAIL; |
| 78 | if (SDL_BlitScaled(surface, NULL, scaled_surface, NULL)) |
| 79 | return ERR::FAIL; |
| 80 | SDL_FreeSurface(surface); |
| 81 | surface = scaled_surface; |
| 82 | } |
73 | 83 | cursor = SDL_CreateColorCursor(surface, hotspotx_, hotspoty_); |
74 | 84 | if (!cursor) |
75 | 85 | return ERR::FAIL; |
… |
… |
class GLCursor
|
99 | 109 | int hotspotx, hotspoty; |
100 | 110 | |
101 | 111 | public: |
102 | | Status create(const PIVFS& vfs, const VfsPath& pathname, int hotspotx_, int hotspoty_) |
| 112 | Status create(const PIVFS& vfs, const VfsPath& pathname, int hotspotx_, int hotspoty_, double scale) |
103 | 113 | { |
104 | 114 | ht = ogl_tex_load(vfs, pathname); |
105 | 115 | RETURN_STATUS_IF_ERR(ht); |
106 | 116 | |
107 | 117 | size_t width, height; |
108 | 118 | (void)ogl_tex_get_size(ht, &width, &height, 0); |
109 | | w = (GLint)width; |
110 | | h = (GLint)height; |
| 119 | w = (GLint)(width * scale); |
| 120 | h = (GLint)(height * scale); |
111 | 121 | |
112 | 122 | hotspotx = hotspotx_; hotspoty = hotspoty_; |
113 | 123 | |
… |
… |
enum CursorKind
|
169 | 179 | |
170 | 180 | struct Cursor |
171 | 181 | { |
| 182 | double scale; |
| 183 | |
172 | 184 | // require kind == CK_OpenGL after reload |
173 | 185 | bool forceGL; |
174 | 186 | |
… |
… |
H_TYPE_DEFINE(Cursor);
|
185 | 197 | |
186 | 198 | static void Cursor_init(Cursor* c, va_list args) |
187 | 199 | { |
| 200 | c->scale = va_arg(args, double); |
188 | 201 | c->forceGL = (va_arg(args, int) != 0); |
189 | 202 | } |
190 | 203 | |
… |
… |
static Status Cursor_reload(Cursor* c, const PIVFS& vfs, const VfsPath& name, Ha
|
227 | 240 | const VfsPath pathnameImage = pathname.ChangeExtension(L".png"); |
228 | 241 | |
229 | 242 | // try loading as SDL2 cursor |
230 | | if (!c->forceGL && c->sdl_cursor.create(vfs, pathnameImage, hotspotx, hotspoty) == INFO::OK) |
| 243 | if (!c->forceGL && c->sdl_cursor.create(vfs, pathnameImage, hotspotx, hotspoty, c->scale) == INFO::OK) |
231 | 244 | c->kind = CK_SDL; |
232 | 245 | // fall back to GLCursor (system cursor code is disabled or failed) |
233 | | else if(c->gl_cursor.create(vfs, pathnameImage, hotspotx, hotspoty) == INFO::OK) |
| 246 | else if(c->gl_cursor.create(vfs, pathnameImage, hotspotx, hotspoty, c->scale) == INFO::OK) |
234 | 247 | { |
235 | 248 | c->kind = CK_OpenGL; |
236 | 249 | } |
… |
… |
static Status Cursor_to_string(const Cursor* c, wchar_t* buf)
|
297 | 310 | // in other words, we continually create/free the cursor resource in |
298 | 311 | // cursor_draw and trust h_mgr's caching to absorb it. |
299 | 312 | |
300 | | static Handle cursor_load(const PIVFS& vfs, const VfsPath& name, bool forceGL) |
| 313 | static Handle cursor_load(const PIVFS& vfs, const VfsPath& name, double scale, bool forceGL) |
301 | 314 | { |
302 | | return h_alloc(H_Cursor, vfs, name, 0, (int)forceGL); |
| 315 | return h_alloc(H_Cursor, vfs, name, 0, scale, (int)forceGL); |
303 | 316 | } |
304 | 317 | |
305 | 318 | void cursor_shutdown() |
… |
… |
static Status cursor_free(Handle& h)
|
313 | 326 | } |
314 | 327 | |
315 | 328 | |
316 | | Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y, bool forceGL) |
| 329 | Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y, double scale, bool forceGL) |
317 | 330 | { |
318 | 331 | // hide the cursor |
319 | 332 | if(!name) |
… |
… |
Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y, bool for
|
322 | 335 | return INFO::OK; |
323 | 336 | } |
324 | 337 | |
325 | | Handle hc = cursor_load(vfs, name, forceGL); |
| 338 | Handle hc = cursor_load(vfs, name, scale, forceGL); |
326 | 339 | // TODO: if forceGL changes at runtime after a cursor is first created, |
327 | 340 | // we might reuse a cached version of the cursor with the old forceGL flag |
328 | 341 | |
diff --git a/source/lib/res/graphics/cursor.h b/source/lib/res/graphics/cursor.h
index 074e9770..3bca60b6 100644
a
|
b
|
|
39 | 39 | * mouse Y coordinate to be subtracted from the client area height. |
40 | 40 | * Making the caller responsible for this avoids a dependency on |
41 | 41 | * the g_yres global variable.) |
| 42 | * @param scale Scale factor for drawing the cursor. |
42 | 43 | * @param forceGL Require the OpenGL cursor implementation, not hardware cursor |
43 | 44 | * |
44 | 45 | * Uses a hardware mouse cursor where available, otherwise a |
45 | 46 | * portable OpenGL implementation. |
46 | 47 | **/ |
47 | | extern Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y, bool forceGL); |
| 48 | extern Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y, double scale, bool forceGL); |
48 | 49 | |
49 | 50 | /** |
50 | 51 | * Forcibly frees all cursor handles. |
diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp
index b834b630..04811b8c 100644
a
|
b
|
void Render()
|
274 | 274 | CStrW cursorName = g_CursorName; |
275 | 275 | if (cursorName.empty()) |
276 | 276 | { |
277 | | cursor_draw(g_VFS, NULL, g_mouse_x, g_yres-g_mouse_y, false); |
| 277 | cursor_draw(g_VFS, NULL, g_mouse_x, g_yres-g_mouse_y, 1.0 / g_GuiScale, false); |
278 | 278 | } |
279 | 279 | else |
280 | 280 | { |
… |
… |
void Render()
|
299 | 299 | #if OS_ANDROID |
300 | 300 | #warning TODO: cursors for Android |
301 | 301 | #else |
302 | | if (cursor_draw(g_VFS, cursorName.c_str(), g_mouse_x, g_yres-g_mouse_y, forceGL) < 0) |
| 302 | if (cursor_draw(g_VFS, cursorName.c_str(), g_mouse_x, g_yres-g_mouse_y, 1.0 / g_GuiScale, forceGL) < 0) |
303 | 303 | LOGWARNING("Failed to draw cursor '%s'", utf8_from_wstring(cursorName)); |
304 | 304 | #endif |
305 | 305 | |
… |
… |
static void ShutdownPs()
|
591 | 591 | UnloadHotkeys(); |
592 | 592 | |
593 | 593 | // disable the special Windows cursor, or free textures for OGL cursors |
594 | | cursor_draw(g_VFS, 0, g_mouse_x, g_yres-g_mouse_y, false); |
| 594 | cursor_draw(g_VFS, 0, g_mouse_x, g_yres-g_mouse_y, 1.0, false); |
595 | 595 | } |
596 | 596 | |
597 | 597 | |