diff options
Diffstat (limited to 'apps/plugins/sdl/src/video/photon/SDL_ph_image.c')
-rw-r--r-- | apps/plugins/sdl/src/video/photon/SDL_ph_image.c | 1059 |
1 files changed, 1059 insertions, 0 deletions
diff --git a/apps/plugins/sdl/src/video/photon/SDL_ph_image.c b/apps/plugins/sdl/src/video/photon/SDL_ph_image.c new file mode 100644 index 0000000000..7d64970ce6 --- /dev/null +++ b/apps/plugins/sdl/src/video/photon/SDL_ph_image.c | |||
@@ -0,0 +1,1059 @@ | |||
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@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 | } | ||