Skip to content

Latest commit

 

History

History
472 lines (394 loc) · 11.6 KB

SDL_ph_image.c

File metadata and controls

472 lines (394 loc) · 11.6 KB
 
Apr 26, 2001
Apr 26, 2001
1
2
/*
SDL - Simple DirectMedia Layer
Mar 6, 2002
Mar 6, 2002
3
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
Apr 26, 2001
Apr 26, 2001
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
Dec 14, 2001
Dec 14, 2001
20
slouken@libsdl.org
Apr 26, 2001
Apr 26, 2001
21
22
23
24
25
26
27
28
29
30
31
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
#include <stdlib.h>
#include <Ph.h>
#include <photon/Pg.h>
Jan 20, 2003
Jan 20, 2003
32
#include "SDL.h"
Apr 26, 2001
Apr 26, 2001
33
34
#include "SDL_error.h"
#include "SDL_endian.h"
Jan 20, 2003
Jan 20, 2003
35
36
#include "SDL_video.h"
#include "SDL_pixels_c.h"
Apr 26, 2001
Apr 26, 2001
37
38
#include "SDL_ph_image_c.h"
Jan 20, 2003
Jan 20, 2003
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/* Mask values for SDL_ReallocFormat() */
struct ColourMasks
{
Uint32 red;
Uint32 green;
Uint32 blue;
Uint32 alpha;
Uint32 bpp;
};
static const struct ColourMasks *ph_GetColourMasks( int format )
{
/* The alpha mask doesn't appear to be needed */
static const struct ColourMasks phColorMasks[5] = {
/* 8 bit */ {0, 0, 0, 0, 8},
/* 15 bit ARGB */ {0x7C00, 0x03E0, 0x001F, 0x8000, 16},
/* 16 bit RGB */ {0xF800, 0x07E0, 0x001F, 0x0000, 16},
/* 24 bit RGB */ {0xFF0000, 0x00FF00, 0x0000FF, 0x000000, 24},
/* 32 bit ARGB */ {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, 32},
};
switch( format )
{
case Pg_IMAGE_PALETTE_BYTE:
return &phColorMasks[0];
break;
case Pg_IMAGE_DIRECT_1555:
case Pg_IMAGE_DIRECT_555:
return &phColorMasks[1];
break;
case Pg_IMAGE_DIRECT_565:
return &phColorMasks[2];
break;
case Pg_IMAGE_DIRECT_888:
return &phColorMasks[3];
break;
case Pg_IMAGE_DIRECT_8888:
return &phColorMasks[4];
break;
}
return NULL;
}
Mar 23, 2002
Mar 23, 2002
81
Apr 26, 2001
Apr 26, 2001
82
83
int ph_SetupImage(_THIS, SDL_Surface *screen)
{
Mar 23, 2002
Mar 23, 2002
84
PgColor_t* palette=NULL;
Jan 20, 2003
Jan 20, 2003
85
const struct ColourMasks* mask;
May 28, 2002
May 28, 2002
86
87
88
89
int type=0;
int bpp;
bpp=screen->format->BitsPerPixel;
Apr 26, 2001
Apr 26, 2001
90
Mar 2, 2002
Mar 2, 2002
91
/* Determine image type */
May 28, 2002
May 28, 2002
92
switch(bpp)
Mar 2, 2002
Mar 2, 2002
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
{
case 8:{
type = Pg_IMAGE_PALETTE_BYTE;
}
break;
case 15:{
type = Pg_IMAGE_DIRECT_555;
}
break;
case 16:{
type = Pg_IMAGE_DIRECT_565;
}
break;
case 24:{
type = Pg_IMAGE_DIRECT_888;
}
break;
case 32:{
type = Pg_IMAGE_DIRECT_8888;
}
break;
default:{
Jan 20, 2003
Jan 20, 2003
115
fprintf(stderr,"ph_SetupImage(): unsupported bpp=%d !\n", bpp);
Mar 2, 2002
Mar 2, 2002
116
117
118
119
return -1;
}
break;
}
Apr 26, 2001
Apr 26, 2001
120
Mar 23, 2002
Mar 23, 2002
121
/* palette emulation code */
May 28, 2002
May 28, 2002
122
if ((bpp==8) && (desktoppal==SDLPH_PAL_EMULATE))
Mar 23, 2002
Mar 23, 2002
123
124
125
126
127
128
129
130
{
/* creating image palette */
palette=malloc(_Pg_MAX_PALETTE*sizeof(PgColor_t));
PgGetPalette(palette);
/* using shared memory for speed (set last param to 1) */
if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, palette, _Pg_MAX_PALETTE, 1)) == NULL)
{
Jan 20, 2003
Jan 20, 2003
131
fprintf(stderr,"ph_SetupImage(): PhCreateImage failed for bpp=8 !\n");
Mar 23, 2002
Mar 23, 2002
132
133
134
135
return -1;
}
}
else
Mar 2, 2002
Mar 2, 2002
136
{
Mar 23, 2002
Mar 23, 2002
137
138
139
/* using shared memory for speed (set last param to 1) */
if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, NULL, 0, 1)) == NULL)
{
Jan 20, 2003
Jan 20, 2003
140
fprintf(stderr,"ph_SetupImage: PhCreateImage failed !\n");
Mar 23, 2002
Mar 23, 2002
141
142
return -1;
}
Mar 2, 2002
Mar 2, 2002
143
}
Jan 20, 2003
Jan 20, 2003
144
Mar 2, 2002
Mar 2, 2002
145
screen->pixels = SDL_Image->image;
May 28, 2002
May 28, 2002
146
screen->pitch = SDL_Image->bpl; /* Recalculated pitch, created by PhCreateImage */
Apr 26, 2001
Apr 26, 2001
147
Jan 20, 2003
Jan 20, 2003
148
149
150
151
152
153
mask = ph_GetColourMasks(type);
if (mask != NULL)
{
SDL_ReallocFormat(screen, mask->bpp, mask->red, mask->green, mask->blue, 0);
}
Mar 2, 2002
Mar 2, 2002
154
this->UpdateRects = ph_NormalUpdate;
Apr 26, 2001
Apr 26, 2001
155
Mar 2, 2002
Mar 2, 2002
156
return 0;
Apr 26, 2001
Apr 26, 2001
157
158
}
Mar 23, 2002
Mar 23, 2002
159
int ph_SetupOCImage(_THIS, SDL_Surface *screen)
Apr 26, 2001
Apr 26, 2001
160
{
Jan 20, 2003
Jan 20, 2003
161
const struct ColourMasks *mask;
May 19, 2002
May 19, 2002
162
int type = 0;
May 28, 2002
May 28, 2002
163
int bpp;
Jan 20, 2003
Jan 20, 2003
164
165
166
screen->flags &= ~SDL_DOUBLEBUF;
OCImage.flags = screen->flags;
May 28, 2002
May 28, 2002
167
168
bpp=screen->format->BitsPerPixel;
Apr 26, 2001
Apr 26, 2001
169
May 19, 2002
May 19, 2002
170
/* Determine image type */
May 28, 2002
May 28, 2002
171
switch(bpp)
May 19, 2002
May 19, 2002
172
173
174
175
176
177
178
{
case 8: {
type = Pg_IMAGE_PALETTE_BYTE;
}
break;
case 15:{
type = Pg_IMAGE_DIRECT_555;
Apr 26, 2001
Apr 26, 2001
179
180
}
break;
May 19, 2002
May 19, 2002
181
182
183
184
185
186
187
188
189
190
191
192
193
case 16:{
type = Pg_IMAGE_DIRECT_565;
}
break;
case 24:{
type = Pg_IMAGE_DIRECT_888;
}
break;
case 32:{
type = Pg_IMAGE_DIRECT_8888;
}
break;
default:{
Jan 20, 2003
Jan 20, 2003
194
fprintf(stderr,"ph_SetupOCImage(): unsupported bpp=%d !\n", bpp);
May 19, 2002
May 19, 2002
195
196
197
198
return -1;
}
break;
}
Apr 26, 2001
Apr 26, 2001
199
Jan 20, 2003
Jan 20, 2003
200
201
/* Currently only offscreen contexts with the same bit depth as the
* display can be created. */
May 19, 2002
May 19, 2002
202
203
204
205
206
207
208
209
OCImage.offscreen_context = PdCreateOffscreenContext(0, screen->w, screen->h, Pg_OSC_MEM_PAGE_ALIGN);
if (OCImage.offscreen_context == NULL)
{
fprintf(stderr, "ph_SetupOCImage(): PdCreateOffscreenContext failed !\n");
return -1;
}
Jan 20, 2003
Jan 20, 2003
210
211
212
213
214
/* If the bit depth of the context is different than was requested,
* these values need to be updated accordingly. SDL will
* allocate a shadow surface if it needs to. */
mask = ph_GetColourMasks(OCImage.offscreen_context->format);
if (mask != NULL)
May 19, 2002
May 19, 2002
215
{
Jan 20, 2003
Jan 20, 2003
216
217
218
219
220
221
SDL_ReallocFormat(screen, mask->bpp, mask->red, mask->green, mask->blue, 0);
if (mask->bpp > 8)
{
screen->flags &= ~SDL_HWPALETTE;
}
May 19, 2002
May 19, 2002
222
223
}
Jan 20, 2003
Jan 20, 2003
224
225
screen->pitch = OCImage.offscreen_context->pitch; /* Recalculated pitch */
May 19, 2002
May 19, 2002
226
227
228
229
230
231
232
233
OCImage.dc_ptr.ptr8 = (unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context);
if (OCImage.dc_ptr.ptr8 == NULL)
{
fprintf(stderr, "ph_SetupOCImage(): PdGetOffscreenContextPtr failed !\n");
return -1;
}
Jan 20, 2003
Jan 20, 2003
234
OCImage.FrameData0 = OCImage.dc_ptr.ptr8;
May 19, 2002
May 19, 2002
235
236
237
238
239
OCImage.CurrentFrameData = OCImage.FrameData0;
OCImage.current = 0;
PhDCSetCurrent(OCImage.offscreen_context);
Jan 20, 2003
Jan 20, 2003
240
screen->pixels = OCImage.CurrentFrameData;
May 19, 2002
May 19, 2002
241
242
243
244
this->UpdateRects = ph_OCUpdate;
return 0;
Apr 26, 2001
Apr 26, 2001
245
246
}
Mar 2, 2002
Mar 2, 2002
247
248
249
250
251
252
int ph_SetupOpenGLImage(_THIS, SDL_Surface* screen)
{
this->UpdateRects = ph_OpenGLUpdate;
return 0;
}
Apr 26, 2001
Apr 26, 2001
253
Jan 20, 2003
Jan 20, 2003
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
int ph_SetupFullScreenImage(_THIS, SDL_Surface* screen)
{
const struct ColourMasks *mask;
screen->flags &= ~SDL_DOUBLEBUF;
OCImage.flags = screen->flags;
OCImage.offscreen_context = PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY);
if (OCImage.offscreen_context == NULL)
{
fprintf(stderr, "ph_SetupFullScreenImage(): PdCreateOffscreenContext failed !\n");
return -1;
}
/* If the bit depth of the context is different than was requested,
* these values need to be updated accordingly. SDL will
* allocate a shadow surface if it needs to. */
mask = ph_GetColourMasks(OCImage.offscreen_context->format);
if (mask != NULL)
{
SDL_ReallocFormat(screen, mask->bpp, mask->red, mask->green, mask->blue, 0);
if (mask->bpp > 8)
{
screen->flags &= ~SDL_HWPALETTE;
}
}
screen->pitch = OCImage.offscreen_context->pitch; /* Recalculated pitch */
OCImage.dc_ptr.ptr8 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context);
if (OCImage.dc_ptr.ptr8 == NULL)
{
fprintf(stderr, "ph_SetupOCImage(): PdGetOffscreenContextPtr failed !\n");
return -1;
}
/* wait for hw */
PgWaitHWIdle();
OCImage.FrameData0 = OCImage.dc_ptr.ptr8;
OCImage.CurrentFrameData = OCImage.FrameData0;
OCImage.current = 0;
PhDCSetCurrent(OCImage.offscreen_context);
screen->pixels = OCImage.CurrentFrameData;
this->UpdateRects = ph_OCUpdate;
return 0;
}
Apr 26, 2001
Apr 26, 2001
308
309
void ph_DestroyImage(_THIS, SDL_Surface *screen)
{
Mar 2, 2002
Mar 2, 2002
310
311
312
313
314
315
316
if (OCImage.offscreen_context != NULL)
{
PhDCRelease(OCImage.offscreen_context);
OCImage.offscreen_context = NULL;
OCImage.FrameData0 = NULL;
OCImage.FrameData1 = NULL;
}
Apr 26, 2001
Apr 26, 2001
317
Mar 2, 2002
Mar 2, 2002
318
319
if (SDL_Image)
{
Mar 23, 2002
Mar 23, 2002
320
321
322
323
324
/* if palette allocated, free it */
if (SDL_Image->palette)
{
free(SDL_Image->palette);
}
Mar 2, 2002
Mar 2, 2002
325
326
327
PgShmemDestroy(SDL_Image->image);
free(SDL_Image);
}
Apr 26, 2001
Apr 26, 2001
328
Mar 23, 2002
Mar 23, 2002
329
330
331
/* Must be zeroed everytime */
SDL_Image = NULL;
Mar 2, 2002
Mar 2, 2002
332
333
334
335
if (screen)
{
screen->pixels = NULL;
}
Apr 26, 2001
Apr 26, 2001
336
337
}
Jan 20, 2003
Jan 20, 2003
338
int ph_SetupUpdateFunction(_THIS, SDL_Surface *screen, Uint32 flags)
Apr 26, 2001
Apr 26, 2001
339
340
341
{
ph_DestroyImage(this, screen);
Jan 20, 2003
Jan 20, 2003
342
343
344
345
346
if ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN)
{
return ph_SetupFullScreenImage(this, screen);
}
if ((flags & SDL_HWSURFACE)==SDL_HWSURFACE)
Apr 26, 2001
Apr 26, 2001
347
{
Mar 2, 2002
Mar 2, 2002
348
return ph_SetupOCImage(this, screen);
Apr 26, 2001
Apr 26, 2001
349
}
Jan 20, 2003
Jan 20, 2003
350
if ((flags & SDL_OPENGL)==SDL_OPENGL)
Apr 26, 2001
Apr 26, 2001
351
{
Mar 23, 2002
Mar 23, 2002
352
return ph_SetupOpenGLImage(this, screen);
Apr 26, 2001
Apr 26, 2001
353
}
Jan 20, 2003
Jan 20, 2003
354
355
return ph_SetupImage(this, screen);
Apr 26, 2001
Apr 26, 2001
356
357
358
}
int ph_AllocHWSurface(_THIS, SDL_Surface *surface)
{
Mar 23, 2002
Mar 23, 2002
359
return(-1);
Apr 26, 2001
Apr 26, 2001
360
361
362
363
}
void ph_FreeHWSurface(_THIS, SDL_Surface *surface)
{
Mar 23, 2002
Mar 23, 2002
364
return;
Apr 26, 2001
Apr 26, 2001
365
366
367
368
}
int ph_FlipHWSurface(_THIS, SDL_Surface *surface)
{
Mar 23, 2002
Mar 23, 2002
369
return(0);
Apr 26, 2001
Apr 26, 2001
370
371
372
373
}
int ph_LockHWSurface(_THIS, SDL_Surface *surface)
{
Mar 23, 2002
Mar 23, 2002
374
return(0);
Apr 26, 2001
Apr 26, 2001
375
376
377
378
}
void ph_UnlockHWSurface(_THIS, SDL_Surface *surface)
{
Mar 23, 2002
Mar 23, 2002
379
return;
Apr 26, 2001
Apr 26, 2001
380
381
}
Mar 2, 2002
Mar 2, 2002
382
383
384
385
386
387
388
void ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect* rects)
{
this->GL_SwapBuffers(this);
return;
}
Apr 26, 2001
Apr 26, 2001
389
390
void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
{
May 28, 2002
May 28, 2002
391
392
393
394
395
PhPoint_t ph_pos;
PhRect_t ph_rect;
int i;
for (i=0; i<numrects; ++i)
Mar 23, 2002
Mar 23, 2002
396
397
398
399
{
if (rects[i].w==0) /* Clipped? */
{
continue;
Apr 26, 2001
Apr 26, 2001
400
401
}
Mar 23, 2002
Mar 23, 2002
402
403
404
405
406
407
408
409
410
ph_pos.x = rects[i].x;
ph_pos.y = rects[i].y;
ph_rect.ul.x = rects[i].x;
ph_rect.ul.y = rects[i].y;
ph_rect.lr.x = rects[i].x + rects[i].w;
ph_rect.lr.y = rects[i].y + rects[i].h;
if (PgDrawPhImageRectmx(&ph_pos, SDL_Image, &ph_rect, 0) < 0)
{
Jan 20, 2003
Jan 20, 2003
411
fprintf(stderr,"ph_NormalUpdate(): PgDrawPhImageRectmx failed !\n");
Mar 23, 2002
Mar 23, 2002
412
413
}
}
Apr 26, 2001
Apr 26, 2001
414
415
if (PgFlush() < 0)
Jan 18, 2002
Jan 18, 2002
416
{
May 19, 2002
May 19, 2002
417
fprintf(stderr,"ph_NormalUpdate(): PgFlush failed.\n");
Apr 26, 2001
Apr 26, 2001
418
419
}
}
May 19, 2002
May 19, 2002
420
Apr 26, 2001
Apr 26, 2001
421
422
void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects)
{
May 28, 2002
May 28, 2002
423
424
int i;
Mar 23, 2002
Mar 23, 2002
425
PhPoint_t zero = {0};
May 19, 2002
May 19, 2002
426
427
PhArea_t src_rect;
PhArea_t dest_rect;
Apr 26, 2001
Apr 26, 2001
428
Mar 23, 2002
Mar 23, 2002
429
PgSetRegion(PtWidgetRid(window));
May 19, 2002
May 19, 2002
430
PgSetClipping(0, NULL);
Mar 23, 2002
Mar 23, 2002
431
432
433
434
435
436
437
PgWaitHWIdle();
for (i=0; i<numrects; ++i)
{
if (rects[i].w == 0) /* Clipped? */
{
continue;
Apr 26, 2001
Apr 26, 2001
438
439
}
May 19, 2002
May 19, 2002
440
441
442
443
src_rect.pos.x=rects[i].x;
src_rect.pos.y=rects[i].y;
dest_rect.pos.x=rects[i].x;
dest_rect.pos.y=rects[i].y;
Mar 23, 2002
Mar 23, 2002
444
May 19, 2002
May 19, 2002
445
446
447
448
src_rect.size.w=rects[i].w;
src_rect.size.h=rects[i].h;
dest_rect.size.w=rects[i].w;
dest_rect.size.h=rects[i].h;
Mar 23, 2002
Mar 23, 2002
449
May 19, 2002
May 19, 2002
450
451
452
zero.x = 0;
zero.y = 0;
PgSetTranslation(&zero, 0);
Mar 23, 2002
Mar 23, 2002
453
PgSetRegion(PtWidgetRid(window));
May 19, 2002
May 19, 2002
454
455
PgSetClipping(0, NULL);
PgContextBlitArea(OCImage.offscreen_context, &src_rect, NULL, &dest_rect);
Mar 23, 2002
Mar 23, 2002
456
}
May 19, 2002
May 19, 2002
457
Apr 26, 2001
Apr 26, 2001
458
if (PgFlush() < 0)
Jan 18, 2002
Jan 18, 2002
459
{
May 19, 2002
May 19, 2002
460
fprintf(stderr,"ph_OCUpdate(): PgFlush failed.\n");
Apr 26, 2001
Apr 26, 2001
461
462
}
Mar 23, 2002
Mar 23, 2002
463
464
465
466
467
468
469
470
471
/* later used to toggling double buffer */
if (OCImage.current == 0)
{
OCImage.CurrentFrameData = OCImage.FrameData0;
}
else
{
OCImage.CurrentFrameData = OCImage.FrameData1;
}
Apr 26, 2001
Apr 26, 2001
472
}