make sdl.hidd build against recent iconv-aware sdls
[tangerine.git] / arch / all-hosted / hidd / sdl / bmclass.c
blob7d0e4613f3f62795632580c9f5cc6e2c1364f9e6
1 /*
2 * sdl.hidd - SDL graphics/sound/keyboard for AROS hosted
3 * Copyright (c) 2007 Robert Norris. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the same terms as AROS itself.
7 */
9 #define __OOP_NOATTRBASES__
11 #include <aros/symbolsets.h>
13 #include <hidd/hidd.h>
14 #include <hidd/graphics.h>
15 #include <utility/tagitem.h>
16 #include <oop/oop.h>
18 #include <proto/exec.h>
19 #include <proto/oop.h>
20 #include <proto/utility.h>
22 #include "sdl_intern.h"
24 #include LC_LIBDEFS_FILE
26 #define DEBUG 0
27 #include <aros/debug.h>
29 #include "icon.h"
31 static OOP_AttrBase HiddPixFmtAttrBase;
32 static OOP_AttrBase HiddBitMapAttrBase;
33 static OOP_AttrBase HiddSDLBitMapAttrBase;
35 static struct OOP_ABDescr attrbases[] = {
36 { IID_Hidd_PixFmt, &HiddPixFmtAttrBase },
37 { IID_Hidd_BitMap, &HiddBitMapAttrBase },
38 { IID_Hidd_SDLBitMap, &HiddSDLBitMapAttrBase },
39 { NULL, NULL }
42 static int sdl_bmclass_init(LIBBASETYPEPTR LIBBASE) {
43 D(bug("[sdl] sdl_bmclass_init\n"));
45 return OOP_ObtainAttrBases(attrbases);
48 static int sdl_bmclass_expunge(LIBBASETYPEPTR LIBBASE) {
49 D(bug("[sdl] sdl_bmclass_expunge\n"));
51 OOP_ReleaseAttrBases(attrbases);
52 return TRUE;
55 ADD2INITLIB(sdl_bmclass_init , 0)
56 ADD2EXPUNGELIB(sdl_bmclass_expunge, 0)
58 #define UPDATE(bmdata, x, y, w, h) \
59 do { \
60 if (bmdata->is_onscreen) \
61 SV(SDL_UpdateRect, bmdata->surface, x, y, w, h); \
62 } while(0)
64 #define LOCK(s) \
65 do { \
66 if (SDL_MUSTLOCK(s)) \
67 SV(SDL_LockSurface, s); \
68 } while(0)
70 #define UNLOCK(s) \
71 do { \
72 if (SDL_MUSTLOCK(s)) \
73 SV(SDL_UnlockSurface, s); \
74 } while(0)
76 static SDL_Surface *icon;
77 static void load_icon(LIBBASETYPEPTR SDLGfxBase) {
78 unsigned char *data, *pixel;
79 int i;
81 icon = S(SDL_CreateRGBSurface, SDL_SWSURFACE, icon_width, icon_height, 24, icon_red_mask, icon_green_mask, icon_blue_mask, 0);
83 LOCK(icon);
85 data = icon_header_data;
86 pixel = icon->pixels;
88 for (i = 0; i < icon_width * icon_height; i++) {
89 ICON_HEADER_PIXEL(data, pixel);
90 pixel += 3;
93 UNLOCK(icon);
96 #define SDLGfxBase ((LIBBASETYPEPTR) cl->UserData)
98 OOP_Object *SDLBitMap__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg) {
99 struct bmdata *bmdata;
100 BOOL framebuffer;
101 int width, height, depth;
102 OOP_Object *pixfmt;
103 SDL_Surface *s;
104 ULONG red_mask, green_mask, blue_mask, alpha_mask;
106 D(bug("[sdl] SDLBitMap::New\n"));
108 o = (OOP_Object *) OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
109 if (o == NULL) {
110 D(bug("[sdl] supermethod failed, bailing out\n"));
111 return NULL;
114 bmdata = OOP_INST_DATA(cl, o);
116 OOP_GetAttr(o, aHidd_BitMap_Width, (IPTR) &width);
117 OOP_GetAttr(o, aHidd_BitMap_Height, (IPTR) &height);
118 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (IPTR) &pixfmt);
120 OOP_GetAttr(pixfmt, aHidd_PixFmt_Depth, (IPTR) &depth);
122 D(bug("[sdl] width %d height %d depth %d\n", width, height, depth));
124 framebuffer = GetTagData(aHidd_BitMap_FrameBuffer, FALSE, msg->attrList);
125 if (framebuffer) {
126 D(bug("[sdl] creating new framebuffer\n"));
128 /* XXX we should free any existing onscreen surface. the problem is
129 * that we can't dispose the existing framebuffer object because the
130 * caller may still have a handle on it. we could fiddle at its
131 * innards well enough (store the current onscreen bitmap in class
132 * static data, and now grab it and free its surface), but then we
133 * have a bitmap with no associated surface, so we need checks for
134 * that.
136 * I expect that if the caller wants to make a new framebuffer, it
137 * should have to free the old one
140 if (!LIBBASE->use_hwsurface)
141 D(bug("[sdl] hardware surface not available, using software surface instead\n"));
143 if (icon == NULL) {
144 D(bug("[sdl] loading window icon\n"));
145 load_icon((LIBBASETYPEPTR) cl->UserData);
146 SV(SDL_WM_SetIcon, icon, NULL);
149 s = S(SDL_SetVideoMode, width, height, depth,
150 (LIBBASE->use_hwsurface ? SDL_HWSURFACE | SDL_HWPALETTE : SDL_SWSURFACE) |
151 (LIBBASE->use_fullscreen ? SDL_FULLSCREEN : 0) |
152 SDL_ANYFORMAT);
154 SV(SDL_WM_SetCaption, "AROS Research Operating System", "AROS");
157 else {
158 OOP_GetAttr(pixfmt, aHidd_PixFmt_RedMask, (IPTR) &red_mask);
159 OOP_GetAttr(pixfmt, aHidd_PixFmt_GreenMask, (IPTR) &green_mask);
160 OOP_GetAttr(pixfmt, aHidd_PixFmt_BlueMask, (IPTR) &blue_mask);
161 OOP_GetAttr(pixfmt, aHidd_PixFmt_AlphaMask, (IPTR) &alpha_mask);
163 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));
165 s = S(SDL_CreateRGBSurface, SDL_SWSURFACE, width, height, depth, red_mask, green_mask, blue_mask, alpha_mask);
168 if (s == NULL) {
169 OOP_MethodID dispose;
171 D(bug("[sdl] failed to create surface: %s\n", S(SDL_GetError, )));
173 dispose = OOP_GetMethodID(IID_Root, moRoot_Dispose);
174 OOP_CoerceMethod(cl, o, (OOP_Msg) &dispose);
176 return NULL;
179 bmdata->surface = s;
181 if (framebuffer)
182 bmdata->is_onscreen = TRUE;
184 D(bug("[sdl] created surface: 0x%08x\n", s));
186 return o;
189 VOID SDLBitMap__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg) {
190 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
192 D(bug("[sdl] SDLBitMap::Dispose\n"));
194 if (bmdata->surface != NULL) {
195 D(bug("[sdl] destroying surface 0x%08x\n", bmdata->surface));
197 SV(SDL_FreeSurface, bmdata->surface);
198 bmdata->surface = NULL;
201 OOP_DoSuperMethod(cl, o, msg);
203 return;
206 VOID SDLBitMap__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg) {
207 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
209 // D(bug("[sdl] SDLBitMap::Get\n"));
211 switch (SDLBM_ATTR(msg->attrID)) {
212 case aoHidd_SDLBitMap_Surface:
213 *msg->storage = (IPTR) bmdata->surface;
214 break;
216 case aoHidd_SDLBitMap_IsOnScreen:
217 *msg->storage = (IPTR) bmdata->is_onscreen;
218 break;
220 default:
221 OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
222 break;
226 BOOL SDLBitMap__Hidd_BitMap__SetColors(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_SetColors *msg) {
227 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
228 HIDDT_PixelFormat *pixfmt;
229 SDL_Color *colors;
230 int i;
232 //D(bug("[sdl] SDLBitMap::SetColors\n"));
234 pixfmt = BM_PIXFMT(o);
235 if (HIDD_PF_COLMODEL(pixfmt) == vHidd_ColorModel_StaticPalette ||
236 HIDD_PF_COLMODEL(pixfmt) == vHidd_ColorModel_TrueColor) {
238 return OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
241 if (!OOP_DoSuperMethod(cl, o, (OOP_Msg) msg))
242 return FALSE;
244 colors = AllocVec(sizeof(SDL_Color) * msg->numColors, MEMF_CLEAR);
246 for (i = 0; i < msg->numColors; i++) {
247 colors[i].r = msg->colors[i].red;
248 colors[i].g = msg->colors[i].green;
249 colors[i].b = msg->colors[i].blue;
252 S(SDL_SetColors, bmdata->surface, colors, msg->firstColor, msg->numColors);
254 D(bug("[sdl] set %d colours for surface 0x%08x\n", msg->numColors, bmdata->surface));
256 return TRUE;
259 #define PUTPIXEL8(p,c) (* (Uint8 *) (p) = (c))
260 #define GETPIXEL8(p) (* (Uint8 *) (p))
262 #define PUTPIXEL16(p,c) (* (Uint16 *) (p)) = (c)
263 #define GETPIXEL16(p) (* (Uint16 *) (p))
265 #define PUTPIXEL32(p,c) (* (Uint32 *) (p)) = (c)
266 #define GETPIXEL32(p) (* (Uint32 *) (p))
268 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
269 #define PUTPIXEL24(p,c) \
270 do { \
271 ((Uint8 *) p)[0] = ((c) >> 16) & 0xff; \
272 ((Uint8 *) p)[1] = ((c) >> 8) & 0xff; \
273 ((Uint8 *) p)[2] = (c) & 0xff; \
274 } while(0)
275 #define GETPIXEL24(p) (((Uint8 *) p)[0] << 16 | ((Uint8 *) p)[1] << 8 | ((Uint8 *)p)[2])
276 #else
277 #define PUTPIXEL24(p,c) \
278 do { \
279 ((Uint8 *) p)[0] = (c) & 0xff; \
280 ((Uint8 *) p)[1] = ((c) >> 8) & 0xff; \
281 ((Uint8 *) p)[2] = ((c) >> 16) & 0xff; \
282 } while(0)
283 #define GETPIXEL24(p) (((Uint8 *) p)[0] | ((Uint8 *) p)[1] << 8 | ((Uint8 *) p)[2] << 16)
284 #endif
286 VOID SDLBitMap__Hidd_BitMap__PutPixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutPixel *msg) {
287 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
288 int bytesperpixel = bmdata->surface->format->BytesPerPixel;
289 Uint8 *p = (Uint8 *) bmdata->surface->pixels + msg->y * bmdata->surface->pitch + msg->x * bytesperpixel;
290 Uint32 c = msg->pixel;
292 //D(bug("[sdl] SDLBitMap::PutPixel\n"));
293 //D(bug("[sdl] x %d y %d colour 0x%08x bytesperpixel %d\n", msg->x, msg->y, c, bytesperpixel));
295 LOCK(bmdata->surface);
297 switch (bytesperpixel) {
298 case 1:
299 PUTPIXEL8(p, c);
300 break;
302 case 2:
303 PUTPIXEL16(p, c);
304 break;
306 case 3:
307 PUTPIXEL24(p, c);
308 break;
310 case 4:
311 PUTPIXEL32(p, c);
312 break;
315 UNLOCK(bmdata->surface);
317 UPDATE(bmdata, msg->x, msg->y, 1, 1);
320 HIDDT_Pixel SDLBitMap__Hidd_BitMap__GetPixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetPixel *msg) {
321 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
322 int bytesperpixel = bmdata->surface->format->BytesPerPixel;
323 Uint8 *p = (Uint8 *) bmdata->surface->pixels + msg->y * bmdata->surface->pitch + msg->x * bytesperpixel;
324 Uint32 c;
326 //D(bug("[sdl] SDLBitMap::GetPixel\n"));
327 //D(bug("[sdl] x %d y %d bytesperpixel %d\n", msg->x, msg->y, bytesperpixel));
329 LOCK(bmdata->surface);
331 switch(bytesperpixel) {
333 case 1:
334 c = GETPIXEL8(p);
335 break;
337 case 2:
338 c = GETPIXEL16(p);
339 break;
341 case 3:
342 c = GETPIXEL24(p);
343 break;
345 case 4:
346 c = GETPIXEL32(p);
347 break;
350 UNLOCK(bmdata->surface);
352 //D(bug("[sdl] returning pixel 0x%08x\n", c));
354 return (HIDDT_Pixel) c;
357 VOID SDLBitMap__Hidd_BitMap__PutImage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutImage *msg) {
358 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
359 int depth;
360 Uint32 red_mask, green_mask, blue_mask, alpha_mask;
361 BOOL native32 = FALSE;
362 SDL_Surface *s;
363 SDL_Rect srect, drect;
365 D(bug("[sdl] SDLBitMap::PutImage\n"));
367 switch (msg->pixFmt) {
368 case vHidd_StdPixFmt_Native32:
369 D(bug("[sdl] native32 format, making a note to ensure 4-byte pixels later\n"));
370 native32 = TRUE;
372 case vHidd_StdPixFmt_Native:
373 D(bug("[sdl] native format, using our attributes\n"));
375 depth = bmdata->surface->format->BitsPerPixel;
376 red_mask = bmdata->surface->format->Rmask;
377 green_mask = bmdata->surface->format->Gmask;
378 blue_mask = bmdata->surface->format->Bmask;
379 alpha_mask = bmdata->surface->format->Amask;
381 break;
383 default:
384 D(bug("[sdl] pixel format %d, asking the gfxhidd for attributes\n", msg->pixFmt));
386 OOP_Object *gfxhidd;
387 OOP_GetAttr(o, aHidd_BitMap_GfxHidd, (IPTR) &gfxhidd);
389 OOP_Object *pixfmt = HIDD_Gfx_GetPixFmt(gfxhidd, msg->pixFmt);
391 OOP_GetAttr(pixfmt, aHidd_PixFmt_Depth, (IPTR) &depth);
392 OOP_GetAttr(pixfmt, aHidd_PixFmt_RedMask, (IPTR) &red_mask);
393 OOP_GetAttr(pixfmt, aHidd_PixFmt_GreenMask, (IPTR) &green_mask);
394 OOP_GetAttr(pixfmt, aHidd_PixFmt_BlueMask, (IPTR) &blue_mask);
395 OOP_GetAttr(pixfmt, aHidd_PixFmt_AlphaMask, (IPTR) &alpha_mask);
397 break;
400 D(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));
402 s = S(SDL_CreateRGBSurfaceFrom, msg->pixels, msg->width, msg->height, depth, msg->modulo, red_mask, green_mask, blue_mask, alpha_mask);
403 if (native32) {
404 D(bug("[sdl] native32 format, setting pixel width to 4 bytes\n"));
405 s->format->BytesPerPixel = 4;
408 srect.x = 0;
409 srect.y = 0;
410 srect.w = msg->width;
411 srect.h = msg->height;
413 drect.x = msg->x;
414 drect.y = msg->y;
416 D(bug("[sdl] blitting %dx%d image to surface 0x%08x at [%d,%d]\n", srect.w, srect.h, bmdata->surface, drect.x, drect.y));
418 S(SDL_BlitSurface, s, &srect, bmdata->surface, &drect);
420 SV(SDL_FreeSurface, s);
422 UPDATE(bmdata, msg->x, msg->y, msg->width, msg->height);
425 VOID SDLBitMap__Hidd_BitMap__GetImage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetImage *msg) {
426 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
427 int depth;
428 Uint32 red_mask, green_mask, blue_mask, alpha_mask;
429 BOOL native32 = FALSE;
430 SDL_Surface *s;
431 SDL_Rect srect;
433 D(bug("[sdl] SDLBitMap::GetImage\n"));
435 switch (msg->pixFmt) {
436 case vHidd_StdPixFmt_Native32:
437 D(bug("[sdl] native32 format, making a note to ensure 4-byte pixels later\n"));
438 native32 = TRUE;
440 case vHidd_StdPixFmt_Native:
441 D(bug("[sdl] native format, using our attributes\n"));
443 depth = bmdata->surface->format->BitsPerPixel;
444 red_mask = bmdata->surface->format->Rmask;
445 green_mask = bmdata->surface->format->Gmask;
446 blue_mask = bmdata->surface->format->Bmask;
447 alpha_mask = bmdata->surface->format->Amask;
449 break;
451 default:
452 D(bug("[sdl] pixel format %d, asking the gfxhidd for attributes\n", msg->pixFmt));
454 OOP_Object *gfxhidd;
455 OOP_GetAttr(o, aHidd_BitMap_GfxHidd, (IPTR) &gfxhidd);
457 OOP_Object *pixfmt = HIDD_Gfx_GetPixFmt(gfxhidd, msg->pixFmt);
459 OOP_GetAttr(pixfmt, aHidd_PixFmt_Depth, (IPTR) &depth);
460 OOP_GetAttr(pixfmt, aHidd_PixFmt_RedMask, (IPTR) &red_mask);
461 OOP_GetAttr(pixfmt, aHidd_PixFmt_GreenMask, (IPTR) &green_mask);
462 OOP_GetAttr(pixfmt, aHidd_PixFmt_BlueMask, (IPTR) &blue_mask);
463 OOP_GetAttr(pixfmt, aHidd_PixFmt_AlphaMask, (IPTR) &alpha_mask);
465 break;
468 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));
470 s = S(SDL_CreateRGBSurfaceFrom, msg->pixels, msg->width, msg->height, depth, msg->modulo, red_mask, green_mask, blue_mask, alpha_mask);
471 if (native32) {
472 D(bug("[sdl] native32 format, setting pixel width to 4 bytes\n"));
473 s->format->BytesPerPixel = 4;
476 srect.x = msg->x;
477 srect.y = msg->y;
478 srect.w = msg->width;
479 srect.h = msg->height;
481 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));
483 S(SDL_BlitSurface, bmdata->surface, &srect, s, NULL);
485 SV(SDL_FreeSurface, s);
488 VOID SDLBitMap__Hidd_BitMap__FillRect(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawRect *msg) {
489 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
490 struct SDL_Rect rect;
491 int bytesperpixel = bmdata->surface->format->BytesPerPixel;
492 HIDDT_Pixel fg = GC_FG(msg->gc);
493 HIDDT_DrawMode mode = GC_DRMD(msg->gc);
495 D(bug("[sdl] SDLBitMap::FillRect\n"));
497 rect.x = msg->minX;
498 rect.y = msg->minY;
499 rect.w = msg->maxX - msg->minX + 1;
500 rect.h = msg->maxY - msg->minY + 1;
502 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));
503 D(bug("[sdl] target rect x %d y %d w %d h %d\n", rect.x, rect.y, rect.h, rect.y));
504 D(bug("[sdl] colour 0x%08x, mode %d\n", fg, mode));
506 switch(mode) {
507 case vHidd_GC_DrawMode_Copy:
508 SV(SDL_FillRect, bmdata->surface, &rect, fg);
510 break;
512 case vHidd_GC_DrawMode_Invert:
513 LOCK(bmdata->surface);
515 HIDD_BM_InvertMemRect(o,
516 bmdata->surface->pixels,
517 msg->minX * bytesperpixel,
518 msg->minY,
519 msg->maxX * bytesperpixel + bytesperpixel - 1,
520 msg->maxY,
521 bmdata->surface->pitch);
523 UNLOCK(bmdata->surface);
525 break;
527 default:
528 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
529 break;
533 UPDATE(bmdata, rect.x, rect.y, rect.w, rect.h);
536 VOID SDLBitMap__Hidd_BitMap__Clear(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_Clear *msg) {
537 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
538 Uint32 c;
540 D(bug("[sdl] SDLBitMap::Clear\n"));
542 c = GC_BG(msg->gc);
544 D(bug("[sdl] filling surface 0x%08x with colour 0x%08x\n", bmdata->surface, c));
546 S(SDL_FillRect, bmdata->surface, NULL, c);
548 UPDATE(bmdata, 0, 0, 0, 0);
551 VOID SDLBitMap__Hidd_BitMap__BlitColorExpansion(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_BlitColorExpansion *msg) {
552 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
553 int bytesperpixel = bmdata->surface->format->BytesPerPixel;
554 Uint8 *p = (Uint8 *) bmdata->surface->pixels + msg->destY * bmdata->surface->pitch + msg->destX * bytesperpixel;
555 int x, y;
556 HIDDT_Pixel fg, bg;
557 ULONG ce;
558 Uint32 pixel;
559 ULONG *srcline;
561 D(bug("[sdl] SDLBitMap::BlitColorExpansion\n"));
563 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));
565 fg = GC_FG(msg->gc);
566 bg = GC_BG(msg->gc);
567 ce = GC_COLEXP(msg->gc);
569 srcline = AllocMem(msg->width * sizeof(ULONG), 0);
571 LOCK(bmdata->surface);
573 switch (ce) {
575 case vHidd_GC_ColExp_Transparent:
576 D(bug("[sdl] transparent colour expansion, fg 0x%08x\n", fg));
578 switch (bytesperpixel) {
580 case 1:
581 for (y = 0; y < msg->height; y++) {
582 HIDD_BM_GetImage(msg->srcBitMap, srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
583 for (x = 0; x < msg->width; x++) {
584 if (srcline[x] != 0)
585 PUTPIXEL8(&p[x], fg);
587 p += bmdata->surface->pitch;
589 break;
591 case 2:
592 for (y = 0; y < msg->height; y++) {
593 HIDD_BM_GetImage(msg->srcBitMap, srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
594 for (x = 0; x < msg->width; x++) {
595 if (srcline[x] != 0)
596 PUTPIXEL16(&(((Uint16 *) p)[x]), fg);
598 p += bmdata->surface->pitch;
600 break;
602 case 3:
603 for (y = 0; y < msg->height; y++) {
604 HIDD_BM_GetImage(msg->srcBitMap, srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
605 for (x = 0; x < msg->width; x++) {
606 if (srcline[x] != 0)
607 PUTPIXEL24(&(((Uint32 *) p)[x]), fg);
609 p += bmdata->surface->pitch;
611 break;
613 case 4:
614 for (y = 0; y < msg->height; y++) {
615 HIDD_BM_GetImage(msg->srcBitMap, srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
616 for (x = 0; x < msg->width; x++) {
617 if (srcline[x] != 0)
618 PUTPIXEL32(&(((Uint32 *) p)[x]), fg);
620 p += bmdata->surface->pitch;
622 break;
625 break;
628 case vHidd_GC_ColExp_Opaque:
629 D(bug("[sdl] opaque colour expansion, fg 0x%08x bg %08x\n", fg, bg));
631 switch (bytesperpixel) {
633 case 1:
634 for (y = 0; y < msg->height; y++) {
635 HIDD_BM_GetImage(msg->srcBitMap, srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
636 for (x = 0; x < msg->width; x++)
637 PUTPIXEL8(&p[x], srcline[x] != 0 ? fg : bg);
638 p += bmdata->surface->pitch;
640 break;
642 case 2:
643 for (y = 0; y < msg->height; y++) {
644 HIDD_BM_GetImage(msg->srcBitMap, srcline, msg->width * sizeof(ULONG), msg->srcY, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
645 for (x = 0; x < msg->width; x++)
646 PUTPIXEL16(&(((Uint16 *) p)[x]), srcline[x] != 0 ? fg : bg);
647 p += bmdata->surface->pitch;
649 break;
651 case 3:
652 for (y = 0; y < msg->height; y++) {
653 HIDD_BM_GetImage(msg->srcBitMap, srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
654 for (x = 0; x < msg->width; x++)
655 PUTPIXEL24(&(((Uint32 *) p)[x]), srcline[x] != 0 ? fg : bg);
656 p += bmdata->surface->pitch;
658 break;
660 case 4:
661 for (y = 0; y < msg->height; y++) {
662 HIDD_BM_GetImage(msg->srcBitMap, srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
663 for (x = 0; x < msg->width; x++)
664 PUTPIXEL32(&(((Uint32 *) p)[x]), srcline[x] != 0 ? fg : bg);
665 p += bmdata->surface->pitch;
667 break;
670 break;
673 UNLOCK(bmdata->surface);
675 FreeMem(srcline, msg->width * sizeof(ULONG));
677 UPDATE(bmdata, msg->destX, msg->destY, msg->width, msg->height);
680 VOID SDLBitMap__Hidd_BitMap__PutAlphaImage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutAlphaImage *msg) {
681 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
682 SDL_Surface *s;
683 SDL_Rect srect, drect;
685 D(bug("[sdl] SDLBitMap::PutAlphaImage\n"));
687 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
688 s = S(SDL_CreateRGBSurfaceFrom, msg->pixels, msg->width, msg->height, 32, msg->modulo, 0xff0000, 0xff00, 0xff, 0xff000000);
689 #else
690 s = S(SDL_CreateRGBSurfaceFrom, msg->pixels, msg->width, msg->height, 32, msg->modulo, 0xff00, 0xff0000, 0xff000000, 0xff);
691 #endif
693 srect.x = 0;
694 srect.y = 0;
695 srect.w = msg->width;
696 srect.h = msg->height;
698 drect.x = msg->x;
699 drect.y = msg->y;
701 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));
703 S(SDL_BlitSurface, s, &srect, bmdata->surface, &drect);
705 SV(SDL_FreeSurface, s);
707 UPDATE(bmdata, drect.x, drect.y, srect.w, srect.h);
710 VOID SDLBitMap__Hidd_BitMap__PutTemplate(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutTemplate *msg) {
711 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
712 SDL_Rect rect;
714 D(bug("[sdl] SDLBitMap::PutTemplate\n"));
716 LOCK(bmdata->surface);
718 switch (bmdata->surface->format->BytesPerPixel) {
719 case 1:
720 HIDD_BM_PutMemTemplate8(o, msg->gc, msg->template, msg->modulo, msg->srcx, bmdata->surface->pixels, bmdata->surface->pitch, msg->x, msg->y, msg->width, msg->height, msg->inverttemplate);
721 break;
723 case 2:
724 HIDD_BM_PutMemTemplate16(o, msg->gc, msg->template, msg->modulo, msg->srcx, bmdata->surface->pixels, bmdata->surface->pitch, msg->x, msg->y, msg->width, msg->height, msg->inverttemplate);
725 break;
727 case 3:
728 HIDD_BM_PutMemTemplate24(o, msg->gc, msg->template, msg->modulo, msg->srcx, bmdata->surface->pixels, bmdata->surface->pitch, msg->x, msg->y, msg->width, msg->height, msg->inverttemplate);
729 break;
731 case 4:
732 HIDD_BM_PutMemTemplate32(o, msg->gc, msg->template, msg->modulo, msg->srcx, bmdata->surface->pixels, bmdata->surface->pitch, msg->x, msg->y, msg->width, msg->height, msg->inverttemplate);
733 break;
736 UNLOCK(bmdata->surface);
737 SV(SDL_UnlockSurface, bmdata->surface);
739 UPDATE(bmdata, msg->x, msg->y, msg->width, msg->height);