1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2004 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 static void SDL_AtariGL_UnloadLibrary(_THIS); 52 53 #if SDL_VIDEO_OPENGL 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 static void SDL_AtariGL_UnloadLibrary(_THIS) 393 { 394 #if SDL_VIDEO_OPENGL 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 #endif 403 } 404 405 /*--- Creation of an OpenGL context using new/old functions ---*/ 406 407 #if SDL_VIDEO_OPENGL 408 static int InitNew(_THIS, SDL_Surface *current) 409 { 410 GLenum osmesa_format; 411 SDL_PixelFormat *pixel_format; 412 Uint32 redmask; 413 int recreatecontext; 414 GLint newaccumsize; 415 416 if (this->gl_config.dll_handle) { 417 if (this->gl_data->OSMesaCreateContextExt == NULL) { 418 return 0; 419 } 420 } 421 422 /* Init OpenGL context using OSMesa */ 423 gl_convert = ConvertNull; 424 gl_copyshadow = CopyShadowNull; 425 gl_upsidedown = SDL_FALSE; 426 427 pixel_format = current->format; 428 redmask = pixel_format->Rmask; 429 switch (pixel_format->BitsPerPixel) { 430 case 15: 431 /* 1555, big and little endian, unsupported */ 432 gl_pixelsize = 2; 433 osmesa_format = OSMESA_RGB_565; 434 if (redmask == 31<<10) { 435 gl_convert = Convert565To555be; 436 } else { 437 gl_convert = Convert565To555le; 438 } 439 break; 440 case 16: 441 gl_pixelsize = 2; 442 if (redmask == 31<<11) { 443 osmesa_format = OSMESA_RGB_565; 444 } else { 445 /* 565, little endian, unsupported */ 446 osmesa_format = OSMESA_RGB_565; 447 gl_convert = Convert565le; 448 } 449 break; 450 case 24: 451 gl_pixelsize = 3; 452 if (redmask == 255<<16) { 453 osmesa_format = OSMESA_RGB; 454 } else { 455 osmesa_format = OSMESA_BGR; 456 } 457 break; 458 case 32: 459 gl_pixelsize = 4; 460 if (redmask == 255<<16) { 461 osmesa_format = OSMESA_ARGB; 462 } else if (redmask == 255<<8) { 463 osmesa_format = OSMESA_BGRA; 464 } else if (redmask == 255<<24) { 465 osmesa_format = OSMESA_RGBA; 466 } else { 467 /* ABGR format unsupported */ 468 osmesa_format = OSMESA_BGRA; 469 gl_convert = ConvertBGRAToABGR; 470 } 471 break; 472 default: 473 gl_pixelsize = 1; 474 osmesa_format = OSMESA_COLOR_INDEX; 475 break; 476 } 477 478 /* Try to keep current context if possible */ 479 newaccumsize = 480 this->gl_config.accum_red_size + 481 this->gl_config.accum_green_size + 482 this->gl_config.accum_blue_size + 483 this->gl_config.accum_alpha_size; 484 recreatecontext=1; 485 if (gl_ctx && 486 (gl_curformat == osmesa_format) && 487 (gl_curdepth == this->gl_config.depth_size) && 488 (gl_curstencil == this->gl_config.stencil_size) && 489 (gl_curaccum == newaccumsize)) { 490 recreatecontext = 0; 491 } 492 if (recreatecontext) { 493 SDL_AtariGL_Quit(this, SDL_FALSE); 494 495 gl_ctx = this->gl_data->OSMesaCreateContextExt( 496 osmesa_format, this->gl_config.depth_size, 497 this->gl_config.stencil_size, newaccumsize, NULL ); 498 499 if (gl_ctx) { 500 gl_curformat = osmesa_format; 501 gl_curdepth = this->gl_config.depth_size; 502 gl_curstencil = this->gl_config.stencil_size; 503 gl_curaccum = newaccumsize; 504 } else { 505 gl_curformat = 0; 506 gl_curdepth = 0; 507 gl_curstencil = 0; 508 gl_curaccum = 0; 509 } 510 } 511 512 return (gl_ctx != NULL); 513 } 514 515 516 static int InitOld(_THIS, SDL_Surface *current) 517 { 518 GLenum osmesa_format; 519 SDL_PixelFormat *pixel_format; 520 Uint32 redmask; 521 int recreatecontext, tinygl_present; 522 523 if (this->gl_config.dll_handle) { 524 if (this->gl_data->OSMesaCreateLDG == NULL) { 525 return 0; 526 } 527 } 528 529 /* TinyGL only supports VDI_RGB (OSMESA_RGB) */ 530 tinygl_present=0; 531 if (this->gl_config.dll_handle) { 532 if (this->gl_data->glFinish == NULL) { 533 tinygl_present=1; 534 } 535 } 536 537 /* Init OpenGL context using OSMesa */ 538 gl_convert = ConvertNull; 539 gl_copyshadow = CopyShadowNull; 540 gl_upsidedown = SDL_FALSE; 541 542 pixel_format = current->format; 543 redmask = pixel_format->Rmask; 544 switch (pixel_format->BitsPerPixel) { 545 case 15: 546 /* 15 bits unsupported */ 547 if (tinygl_present) { 548 gl_pixelsize = 3; 549 osmesa_format = VDI_RGB; 550 if (redmask == 31<<10) { 551 gl_copyshadow = CopyShadowRGBTo555; 552 } else { 553 gl_copyshadow = CopyShadowRGBTo565; 554 gl_convert = Convert565To555le; 555 } 556 } else { 557 gl_pixelsize = 4; 558 gl_upsidedown = SDL_TRUE; 559 osmesa_format = OSMESA_ARGB; 560 if (redmask == 31<<10) { 561 gl_copyshadow = CopyShadow8888To555; 562 } else { 563 gl_copyshadow = CopyShadow8888To565; 564 gl_convert = Convert565To555le; 565 } 566 } 567 break; 568 case 16: 569 /* 16 bits unsupported */ 570 if (tinygl_present) { 571 gl_pixelsize = 3; 572 osmesa_format = VDI_RGB; 573 gl_copyshadow = CopyShadowRGBTo565; 574 if (redmask != 31<<11) { 575 /* 565, little endian, unsupported */ 576 gl_convert = Convert565le; 577 } 578 } else { 579 gl_pixelsize = 4; 580 gl_upsidedown = SDL_TRUE; 581 osmesa_format = OSMESA_ARGB; 582 gl_copyshadow = CopyShadow8888To565; 583 if (redmask != 31<<11) { 584 /* 565, little endian, unsupported */ 585 gl_convert = Convert565le; 586 } 587 } 588 break; 589 case 24: 590 gl_pixelsize = 3; 591 if (tinygl_present) { 592 osmesa_format = VDI_RGB; 593 gl_copyshadow = CopyShadowDirect; 594 if (redmask != 255<<16) { 595 gl_copyshadow = CopyShadowRGBSwap; 596 } 597 } else { 598 gl_copyshadow = CopyShadowDirect; 599 gl_upsidedown = SDL_TRUE; 600 if (redmask == 255<<16) { 601 osmesa_format = OSMESA_RGB; 602 } else { 603 osmesa_format = OSMESA_BGR; 604 } 605 } 606 break; 607 case 32: 608 if (tinygl_present) { 609 gl_pixelsize = 3; 610 osmesa_format = VDI_RGB; 611 gl_copyshadow = CopyShadowRGBToARGB; 612 if (redmask == 255) { 613 gl_convert = CopyShadowRGBToABGR; 614 } else if (redmask == 255<<8) { 615 gl_convert = CopyShadowRGBToBGRA; 616 } else if (redmask == 255<<24) { 617 gl_convert = CopyShadowRGBToRGBA; 618 } 619 } else { 620 gl_pixelsize = 4; 621 gl_upsidedown = SDL_TRUE; 622 gl_copyshadow = CopyShadowDirect; 623 if (redmask == 255<<16) { 624 osmesa_format = OSMESA_ARGB; 625 } else if (redmask == 255<<8) { 626 osmesa_format = OSMESA_BGRA; 627 } else if (redmask == 255<<24) { 628 osmesa_format = OSMESA_RGBA; 629 } else { 630 /* ABGR format unsupported */ 631 osmesa_format = OSMESA_BGRA; 632 gl_convert = ConvertBGRAToABGR; 633 } 634 } 635 break; 636 default: 637 if (tinygl_present) { 638 SDL_AtariGL_Quit(this, SDL_FALSE); 639 return 0; 640 } 641 gl_pixelsize = 1; 642 gl_copyshadow = CopyShadowDirect; 643 osmesa_format = OSMESA_COLOR_INDEX; 644 break; 645 } 646 647 /* Try to keep current context if possible */ 648 recreatecontext=1; 649 if (gl_shadow && 650 (gl_curformat == osmesa_format) && 651 (gl_curwidth == current->w) && 652 (gl_curheight == current->h)) { 653 recreatecontext = 0; 654 } 655 if (recreatecontext) { 656 SDL_AtariGL_Quit(this, SDL_FALSE); 657 658 gl_shadow = this->gl_data->OSMesaCreateLDG( 659 osmesa_format, GL_UNSIGNED_BYTE, current->w, current->h 660 ); 661 662 if (gl_shadow) { 663 gl_curformat = osmesa_format; 664 gl_curwidth = current->w; 665 gl_curheight = current->h; 666 } else { 667 gl_curformat = 0; 668 gl_curwidth = 0; 669 gl_curheight = 0; 670 } 671 } 672 673 return (gl_shadow != NULL); 674 } 675 676 /*--- Conversions routines from shadow buffer to the screen ---*/ 677 678 static void CopyShadowNull(_THIS, SDL_Surface *surface) 679 { 680 } 681 682 static void CopyShadowDirect(_THIS, SDL_Surface *surface) 683 { 684 int y, srcpitch, dstpitch; 685 Uint8 *srcline, *dstline; 686 687 srcline = gl_shadow; 688 srcpitch = surface->w * gl_pixelsize; 689 dstline = surface->pixels; 690 dstpitch = surface->pitch; 691 if (gl_upsidedown) { 692 srcline += (surface->h-1)*srcpitch; 693 srcpitch = -srcpitch; 694 } 695 696 for (y=0; y<surface->h; y++) { 697 SDL_memcpy(dstline, srcline, srcpitch); 698 699 srcline += srcpitch; 700 dstline += dstpitch; 701 } 702 } 703 704 static void CopyShadowRGBTo555(_THIS, SDL_Surface *surface) 705 { 706 int x,y, srcpitch, dstpitch; 707 Uint16 *dstline, *dstcol; 708 Uint8 *srcline, *srccol; 709 710 srcline = (Uint8 *)gl_shadow; 711 srcpitch = surface->w * gl_pixelsize; 712 dstline = surface->pixels; 713 dstpitch = surface->pitch >>1; 714 if (gl_upsidedown) { 715 srcline += (surface->h-1)*srcpitch; 716 srcpitch = -srcpitch; 717 } 718 719 for (y=0; y<surface->h; y++) { 720 srccol = srcline; 721 dstcol = dstline; 722 for (x=0; x<surface->w; x++) { 723 Uint16 dstcolor; 724 725 dstcolor = ((*srccol++)<<7) & (31<<10); 726 dstcolor |= ((*srccol++)<<2) & (31<<5); 727 dstcolor |= ((*srccol++)>>3) & 31; 728 *dstcol++ = dstcolor; 729 } 730 731 srcline += srcpitch; 732 dstline += dstpitch; 733 } 734 } 735 736 static void CopyShadowRGBTo565(_THIS, SDL_Surface *surface) 737 { 738 int x,y, srcpitch, dstpitch; 739 Uint16 *dstline, *dstcol; 740 Uint8 *srcline, *srccol; 741 742 srcline = (Uint8 *)gl_shadow; 743 srcpitch = surface->w * gl_pixelsize; 744 dstline = surface->pixels; 745 dstpitch = surface->pitch >>1; 746 if (gl_upsidedown) { 747 srcline += (surface->h-1)*srcpitch; 748 srcpitch = -srcpitch; 749 } 750 751 for (y=0; y<surface->h; y++) { 752 srccol = srcline; 753 dstcol = dstline; 754 755 for (x=0; x<surface->w; x++) { 756 Uint16 dstcolor; 757 758 dstcolor = ((*srccol++)<<8) & (31<<11); 759 dstcolor |= ((*srccol++)<<3) & (63<<5); 760 dstcolor |= ((*srccol++)>>3) & 31; 761 *dstcol++ = dstcolor; 762 } 763 764 srcline += srcpitch; 765 dstline += dstpitch; 766 } 767 } 768 769 static void CopyShadowRGBSwap(_THIS, SDL_Surface *surface) 770 { 771 int x,y, srcpitch, dstpitch; 772 Uint8 *dstline, *dstcol; 773 Uint8 *srcline, *srccol; 774 775 srcline = (Uint8 *)gl_shadow; 776 srcpitch = surface->w * gl_pixelsize; 777 dstline = surface->pixels; 778 dstpitch = surface->pitch; 779 if (gl_upsidedown) { 780 srcline += (surface->h-1)*srcpitch; 781 srcpitch = -srcpitch; 782 } 783 784 for (y=0; y<surface->h; y++) { 785 srccol = srcline; 786 dstcol = dstline; 787 788 for (x=0; x<surface->w; x++) { 789 *dstcol++ = srccol[2]; 790 *dstcol++ = srccol[1]; 791 *dstcol++ = srccol[0]; 792 srccol += 3; 793 } 794 795 srcline += srcpitch; 796 dstline += dstpitch; 797 } 798 } 799 800 static void CopyShadowRGBToARGB(_THIS, SDL_Surface *surface) 801 { 802 int x,y, srcpitch, dstpitch; 803 Uint32 *dstline, *dstcol; 804 Uint8 *srcline, *srccol; 805 806 srcline = (Uint8 *)gl_shadow; 807 srcpitch = surface->w * gl_pixelsize; 808 dstline = surface->pixels; 809 dstpitch = surface->pitch >>2; 810 if (gl_upsidedown) { 811 srcline += (surface->h-1)*srcpitch; 812 srcpitch = -srcpitch; 813 } 814 815 for (y=0; y<surface->h; y++) { 816 srccol = srcline; 817 dstcol = dstline; 818 819 for (x=0; x<surface->w; x++) { 820 Uint32 dstcolor; 821 822 dstcolor = (*srccol++)<<16; 823 dstcolor |= (*srccol++)<<8; 824 dstcolor |= *srccol++; 825 826 *dstcol++ = dstcolor; 827 } 828 829 srcline += srcpitch; 830 dstline += dstpitch; 831 } 832 } 833 834 static void CopyShadowRGBToABGR(_THIS, SDL_Surface *surface) 835 { 836 int x,y, srcpitch, dstpitch; 837 Uint32 *dstline, *dstcol; 838 Uint8 *srcline, *srccol; 839 840 srcline = (Uint8 *)gl_shadow; 841 srcpitch = surface->w * gl_pixelsize; 842 dstline = surface->pixels; 843 dstpitch = surface->pitch >>2; 844 if (gl_upsidedown) { 845 srcline += (surface->h-1)*srcpitch; 846 srcpitch = -srcpitch; 847 } 848 849 for (y=0; y<surface->h; y++) { 850 srccol = srcline; 851 dstcol = dstline; 852 853 for (x=0; x<surface->w; x++) { 854 Uint32 dstcolor; 855 856 dstcolor = *srccol++; 857 dstcolor |= (*srccol++)<<8; 858 dstcolor |= (*srccol++)<<16; 859 860 *dstcol++ = dstcolor; 861 } 862 863 srcline += srcpitch; 864 dstline += dstpitch; 865 } 866 } 867 868 static void CopyShadowRGBToBGRA(_THIS, SDL_Surface *surface) 869 { 870 int x,y, srcpitch, dstpitch; 871 Uint32 *dstline, *dstcol; 872 Uint8 *srcline, *srccol; 873 874 srcline = (Uint8 *)gl_shadow; 875 srcpitch = surface->w * gl_pixelsize; 876 dstline = surface->pixels; 877 dstpitch = surface->pitch >>2; 878 if (gl_upsidedown) { 879 srcline += (surface->h-1)*srcpitch; 880 srcpitch = -srcpitch; 881 } 882 883 for (y=0; y<surface->h; y++) { 884 srccol = srcline; 885 dstcol = dstline; 886 887 for (x=0; x<surface->w; x++) { 888 Uint32 dstcolor; 889 890 dstcolor = (*srccol++)<<8; 891 dstcolor |= (*srccol++)<<16; 892 dstcolor |= (*srccol++)<<24; 893 894 *dstcol++ = dstcolor; 895 } 896 897 srcline += srcpitch; 898 dstline += dstpitch; 899 } 900 } 901 902 static void CopyShadowRGBToRGBA(_THIS, SDL_Surface *surface) 903 { 904 int x,y, srcpitch, dstpitch; 905 Uint32 *dstline, *dstcol; 906 Uint8 *srcline, *srccol; 907 908 srcline = (Uint8 *)gl_shadow; 909 srcpitch = surface->w * gl_pixelsize; 910 dstline = surface->pixels; 911 dstpitch = surface->pitch >>2; 912 if (gl_upsidedown) { 913 srcline += (surface->h-1)*srcpitch; 914 srcpitch = -srcpitch; 915 } 916 917 for (y=0; y<surface->h; y++) { 918 srccol = srcline; 919 dstcol = dstline; 920 921 for (x=0; x<surface->w; x++) { 922 Uint32 dstcolor; 923 924 dstcolor = (*srccol++)<<24; 925 dstcolor |= (*srccol++)<<16; 926 dstcolor |= (*srccol++)<<8; 927 928 *dstcol++ = dstcolor; 929 } 930 931 srcline += srcpitch; 932 dstline += dstpitch; 933 } 934 } 935 936 static void CopyShadow8888To555(_THIS, SDL_Surface *surface) 937 { 938 int x,y, srcpitch, dstpitch; 939 Uint16 *dstline, *dstcol; 940 Uint32 *srcline, *srccol; 941 942 srcline = (Uint32 *)gl_shadow; 943 srcpitch = (surface->w * gl_pixelsize) >>2; 944 dstline = surface->pixels; 945 dstpitch = surface->pitch >>1; 946 if (gl_upsidedown) { 947 srcline += (surface->h-1)*srcpitch; 948 srcpitch = -srcpitch; 949 } 950 951 for (y=0; y<surface->h; y++) { 952 srccol = srcline; 953 dstcol = dstline; 954 for (x=0; x<surface->w; x++) { 955 Uint32 srccolor; 956 Uint16 dstcolor; 957 958 srccolor = *srccol++; 959 dstcolor = (srccolor>>9) & (31<<10); 960 dstcolor |= (srccolor>>6) & (31<<5); 961 dstcolor |= (srccolor>>3) & 31; 962 *dstcol++ = dstcolor; 963 } 964 965 srcline += srcpitch; 966 dstline += dstpitch; 967 } 968 } 969 970 static void CopyShadow8888To565(_THIS, SDL_Surface *surface) 971 { 972 int x,y, srcpitch, dstpitch; 973 Uint16 *dstline, *dstcol; 974 Uint32 *srcline, *srccol; 975 976 srcline = (Uint32 *)gl_shadow; 977 srcpitch = (surface->w * gl_pixelsize) >> 2; 978 dstline = surface->pixels; 979 dstpitch = surface->pitch >>1; 980 if (gl_upsidedown) { 981 srcline += (surface->h-1)*srcpitch; 982 srcpitch = -srcpitch; 983 } 984 985 for (y=0; y<surface->h; y++) { 986 srccol = srcline; 987 dstcol = dstline; 988 989 for (x=0; x<surface->w; x++) { 990 Uint32 srccolor; 991 Uint16 dstcolor; 992 993 srccolor = *srccol++; 994 dstcolor = (srccolor>>8) & (31<<11); 995 dstcolor |= (srccolor>>5) & (63<<5); 996 dstcolor |= (srccolor>>3) & 31; 997 *dstcol++ = dstcolor; 998 } 999 1000 srcline += srcpitch; 1001 dstline += dstpitch; 1002 } 1003 } 1004 1005 /*--- Conversions routines in the screen ---*/ 1006 1007 static void ConvertNull(_THIS, SDL_Surface *surface) 1008 { 1009 } 1010 1011 static void Convert565To555be(_THIS, SDL_Surface *surface) 1012 { 1013 int x,y, pitch; 1014 unsigned short *line, *pixel; 1015 1016 line = surface->pixels; 1017 pitch = surface->pitch >> 1; 1018 for (y=0; y<surface->h; y++) { 1019 pixel = line; 1020 for (x=0; x<surface->w; x++) { 1021 unsigned short color = *pixel; 1022 1023 *pixel++ = (color & 0x1f)|((color>>1) & 0xffe0); 1024 } 1025 1026 line += pitch; 1027 } 1028 } 1029 1030 static void Convert565To555le(_THIS, SDL_Surface *surface) 1031 { 1032 int x,y, pitch; 1033 unsigned short *line, *pixel; 1034 1035 line = surface->pixels; 1036 pitch = surface->pitch >>1; 1037 for (y=0; y<surface->h; y++) { 1038 pixel = line; 1039 for (x=0; x<surface->w; x++) { 1040 unsigned short color = *pixel; 1041 1042 color = (color & 0x1f)|((color>>1) & 0xffe0); 1043 *pixel++ = SDL_Swap16(color); 1044 } 1045 1046 line += pitch; 1047 } 1048 } 1049 1050 static void Convert565le(_THIS, SDL_Surface *surface) 1051 { 1052 int x,y, pitch; 1053 unsigned short *line, *pixel; 1054 1055 line = surface->pixels; 1056 pitch = surface->pitch >>1; 1057 for (y=0; y<surface->h; y++) { 1058 pixel = line; 1059 for (x=0; x<surface->w; x++) { 1060 unsigned short color = *pixel; 1061 1062 *pixel++ = SDL_Swap16(color); 1063 } 1064 1065 line += pitch; 1066 } 1067 } 1068 1069 static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface) 1070 { 1071 int x,y, pitch; 1072 unsigned long *line, *pixel; 1073 1074 line = surface->pixels; 1075 pitch = surface->pitch >>2; 1076 for (y=0; y<surface->h; y++) { 1077 pixel = line; 1078 for (x=0; x<surface->w; x++) { 1079 unsigned long color = *pixel; 1080 1081 *pixel++ = (color<<24)|(color>>8); 1082 } 1083 1084 line += pitch; 1085 } 1086 } 1087 1088 #endif /* SDL_VIDEO_OPENGL */ 1089