1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 Sam Lantinga 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public 7 License as published by the Free Software Foundation; either 8 version 2 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public 16 License along with this library; if not, write to the Free 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 Sam Lantinga 20 slouken (at) libsdl.org 21 */ 22 #include "SDL_config.h" 23 24 /* Atari OSMesa.ldg implementation of SDL OpenGL support */ 25 26 /*--- Includes ---*/ 27 28 #if SDL_VIDEO_OPENGL 29 #include <GL/osmesa.h> 30 #endif 31 32 #include <mint/osbind.h> 33 34 #include "SDL_endian.h" 35 #include "SDL_video.h" 36 #include "SDL_atarigl_c.h" 37 #if SDL_VIDEO_OPENGL_OSMESA_DYNAMIC 38 #include "SDL_loadso.h" 39 #endif 40 41 /*--- Defines ---*/ 42 43 #define PATH_OSMESA_LDG "osmesa.ldg" 44 #define PATH_MESAGL_LDG "mesa_gl.ldg" 45 #define PATH_TINYGL_LDG "tiny_gl.ldg" 46 47 #define VDI_RGB 0xf 48 49 /*--- Functions prototypes ---*/ 50 51 #if SDL_VIDEO_OPENGL 52 static void SDL_AtariGL_UnloadLibrary(_THIS); 53 54 static void CopyShadowNull(_THIS, SDL_Surface *surface); 55 static void CopyShadowDirect(_THIS, SDL_Surface *surface); 56 static void CopyShadowRGBTo555(_THIS, SDL_Surface *surface); 57 static void CopyShadowRGBTo565(_THIS, SDL_Surface *surface); 58 static void CopyShadowRGBSwap(_THIS, SDL_Surface *surface); 59 static void CopyShadowRGBToARGB(_THIS, SDL_Surface *surface); 60 static void CopyShadowRGBToABGR(_THIS, SDL_Surface *surface); 61 static void CopyShadowRGBToBGRA(_THIS, SDL_Surface *surface); 62 static void CopyShadowRGBToRGBA(_THIS, SDL_Surface *surface); 63 static void CopyShadow8888To555(_THIS, SDL_Surface *surface); 64 static void CopyShadow8888To565(_THIS, SDL_Surface *surface); 65 66 static void ConvertNull(_THIS, SDL_Surface *surface); 67 static void Convert565To555be(_THIS, SDL_Surface *surface); 68 static void Convert565To555le(_THIS, SDL_Surface *surface); 69 static void Convert565le(_THIS, SDL_Surface *surface); 70 static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface); 71 72 static int InitNew(_THIS, SDL_Surface *current); 73 static int InitOld(_THIS, SDL_Surface *current); 74 #endif 75 76 /*--- Public functions ---*/ 77 78 int SDL_AtariGL_Init(_THIS, SDL_Surface *current) 79 { 80 #if SDL_VIDEO_OPENGL 81 if (gl_oldmesa) { 82 gl_active = InitOld(this, current); 83 } else { 84 gl_active = InitNew(this, current); 85 } 86 #endif 87 88 return (gl_active); 89 } 90 91 void SDL_AtariGL_Quit(_THIS, SDL_bool unload) 92 { 93 #if SDL_VIDEO_OPENGL 94 if (gl_oldmesa) { 95 /* Old mesa implementations */ 96 if (this->gl_data->OSMesaDestroyLDG) { 97 this->gl_data->OSMesaDestroyLDG(); 98 } 99 if (gl_shadow) { 100 Mfree(gl_shadow); 101 gl_shadow = NULL; 102 } 103 } else { 104 /* New mesa implementation */ 105 if (gl_ctx) { 106 if (this->gl_data->OSMesaDestroyContext) { 107 this->gl_data->OSMesaDestroyContext(gl_ctx); 108 } 109 gl_ctx = NULL; 110 } 111 } 112 113 if (unload) { 114 SDL_AtariGL_UnloadLibrary(this); 115 } 116 117 #endif /* SDL_VIDEO_OPENGL */ 118 gl_active = 0; 119 } 120 121 int SDL_AtariGL_LoadLibrary(_THIS, const char *path) 122 { 123 #if SDL_VIDEO_OPENGL 124 125 #if SDL_VIDEO_OPENGL_OSMESA_DYNAMIC 126 void *handle; 127 SDL_bool cancel_load; 128 129 if (gl_active) { 130 SDL_SetError("OpenGL context already created"); 131 return -1; 132 } 133 134 /* Unload previous driver */ 135 SDL_AtariGL_UnloadLibrary(this); 136 137 /* Load library given by path */ 138 handle = SDL_LoadObject(path); 139 if (handle == NULL) { 140 /* Try to load another one */ 141 path = SDL_getenv("SDL_VIDEO_GL_DRIVER"); 142 if ( path != NULL ) { 143 handle = SDL_LoadObject(path); 144 } 145 146 /* If it does not work, try some other */ 147 if (handle == NULL) { 148 path = PATH_OSMESA_LDG; 149 handle = SDL_LoadObject(path); 150 } 151 152 if (handle == NULL) { 153 path = PATH_MESAGL_LDG; 154 handle = SDL_LoadObject(path); 155 } 156 157 if (handle == NULL) { 158 path = PATH_TINYGL_LDG; 159 handle = SDL_LoadObject(path); 160 } 161 } 162 163 if (handle == NULL) { 164 SDL_SetError("Could not load OpenGL library"); 165 return -1; 166 } 167 168 this->gl_data->glGetIntegerv = SDL_LoadFunction(handle, "glGetIntegerv"); 169 this->gl_data->glFinish = SDL_LoadFunction(handle, "glFinish"); 170 this->gl_data->glFlush = SDL_LoadFunction(handle, "glFlush"); 171 172 cancel_load = SDL_FALSE; 173 if (this->gl_data->glGetIntegerv == NULL) { 174 cancel_load = SDL_TRUE; 175 } else { 176 /* We need either glFinish (OSMesa) or glFlush (TinyGL) */ 177 if ((this->gl_data->glFinish == NULL) && 178 (this->gl_data->glFlush == NULL)) { 179 cancel_load = SDL_TRUE; 180 } 181 } 182 if (cancel_load) { 183 SDL_SetError("Could not retrieve OpenGL functions"); 184 SDL_UnloadObject(handle); 185 /* Restore pointers to static library */ 186 SDL_AtariGL_InitPointers(this); 187 return -1; 188 } 189 190 /* Load functions pointers (osmesa.ldg) */ 191 this->gl_data->OSMesaCreateContextExt = SDL_LoadFunction(handle, "OSMesaCreateContextExt"); 192 this->gl_data->OSMesaDestroyContext = SDL_LoadFunction(handle, "OSMesaDestroyContext"); 193 this->gl_data->OSMesaMakeCurrent = SDL_LoadFunction(handle, "OSMesaMakeCurrent"); 194 this->gl_data->OSMesaPixelStore = SDL_LoadFunction(handle, "OSMesaPixelStore"); 195 this->gl_data->OSMesaGetProcAddress = SDL_LoadFunction(handle, "OSMesaGetProcAddress"); 196 197 /* Load old functions pointers (mesa_gl.ldg, tiny_gl.ldg) */ 198 this->gl_data->OSMesaCreateLDG = SDL_LoadFunction(handle, "OSMesaCreateLDG"); 199 this->gl_data->OSMesaDestroyLDG = SDL_LoadFunction(handle, "OSMesaDestroyLDG"); 200 201 gl_oldmesa = 0; 202 203 if ( (this->gl_data->OSMesaCreateContextExt == NULL) || 204 (this->gl_data->OSMesaDestroyContext == NULL) || 205 (this->gl_data->OSMesaMakeCurrent == NULL) || 206 (this->gl_data->OSMesaPixelStore == NULL) || 207 (this->gl_data->OSMesaGetProcAddress == NULL)) { 208 /* Hum, maybe old library ? */ 209 if ( (this->gl_data->OSMesaCreateLDG == NULL) || 210 (this->gl_data->OSMesaDestroyLDG == NULL)) { 211 SDL_SetError("Could not retrieve OSMesa functions"); 212 SDL_UnloadObject(handle); 213 /* Restore pointers to static library */ 214 SDL_AtariGL_InitPointers(this); 215 return -1; 216 } else { 217 gl_oldmesa = 1; 218 } 219 } 220 221 this->gl_config.dll_handle = handle; 222 if ( path ) { 223 SDL_strlcpy(this->gl_config.driver_path, path, 224 SDL_arraysize(this->gl_config.driver_path)); 225 } else { 226 *this->gl_config.driver_path = '\0'; 227 } 228 229 #endif 230 this->gl_config.driver_loaded = 1; 231 232 return 0; 233 #else 234 return -1; 235 #endif 236 } 237 238 void *SDL_AtariGL_GetProcAddress(_THIS, const char *proc) 239 { 240 void *func = NULL; 241 #if SDL_VIDEO_OPENGL 242 243 if (this->gl_config.dll_handle) { 244 func = SDL_LoadFunction(this->gl_config.dll_handle, (void *)proc); 245 } else if (this->gl_data->OSMesaGetProcAddress) { 246 func = this->gl_data->OSMesaGetProcAddress(proc); 247 } 248 249 #endif 250 return func; 251 } 252 253 int SDL_AtariGL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) 254 { 255 #if SDL_VIDEO_OPENGL 256 GLenum mesa_attrib; 257 SDL_Surface *surface; 258 259 if (!gl_active) { 260 return -1; 261 } 262 263 switch(attrib) { 264 case SDL_GL_RED_SIZE: 265 mesa_attrib = GL_RED_BITS; 266 break; 267 case SDL_GL_GREEN_SIZE: 268 mesa_attrib = GL_GREEN_BITS; 269 break; 270 case SDL_GL_BLUE_SIZE: 271 mesa_attrib = GL_BLUE_BITS; 272 break; 273 case SDL_GL_ALPHA_SIZE: 274 mesa_attrib = GL_ALPHA_BITS; 275 break; 276 case SDL_GL_DOUBLEBUFFER: 277 surface = this->screen; 278 *value = ((surface->flags & SDL_DOUBLEBUF)==SDL_DOUBLEBUF); 279 return 0; 280 case SDL_GL_DEPTH_SIZE: 281 mesa_attrib = GL_DEPTH_BITS; 282 break; 283 case SDL_GL_STENCIL_SIZE: 284 mesa_attrib = GL_STENCIL_BITS; 285 break; 286 case SDL_GL_ACCUM_RED_SIZE: 287 mesa_attrib = GL_ACCUM_RED_BITS; 288 break; 289 case SDL_GL_ACCUM_GREEN_SIZE: 290 mesa_attrib = GL_ACCUM_GREEN_BITS; 291 break; 292 case SDL_GL_ACCUM_BLUE_SIZE: 293 mesa_attrib = GL_ACCUM_BLUE_BITS; 294 break; 295 case SDL_GL_ACCUM_ALPHA_SIZE: 296 mesa_attrib = GL_ACCUM_ALPHA_BITS; 297 break; 298 default : 299 return -1; 300 } 301 302 this->gl_data->glGetIntegerv(mesa_attrib, value); 303 return 0; 304 #else 305 return -1; 306 #endif 307 } 308 309 int SDL_AtariGL_MakeCurrent(_THIS) 310 { 311 #if SDL_VIDEO_OPENGL 312 SDL_Surface *surface; 313 GLenum type; 314 315 if (gl_oldmesa && gl_active) { 316 return 0; 317 } 318 319 if (this->gl_config.dll_handle) { 320 if ((this->gl_data->OSMesaMakeCurrent == NULL) || 321 (this->gl_data->OSMesaPixelStore == NULL)) { 322 return -1; 323 } 324 } 325 326 if (!gl_active) { 327 SDL_SetError("Invalid OpenGL context"); 328 return -1; 329 } 330 331 surface = this->screen; 332 333 if ((surface->format->BitsPerPixel == 15) || (surface->format->BitsPerPixel == 16)) { 334 type = GL_UNSIGNED_SHORT_5_6_5; 335 } else { 336 type = GL_UNSIGNED_BYTE; 337 } 338 339 if (!(this->gl_data->OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w, surface->h))) { 340 SDL_SetError("Can not make OpenGL context current"); 341 return -1; 342 } 343 344 /* OSMesa draws upside down */ 345 this->gl_data->OSMesaPixelStore(OSMESA_Y_UP, 0); 346 347 return 0; 348 #else 349 return -1; 350 #endif 351 } 352 353 void SDL_AtariGL_SwapBuffers(_THIS) 354 { 355 #if SDL_VIDEO_OPENGL 356 if (gl_active) { 357 if (this->gl_config.dll_handle) { 358 if (this->gl_data->glFinish) { 359 this->gl_data->glFinish(); 360 } else if (this->gl_data->glFlush) { 361 this->gl_data->glFlush(); 362 } 363 } else { 364 this->gl_data->glFinish(); 365 } 366 gl_copyshadow(this, this->screen); 367 gl_convert(this, this->screen); 368 } 369 #endif 370 } 371 372 void SDL_AtariGL_InitPointers(_THIS) 373 { 374 #if SDL_VIDEO_OPENGL 375 this->gl_data->OSMesaCreateContextExt = OSMesaCreateContextExt; 376 this->gl_data->OSMesaDestroyContext = OSMesaDestroyContext; 377 this->gl_data->OSMesaMakeCurrent = OSMesaMakeCurrent; 378 this->gl_data->OSMesaPixelStore = OSMesaPixelStore; 379 this->gl_data->OSMesaGetProcAddress = OSMesaGetProcAddress; 380 381 this->gl_data->glGetIntegerv = glGetIntegerv; 382 this->gl_data->glFinish = glFinish; 383 this->gl_data->glFlush = glFlush; 384 385 this->gl_data->OSMesaCreateLDG = NULL; 386 this->gl_data->OSMesaDestroyLDG = NULL; 387 #endif 388 } 389 390 /*--- Private functions ---*/ 391 392 #if SDL_VIDEO_OPENGL 393 static void SDL_AtariGL_UnloadLibrary(_THIS) 394 { 395 if (this->gl_config.dll_handle) { 396 SDL_UnloadObject(this->gl_config.dll_handle); 397 this->gl_config.dll_handle = NULL; 398 399 /* Restore pointers to static library */ 400 SDL_AtariGL_InitPointers(this); 401 } 402 } 403 404 /*--- Creation of an OpenGL context using new/old functions ---*/ 405 406 static int InitNew(_THIS, SDL_Surface *current) 407 { 408 GLenum osmesa_format; 409 SDL_PixelFormat *pixel_format; 410 Uint32 redmask; 411 int recreatecontext; 412 GLint newaccumsize; 413 414 if (this->gl_config.dll_handle) { 415 if (this->gl_data->OSMesaCreateContextExt == NULL) { 416 return 0; 417 } 418 } 419 420 /* Init OpenGL context using OSMesa */ 421 gl_convert = ConvertNull; 422 gl_copyshadow = CopyShadowNull; 423 gl_upsidedown = SDL_FALSE; 424 425 pixel_format = current->format; 426 redmask = pixel_format->Rmask; 427 switch (pixel_format->BitsPerPixel) { 428 case 15: 429 /* 1555, big and little endian, unsupported */ 430 gl_pixelsize = 2; 431 osmesa_format = OSMESA_RGB_565; 432 if (redmask == 31<<10) { 433 gl_convert = Convert565To555be; 434 } else { 435 gl_convert = Convert565To555le; 436 } 437 break; 438 case 16: 439 gl_pixelsize = 2; 440 if (redmask == 31<<11) { 441 osmesa_format = OSMESA_RGB_565; 442 } else { 443 /* 565, little endian, unsupported */ 444 osmesa_format = OSMESA_RGB_565; 445 gl_convert = Convert565le; 446 } 447 break; 448 case 24: 449 gl_pixelsize = 3; 450 if (redmask == 255<<16) { 451 osmesa_format = OSMESA_RGB; 452 } else { 453 osmesa_format = OSMESA_BGR; 454 } 455 break; 456 case 32: 457 gl_pixelsize = 4; 458 if (redmask == 255<<16) { 459 osmesa_format = OSMESA_ARGB; 460 } else if (redmask == 255<<8) { 461 osmesa_format = OSMESA_BGRA; 462 } else if (redmask == 255<<24) { 463 osmesa_format = OSMESA_RGBA; 464 } else { 465 /* ABGR format unsupported */ 466 osmesa_format = OSMESA_BGRA; 467 gl_convert = ConvertBGRAToABGR; 468 } 469 break; 470 default: 471 gl_pixelsize = 1; 472 osmesa_format = OSMESA_COLOR_INDEX; 473 break; 474 } 475 476 /* Try to keep current context if possible */ 477 newaccumsize = 478 this->gl_config.accum_red_size + 479 this->gl_config.accum_green_size + 480 this->gl_config.accum_blue_size + 481 this->gl_config.accum_alpha_size; 482 recreatecontext=1; 483 if (gl_ctx && 484 (gl_curformat == osmesa_format) && 485 (gl_curdepth == this->gl_config.depth_size) && 486 (gl_curstencil == this->gl_config.stencil_size) && 487 (gl_curaccum == newaccumsize)) { 488 recreatecontext = 0; 489 } 490 if (recreatecontext) { 491 SDL_AtariGL_Quit(this, SDL_FALSE); 492 493 gl_ctx = this->gl_data->OSMesaCreateContextExt( 494 osmesa_format, this->gl_config.depth_size, 495 this->gl_config.stencil_size, newaccumsize, NULL ); 496 497 if (gl_ctx) { 498 gl_curformat = osmesa_format; 499 gl_curdepth = this->gl_config.depth_size; 500 gl_curstencil = this->gl_config.stencil_size; 501 gl_curaccum = newaccumsize; 502 } else { 503 gl_curformat = 0; 504 gl_curdepth = 0; 505 gl_curstencil = 0; 506 gl_curaccum = 0; 507 } 508 } 509 510 return (gl_ctx != NULL); 511 } 512 513 514 static int InitOld(_THIS, SDL_Surface *current) 515 { 516 GLenum osmesa_format; 517 SDL_PixelFormat *pixel_format; 518 Uint32 redmask; 519 int recreatecontext, tinygl_present; 520 521 if (this->gl_config.dll_handle) { 522 if (this->gl_data->OSMesaCreateLDG == NULL) { 523 return 0; 524 } 525 } 526 527 /* TinyGL only supports VDI_RGB (OSMESA_RGB) */ 528 tinygl_present=0; 529 if (this->gl_config.dll_handle) { 530 if (this->gl_data->glFinish == NULL) { 531 tinygl_present=1; 532 } 533 } 534 535 /* Init OpenGL context using OSMesa */ 536 gl_convert = ConvertNull; 537 gl_copyshadow = CopyShadowNull; 538 gl_upsidedown = SDL_FALSE; 539 540 pixel_format = current->format; 541 redmask = pixel_format->Rmask; 542 switch (pixel_format->BitsPerPixel) { 543 case 15: 544 /* 15 bits unsupported */ 545 if (tinygl_present) { 546 gl_pixelsize = 3; 547 osmesa_format = VDI_RGB; 548 if (redmask == 31<<10) { 549 gl_copyshadow = CopyShadowRGBTo555; 550 } else { 551 gl_copyshadow = CopyShadowRGBTo565; 552 gl_convert = Convert565To555le; 553 } 554 } else { 555 gl_pixelsize = 4; 556 gl_upsidedown = SDL_TRUE; 557 osmesa_format = OSMESA_ARGB; 558 if (redmask == 31<<10) { 559 gl_copyshadow = CopyShadow8888To555; 560 } else { 561 gl_copyshadow = CopyShadow8888To565; 562 gl_convert = Convert565To555le; 563 } 564 } 565 break; 566 case 16: 567 /* 16 bits unsupported */ 568 if (tinygl_present) { 569 gl_pixelsize = 3; 570 osmesa_format = VDI_RGB; 571 gl_copyshadow = CopyShadowRGBTo565; 572 if (redmask != 31<<11) { 573 /* 565, little endian, unsupported */ 574 gl_convert = Convert565le; 575 } 576 } else { 577 gl_pixelsize = 4; 578 gl_upsidedown = SDL_TRUE; 579 osmesa_format = OSMESA_ARGB; 580 gl_copyshadow = CopyShadow8888To565; 581 if (redmask != 31<<11) { 582 /* 565, little endian, unsupported */ 583 gl_convert = Convert565le; 584 } 585 } 586 break; 587 case 24: 588 gl_pixelsize = 3; 589 if (tinygl_present) { 590 osmesa_format = VDI_RGB; 591 gl_copyshadow = CopyShadowDirect; 592 if (redmask != 255<<16) { 593 gl_copyshadow = CopyShadowRGBSwap; 594 } 595 } else { 596 gl_copyshadow = CopyShadowDirect; 597 gl_upsidedown = SDL_TRUE; 598 if (redmask == 255<<16) { 599 osmesa_format = OSMESA_RGB; 600 } else { 601 osmesa_format = OSMESA_BGR; 602 } 603 } 604 break; 605 case 32: 606 if (tinygl_present) { 607 gl_pixelsize = 3; 608 osmesa_format = VDI_RGB; 609 gl_copyshadow = CopyShadowRGBToARGB; 610 if (redmask == 255) { 611 gl_convert = CopyShadowRGBToABGR; 612 } else if (redmask == 255<<8) { 613 gl_convert = CopyShadowRGBToBGRA; 614 } else if (redmask == 255<<24) { 615 gl_convert = CopyShadowRGBToRGBA; 616 } 617 } else { 618 gl_pixelsize = 4; 619 gl_upsidedown = SDL_TRUE; 620 gl_copyshadow = CopyShadowDirect; 621 if (redmask == 255<<16) { 622 osmesa_format = OSMESA_ARGB; 623 } else if (redmask == 255<<8) { 624 osmesa_format = OSMESA_BGRA; 625 } else if (redmask == 255<<24) { 626 osmesa_format = OSMESA_RGBA; 627 } else { 628 /* ABGR format unsupported */ 629 osmesa_format = OSMESA_BGRA; 630 gl_convert = ConvertBGRAToABGR; 631 } 632 } 633 break; 634 default: 635 if (tinygl_present) { 636 SDL_AtariGL_Quit(this, SDL_FALSE); 637 return 0; 638 } 639 gl_pixelsize = 1; 640 gl_copyshadow = CopyShadowDirect; 641 osmesa_format = OSMESA_COLOR_INDEX; 642 break; 643 } 644 645 /* Try to keep current context if possible */ 646 recreatecontext=1; 647 if (gl_shadow && 648 (gl_curformat == osmesa_format) && 649 (gl_curwidth == current->w) && 650 (gl_curheight == current->h)) { 651 recreatecontext = 0; 652 } 653 if (recreatecontext) { 654 SDL_AtariGL_Quit(this, SDL_FALSE); 655 656 gl_shadow = this->gl_data->OSMesaCreateLDG( 657 osmesa_format, GL_UNSIGNED_BYTE, current->w, current->h 658 ); 659 660 if (gl_shadow) { 661 gl_curformat = osmesa_format; 662 gl_curwidth = current->w; 663 gl_curheight = current->h; 664 } else { 665 gl_curformat = 0; 666 gl_curwidth = 0; 667 gl_curheight = 0; 668 } 669 } 670 671 return (gl_shadow != NULL); 672 } 673 674 /*--- Conversions routines from shadow buffer to the screen ---*/ 675 676 static void CopyShadowNull(_THIS, SDL_Surface *surface) 677 { 678 } 679 680 static void CopyShadowDirect(_THIS, SDL_Surface *surface) 681 { 682 int y, srcpitch, dstpitch; 683 Uint8 *srcline, *dstline; 684 685 srcline = gl_shadow; 686 srcpitch = surface->w * gl_pixelsize; 687 dstline = surface->pixels; 688 dstpitch = surface->pitch; 689 if (gl_upsidedown) { 690 srcline += (surface->h-1)*srcpitch; 691 srcpitch = -srcpitch; 692 } 693 694 for (y=0; y<surface->h; y++) { 695 SDL_memcpy(dstline, srcline, srcpitch); 696 697 srcline += srcpitch; 698 dstline += dstpitch; 699 } 700 } 701 702 static void CopyShadowRGBTo555(_THIS, SDL_Surface *surface) 703 { 704 int x,y, srcpitch, dstpitch; 705 Uint16 *dstline, *dstcol; 706 Uint8 *srcline, *srccol; 707 708 srcline = (Uint8 *)gl_shadow; 709 srcpitch = surface->w * gl_pixelsize; 710 dstline = surface->pixels; 711 dstpitch = surface->pitch >>1; 712 if (gl_upsidedown) { 713 srcline += (surface->h-1)*srcpitch; 714 srcpitch = -srcpitch; 715 } 716 717 for (y=0; y<surface->h; y++) { 718 srccol = srcline; 719 dstcol = dstline; 720 for (x=0; x<surface->w; x++) { 721 Uint16 dstcolor; 722 723 dstcolor = ((*srccol++)<<7) & (31<<10); 724 dstcolor |= ((*srccol++)<<2) & (31<<5); 725 dstcolor |= ((*srccol++)>>3) & 31; 726 *dstcol++ = dstcolor; 727 } 728 729 srcline += srcpitch; 730 dstline += dstpitch; 731 } 732 } 733 734 static void CopyShadowRGBTo565(_THIS, SDL_Surface *surface) 735 { 736 int x,y, srcpitch, dstpitch; 737 Uint16 *dstline, *dstcol; 738 Uint8 *srcline, *srccol; 739 740 srcline = (Uint8 *)gl_shadow; 741 srcpitch = surface->w * gl_pixelsize; 742 dstline = surface->pixels; 743 dstpitch = surface->pitch >>1; 744 if (gl_upsidedown) { 745 srcline += (surface->h-1)*srcpitch; 746 srcpitch = -srcpitch; 747 } 748 749 for (y=0; y<surface->h; y++) { 750 srccol = srcline; 751 dstcol = dstline; 752 753 for (x=0; x<surface->w; x++) { 754 Uint16 dstcolor; 755 756 dstcolor = ((*srccol++)<<8) & (31<<11); 757 dstcolor |= ((*srccol++)<<3) & (63<<5); 758 dstcolor |= ((*srccol++)>>3) & 31; 759 *dstcol++ = dstcolor; 760 } 761 762 srcline += srcpitch; 763 dstline += dstpitch; 764 } 765 } 766 767 static void CopyShadowRGBSwap(_THIS, SDL_Surface *surface) 768 { 769 int x,y, srcpitch, dstpitch; 770 Uint8 *dstline, *dstcol; 771 Uint8 *srcline, *srccol; 772 773 srcline = (Uint8 *)gl_shadow; 774 srcpitch = surface->w * gl_pixelsize; 775 dstline = surface->pixels; 776 dstpitch = surface->pitch; 777 if (gl_upsidedown) { 778 srcline += (surface->h-1)*srcpitch; 779 srcpitch = -srcpitch; 780 } 781 782 for (y=0; y<surface->h; y++) { 783 srccol = srcline; 784 dstcol = dstline; 785 786 for (x=0; x<surface->w; x++) { 787 *dstcol++ = srccol[2]; 788 *dstcol++ = srccol[1]; 789 *dstcol++ = srccol[0]; 790 srccol += 3; 791 } 792 793 srcline += srcpitch; 794 dstline += dstpitch; 795 } 796 } 797 798 static void CopyShadowRGBToARGB(_THIS, SDL_Surface *surface) 799 { 800 int x,y, srcpitch, dstpitch; 801 Uint32 *dstline, *dstcol; 802 Uint8 *srcline, *srccol; 803 804 srcline = (Uint8 *)gl_shadow; 805 srcpitch = surface->w * gl_pixelsize; 806 dstline = surface->pixels; 807 dstpitch = surface->pitch >>2; 808 if (gl_upsidedown) { 809 srcline += (surface->h-1)*srcpitch; 810 srcpitch = -srcpitch; 811 } 812 813 for (y=0; y<surface->h; y++) { 814 srccol = srcline; 815 dstcol = dstline; 816 817 for (x=0; x<surface->w; x++) { 818 Uint32 dstcolor; 819 820 dstcolor = (*srccol++)<<16; 821 dstcolor |= (*srccol++)<<8; 822 dstcolor |= *srccol++; 823 824 *dstcol++ = dstcolor; 825 } 826 827 srcline += srcpitch; 828 dstline += dstpitch; 829 } 830 } 831 832 static void CopyShadowRGBToABGR(_THIS, SDL_Surface *surface) 833 { 834 int x,y, srcpitch, dstpitch; 835 Uint32 *dstline, *dstcol; 836 Uint8 *srcline, *srccol; 837 838 srcline = (Uint8 *)gl_shadow; 839 srcpitch = surface->w * gl_pixelsize; 840 dstline = surface->pixels; 841 dstpitch = surface->pitch >>2; 842 if (gl_upsidedown) { 843 srcline += (surface->h-1)*srcpitch; 844 srcpitch = -srcpitch; 845 } 846 847 for (y=0; y<surface->h; y++) { 848 srccol = srcline; 849 dstcol = dstline; 850 851 for (x=0; x<surface->w; x++) { 852 Uint32 dstcolor; 853 854 dstcolor = *srccol++; 855 dstcolor |= (*srccol++)<<8; 856 dstcolor |= (*srccol++)<<16; 857 858 *dstcol++ = dstcolor; 859 } 860 861 srcline += srcpitch; 862 dstline += dstpitch; 863 } 864 } 865 866 static void CopyShadowRGBToBGRA(_THIS, SDL_Surface *surface) 867 { 868 int x,y, srcpitch, dstpitch; 869 Uint32 *dstline, *dstcol; 870 Uint8 *srcline, *srccol; 871 872 srcline = (Uint8 *)gl_shadow; 873 srcpitch = surface->w * gl_pixelsize; 874 dstline = surface->pixels; 875 dstpitch = surface->pitch >>2; 876 if (gl_upsidedown) { 877 srcline += (surface->h-1)*srcpitch; 878 srcpitch = -srcpitch; 879 } 880 881 for (y=0; y<surface->h; y++) { 882 srccol = srcline; 883 dstcol = dstline; 884 885 for (x=0; x<surface->w; x++) { 886 Uint32 dstcolor; 887 888 dstcolor = (*srccol++)<<8; 889 dstcolor |= (*srccol++)<<16; 890 dstcolor |= (*srccol++)<<24; 891 892 *dstcol++ = dstcolor; 893 } 894 895 srcline += srcpitch; 896 dstline += dstpitch; 897 } 898 } 899 900 static void CopyShadowRGBToRGBA(_THIS, SDL_Surface *surface) 901 { 902 int x,y, srcpitch, dstpitch; 903 Uint32 *dstline, *dstcol; 904 Uint8 *srcline, *srccol; 905 906 srcline = (Uint8 *)gl_shadow; 907 srcpitch = surface->w * gl_pixelsize; 908 dstline = surface->pixels; 909 dstpitch = surface->pitch >>2; 910 if (gl_upsidedown) { 911 srcline += (surface->h-1)*srcpitch; 912 srcpitch = -srcpitch; 913 } 914 915 for (y=0; y<surface->h; y++) { 916 srccol = srcline; 917 dstcol = dstline; 918 919 for (x=0; x<surface->w; x++) { 920 Uint32 dstcolor; 921 922 dstcolor = (*srccol++)<<24; 923 dstcolor |= (*srccol++)<<16; 924 dstcolor |= (*srccol++)<<8; 925 926 *dstcol++ = dstcolor; 927 } 928 929 srcline += srcpitch; 930 dstline += dstpitch; 931 } 932 } 933 934 static void CopyShadow8888To555(_THIS, SDL_Surface *surface) 935 { 936 int x,y, srcpitch, dstpitch; 937 Uint16 *dstline, *dstcol; 938 Uint32 *srcline, *srccol; 939 940 srcline = (Uint32 *)gl_shadow; 941 srcpitch = (surface->w * gl_pixelsize) >>2; 942 dstline = surface->pixels; 943 dstpitch = surface->pitch >>1; 944 if (gl_upsidedown) { 945 srcline += (surface->h-1)*srcpitch; 946 srcpitch = -srcpitch; 947 } 948 949 for (y=0; y<surface->h; y++) { 950 srccol = srcline; 951 dstcol = dstline; 952 for (x=0; x<surface->w; x++) { 953 Uint32 srccolor; 954 Uint16 dstcolor; 955 956 srccolor = *srccol++; 957 dstcolor = (srccolor>>9) & (31<<10); 958 dstcolor |= (srccolor>>6) & (31<<5); 959 dstcolor |= (srccolor>>3) & 31; 960 *dstcol++ = dstcolor; 961 } 962 963 srcline += srcpitch; 964 dstline += dstpitch; 965 } 966 } 967 968 static void CopyShadow8888To565(_THIS, SDL_Surface *surface) 969 { 970 int x,y, srcpitch, dstpitch; 971 Uint16 *dstline, *dstcol; 972 Uint32 *srcline, *srccol; 973 974 srcline = (Uint32 *)gl_shadow; 975 srcpitch = (surface->w * gl_pixelsize) >> 2; 976 dstline = surface->pixels; 977 dstpitch = surface->pitch >>1; 978 if (gl_upsidedown) { 979 srcline += (surface->h-1)*srcpitch; 980 srcpitch = -srcpitch; 981 } 982 983 for (y=0; y<surface->h; y++) { 984 srccol = srcline; 985 dstcol = dstline; 986 987 for (x=0; x<surface->w; x++) { 988 Uint32 srccolor; 989 Uint16 dstcolor; 990 991 srccolor = *srccol++; 992 dstcolor = (srccolor>>8) & (31<<11); 993 dstcolor |= (srccolor>>5) & (63<<5); 994 dstcolor |= (srccolor>>3) & 31; 995 *dstcol++ = dstcolor; 996 } 997 998 srcline += srcpitch; 999 dstline += dstpitch; 1000 } 1001 } 1002 1003 /*--- Conversions routines in the screen ---*/ 1004 1005 static void ConvertNull(_THIS, SDL_Surface *surface) 1006 { 1007 } 1008 1009 static void Convert565To555be(_THIS, SDL_Surface *surface) 1010 { 1011 int x,y, pitch; 1012 unsigned short *line, *pixel; 1013 1014 line = surface->pixels; 1015 pitch = surface->pitch >> 1; 1016 for (y=0; y<surface->h; y++) { 1017 pixel = line; 1018 for (x=0; x<surface->w; x++) { 1019 unsigned short color = *pixel; 1020 1021 *pixel++ = (color & 0x1f)|((color>>1) & 0xffe0); 1022 } 1023 1024 line += pitch; 1025 } 1026 } 1027 1028 static void Convert565To555le(_THIS, SDL_Surface *surface) 1029 { 1030 int x,y, pitch; 1031 unsigned short *line, *pixel; 1032 1033 line = surface->pixels; 1034 pitch = surface->pitch >>1; 1035 for (y=0; y<surface->h; y++) { 1036 pixel = line; 1037 for (x=0; x<surface->w; x++) { 1038 unsigned short color = *pixel; 1039 1040 color = (color & 0x1f)|((color>>1) & 0xffe0); 1041 *pixel++ = SDL_Swap16(color); 1042 } 1043 1044 line += pitch; 1045 } 1046 } 1047 1048 static void Convert565le(_THIS, SDL_Surface *surface) 1049 { 1050 int x,y, pitch; 1051 unsigned short *line, *pixel; 1052 1053 line = surface->pixels; 1054 pitch = surface->pitch >>1; 1055 for (y=0; y<surface->h; y++) { 1056 pixel = line; 1057 for (x=0; x<surface->w; x++) { 1058 unsigned short color = *pixel; 1059 1060 *pixel++ = SDL_Swap16(color); 1061 } 1062 1063 line += pitch; 1064 } 1065 } 1066 1067 static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface) 1068 { 1069 int x,y, pitch; 1070 unsigned long *line, *pixel; 1071 1072 line = surface->pixels; 1073 pitch = surface->pitch >>2; 1074 for (y=0; y<surface->h; y++) { 1075 pixel = line; 1076 for (x=0; x<surface->w; x++) { 1077 unsigned long color = *pixel; 1078 1079 *pixel++ = (color<<24)|(color>>8); 1080 } 1081 1082 line += pitch; 1083 } 1084 } 1085 1086 #endif /* SDL_VIDEO_OPENGL */ 1087