Index: ps/trunk/source/lib/res/graphics/cursor.h =================================================================== --- ps/trunk/source/lib/res/graphics/cursor.h +++ ps/trunk/source/lib/res/graphics/cursor.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010 Wildfire Games +/* Copyright (c) 2017 Wildfire Games * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -39,12 +39,13 @@ * mouse Y coordinate to be subtracted from the client area height. * Making the caller responsible for this avoids a dependency on * the g_yres global variable.) + * @param scale Scale factor for drawing size the cursor. * @param forceGL Require the OpenGL cursor implementation, not hardware cursor * * Uses a hardware mouse cursor where available, otherwise a * portable OpenGL implementation. **/ -extern Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y, bool forceGL); +extern Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y, double scale, bool forceGL); /** * Forcibly frees all cursor handles. Index: ps/trunk/source/lib/res/graphics/cursor.cpp =================================================================== --- ps/trunk/source/lib/res/graphics/cursor.cpp +++ ps/trunk/source/lib/res/graphics/cursor.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014 Wildfire Games +/* Copyright (c) 2017 Wildfire Games * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -52,7 +52,7 @@ SDL_Cursor* cursor; public: - Status create(const PIVFS& vfs, const VfsPath& pathname, int hotspotx_, int hotspoty_) + Status create(const PIVFS& vfs, const VfsPath& pathname, int hotspotx_, int hotspoty_, double scale) { shared_ptr file; size_t fileSize; RETURN_STATUS_IF_ERR(vfs->LoadFile(pathname, file, fileSize)); @@ -70,6 +70,16 @@ surface = SDL_CreateRGBSurfaceFrom(bgra_img, (int)t.m_Width, (int)t.m_Height, 32, (int)t.m_Width*4, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); if (!surface) return ERR::FAIL; + if (scale != 1.0) + { + SDL_Surface* scaled_surface = SDL_CreateRGBSurface(0, surface->w * scale, surface->h * scale, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); + if (!scaled_surface) + return ERR::FAIL; + if (SDL_BlitScaled(surface, NULL, scaled_surface, NULL)) + return ERR::FAIL; + SDL_FreeSurface(surface); + surface = scaled_surface; + } cursor = SDL_CreateColorCursor(surface, hotspotx_, hotspoty_); if (!cursor) return ERR::FAIL; @@ -99,15 +109,15 @@ int hotspotx, hotspoty; public: - Status create(const PIVFS& vfs, const VfsPath& pathname, int hotspotx_, int hotspoty_) + Status create(const PIVFS& vfs, const VfsPath& pathname, int hotspotx_, int hotspoty_, double scale) { ht = ogl_tex_load(vfs, pathname); RETURN_STATUS_IF_ERR(ht); size_t width, height; (void)ogl_tex_get_size(ht, &width, &height, 0); - w = (GLint)width; - h = (GLint)height; + w = (GLint)(width * scale); + h = (GLint)(height * scale); hotspotx = hotspotx_; hotspoty = hotspoty_; @@ -169,6 +179,8 @@ struct Cursor { + double scale; + // require kind == CK_OpenGL after reload bool forceGL; @@ -185,6 +197,7 @@ static void Cursor_init(Cursor* c, va_list args) { + c->scale = va_arg(args, double); c->forceGL = (va_arg(args, int) != 0); } @@ -227,13 +240,11 @@ const VfsPath pathnameImage = pathname.ChangeExtension(L".png"); // try loading as SDL2 cursor - if (!c->forceGL && c->sdl_cursor.create(vfs, pathnameImage, hotspotx, hotspoty) == INFO::OK) + if (!c->forceGL && c->sdl_cursor.create(vfs, pathnameImage, hotspotx, hotspoty, c->scale) == INFO::OK) c->kind = CK_SDL; // fall back to GLCursor (system cursor code is disabled or failed) - else if(c->gl_cursor.create(vfs, pathnameImage, hotspotx, hotspoty) == INFO::OK) - { + else if (c->gl_cursor.create(vfs, pathnameImage, hotspotx, hotspoty, c->scale) == INFO::OK) c->kind = CK_OpenGL; - } // everything failed, leave cursor unchanged else c->kind = CK_Default; @@ -297,9 +308,9 @@ // in other words, we continually create/free the cursor resource in // cursor_draw and trust h_mgr's caching to absorb it. -static Handle cursor_load(const PIVFS& vfs, const VfsPath& name, bool forceGL) +static Handle cursor_load(const PIVFS& vfs, const VfsPath& name, double scale, bool forceGL) { - return h_alloc(H_Cursor, vfs, name, 0, (int)forceGL); + return h_alloc(H_Cursor, vfs, name, 0, scale, (int)forceGL); } void cursor_shutdown() @@ -313,7 +324,7 @@ } -Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y, bool forceGL) +Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y, double scale, bool forceGL) { // hide the cursor if(!name) @@ -322,7 +333,7 @@ return INFO::OK; } - Handle hc = cursor_load(vfs, name, forceGL); + Handle hc = cursor_load(vfs, name, scale, forceGL); // TODO: if forceGL changes at runtime after a cursor is first created, // we might reuse a cached version of the cursor with the old forceGL flag Index: ps/trunk/source/ps/GameSetup/GameSetup.cpp =================================================================== --- ps/trunk/source/ps/GameSetup/GameSetup.cpp +++ ps/trunk/source/ps/GameSetup/GameSetup.cpp @@ -281,7 +281,7 @@ CStrW cursorName = g_CursorName; if (cursorName.empty()) { - cursor_draw(g_VFS, NULL, g_mouse_x, g_yres-g_mouse_y, false); + cursor_draw(g_VFS, NULL, g_mouse_x, g_yres-g_mouse_y, 1.0 / g_GuiScale, false); } else { @@ -306,7 +306,7 @@ #if OS_ANDROID #warning TODO: cursors for Android #else - if (cursor_draw(g_VFS, cursorName.c_str(), g_mouse_x, g_yres-g_mouse_y, forceGL) < 0) + if (cursor_draw(g_VFS, cursorName.c_str(), g_mouse_x, g_yres-g_mouse_y, 1.0 / g_GuiScale, forceGL) < 0) LOGWARNING("Failed to draw cursor '%s'", utf8_from_wstring(cursorName)); #endif @@ -598,7 +598,7 @@ UnloadHotkeys(); // disable the special Windows cursor, or free textures for OGL cursors - cursor_draw(g_VFS, 0, g_mouse_x, g_yres-g_mouse_y, false); + cursor_draw(g_VFS, 0, g_mouse_x, g_yres-g_mouse_y, 1.0, false); }