rename the directory
[AROS.git] / arch / all-hosted / hidd / sdl / bmclass.c
blobb15d1bc2f46194affe266222d6740eacba997b16
1 /*
2 * sdl.hidd - SDL graphics/sound/keyboard for AROS hosted
3 * Copyright (c) 2007 Robert Norris. All rights reserved.
4 * Copyright (c) 2010 The AROS Development Team. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the same terms as AROS itself.
8 */
10 #include <hidd/hidd.h>
11 #include <hidd/graphics.h>
12 #include <utility/tagitem.h>
13 #include <oop/oop.h>
15 #include <proto/exec.h>
16 #include <proto/oop.h>
17 #include <proto/utility.h>
19 #ifdef __THROW
20 #undef __THROW
21 #endif
22 #ifdef __CONCAT
23 #undef __CONCAT
24 #endif
26 #include "sdl_intern.h"
28 #define DEBUG 0
29 #include <aros/debug.h>
31 #define DPUTIMAGE(x)
33 #include "icon.h"
35 #define LOCK(s) \
36 do { \
37 if (SDL_MUSTLOCK(s)) \
38 SV(SDL_LockSurface, s); \
39 } while(0)
41 #define UNLOCK(s) \
42 do { \
43 if (SDL_MUSTLOCK(s)) \
44 SV(SDL_UnlockSurface, s); \
45 } while(0)
47 #define LIBBASE (&xsd)
50 static void load_icon(LIBBASETYPEPTR SDLGfxBase) {
51 unsigned char *data, *pixel;
52 int i;
54 // already loaded?
55 if (SDLGfxBase->icon)
56 return;
58 if ((SDLGfxBase->icon = SP(SDL_CreateRGBSurface, SDL_SWSURFACE, icon_width, icon_height, 24, icon_red_mask, icon_green_mask, icon_blue_mask, 0)) != NULL)
60 LOCK(SDLGfxBase->icon);
62 data = icon_header_data;
63 pixel = SDLGfxBase->icon->pixels;
65 for (i = 0; i < icon_width * icon_height; i++) {
66 ICON_HEADER_PIXEL(data, pixel);
67 pixel += 3;
70 UNLOCK(SDLGfxBase->icon);
74 #define SDLGfxBase ((LIBBASETYPEPTR) cl->UserData)
76 OOP_Object *SDLBitMap__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg) {
77 struct bmdata *bmdata;
78 BOOL framebuffer;
79 IPTR width, height, depth;
80 OOP_Object *pixfmt;
81 SDL_Surface *s;
82 IPTR red_mask, green_mask, blue_mask, alpha_mask;
84 D(bug("[sdl] SDLBitMap::New\n"));
86 o = (OOP_Object *) OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
87 if (o == NULL) {
88 D(bug("[sdl] supermethod failed, bailing out\n"));
89 return NULL;
92 bmdata = OOP_INST_DATA(cl, o);
94 OOP_GetAttr(o, aHidd_BitMap_Width, &width);
95 OOP_GetAttr(o, aHidd_BitMap_Height, &height);
96 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (IPTR *)&pixfmt);
98 OOP_GetAttr(pixfmt, aHidd_PixFmt_Depth, &depth);
100 D(bug("[sdl] width %d height %d depth %d\n", width, height, depth));
102 framebuffer = GetTagData(aHidd_BitMap_FrameBuffer, FALSE, msg->attrList);
103 if (framebuffer) {
104 D(bug("[sdl] creating new framebuffer\n"));
106 /* XXX we should free any existing onscreen surface. the problem is
107 * that we can't dispose the existing framebuffer object because the
108 * caller may still have a handle on it. we could fiddle at its
109 * innards well enough (store the current onscreen bitmap in class
110 * static data, and now grab it and free its surface), but then we
111 * have a bitmap with no associated surface, so we need checks for
112 * that.
114 * I expect that if the caller wants to make a new framebuffer, it
115 * should have to free the old one
118 if (!LIBBASE->use_hwsurface)
119 D(bug("[sdl] hardware surface not available, using software surface instead\n"));
121 if (LIBBASE->icon == NULL) {
122 D(bug("[sdl] loading window icon\n"));
123 load_icon((LIBBASETYPEPTR) cl->UserData);
126 if (LIBBASE->icon)
127 SV(SDL_WM_SetIcon, LIBBASE->icon, NULL);
129 s = SP(SDL_SetVideoMode, width, height, depth,
130 (LIBBASE->use_hwsurface ? SDL_HWSURFACE | SDL_HWPALETTE : SDL_SWSURFACE) |
131 (LIBBASE->use_fullscreen ? SDL_FULLSCREEN : 0) |
132 SDL_ANYFORMAT);
134 SV(SDL_WM_SetCaption, "AROS Research Operating System", "AROS");
137 else {
138 OOP_GetAttr(pixfmt, aHidd_PixFmt_RedMask, &red_mask);
139 OOP_GetAttr(pixfmt, aHidd_PixFmt_GreenMask, &green_mask);
140 OOP_GetAttr(pixfmt, aHidd_PixFmt_BlueMask, &blue_mask);
141 OOP_GetAttr(pixfmt, aHidd_PixFmt_AlphaMask, &alpha_mask);
143 D(bug("[sdl] creating new offscreen surface; masks: red 0x%08x green 0x%08x blue 0x%08x alpha 0x%08x\n", red_mask, green_mask, blue_mask, alpha_mask));
145 s = SP(SDL_CreateRGBSurface, SDL_SWSURFACE, width, height, depth, red_mask, green_mask, blue_mask, alpha_mask);
148 if (s == NULL) {
149 OOP_MethodID dispose;
151 D(bug("[sdl] failed to create surface: %s\n", S(SDL_GetError, )));
153 dispose = OOP_GetMethodID(IID_Root, moRoot_Dispose);
154 OOP_CoerceMethod(cl, o, (OOP_Msg) &dispose);
156 return NULL;
159 bmdata->surface = s;
161 if (framebuffer)
162 bmdata->is_onscreen = TRUE;
164 D(bug("[sdl] created surface: 0x%08x\n", s));
166 return o;
169 VOID SDLBitMap__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg) {
170 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
172 D(bug("[sdl] SDLBitMap::Dispose\n"));
174 if (bmdata->surface != NULL) {
175 D(bug("[sdl] destroying surface 0x%08x\n", bmdata->surface));
177 SV(SDL_FreeSurface, bmdata->surface);
178 bmdata->surface = NULL;
181 OOP_DoSuperMethod(cl, o, msg);
183 return;
186 VOID SDLBitMap__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg) {
187 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
189 // D(bug("[sdl] SDLBitMap::Get\n"));
191 switch (SDLBM_ATTR(msg->attrID)) {
192 case aoHidd_SDLBitMap_Surface:
193 *msg->storage = (IPTR) bmdata->surface;
194 break;
196 default:
197 OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
198 break;
202 VOID SDLBitMap__Root__Set(OOP_Class *cl, OOP_Object *o, struct pRoot_Set *msg)
204 struct bmdata *data = OOP_INST_DATA(cl, o);
205 struct TagItem *tag, *tstate;
206 ULONG idx;
208 tstate = msg->attrList;
209 while((tag = NextTagItem(&tstate))) {
210 idx = SDLBM_ATTR(tag->ti_Tag);
211 if (idx < num_Hidd_SDLBitMap_Attrs) {
212 switch(idx) {
213 case aoHidd_SDLBitMap_Surface:
214 data->surface = (SDL_Surface *)tag->ti_Data;
215 break;
220 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
223 BOOL SDLBitMap__Hidd_BitMap__SetColors(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_SetColors *msg) {
224 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
225 HIDDT_PixelFormat *pixfmt;
226 SDL_Color *colors;
227 int i;
229 //D(bug("[sdl] SDLBitMap::SetColors\n"));
231 pixfmt = BM_PIXFMT(o);
232 if (HIDD_PF_COLMODEL(pixfmt) == vHidd_ColorModel_StaticPalette ||
233 HIDD_PF_COLMODEL(pixfmt) == vHidd_ColorModel_TrueColor) {
235 return OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
238 if (!OOP_DoSuperMethod(cl, o, (OOP_Msg) msg))
239 return FALSE;
241 colors = AllocVec(sizeof(SDL_Color) * msg->numColors, MEMF_CLEAR);
243 for (i = 0; i < msg->numColors; i++) {
244 colors[i].r = msg->colors[i].red;
245 colors[i].g = msg->colors[i].green;
246 colors[i].b = msg->colors[i].blue;
249 S(SDL_SetColors, bmdata->surface, colors, msg->firstColor, msg->numColors);
251 D(bug("[sdl] set %d colours for surface 0x%08x\n", msg->numColors, bmdata->surface));
253 return TRUE;
256 #define PUTPIXEL8(p,c) (* (Uint8 *) (p) = (c))
257 #define GETPIXEL8(p) (* (Uint8 *) (p))
259 #define PUTPIXEL16(p,c) (* (Uint16 *) (p)) = (c)
260 #define GETPIXEL16(p) (* (Uint16 *) (p))
262 #define PUTPIXEL32(p,c) (* (Uint32 *) (p)) = (c)
263 #define GETPIXEL32(p) (* (Uint32 *) (p))
265 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
266 #define PUTPIXEL24(p,c) \
267 do { \
268 ((Uint8 *) p)[0] = ((c) >> 16) & 0xff; \
269 ((Uint8 *) p)[1] = ((c) >> 8) & 0xff; \
270 ((Uint8 *) p)[2] = (c) & 0xff; \
271 } while(0)
272 #define GETPIXEL24(p) (((Uint8 *) p)[0] << 16 | ((Uint8 *) p)[1] << 8 | ((Uint8 *)p)[2])
273 #else
274 #define PUTPIXEL24(p,c) \
275 do { \
276 ((Uint8 *) p)[0] = (c) & 0xff; \
277 ((Uint8 *) p)[1] = ((c) >> 8) & 0xff; \
278 ((Uint8 *) p)[2] = ((c) >> 16) & 0xff; \
279 } while(0)
280 #define GETPIXEL24(p) (((Uint8 *) p)[0] | ((Uint8 *) p)[1] << 8 | ((Uint8 *) p)[2] << 16)
281 #endif
283 VOID SDLBitMap__Hidd_BitMap__PutPixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutPixel *msg) {
284 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
285 int bytesperpixel = bmdata->surface->format->BytesPerPixel;
286 Uint8 *p = (Uint8 *) bmdata->surface->pixels + msg->y * bmdata->surface->pitch + msg->x * bytesperpixel;
287 Uint32 c = msg->pixel;
289 //D(bug("[sdl] SDLBitMap::PutPixel\n"));
290 //D(bug("[sdl] x %d y %d colour 0x%08x bytesperpixel %d\n", msg->x, msg->y, c, bytesperpixel));
292 LOCK(bmdata->surface);
294 switch (bytesperpixel) {
295 case 1:
296 PUTPIXEL8(p, c);
297 break;
299 case 2:
300 PUTPIXEL16(p, c);
301 break;
303 case 3:
304 PUTPIXEL24(p, c);
305 break;
307 case 4:
308 PUTPIXEL32(p, c);
309 break;
312 UNLOCK(bmdata->surface);
315 HIDDT_Pixel SDLBitMap__Hidd_BitMap__GetPixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetPixel *msg) {
316 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
317 int bytesperpixel = bmdata->surface->format->BytesPerPixel;
318 Uint8 *p = (Uint8 *) bmdata->surface->pixels + msg->y * bmdata->surface->pitch + msg->x * bytesperpixel;
319 Uint32 c = 0;
321 //D(bug("[sdl] SDLBitMap::GetPixel\n"));
322 //D(bug("[sdl] x %d y %d bytesperpixel %d\n", msg->x, msg->y, bytesperpixel));
324 LOCK(bmdata->surface);
326 switch(bytesperpixel) {
328 case 1:
329 c = GETPIXEL8(p);
330 break;
332 case 2:
333 c = GETPIXEL16(p);
334 break;
336 case 3:
337 c = GETPIXEL24(p);
338 break;
340 case 4:
341 c = GETPIXEL32(p);
342 break;
345 UNLOCK(bmdata->surface);
347 //D(bug("[sdl] returning pixel 0x%08x\n", c));
349 return (HIDDT_Pixel) c;
352 VOID SDLBitMap__Hidd_BitMap__UpdateRect(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_UpdateRect *msg) {
353 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
355 D(bug("[sdl] SDLBitMap::UpdateRect\n"));
356 D(bug("[sdl] Updating region (%d,%d) [%d,%d]\n", msg->x, msg->y, msg->width, msg->height));
358 if (bmdata->is_onscreen)
359 SV(SDL_UpdateRect, bmdata->surface, msg->x, msg->y, msg->width, msg->height);
362 VOID SDLBitMap__Hidd_BitMap__PutImage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutImage *msg) {
363 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
364 IPTR depth;
365 IPTR red_mask, green_mask, blue_mask, alpha_mask;
366 BOOL native32 = FALSE;
367 SDL_Surface *s;
368 SDL_Rect srect, drect;
370 DPUTIMAGE(bug("[sdl] SDLBitMap::PutImage\n"));
372 switch (msg->pixFmt) {
373 case vHidd_StdPixFmt_Native32:
374 DPUTIMAGE(bug("[sdl] native32 format, making a note to ensure 4-byte pixels later\n"));
375 native32 = TRUE;
377 case vHidd_StdPixFmt_Native:
378 DPUTIMAGE(bug("[sdl] native format, using our attributes\n"));
380 depth = bmdata->surface->format->BitsPerPixel;
381 red_mask = bmdata->surface->format->Rmask;
382 green_mask = bmdata->surface->format->Gmask;
383 blue_mask = bmdata->surface->format->Bmask;
384 alpha_mask = bmdata->surface->format->Amask;
386 break;
388 default:
389 DPUTIMAGE(bug("[sdl] pixel format %d, asking the gfxhidd for attributes\n", msg->pixFmt));
391 OOP_Object *gfxhidd;
392 OOP_GetAttr(o, aHidd_BitMap_GfxHidd, (IPTR *)&gfxhidd);
394 OOP_Object *pixfmt = HIDD_Gfx_GetPixFmt(gfxhidd, msg->pixFmt);
396 OOP_GetAttr(pixfmt, aHidd_PixFmt_Depth, &depth);
397 OOP_GetAttr(pixfmt, aHidd_PixFmt_RedMask, &red_mask);
398 OOP_GetAttr(pixfmt, aHidd_PixFmt_GreenMask, &green_mask);
399 OOP_GetAttr(pixfmt, aHidd_PixFmt_BlueMask, &blue_mask);
400 /* Alpha blitting is done using PutAlphaImage(). This method
401 should ignore alpha channel data. Otherwise data without
402 alpha channel (with alpha == 0) is assumed to contain valid
403 alpha values and we see nothing as a result.
404 This is known to affect TrueType fonts. */
405 alpha_mask = 0;
407 break;
410 DPUTIMAGE(bug("[sdl] source format: depth %d red 0x%08x green 0x%08x blue 0x%08x alpha 0x%08x\n", depth, red_mask, green_mask, blue_mask, alpha_mask));
412 s = SP(SDL_CreateRGBSurfaceFrom, msg->pixels, msg->width, msg->height, depth, msg->modulo, red_mask, green_mask, blue_mask, alpha_mask);
413 if (native32) {
414 DPUTIMAGE(bug("[sdl] native32 format, setting pixel width to 4 bytes\n"));
415 s->format->BytesPerPixel = 4;
418 srect.x = 0;
419 srect.y = 0;
420 srect.w = msg->width;
421 srect.h = msg->height;
423 drect.x = msg->x;
424 drect.y = msg->y;
426 DPUTIMAGE(bug("[sdl] blitting %dx%d image to surface 0x%08x at [%d,%d]\n", srect.w, srect.h, bmdata->surface, drect.x, drect.y));
428 S(SDL_BlitSurface, s, &srect, bmdata->surface, &drect);
430 SV(SDL_FreeSurface, s);
433 VOID SDLBitMap__Hidd_BitMap__GetImage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetImage *msg) {
434 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
435 IPTR depth;
436 IPTR red_mask, green_mask, blue_mask, alpha_mask;
437 BOOL native32 = FALSE;
438 SDL_Surface *s;
439 SDL_Rect srect;
441 D(bug("[sdl] SDLBitMap::GetImage\n"));
443 switch (msg->pixFmt) {
444 case vHidd_StdPixFmt_Native32:
445 D(bug("[sdl] native32 format, making a note to ensure 4-byte pixels later\n"));
446 native32 = TRUE;
448 case vHidd_StdPixFmt_Native:
449 D(bug("[sdl] native format, using our attributes\n"));
451 depth = bmdata->surface->format->BitsPerPixel;
452 red_mask = bmdata->surface->format->Rmask;
453 green_mask = bmdata->surface->format->Gmask;
454 blue_mask = bmdata->surface->format->Bmask;
455 alpha_mask = bmdata->surface->format->Amask;
457 break;
459 default:
460 D(bug("[sdl] pixel format %d, asking the gfxhidd for attributes\n", msg->pixFmt));
462 OOP_Object *gfxhidd;
463 OOP_GetAttr(o, aHidd_BitMap_GfxHidd, (IPTR *)&gfxhidd);
465 OOP_Object *pixfmt = HIDD_Gfx_GetPixFmt(gfxhidd, msg->pixFmt);
467 OOP_GetAttr(pixfmt, aHidd_PixFmt_Depth, &depth);
468 OOP_GetAttr(pixfmt, aHidd_PixFmt_RedMask, &red_mask);
469 OOP_GetAttr(pixfmt, aHidd_PixFmt_GreenMask, &green_mask);
470 OOP_GetAttr(pixfmt, aHidd_PixFmt_BlueMask, &blue_mask);
471 OOP_GetAttr(pixfmt, aHidd_PixFmt_AlphaMask, &alpha_mask);
473 break;
476 D(bug("[sdl] target format: depth %d red 0x%08x green 0x%08x blue 0x%08x alpha 0x%08x\n", depth, red_mask, green_mask, blue_mask, alpha_mask));
478 s = SP(SDL_CreateRGBSurfaceFrom, msg->pixels, msg->width, msg->height, depth, msg->modulo, red_mask, green_mask, blue_mask, alpha_mask);
479 if (native32) {
480 D(bug("[sdl] native32 format, setting pixel width to 4 bytes\n"));
481 s->format->BytesPerPixel = 4;
484 srect.x = msg->x;
485 srect.y = msg->y;
486 srect.w = msg->width;
487 srect.h = msg->height;
489 D(bug("[sdl] blitting %dx%d image at [%d,%d] to surface 0x%08x\n", srect.w, srect.h, srect.x, srect.y, bmdata->surface));
491 S(SDL_BlitSurface, bmdata->surface, &srect, s, NULL);
493 SV(SDL_FreeSurface, s);
496 VOID SDLBitMap__Hidd_BitMap__FillRect(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawRect *msg) {
497 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
498 struct SDL_Rect rect;
499 int bytesperpixel = bmdata->surface->format->BytesPerPixel;
500 HIDDT_Pixel fg = GC_FG(msg->gc);
501 HIDDT_DrawMode mode = GC_DRMD(msg->gc);
503 D(bug("[sdl] SDLBitMap::FillRect\n"));
505 rect.x = msg->minX;
506 rect.y = msg->minY;
507 rect.w = msg->maxX - msg->minX + 1;
508 rect.h = msg->maxY - msg->minY + 1;
510 D(bug("[sdl] target surface 0x%08x, width %d, height %d, depth %d\n", bmdata->surface, bmdata->surface->w, bmdata->surface->h, bmdata->surface->format->BitsPerPixel));
511 D(bug("[sdl] target rect x %d y %d w %d h %d\n", rect.x, rect.y, rect.h, rect.y));
512 D(bug("[sdl] colour 0x%08x, mode %d\n", fg, mode));
514 switch(mode) {
515 case vHidd_GC_DrawMode_Copy:
516 SV(SDL_FillRect, bmdata->surface, &rect, fg);
518 break;
520 case vHidd_GC_DrawMode_Invert:
521 LOCK(bmdata->surface);
523 HIDD_BM_InvertMemRect(o,
524 bmdata->surface->pixels,
525 msg->minX * bytesperpixel,
526 msg->minY,
527 msg->maxX * bytesperpixel + bytesperpixel - 1,
528 msg->maxY,
529 bmdata->surface->pitch);
531 UNLOCK(bmdata->surface);
533 break;
535 default:
536 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
537 break;
542 VOID SDLBitMap__Hidd_BitMap__Clear(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_Clear *msg) {
543 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
544 Uint32 c;
546 D(bug("[sdl] SDLBitMap::Clear\n"));
548 c = GC_BG(msg->gc);
550 D(bug("[sdl] filling surface 0x%08x with colour 0x%08x\n", bmdata->surface, c));
552 S(SDL_FillRect, bmdata->surface, NULL, c);
555 VOID SDLBitMap__Hidd_BitMap__BlitColorExpansion(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_BlitColorExpansion *msg) {
556 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
557 int bytesperpixel = bmdata->surface->format->BytesPerPixel;
558 Uint8 *p = (Uint8 *) bmdata->surface->pixels + msg->destY * bmdata->surface->pitch + msg->destX * bytesperpixel;
559 int x, y;
560 HIDDT_Pixel fg, bg;
561 ULONG ce;
562 ULONG *srcline;
564 D(bug("[sdl] SDLBitMap::BlitColorExpansion\n"));
566 D(bug("[sdl] target surface 0x%08x rect x %d y %d w %d h %d\n", bmdata->surface, msg->destX, msg->destY, msg->width, msg->height));
568 fg = GC_FG(msg->gc);
569 bg = GC_BG(msg->gc);
570 ce = GC_COLEXP(msg->gc);
572 srcline = AllocMem(msg->width * sizeof(ULONG), 0);
574 LOCK(bmdata->surface);
576 switch (ce) {
578 case vHidd_GC_ColExp_Transparent:
579 D(bug("[sdl] transparent colour expansion, fg 0x%08x\n", fg));
581 switch (bytesperpixel) {
583 case 1:
584 for (y = 0; y < msg->height; y++) {
585 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
586 for (x = 0; x < msg->width; x++) {
587 if (srcline[x] != 0)
588 PUTPIXEL8(&p[x], fg);
590 p += bmdata->surface->pitch;
592 break;
594 case 2:
595 for (y = 0; y < msg->height; y++) {
596 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
597 for (x = 0; x < msg->width; x++) {
598 if (srcline[x] != 0)
599 PUTPIXEL16(&(((Uint16 *) p)[x]), fg);
601 p += bmdata->surface->pitch;
603 break;
605 case 3:
606 for (y = 0; y < msg->height; y++) {
607 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
608 for (x = 0; x < msg->width; x++) {
609 if (srcline[x] != 0)
610 PUTPIXEL24(&(((Uint32 *) p)[x]), fg);
612 p += bmdata->surface->pitch;
614 break;
616 case 4:
617 for (y = 0; y < msg->height; y++) {
618 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
619 for (x = 0; x < msg->width; x++) {
620 if (srcline[x] != 0)
621 PUTPIXEL32(&(((Uint32 *) p)[x]), fg);
623 p += bmdata->surface->pitch;
625 break;
628 break;
631 case vHidd_GC_ColExp_Opaque:
632 D(bug("[sdl] opaque colour expansion, fg 0x%08x bg %08x\n", fg, bg));
634 switch (bytesperpixel) {
636 case 1:
637 for (y = 0; y < msg->height; y++) {
638 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
639 for (x = 0; x < msg->width; x++)
640 PUTPIXEL8(&p[x], srcline[x] != 0 ? fg : bg);
641 p += bmdata->surface->pitch;
643 break;
645 case 2:
646 for (y = 0; y < msg->height; y++) {
647 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcY, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
648 for (x = 0; x < msg->width; x++)
649 PUTPIXEL16(&(((Uint16 *) p)[x]), srcline[x] != 0 ? fg : bg);
650 p += bmdata->surface->pitch;
652 break;
654 case 3:
655 for (y = 0; y < msg->height; y++) {
656 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
657 for (x = 0; x < msg->width; x++)
658 PUTPIXEL24(&(((Uint32 *) p)[x]), srcline[x] != 0 ? fg : bg);
659 p += bmdata->surface->pitch;
661 break;
663 case 4:
664 for (y = 0; y < msg->height; y++) {
665 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
666 for (x = 0; x < msg->width; x++)
667 PUTPIXEL32(&(((Uint32 *) p)[x]), srcline[x] != 0 ? fg : bg);
668 p += bmdata->surface->pitch;
670 break;
673 break;
676 UNLOCK(bmdata->surface);
678 FreeMem(srcline, msg->width * sizeof(ULONG));
681 VOID SDLBitMap__Hidd_BitMap__PutAlphaImage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutAlphaImage *msg) {
682 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
683 SDL_Surface *s;
684 SDL_Rect srect, drect;
686 D(bug("[sdl] SDLBitMap::PutAlphaImage\n"));
688 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
689 s = SP(SDL_CreateRGBSurfaceFrom, msg->pixels, msg->width, msg->height, 32, msg->modulo, 0xff0000, 0xff00, 0xff, 0xff000000);
690 #else
691 s = SP(SDL_CreateRGBSurfaceFrom, msg->pixels, msg->width, msg->height, 32, msg->modulo, 0xff00, 0xff0000, 0xff000000, 0xff);
692 #endif
694 srect.x = 0;
695 srect.y = 0;
696 srect.w = msg->width;
697 srect.h = msg->height;
699 drect.x = msg->x;
700 drect.y = msg->y;
702 D(bug("[sdl] blitting %dx%d alpha image to surface 0x%08x at [%d,%d]\n", srect.w, srect.h, bmdata->surface, drect.x, drect.y));
704 S(SDL_BlitSurface, s, &srect, bmdata->surface, &drect);
706 SV(SDL_FreeSurface, s);
709 VOID SDLBitMap__Hidd_BitMap__PutTemplate(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutTemplate *msg) {
710 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
712 D(bug("[sdl] SDLBitMap::PutTemplate\n"));
714 LOCK(bmdata->surface);
716 switch (bmdata->surface->format->BytesPerPixel) {
717 case 1:
718 HIDD_BM_PutMemTemplate8(o, msg->gc, msg->masktemplate, msg->modulo, msg->srcx, bmdata->surface->pixels, bmdata->surface->pitch, msg->x, msg->y, msg->width, msg->height, msg->inverttemplate);
719 break;
721 case 2:
722 HIDD_BM_PutMemTemplate16(o, msg->gc, msg->masktemplate, msg->modulo, msg->srcx, bmdata->surface->pixels, bmdata->surface->pitch, msg->x, msg->y, msg->width, msg->height, msg->inverttemplate);
723 break;
725 case 3:
726 HIDD_BM_PutMemTemplate24(o, msg->gc, msg->masktemplate, msg->modulo, msg->srcx, bmdata->surface->pixels, bmdata->surface->pitch, msg->x, msg->y, msg->width, msg->height, msg->inverttemplate);
727 break;
729 case 4:
730 HIDD_BM_PutMemTemplate32(o, msg->gc, msg->masktemplate, msg->modulo, msg->srcx, bmdata->surface->pixels, bmdata->surface->pitch, msg->x, msg->y, msg->width, msg->height, msg->inverttemplate);
731 break;
734 UNLOCK(bmdata->surface);
737 static struct OOP_MethodDescr SDLBitMap_Root_descr[] = {
738 {(OOP_MethodFunc)SDLBitMap__Root__New, moRoot_New},
739 {(OOP_MethodFunc)SDLBitMap__Root__Dispose, moRoot_Dispose},
740 {(OOP_MethodFunc)SDLBitMap__Root__Get, moRoot_Get},
741 {(OOP_MethodFunc)SDLBitMap__Root__Set, moRoot_Set},
742 {NULL, 0}
744 #define NUM_SDLBitMap_Root_METHODS 4
746 static struct OOP_MethodDescr SDLBitMap_Hidd_BitMap_descr[] = {
747 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__SetColors, moHidd_BitMap_SetColors},
748 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__PutPixel, moHidd_BitMap_PutPixel},
749 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__GetPixel, moHidd_BitMap_GetPixel},
750 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__UpdateRect, moHidd_BitMap_UpdateRect},
751 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__PutImage, moHidd_BitMap_PutImage},
752 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__GetImage, moHidd_BitMap_GetImage},
753 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__FillRect, moHidd_BitMap_FillRect},
754 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__Clear, moHidd_BitMap_Clear},
755 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__BlitColorExpansion, moHidd_BitMap_BlitColorExpansion},
756 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__PutAlphaImage, moHidd_BitMap_PutAlphaImage},
757 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__PutTemplate, moHidd_BitMap_PutTemplate},
758 {NULL, 0}
760 #define NUM_SDLBitMap_Hidd_BitMap_METHODS 11
762 struct OOP_InterfaceDescr SDLBitMap_ifdescr[] = {
763 {SDLBitMap_Root_descr , IID_Root , NUM_SDLBitMap_Root_METHODS },
764 {SDLBitMap_Hidd_BitMap_descr, IID_Hidd_BitMap, NUM_SDLBitMap_Hidd_BitMap_METHODS},
765 {NULL , NULL }