Ticket #935: SDL2_color_cursors_wip.patch
File SDL2_color_cursors_wip.patch, 4.7 KB (added by , 11 years ago) |
---|
-
source/lib/res/graphics/cursor.cpp
1 /* Copyright (c) 201 2Wildfire Games1 /* Copyright (c) 2013 Wildfire Games 2 2 * 3 3 * Permission is hereby granted, free of charge, to any person obtaining 4 4 * a copy of this software and associated documentation files (the … … 31 31 #include <cstdio> 32 32 #include <sstream> 33 33 34 #include "lib/external_libraries/libsdl.h" 34 35 #include "lib/ogl.h" 35 36 #include "lib/sysdep/cursor.h" 36 37 #include "ogl_tex.h" … … 76 77 } 77 78 78 79 80 class SDLCursor 81 { 82 SDL_Surface* surface; 83 SDL_Cursor* cursor; 84 85 public: 86 Status create(const PIVFS& vfs, const VfsPath& pathname, int hotspotx_, int hotspoty_) 87 { 88 shared_ptr<u8> file; size_t fileSize; 89 RETURN_STATUS_IF_ERR(vfs->LoadFile(pathname, file, fileSize)); 90 91 ScopedTex t; 92 RETURN_STATUS_IF_ERR(tex_decode(file, fileSize, &t)); 93 94 // convert to required BGRA format. 95 const size_t flags = (t.flags | TEX_BGR) & ~TEX_DXT; 96 RETURN_STATUS_IF_ERR(tex_transform_to(&t, flags)); 97 void* bgra_img = tex_get_data(&t); 98 if(!bgra_img) 99 WARN_RETURN(ERR::FAIL); 100 101 surface = SDL_CreateRGBSurfaceFrom(bgra_img, (int)t.w, (int)t.h, 32, (int)t.w*4, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); 102 if (!surface) 103 return ERR::FAIL; 104 cursor = SDL_CreateColorCursor(surface, hotspotx_, hotspoty_); 105 if (!cursor) 106 return ERR::FAIL; 107 108 return INFO::OK; 109 } 110 111 void set() 112 { 113 SDL_SetCursor(cursor); 114 } 115 116 void destroy() 117 { 118 SDL_FreeCursor(cursor); 119 SDL_FreeSurface(surface); 120 } 121 }; 122 79 123 // no init is necessary because this is stored in struct Cursor, which 80 124 // is 0-initialized by h_mgr. 81 125 class GLCursor … … 151 195 { 152 196 CK_Default, 153 197 CK_System, 198 CK_SDL, 154 199 CK_OpenGL 155 200 }; 156 201 … … 164 209 // valid iff kind == CK_System 165 210 sys_cursor system_cursor; 166 211 212 // valid iff kind == CK_SDL 213 SDLCursor sdl_cursor; 214 167 215 // valid iff kind == CK_OpenGL 168 216 GLCursor gl_cursor; 169 217 sys_cursor gl_empty_system_cursor; … … 187 235 sys_cursor_free(c->system_cursor); 188 236 break; 189 237 238 case CK_SDL: 239 c->sdl_cursor.destroy(); 240 break; 241 190 242 case CK_OpenGL: 191 243 c->gl_cursor.destroy(); 244 #if !SDL_VERSION_ATLEAST(2, 0, 0) 192 245 sys_cursor_free(c->gl_empty_system_cursor); 246 #endif 193 247 break; 194 248 195 249 default: … … 215 269 216 270 const VfsPath pathnameImage = pathname.ChangeExtension(L".png"); 217 271 218 // try loading as system cursor (2d, hardware accelerated) 219 if(!c->forceGL && load_sys_cursor(vfs, pathnameImage, hotspotx, hotspoty, &c->system_cursor) == INFO::OK) 220 c->kind = CK_System; 272 if(!c->forceGL) 273 { 274 #if SDL_VERSION_ATLEAST(2, 0, 0) 275 // try loading as SDL 2.0 cursor 276 if (c->sdl_cursor.create(vfs, pathnameImage, hotspotx, hotspoty) == INFO::OK) 277 c->kind = CK_SDL; 278 #else 279 // try loading as system cursor (2d, hardware accelerated) 280 if (load_sys_cursor(vfs, pathnameImage, hotspotx, hotspoty, &c->system_cursor) == INFO::OK) 281 c->kind = CK_System; 282 #endif 283 } 221 284 // fall back to GLCursor (system cursor code is disabled or failed) 222 285 else if(c->gl_cursor.create(vfs, pathnameImage, hotspotx, hotspoty) == INFO::OK) 223 286 { 224 287 c->kind = CK_OpenGL; 288 #if !SDL_VERSION_ATLEAST(2, 0, 0) 225 289 // (we need to hide the system cursor when using a OpenGL cursor) 226 290 sys_cursor_create_empty(&c->gl_empty_system_cursor); 291 #endif 227 292 } 228 293 // everything failed, leave cursor unchanged 229 294 else … … 244 309 WARN_RETURN(ERR::_1); 245 310 break; 246 311 312 case CK_SDL: 313 break; // nothing to do 314 247 315 case CK_OpenGL: 248 316 RETURN_STATUS_IF_ERR(c->gl_cursor.validate()); 249 317 break; … … 269 337 type = L"sys"; 270 338 break; 271 339 340 case CK_SDL: 341 type = L"sdl"; 342 break; 343 272 344 case CK_OpenGL: 273 345 type = L"gl"; 274 346 break; … … 311 383 // hide the cursor 312 384 if(!name) 313 385 { 386 #if !SDL_VERSION_ATLEAST(2, 0, 0) 314 387 sys_cursor_set(0); 388 #else 389 SDL_ShowCursor(SDL_DISABLE); 390 #endif 315 391 return INFO::OK; 316 392 } 317 393 … … 331 407 case CK_System: 332 408 sys_cursor_set(c->system_cursor); 333 409 break; 410 411 case CK_SDL: 412 c->sdl_cursor.set(); 413 SDL_ShowCursor(SDL_ENABLE); 414 break; 334 415 335 416 case CK_OpenGL: 336 417 c->gl_cursor.draw(x, y); 418 #if !SDL_VERSION_ATLEAST(2, 0, 0) 337 419 // note: gl_empty_system_cursor can be 0 if sys_cursor_create_empty 338 420 // failed; in that case we don't want to sys_cursor_set because that 339 421 // would restore the default cursor (which is exactly what we're 340 422 // trying to avoid here) 341 423 if(c->gl_empty_system_cursor) 342 424 sys_cursor_set(c->gl_empty_system_cursor); 425 #else 426 SDL_ShowCursor(SDL_DISABLE); 427 #endif 343 428 break; 344 429 345 430 default: