1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2006 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@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
ph_SetupImage(_THIS,SDL_Surface * screen)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
ph_SetupOCImage(_THIS,SDL_Surface * screen)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
ph_SetupFullScreenImage(_THIS,SDL_Surface * screen)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
ph_SetupOpenGLImage(_THIS,SDL_Surface * screen)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
ph_DestroyImage(_THIS,SDL_Surface * screen)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
ph_UpdateHWInfo(_THIS)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
ph_SetupUpdateFunction(_THIS,SDL_Surface * screen,Uint32 flags)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
ph_AllocHWSurface(_THIS,SDL_Surface * surface)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
ph_FreeHWSurface(_THIS,SDL_Surface * surface)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
ph_CheckHWBlit(_THIS,SDL_Surface * src,SDL_Surface * dst)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
ph_ExpandColor(_THIS,SDL_Surface * surface,Uint32 color)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
ph_FillHWRect(_THIS,SDL_Surface * surface,SDL_Rect * rect,Uint32 color)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
ph_FlipHWSurface(_THIS,SDL_Surface * screen)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
ph_LockHWSurface(_THIS,SDL_Surface * surface)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
ph_UnlockHWSurface(_THIS,SDL_Surface * surface)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
ph_HWAccelBlit(SDL_Surface * src,SDL_Rect * srcrect,SDL_Surface * dst,SDL_Rect * dstrect)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
ph_SetHWColorKey(_THIS,SDL_Surface * surface,Uint32 key)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
ph_SetHWAlpha(_THIS,SDL_Surface * surface,Uint8 alpha)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
ph_OpenGLUpdate(_THIS,int numrects,SDL_Rect * rects)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
ph_NormalUpdate(_THIS,int numrects,SDL_Rect * rects)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
ph_OCUpdate(_THIS,int numrects,SDL_Rect * rects)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
ph_OCDCUpdate(_THIS,int numrects,SDL_Rect * rects)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