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 Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 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 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 19 Sam Lantinga 20 slouken (at) libsdl.org 21 */ 22 #include "SDL_config.h" 23 24 #include <Ph.h> 25 #include <photon/Pg.h> 26 27 #include "SDL_endian.h" 28 #include "SDL_video.h" 29 #include "../SDL_pixels_c.h" 30 #include "SDL_ph_video.h" 31 #include "SDL_ph_image_c.h" 32 #include "SDL_ph_modes_c.h" 33 #include "SDL_ph_gl.h" 34 35 int ph_SetupImage(_THIS, SDL_Surface *screen) 36 { 37 PgColor_t* palette=NULL; 38 int type=0; 39 int bpp; 40 41 bpp=screen->format->BitsPerPixel; 42 43 /* Determine image type */ 44 switch(bpp) 45 { 46 case 8:{ 47 type = Pg_IMAGE_PALETTE_BYTE; 48 } 49 break; 50 case 15:{ 51 type = Pg_IMAGE_DIRECT_555; 52 } 53 break; 54 case 16:{ 55 type = Pg_IMAGE_DIRECT_565; 56 } 57 break; 58 case 24:{ 59 type = Pg_IMAGE_DIRECT_888; 60 } 61 break; 62 case 32:{ 63 type = Pg_IMAGE_DIRECT_8888; 64 } 65 break; 66 default:{ 67 SDL_SetError("ph_SetupImage(): unsupported bpp=%d !\n", bpp); 68 return -1; 69 } 70 break; 71 } 72 73 /* palette emulation code */ 74 if ((bpp==8) && (desktoppal==SDLPH_PAL_EMULATE)) 75 { 76 /* creating image palette */ 77 palette=SDL_malloc(_Pg_MAX_PALETTE*sizeof(PgColor_t)); 78 if (palette==NULL) 79 { 80 SDL_SetError("ph_SetupImage(): can't allocate memory for palette !\n"); 81 return -1; 82 } 83 PgGetPalette(palette); 84 85 /* using shared memory for speed (set last param to 1) */ 86 if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, palette, _Pg_MAX_PALETTE, 1)) == NULL) 87 { 88 SDL_SetError("ph_SetupImage(): PhCreateImage() failed for bpp=8 !\n"); 89 SDL_free(palette); 90 return -1; 91 } 92 } 93 else 94 { 95 /* using shared memory for speed (set last param to 1) */ 96 if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, NULL, 0, 1)) == NULL) 97 { 98 SDL_SetError("ph_SetupImage(): PhCreateImage() failed for bpp=%d !\n", bpp); 99 return -1; 100 } 101 } 102 103 screen->pixels = SDL_Image->image; 104 screen->pitch = SDL_Image->bpl; 105 106 this->UpdateRects = ph_NormalUpdate; 107 108 return 0; 109 } 110 111 int ph_SetupOCImage(_THIS, SDL_Surface *screen) 112 { 113 int type = 0; 114 int bpp; 115 116 OCImage.flags = screen->flags; 117 118 bpp=screen->format->BitsPerPixel; 119 120 /* Determine image type */ 121 switch(bpp) 122 { 123 case 8: { 124 type = Pg_IMAGE_PALETTE_BYTE; 125 } 126 break; 127 case 15:{ 128 type = Pg_IMAGE_DIRECT_555; 129 } 130 break; 131 case 16:{ 132 type = Pg_IMAGE_DIRECT_565; 133 } 134 break; 135 case 24:{ 136 type = Pg_IMAGE_DIRECT_888; 137 } 138 break; 139 case 32:{ 140 type = Pg_IMAGE_DIRECT_8888; 141 } 142 break; 143 default:{ 144 SDL_SetError("ph_SetupOCImage(): unsupported bpp=%d !\n", bpp); 145 return -1; 146 } 147 break; 148 } 149 150 /* Currently offscreen contexts with the same bit depth as display bpp only can be created */ 151 OCImage.offscreen_context = PdCreateOffscreenContext(0, screen->w, screen->h, Pg_OSC_MEM_PAGE_ALIGN); 152 153 if (OCImage.offscreen_context == NULL) 154 { 155 SDL_SetError("ph_SetupOCImage(): PdCreateOffscreenContext() function failed !\n"); 156 return -1; 157 } 158 159 screen->pitch = OCImage.offscreen_context->pitch; 160 161 OCImage.dc_ptr = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context); 162 163 if (OCImage.dc_ptr == NULL) 164 { 165 SDL_SetError("ph_SetupOCImage(): PdGetOffscreenContextPtr function failed !\n"); 166 PhDCRelease(OCImage.offscreen_context); 167 return -1; 168 } 169 170 OCImage.FrameData0 = OCImage.dc_ptr; 171 OCImage.CurrentFrameData = OCImage.FrameData0; 172 OCImage.current = 0; 173 174 PhDCSetCurrent(OCImage.offscreen_context); 175 176 screen->pixels = OCImage.CurrentFrameData; 177 178 this->UpdateRects = ph_OCUpdate; 179 180 return 0; 181 } 182 183 int ph_SetupFullScreenImage(_THIS, SDL_Surface* screen) 184 { 185 OCImage.flags = screen->flags; 186 187 /* Begin direct and fullscreen mode */ 188 if (!ph_EnterFullScreen(this, screen, PH_ENTER_DIRECTMODE)) 189 { 190 return -1; 191 } 192 193 /* store palette for fullscreen */ 194 if ((screen->format->BitsPerPixel==8) && (desktopbpp!=8)) 195 { 196 PgGetPalette(savedpal); 197 PgGetPalette(syspalph); 198 } 199 200 OCImage.offscreen_context = PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY | Pg_OSC_MEM_PAGE_ALIGN | Pg_OSC_CRTC_SAFE); 201 if (OCImage.offscreen_context == NULL) 202 { 203 SDL_SetError("ph_SetupFullScreenImage(): PdCreateOffscreenContext() function failed !\n"); 204 return -1; 205 } 206 207 if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) 208 { 209 OCImage.offscreen_backcontext = PdDupOffscreenContext(OCImage.offscreen_context, Pg_OSC_MEM_PAGE_ALIGN | Pg_OSC_CRTC_SAFE); 210 if (OCImage.offscreen_backcontext == NULL) 211 { 212 SDL_SetError("ph_SetupFullScreenImage(): PdCreateOffscreenContext(back) function failed !\n"); 213 return -1; 214 } 215 } 216 217 OCImage.FrameData0 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context); 218 if (OCImage.FrameData0 == NULL) 219 { 220 SDL_SetError("ph_SetupFullScreenImage(): PdGetOffscreenContextPtr() function failed !\n"); 221 ph_DestroyImage(this, screen); 222 return -1; 223 } 224 225 if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) 226 { 227 OCImage.FrameData1 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_backcontext); 228 if (OCImage.FrameData1 == NULL) 229 { 230 SDL_SetError("ph_SetupFullScreenImage(back): PdGetOffscreenContextPtr() function failed !\n"); 231 ph_DestroyImage(this, screen); 232 return -1; 233 } 234 } 235 236 /* wait for the hardware */ 237 PgFlush(); 238 PgWaitHWIdle(); 239 240 if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) 241 { 242 OCImage.current = 0; 243 PhDCSetCurrent(OCImage.offscreen_context); 244 screen->pitch = OCImage.offscreen_context->pitch; 245 screen->pixels = OCImage.FrameData0; 246 247 /* emulate 640x400 videomode */ 248 if (videomode_emulatemode==1) 249 { 250 int i; 251 252 for (i=0; i<40; i++) 253 { 254 SDL_memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch); 255 } 256 for (i=440; i<480; i++) 257 { 258 SDL_memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch); 259 } 260 screen->pixels+=screen->pitch*40; 261 } 262 PgSwapDisplay(OCImage.offscreen_backcontext, 0); 263 } 264 else 265 { 266 OCImage.current = 0; 267 PhDCSetCurrent(OCImage.offscreen_context); 268 screen->pitch = OCImage.offscreen_context->pitch; 269 screen->pixels = OCImage.FrameData0; 270 271 /* emulate 640x400 videomode */ 272 if (videomode_emulatemode==1) 273 { 274 int i; 275 276 for (i=0; i<40; i++) 277 { 278 SDL_memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch); 279 } 280 for (i=440; i<480; i++) 281 { 282 SDL_memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch); 283 } 284 screen->pixels+=screen->pitch*40; 285 } 286 } 287 288 this->UpdateRects = ph_OCDCUpdate; 289 290 /* wait for the hardware */ 291 PgFlush(); 292 PgWaitHWIdle(); 293 294 return 0; 295 } 296 297 #if SDL_VIDEO_OPENGL 298 299 int ph_SetupOpenGLImage(_THIS, SDL_Surface* screen) 300 { 301 this->UpdateRects = ph_OpenGLUpdate; 302 screen->pixels=NULL; 303 screen->pitch=NULL; 304 305 #if (_NTO_VERSION >= 630) 306 if ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) 307 { 308 if (!ph_EnterFullScreen(this, screen, PH_IGNORE_DIRECTMODE)) 309 { 310 screen->flags &= ~SDL_FULLSCREEN; 311 return -1; 312 } 313 } 314 #endif /* 6.3.0 */ 315 316 if (ph_SetupOpenGLContext(this, screen->w, screen->h, screen->format->BitsPerPixel, screen->flags)!=0) 317 { 318 screen->flags &= ~SDL_OPENGL; 319 return -1; 320 } 321 322 return 0; 323 } 324 325 #endif /* SDL_VIDEO_OPENGL */ 326 327 void ph_DestroyImage(_THIS, SDL_Surface* screen) 328 { 329 330 #if SDL_VIDEO_OPENGL 331 if ((screen->flags & SDL_OPENGL)==SDL_OPENGL) 332 { 333 if (oglctx) 334 { 335 #if (_NTO_VERSION < 630) 336 PhDCSetCurrent(NULL); 337 PhDCRelease(oglctx); 338 #else 339 qnxgl_context_destroy(oglctx); 340 qnxgl_buffers_destroy(oglbuffers); 341 qnxgl_finish(); 342 #endif /* 6.3.0 */ 343 oglctx=NULL; 344 oglbuffers=NULL; 345 oglflags=0; 346 oglbpp=0; 347 } 348 349 #if (_NTO_VERSION >= 630) 350 if (currently_fullscreen) 351 { 352 ph_LeaveFullScreen(this); 353 } 354 #endif /* 6.3.0 */ 355 356 return; 357 } 358 #endif /* SDL_VIDEO_OPENGL */ 359 360 if (currently_fullscreen) 361 { 362 /* if we right now in 8bpp fullscreen we must release palette */ 363 if ((screen->format->BitsPerPixel==8) && (desktopbpp!=8)) 364 { 365 PgSetPalette(syspalph, 0, -1, 0, 0, 0); 366 PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0); 367 PgFlush(); 368 } 369 ph_LeaveFullScreen(this); 370 } 371 372 if (OCImage.offscreen_context != NULL) 373 { 374 PhDCRelease(OCImage.offscreen_context); 375 OCImage.offscreen_context = NULL; 376 OCImage.FrameData0 = NULL; 377 } 378 if (OCImage.offscreen_backcontext != NULL) 379 { 380 PhDCRelease(OCImage.offscreen_backcontext); 381 OCImage.offscreen_backcontext = NULL; 382 OCImage.FrameData1 = NULL; 383 } 384 OCImage.CurrentFrameData = NULL; 385 386 if (SDL_Image) 387 { 388 /* if palette allocated, free it */ 389 if (SDL_Image->palette) 390 { 391 SDL_free(SDL_Image->palette); 392 } 393 PgShmemDestroy(SDL_Image->image); 394 SDL_free(SDL_Image); 395 } 396 397 /* Must be zeroed everytime */ 398 SDL_Image = NULL; 399 400 if (screen) 401 { 402 screen->pixels = NULL; 403 } 404 } 405 406 int ph_UpdateHWInfo(_THIS) 407 { 408 PgVideoModeInfo_t vmode; 409 PgHWCaps_t hwcaps; 410 411 /* Update video ram amount */ 412 if (PgGetGraphicsHWCaps(&hwcaps) < 0) 413 { 414 SDL_SetError("ph_UpdateHWInfo(): GetGraphicsHWCaps() function failed !\n"); 415 return -1; 416 } 417 this->info.video_mem=hwcaps.currently_available_video_ram/1024; 418 419 /* obtain current mode capabilities */ 420 if (PgGetVideoModeInfo(hwcaps.current_video_mode, &vmode) < 0) 421 { 422 SDL_SetError("ph_UpdateHWInfo(): GetVideoModeInfo() function failed !\n"); 423 return -1; 424 } 425 426 if ((vmode.mode_capabilities1 & PgVM_MODE_CAP1_OFFSCREEN) == PgVM_MODE_CAP1_OFFSCREEN) 427 { 428 /* this is a special test for drivers which tries to lie about offscreen capability */ 429 if (hwcaps.currently_available_video_ram!=0) 430 { 431 this->info.hw_available = 1; 432 } 433 else 434 { 435 this->info.hw_available = 0; 436 } 437 } 438 else 439 { 440 this->info.hw_available = 0; 441 } 442 443 if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_RECTANGLE) == PgVM_MODE_CAP2_RECTANGLE) 444 { 445 this->info.blit_fill = 1; 446 } 447 else 448 { 449 this->info.blit_fill = 0; 450 } 451 452 if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_BITBLT) == PgVM_MODE_CAP2_BITBLT) 453 { 454 this->info.blit_hw = 1; 455 } 456 else 457 { 458 this->info.blit_hw = 0; 459 } 460 461 if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_ALPHA_BLEND) == PgVM_MODE_CAP2_ALPHA_BLEND) 462 { 463 this->info.blit_hw_A = 1; 464 } 465 else 466 { 467 this->info.blit_hw_A = 0; 468 } 469 470 if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_CHROMA) == PgVM_MODE_CAP2_CHROMA) 471 { 472 this->info.blit_hw_CC = 1; 473 } 474 else 475 { 476 this->info.blit_hw_CC = 0; 477 } 478 479 return 0; 480 } 481 482 int ph_SetupUpdateFunction(_THIS, SDL_Surface* screen, Uint32 flags) 483 { 484 int setupresult=-1; 485 486 ph_DestroyImage(this, screen); 487 488 #if SDL_VIDEO_OPENGL 489 if ((flags & SDL_OPENGL)==SDL_OPENGL) 490 { 491 setupresult=ph_SetupOpenGLImage(this, screen); 492 } 493 else 494 { 495 #endif 496 if ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN) 497 { 498 setupresult=ph_SetupFullScreenImage(this, screen); 499 } 500 else 501 { 502 if ((flags & SDL_HWSURFACE)==SDL_HWSURFACE) 503 { 504 setupresult=ph_SetupOCImage(this, screen); 505 } 506 else 507 { 508 setupresult=ph_SetupImage(this, screen); 509 } 510 } 511 #if SDL_VIDEO_OPENGL 512 } 513 #endif 514 if (setupresult!=-1) 515 { 516 ph_UpdateHWInfo(this); 517 } 518 519 return setupresult; 520 } 521 522 int ph_AllocHWSurface(_THIS, SDL_Surface* surface) 523 { 524 PgHWCaps_t hwcaps; 525 526 if (surface->hwdata!=NULL) 527 { 528 SDL_SetError("ph_AllocHWSurface(): hwdata already exists!\n"); 529 return -1; 530 } 531 surface->hwdata=SDL_malloc(sizeof(struct private_hwdata)); 532 SDL_memset(surface->hwdata, 0x00, sizeof(struct private_hwdata)); 533 surface->hwdata->offscreenctx=PdCreateOffscreenContext(0, surface->w, surface->h, Pg_OSC_MEM_PAGE_ALIGN); 534 if (surface->hwdata->offscreenctx == NULL) 535 { 536 SDL_SetError("ph_AllocHWSurface(): PdCreateOffscreenContext() function failed !\n"); 537 return -1; 538 } 539 surface->pixels=PdGetOffscreenContextPtr(surface->hwdata->offscreenctx); 540 if (surface->pixels==NULL) 541 { 542 PhDCRelease(surface->hwdata->offscreenctx); 543 SDL_SetError("ph_AllocHWSurface(): PdGetOffscreenContextPtr() function failed !\n"); 544 return -1; 545 } 546 surface->pitch=surface->hwdata->offscreenctx->pitch; 547 surface->flags|=SDL_HWSURFACE; 548 surface->flags|=SDL_PREALLOC; 549 550 #if 0 /* FIXME */ 551 /* create simple offscreen lock */ 552 surface->hwdata->crlockparam.flags=0; 553 if (PdCreateOffscreenLock(surface->hwdata->offscreenctx, &surface->hwdata->crlockparam)!=EOK) 554 { 555 PhDCRelease(surface->hwdata->offscreenctx); 556 SDL_SetError("ph_AllocHWSurface(): Can't create offscreen lock !\n"); 557 return -1; 558 } 559 #endif /* 0 */ 560 561 /* Update video ram amount */ 562 if (PgGetGraphicsHWCaps(&hwcaps) < 0) 563 { 564 PdDestroyOffscreenLock(surface->hwdata->offscreenctx); 565 PhDCRelease(surface->hwdata->offscreenctx); 566 SDL_SetError("ph_AllocHWSurface(): GetGraphicsHWCaps() function failed !\n"); 567 return -1; 568 } 569 this->info.video_mem=hwcaps.currently_available_video_ram/1024; 570 571 return 0; 572 } 573 574 void ph_FreeHWSurface(_THIS, SDL_Surface* surface) 575 { 576 PgHWCaps_t hwcaps; 577 578 if (surface->hwdata==NULL) 579 { 580 SDL_SetError("ph_FreeHWSurface(): no hwdata!\n"); 581 return; 582 } 583 if (surface->hwdata->offscreenctx == NULL) 584 { 585 SDL_SetError("ph_FreeHWSurface(): no offscreen context to delete!\n"); 586 return; 587 } 588 589 #if 0 /* FIXME */ 590 /* unlock the offscreen context if it has been locked before destroy it */ 591 if (PdIsOffscreenLocked(surface->hwdata->offscreenctx)==Pg_OSC_LOCKED) 592 { 593 PdUnlockOffscreen(surface->hwdata->offscreenctx); 594 } 595 596 PdDestroyOffscreenLock(surface->hwdata->offscreenctx); 597 #endif /* 0 */ 598 599 PhDCRelease(surface->hwdata->offscreenctx); 600 601 SDL_free(surface->hwdata); 602 surface->hwdata=NULL; 603 604 /* Update video ram amount */ 605 if (PgGetGraphicsHWCaps(&hwcaps) < 0) 606 { 607 SDL_SetError("ph_FreeHWSurface(): GetGraphicsHWCaps() function failed !\n"); 608 return; 609 } 610 this->info.video_mem=hwcaps.currently_available_video_ram/1024; 611 612 return; 613 } 614 615 int ph_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst) 616 { 617 if ((src->hwdata==NULL) && (src != this->screen)) 618 { 619 SDL_SetError("ph_CheckHWBlit(): Source surface haven't hardware specific data.\n"); 620 src->flags&=~SDL_HWACCEL; 621 return -1; 622 } 623 if ((src->flags & SDL_HWSURFACE) != SDL_HWSURFACE) 624 { 625 SDL_SetError("ph_CheckHWBlit(): Source surface isn't a hardware surface.\n"); 626 src->flags&=~SDL_HWACCEL; 627 return -1; 628 } 629 630 if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) 631 { 632 if (this->info.blit_hw_CC!=1) 633 { 634 src->flags&=~SDL_HWACCEL; 635 src->map->hw_blit=NULL; 636 return -1; 637 } 638 } 639 640 if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) 641 { 642 if (this->info.blit_hw_A!=1) 643 { 644 src->flags&=~SDL_HWACCEL; 645 src->map->hw_blit=NULL; 646 return -1; 647 } 648 } 649 650 src->flags|=SDL_HWACCEL; 651 src->map->hw_blit = ph_HWAccelBlit; 652 653 return 1; 654 } 655 656 PgColor_t ph_ExpandColor(_THIS, SDL_Surface* surface, Uint32 color) 657 { 658 Uint32 truecolor; 659 660 /* Photon API accepts true colors only during hw filling operations */ 661 switch(surface->format->BitsPerPixel) 662 { 663 case 8: 664 { 665 if ((surface->format->palette) && (color<=surface->format->palette->ncolors)) 666 { 667 truecolor=PgRGB(surface->format->palette->colors[color].r, 668 surface->format->palette->colors[color].g, 669 surface->format->palette->colors[color].b); 670 } 671 else 672 { 673 SDL_SetError("ph_ExpandColor(): Color out of range for the 8bpp mode !\n"); 674 return 0xFFFFFFFFUL; 675 } 676 } 677 break; 678 case 15: 679 { 680 truecolor = ((color & 0x00007C00UL) << 9) | /* R */ 681 ((color & 0x000003E0UL) << 6) | /* G */ 682 ((color & 0x0000001FUL) << 3) | /* B */ 683 ((color & 0x00007000UL) << 4) | /* R compensation */ 684 ((color & 0x00000380UL) << 1) | /* G compensation */ 685 ((color & 0x0000001CUL) >> 2); /* B compensation */ 686 } 687 break; 688 case 16: 689 { 690 truecolor = ((color & 0x0000F800UL) << 8) | /* R */ 691 ((color & 0x000007E0UL) << 5) | /* G */ 692 ((color & 0x0000001FUL) << 3) | /* B */ 693 ((color & 0x0000E000UL) << 3) | /* R compensation */ 694 ((color & 0x00000600UL) >> 1) | /* G compensation */ 695 ((color & 0x0000001CUL) >> 2); /* B compensation */ 696 697 } 698 break; 699 case 24: 700 { 701 truecolor=color & 0x00FFFFFFUL; 702 } 703 break; 704 case 32: 705 { 706 truecolor=color; 707 } 708 break; 709 default: 710 { 711 SDL_SetError("ph_ExpandColor(): Unsupported depth for the hardware operations !\n"); 712 return 0xFFFFFFFFUL; 713 } 714 } 715 716 return truecolor; 717 } 718 719 int ph_FillHWRect(_THIS, SDL_Surface* surface, SDL_Rect* rect, Uint32 color) 720 { 721 PgColor_t oldcolor; 722 Uint32 truecolor; 723 int ydisp=0; 724 725 if (this->info.blit_fill!=1) 726 { 727 return -1; 728 } 729 730 truecolor=ph_ExpandColor(this, surface, color); 731 if (truecolor==0xFFFFFFFFUL) 732 { 733 return -1; 734 } 735 736 oldcolor=PgSetFillColor(truecolor); 737 738 /* 640x400 videomode emulation */ 739 if (videomode_emulatemode==1) 740 { 741 ydisp+=40; 742 } 743 744 PgDrawIRect(rect->x, rect->y+ydisp, rect->w+rect->x-1, rect->h+rect->y+ydisp-1, Pg_DRAW_FILL); 745 PgSetFillColor(oldcolor); 746 PgFlush(); 747 PgWaitHWIdle(); 748 749 return 0; 750 } 751 752 int ph_FlipHWSurface(_THIS, SDL_Surface* screen) 753 { 754 PhArea_t farea; 755 756 if ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) 757 { 758 /* flush all drawing ops before blitting */ 759 PgFlush(); 760 PgWaitHWIdle(); 761 762 farea.pos.x=0; 763 farea.pos.y=0; 764 farea.size.w=screen->w; 765 farea.size.h=screen->h; 766 767 /* emulate 640x400 videomode */ 768 if (videomode_emulatemode==1) 769 { 770 farea.pos.y+=40; 771 } 772 773 PgContextBlitArea(OCImage.offscreen_context, &farea, OCImage.offscreen_backcontext, &farea); 774 775 /* flush the blitting */ 776 PgFlush(); 777 PgWaitHWIdle(); 778 } 779 return 0; 780 } 781 782 int ph_LockHWSurface(_THIS, SDL_Surface* surface) 783 { 784 785 #if 0 /* FIXME */ 786 int lockresult; 787 788 if (surface->hwdata == NULL) 789 { 790 return; 791 } 792 793 surface->hwdata->lockparam.flags=0; 794 surface->hwdata->lockparam.time_out=NULL; 795 lockresult=PdLockOffscreen(surface->hwdata->offscreenctx, &surface->hwdata->lockparam); 796 797 switch (lockresult) 798 { 799 case EOK: 800 break; 801 case Pg_OSC_LOCK_DEADLOCK: 802 SDL_SetError("ph_LockHWSurface(): Deadlock detected !\n"); 803 return -1; 804 case Pg_OSC_LOCK_INVALID: 805 SDL_SetError("ph_LockHWSurface(): Lock invalid !\n"); 806 return -1; 807 default: 808 SDL_SetError("ph_LockHWSurface(): Can't lock the surface !\n"); 809 return -1; 810 } 811 #endif /* 0 */ 812 813 return 0; 814 } 815 816 void ph_UnlockHWSurface(_THIS, SDL_Surface* surface) 817 { 818 819 #if 0 /* FIXME */ 820 int unlockresult; 821 822 if ((surface == NULL) || (surface->hwdata == NULL)) 823 { 824 return; 825 } 826 827 if (PdIsOffscreenLocked(surface->hwdata->offscreenctx)==Pg_OSC_LOCKED) 828 { 829 unlockresult=PdUnlockOffscreen(surface->hwdata->offscreenctx); 830 } 831 #endif /* 0 */ 832 833 return; 834 } 835 836 int ph_HWAccelBlit(SDL_Surface* src, SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect) 837 { 838 SDL_VideoDevice* this=current_video; 839 PhArea_t srcarea; 840 PhArea_t dstarea; 841 int ydisp=0; 842 843 /* 640x400 videomode emulation */ 844 if (videomode_emulatemode==1) 845 { 846 ydisp+=40; 847 } 848 849 srcarea.pos.x=srcrect->x; 850 srcarea.pos.y=srcrect->y; 851 srcarea.size.w=srcrect->w; 852 srcarea.size.h=srcrect->h; 853 854 dstarea.pos.x=dstrect->x; 855 dstarea.pos.y=dstrect->y; 856 dstarea.size.w=dstrect->w; 857 dstarea.size.h=dstrect->h; 858 859 if (((src == this->screen) || (src->hwdata!=NULL)) && ((dst == this->screen) || (dst->hwdata!=NULL))) 860 { 861 if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) 862 { 863 ph_SetHWColorKey(this, src, src->format->colorkey); 864 PgChromaOn(); 865 } 866 867 if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) 868 { 869 ph_SetHWAlpha(this, src, src->format->alpha); 870 PgAlphaOn(); 871 } 872 873 if (dst == this->screen) 874 { 875 if (src == this->screen) 876 { 877 /* blitting from main screen to main screen */ 878 dstarea.pos.y+=ydisp; 879 srcarea.pos.y+=ydisp; 880 PgContextBlitArea(OCImage.offscreen_context, &srcarea, OCImage.offscreen_context, &dstarea); 881 } 882 else 883 { 884 /* blitting from offscreen to main screen */ 885 dstarea.pos.y+=ydisp; 886 PgContextBlitArea(src->hwdata->offscreenctx, &srcarea, OCImage.offscreen_context, &dstarea); 887 } 888 } 889 else 890 { 891 if (src == this->screen) 892 { 893 /* blitting from main screen to offscreen */ 894 srcarea.pos.y+=ydisp; 895 PgContextBlitArea(OCImage.offscreen_context, &srcarea, dst->hwdata->offscreenctx, &dstarea); 896 } 897 else 898 { 899 /* blitting offscreen to offscreen */ 900 PgContextBlitArea(src->hwdata->offscreenctx, &srcarea, dst->hwdata->offscreenctx, &dstarea); 901 } 902 } 903 904 if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) 905 { 906 PgAlphaOff(); 907 } 908 909 if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) 910 { 911 PgChromaOff(); 912 } 913 } 914 else 915 { 916 SDL_SetError("ph_HWAccelBlit(): Source or target surface is not a hardware surface !\n"); 917 return -1; 918 } 919 920 PgFlush(); 921 PgWaitHWIdle(); 922 923 return 0; 924 } 925 926 int ph_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key) 927 { 928 if (this->info.blit_hw_CC!=1) 929 { 930 return -1; 931 } 932 933 if (surface->hwdata!=NULL) 934 { 935 surface->hwdata->colorkey=ph_ExpandColor(this, surface, key); 936 if (surface->hwdata->colorkey==0xFFFFFFFFUL) 937 { 938 return -1; 939 } 940 } 941 PgSetChroma(surface->hwdata->colorkey, Pg_CHROMA_SRC_MATCH | Pg_CHROMA_NODRAW); 942 943 return 0; 944 } 945 946 int ph_SetHWAlpha(_THIS, SDL_Surface* surface, Uint8 alpha) 947 { 948 if (this->info.blit_hw_A!=1) 949 { 950 return -1; 951 } 952 953 PgSetAlphaBlend(NULL, alpha); 954 955 return 0; 956 } 957 958 #if SDL_VIDEO_OPENGL 959 void ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect* rects) 960 { 961 this->GL_SwapBuffers(this); 962 963 return; 964 } 965 #endif /* SDL_VIDEO_OPENGL */ 966 967 void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) 968 { 969 PhPoint_t ph_pos; 970 PhRect_t ph_rect; 971 int i; 972 973 for (i=0; i<numrects; ++i) 974 { 975 if (rects[i].w==0) /* Clipped? dunno why but this occurs sometime. */ 976 { 977 continue; 978 } 979 980 if (rects[i].h==0) /* Clipped? dunno why but this occurs sometime. */ 981 { 982 continue; 983 } 984 985 ph_pos.x = rects[i].x; 986 ph_pos.y = rects[i].y; 987 ph_rect.ul.x = rects[i].x; 988 ph_rect.ul.y = rects[i].y; 989 ph_rect.lr.x = rects[i].x + rects[i].w; 990 ph_rect.lr.y = rects[i].y + rects[i].h; 991 992 if (PgDrawPhImageRectmx(&ph_pos, SDL_Image, &ph_rect, 0) < 0) 993 { 994 SDL_SetError("ph_NormalUpdate(): PgDrawPhImageRectmx failed!\n"); 995 return; 996 } 997 } 998 999 if (PgFlush() < 0) 1000 { 1001 SDL_SetError("ph_NormalUpdate(): PgFlush() function failed!\n"); 1002 } 1003 } 1004 1005 void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects) 1006 { 1007 int i; 1008 1009 PhPoint_t zero = {0, 0}; 1010 PhArea_t src_rect; 1011 PhArea_t dest_rect; 1012 1013 PgSetTranslation(&zero, 0); 1014 PgSetRegion(PtWidgetRid(window)); 1015 PgSetClipping(0, NULL); 1016 1017 PgFlush(); 1018 PgWaitHWIdle(); 1019 1020 for (i=0; i<numrects; ++i) 1021 { 1022 if (rects[i].w == 0) /* Clipped? */ 1023 { 1024 continue; 1025 } 1026 1027 if (rects[i].h == 0) /* Clipped? */ 1028 { 1029 continue; 1030 } 1031 1032 src_rect.pos.x=rects[i].x; 1033 src_rect.pos.y=rects[i].y; 1034 dest_rect.pos.x=rects[i].x; 1035 dest_rect.pos.y=rects[i].y; 1036 1037 src_rect.size.w=rects[i].w; 1038 src_rect.size.h=rects[i].h; 1039 dest_rect.size.w=rects[i].w; 1040 dest_rect.size.h=rects[i].h; 1041 1042 PgContextBlitArea(OCImage.offscreen_context, &src_rect, NULL, &dest_rect); 1043 } 1044 1045 if (PgFlush() < 0) 1046 { 1047 SDL_SetError("ph_OCUpdate(): PgFlush failed.\n"); 1048 } 1049 } 1050 1051 void ph_OCDCUpdate(_THIS, int numrects, SDL_Rect *rects) 1052 { 1053 PgWaitHWIdle(); 1054 1055 if (PgFlush() < 0) 1056 { 1057 SDL_SetError("ph_OCDCUpdate(): PgFlush failed.\n"); 1058 } 1059 } 1060