Added missing properties.
[AROS.git] / arch / all-hosted / hidd / sdl / bmclass.c
blob2842470145464086df08e9e7ecbd5dd048c8bb8b
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)
49 static SDL_Surface *icon;
50 static void load_icon(LIBBASETYPEPTR SDLGfxBase) {
51 unsigned char *data, *pixel;
52 int i;
54 icon = SP(SDL_CreateRGBSurface, SDL_SWSURFACE, icon_width, icon_height, 24, icon_red_mask, icon_green_mask, icon_blue_mask, 0);
56 LOCK(icon);
58 data = icon_header_data;
59 pixel = icon->pixels;
61 for (i = 0; i < icon_width * icon_height; i++) {
62 ICON_HEADER_PIXEL(data, pixel);
63 pixel += 3;
66 UNLOCK(icon);
69 #define SDLGfxBase ((LIBBASETYPEPTR) cl->UserData)
71 OOP_Object *SDLBitMap__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg) {
72 struct bmdata *bmdata;
73 BOOL framebuffer;
74 IPTR width, height, depth;
75 OOP_Object *pixfmt;
76 SDL_Surface *s;
77 IPTR red_mask, green_mask, blue_mask, alpha_mask;
79 D(bug("[sdl] SDLBitMap::New\n"));
81 o = (OOP_Object *) OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
82 if (o == NULL) {
83 D(bug("[sdl] supermethod failed, bailing out\n"));
84 return NULL;
87 bmdata = OOP_INST_DATA(cl, o);
89 OOP_GetAttr(o, aHidd_BitMap_Width, &width);
90 OOP_GetAttr(o, aHidd_BitMap_Height, &height);
91 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (IPTR *)&pixfmt);
93 OOP_GetAttr(pixfmt, aHidd_PixFmt_Depth, &depth);
95 D(bug("[sdl] width %d height %d depth %d\n", width, height, depth));
97 framebuffer = GetTagData(aHidd_BitMap_FrameBuffer, FALSE, msg->attrList);
98 if (framebuffer) {
99 D(bug("[sdl] creating new framebuffer\n"));
101 /* XXX we should free any existing onscreen surface. the problem is
102 * that we can't dispose the existing framebuffer object because the
103 * caller may still have a handle on it. we could fiddle at its
104 * innards well enough (store the current onscreen bitmap in class
105 * static data, and now grab it and free its surface), but then we
106 * have a bitmap with no associated surface, so we need checks for
107 * that.
109 * I expect that if the caller wants to make a new framebuffer, it
110 * should have to free the old one
113 if (!LIBBASE->use_hwsurface)
114 D(bug("[sdl] hardware surface not available, using software surface instead\n"));
116 if (icon == NULL) {
117 D(bug("[sdl] loading window icon\n"));
118 load_icon((LIBBASETYPEPTR) cl->UserData);
119 SV(SDL_WM_SetIcon, icon, NULL);
122 s = SP(SDL_SetVideoMode, width, height, depth,
123 (LIBBASE->use_hwsurface ? SDL_HWSURFACE | SDL_HWPALETTE : SDL_SWSURFACE) |
124 (LIBBASE->use_fullscreen ? SDL_FULLSCREEN : 0) |
125 SDL_ANYFORMAT);
127 SV(SDL_WM_SetCaption, "AROS Research Operating System", "AROS");
130 else {
131 OOP_GetAttr(pixfmt, aHidd_PixFmt_RedMask, &red_mask);
132 OOP_GetAttr(pixfmt, aHidd_PixFmt_GreenMask, &green_mask);
133 OOP_GetAttr(pixfmt, aHidd_PixFmt_BlueMask, &blue_mask);
134 OOP_GetAttr(pixfmt, aHidd_PixFmt_AlphaMask, &alpha_mask);
136 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));
138 s = SP(SDL_CreateRGBSurface, SDL_SWSURFACE, width, height, depth, red_mask, green_mask, blue_mask, alpha_mask);
141 if (s == NULL) {
142 OOP_MethodID dispose;
144 D(bug("[sdl] failed to create surface: %s\n", S(SDL_GetError, )));
146 dispose = OOP_GetMethodID(IID_Root, moRoot_Dispose);
147 OOP_CoerceMethod(cl, o, (OOP_Msg) &dispose);
149 return NULL;
152 bmdata->surface = s;
154 if (framebuffer)
155 bmdata->is_onscreen = TRUE;
157 D(bug("[sdl] created surface: 0x%08x\n", s));
159 return o;
162 VOID SDLBitMap__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg) {
163 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
165 D(bug("[sdl] SDLBitMap::Dispose\n"));
167 if (bmdata->surface != NULL) {
168 D(bug("[sdl] destroying surface 0x%08x\n", bmdata->surface));
170 SV(SDL_FreeSurface, bmdata->surface);
171 bmdata->surface = NULL;
174 OOP_DoSuperMethod(cl, o, msg);
176 return;
179 VOID SDLBitMap__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg) {
180 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
182 // D(bug("[sdl] SDLBitMap::Get\n"));
184 switch (SDLBM_ATTR(msg->attrID)) {
185 case aoHidd_SDLBitMap_Surface:
186 *msg->storage = (IPTR) bmdata->surface;
187 break;
189 default:
190 OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
191 break;
195 VOID SDLBitMap__Root__Set(OOP_Class *cl, OOP_Object *o, struct pRoot_Set *msg)
197 struct bmdata *data = OOP_INST_DATA(cl, o);
198 struct TagItem *tag, *tstate;
199 ULONG idx;
201 tstate = msg->attrList;
202 while((tag = NextTagItem(&tstate))) {
203 idx = SDLBM_ATTR(tag->ti_Tag);
204 if (idx < num_Hidd_SDLBitMap_Attrs) {
205 switch(idx) {
206 case aoHidd_SDLBitMap_Surface:
207 data->surface = (SDL_Surface *)tag->ti_Data;
208 break;
213 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
216 BOOL SDLBitMap__Hidd_BitMap__SetColors(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_SetColors *msg) {
217 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
218 HIDDT_PixelFormat *pixfmt;
219 SDL_Color *colors;
220 int i;
222 //D(bug("[sdl] SDLBitMap::SetColors\n"));
224 pixfmt = BM_PIXFMT(o);
225 if (HIDD_PF_COLMODEL(pixfmt) == vHidd_ColorModel_StaticPalette ||
226 HIDD_PF_COLMODEL(pixfmt) == vHidd_ColorModel_TrueColor) {
228 return OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
231 if (!OOP_DoSuperMethod(cl, o, (OOP_Msg) msg))
232 return FALSE;
234 colors = AllocVec(sizeof(SDL_Color) * msg->numColors, MEMF_CLEAR);
236 for (i = 0; i < msg->numColors; i++) {
237 colors[i].r = msg->colors[i].red;
238 colors[i].g = msg->colors[i].green;
239 colors[i].b = msg->colors[i].blue;
242 S(SDL_SetColors, bmdata->surface, colors, msg->firstColor, msg->numColors);
244 D(bug("[sdl] set %d colours for surface 0x%08x\n", msg->numColors, bmdata->surface));
246 return TRUE;
249 #define PUTPIXEL8(p,c) (* (Uint8 *) (p) = (c))
250 #define GETPIXEL8(p) (* (Uint8 *) (p))
252 #define PUTPIXEL16(p,c) (* (Uint16 *) (p)) = (c)
253 #define GETPIXEL16(p) (* (Uint16 *) (p))
255 #define PUTPIXEL32(p,c) (* (Uint32 *) (p)) = (c)
256 #define GETPIXEL32(p) (* (Uint32 *) (p))
258 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
259 #define PUTPIXEL24(p,c) \
260 do { \
261 ((Uint8 *) p)[0] = ((c) >> 16) & 0xff; \
262 ((Uint8 *) p)[1] = ((c) >> 8) & 0xff; \
263 ((Uint8 *) p)[2] = (c) & 0xff; \
264 } while(0)
265 #define GETPIXEL24(p) (((Uint8 *) p)[0] << 16 | ((Uint8 *) p)[1] << 8 | ((Uint8 *)p)[2])
266 #else
267 #define PUTPIXEL24(p,c) \
268 do { \
269 ((Uint8 *) p)[0] = (c) & 0xff; \
270 ((Uint8 *) p)[1] = ((c) >> 8) & 0xff; \
271 ((Uint8 *) p)[2] = ((c) >> 16) & 0xff; \
272 } while(0)
273 #define GETPIXEL24(p) (((Uint8 *) p)[0] | ((Uint8 *) p)[1] << 8 | ((Uint8 *) p)[2] << 16)
274 #endif
276 VOID SDLBitMap__Hidd_BitMap__PutPixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutPixel *msg) {
277 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
278 int bytesperpixel = bmdata->surface->format->BytesPerPixel;
279 Uint8 *p = (Uint8 *) bmdata->surface->pixels + msg->y * bmdata->surface->pitch + msg->x * bytesperpixel;
280 Uint32 c = msg->pixel;
282 //D(bug("[sdl] SDLBitMap::PutPixel\n"));
283 //D(bug("[sdl] x %d y %d colour 0x%08x bytesperpixel %d\n", msg->x, msg->y, c, bytesperpixel));
285 LOCK(bmdata->surface);
287 switch (bytesperpixel) {
288 case 1:
289 PUTPIXEL8(p, c);
290 break;
292 case 2:
293 PUTPIXEL16(p, c);
294 break;
296 case 3:
297 PUTPIXEL24(p, c);
298 break;
300 case 4:
301 PUTPIXEL32(p, c);
302 break;
305 UNLOCK(bmdata->surface);
308 HIDDT_Pixel SDLBitMap__Hidd_BitMap__GetPixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetPixel *msg) {
309 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
310 int bytesperpixel = bmdata->surface->format->BytesPerPixel;
311 Uint8 *p = (Uint8 *) bmdata->surface->pixels + msg->y * bmdata->surface->pitch + msg->x * bytesperpixel;
312 Uint32 c = 0;
314 //D(bug("[sdl] SDLBitMap::GetPixel\n"));
315 //D(bug("[sdl] x %d y %d bytesperpixel %d\n", msg->x, msg->y, bytesperpixel));
317 LOCK(bmdata->surface);
319 switch(bytesperpixel) {
321 case 1:
322 c = GETPIXEL8(p);
323 break;
325 case 2:
326 c = GETPIXEL16(p);
327 break;
329 case 3:
330 c = GETPIXEL24(p);
331 break;
333 case 4:
334 c = GETPIXEL32(p);
335 break;
338 UNLOCK(bmdata->surface);
340 //D(bug("[sdl] returning pixel 0x%08x\n", c));
342 return (HIDDT_Pixel) c;
345 VOID SDLBitMap__Hidd_BitMap__UpdateRect(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_UpdateRect *msg) {
346 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
348 D(bug("[sdl] SDLBitMap::UpdateRect\n"));
349 D(bug("[sdl] Updating region (%d,%d) [%d,%d]\n", msg->x, msg->y, msg->width, msg->height));
351 if (bmdata->is_onscreen)
352 SV(SDL_UpdateRect, bmdata->surface, msg->x, msg->y, msg->width, msg->height);
355 VOID SDLBitMap__Hidd_BitMap__PutImage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutImage *msg) {
356 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
357 IPTR depth;
358 IPTR red_mask, green_mask, blue_mask, alpha_mask;
359 BOOL native32 = FALSE;
360 SDL_Surface *s;
361 SDL_Rect srect, drect;
363 DPUTIMAGE(bug("[sdl] SDLBitMap::PutImage\n"));
365 switch (msg->pixFmt) {
366 case vHidd_StdPixFmt_Native32:
367 DPUTIMAGE(bug("[sdl] native32 format, making a note to ensure 4-byte pixels later\n"));
368 native32 = TRUE;
370 case vHidd_StdPixFmt_Native:
371 DPUTIMAGE(bug("[sdl] native format, using our attributes\n"));
373 depth = bmdata->surface->format->BitsPerPixel;
374 red_mask = bmdata->surface->format->Rmask;
375 green_mask = bmdata->surface->format->Gmask;
376 blue_mask = bmdata->surface->format->Bmask;
377 alpha_mask = bmdata->surface->format->Amask;
379 break;
381 default:
382 DPUTIMAGE(bug("[sdl] pixel format %d, asking the gfxhidd for attributes\n", msg->pixFmt));
384 OOP_Object *gfxhidd;
385 OOP_GetAttr(o, aHidd_BitMap_GfxHidd, (IPTR *)&gfxhidd);
387 OOP_Object *pixfmt = HIDD_Gfx_GetPixFmt(gfxhidd, msg->pixFmt);
389 OOP_GetAttr(pixfmt, aHidd_PixFmt_Depth, &depth);
390 OOP_GetAttr(pixfmt, aHidd_PixFmt_RedMask, &red_mask);
391 OOP_GetAttr(pixfmt, aHidd_PixFmt_GreenMask, &green_mask);
392 OOP_GetAttr(pixfmt, aHidd_PixFmt_BlueMask, &blue_mask);
393 /* Alpha blitting is done using PutAlphaImage(). This method
394 should ignore alpha channel data. Otherwise data without
395 alpha channel (with alpha == 0) is assumed to contain valid
396 alpha values and we see nothing as a result.
397 This is known to affect TrueType fonts. */
398 alpha_mask = 0;
400 break;
403 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));
405 s = SP(SDL_CreateRGBSurfaceFrom, msg->pixels, msg->width, msg->height, depth, msg->modulo, red_mask, green_mask, blue_mask, alpha_mask);
406 if (native32) {
407 DPUTIMAGE(bug("[sdl] native32 format, setting pixel width to 4 bytes\n"));
408 s->format->BytesPerPixel = 4;
411 srect.x = 0;
412 srect.y = 0;
413 srect.w = msg->width;
414 srect.h = msg->height;
416 drect.x = msg->x;
417 drect.y = msg->y;
419 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));
421 S(SDL_BlitSurface, s, &srect, bmdata->surface, &drect);
423 SV(SDL_FreeSurface, s);
426 VOID SDLBitMap__Hidd_BitMap__GetImage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetImage *msg) {
427 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
428 IPTR depth;
429 IPTR red_mask, green_mask, blue_mask, alpha_mask;
430 BOOL native32 = FALSE;
431 SDL_Surface *s;
432 SDL_Rect srect;
434 D(bug("[sdl] SDLBitMap::GetImage\n"));
436 switch (msg->pixFmt) {
437 case vHidd_StdPixFmt_Native32:
438 D(bug("[sdl] native32 format, making a note to ensure 4-byte pixels later\n"));
439 native32 = TRUE;
441 case vHidd_StdPixFmt_Native:
442 D(bug("[sdl] native format, using our attributes\n"));
444 depth = bmdata->surface->format->BitsPerPixel;
445 red_mask = bmdata->surface->format->Rmask;
446 green_mask = bmdata->surface->format->Gmask;
447 blue_mask = bmdata->surface->format->Bmask;
448 alpha_mask = bmdata->surface->format->Amask;
450 break;
452 default:
453 D(bug("[sdl] pixel format %d, asking the gfxhidd for attributes\n", msg->pixFmt));
455 OOP_Object *gfxhidd;
456 OOP_GetAttr(o, aHidd_BitMap_GfxHidd, (IPTR *)&gfxhidd);
458 OOP_Object *pixfmt = HIDD_Gfx_GetPixFmt(gfxhidd, msg->pixFmt);
460 OOP_GetAttr(pixfmt, aHidd_PixFmt_Depth, &depth);
461 OOP_GetAttr(pixfmt, aHidd_PixFmt_RedMask, &red_mask);
462 OOP_GetAttr(pixfmt, aHidd_PixFmt_GreenMask, &green_mask);
463 OOP_GetAttr(pixfmt, aHidd_PixFmt_BlueMask, &blue_mask);
464 OOP_GetAttr(pixfmt, aHidd_PixFmt_AlphaMask, &alpha_mask);
466 break;
469 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));
471 s = SP(SDL_CreateRGBSurfaceFrom, msg->pixels, msg->width, msg->height, depth, msg->modulo, red_mask, green_mask, blue_mask, alpha_mask);
472 if (native32) {
473 D(bug("[sdl] native32 format, setting pixel width to 4 bytes\n"));
474 s->format->BytesPerPixel = 4;
477 srect.x = msg->x;
478 srect.y = msg->y;
479 srect.w = msg->width;
480 srect.h = msg->height;
482 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));
484 S(SDL_BlitSurface, bmdata->surface, &srect, s, NULL);
486 SV(SDL_FreeSurface, s);
489 VOID SDLBitMap__Hidd_BitMap__FillRect(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawRect *msg) {
490 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
491 struct SDL_Rect rect;
492 int bytesperpixel = bmdata->surface->format->BytesPerPixel;
493 HIDDT_Pixel fg = GC_FG(msg->gc);
494 HIDDT_DrawMode mode = GC_DRMD(msg->gc);
496 D(bug("[sdl] SDLBitMap::FillRect\n"));
498 rect.x = msg->minX;
499 rect.y = msg->minY;
500 rect.w = msg->maxX - msg->minX + 1;
501 rect.h = msg->maxY - msg->minY + 1;
503 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));
504 D(bug("[sdl] target rect x %d y %d w %d h %d\n", rect.x, rect.y, rect.h, rect.y));
505 D(bug("[sdl] colour 0x%08x, mode %d\n", fg, mode));
507 switch(mode) {
508 case vHidd_GC_DrawMode_Copy:
509 SV(SDL_FillRect, bmdata->surface, &rect, fg);
511 break;
513 case vHidd_GC_DrawMode_Invert:
514 LOCK(bmdata->surface);
516 HIDD_BM_InvertMemRect(o,
517 bmdata->surface->pixels,
518 msg->minX * bytesperpixel,
519 msg->minY,
520 msg->maxX * bytesperpixel + bytesperpixel - 1,
521 msg->maxY,
522 bmdata->surface->pitch);
524 UNLOCK(bmdata->surface);
526 break;
528 default:
529 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
530 break;
535 VOID SDLBitMap__Hidd_BitMap__Clear(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_Clear *msg) {
536 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
537 Uint32 c;
539 D(bug("[sdl] SDLBitMap::Clear\n"));
541 c = GC_BG(msg->gc);
543 D(bug("[sdl] filling surface 0x%08x with colour 0x%08x\n", bmdata->surface, c));
545 S(SDL_FillRect, bmdata->surface, NULL, c);
548 VOID SDLBitMap__Hidd_BitMap__BlitColorExpansion(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_BlitColorExpansion *msg) {
549 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
550 int bytesperpixel = bmdata->surface->format->BytesPerPixel;
551 Uint8 *p = (Uint8 *) bmdata->surface->pixels + msg->destY * bmdata->surface->pitch + msg->destX * bytesperpixel;
552 int x, y;
553 HIDDT_Pixel fg, bg;
554 ULONG ce;
555 ULONG *srcline;
557 D(bug("[sdl] SDLBitMap::BlitColorExpansion\n"));
559 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));
561 fg = GC_FG(msg->gc);
562 bg = GC_BG(msg->gc);
563 ce = GC_COLEXP(msg->gc);
565 srcline = AllocMem(msg->width * sizeof(ULONG), 0);
567 LOCK(bmdata->surface);
569 switch (ce) {
571 case vHidd_GC_ColExp_Transparent:
572 D(bug("[sdl] transparent colour expansion, fg 0x%08x\n", fg));
574 switch (bytesperpixel) {
576 case 1:
577 for (y = 0; y < msg->height; y++) {
578 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
579 for (x = 0; x < msg->width; x++) {
580 if (srcline[x] != 0)
581 PUTPIXEL8(&p[x], fg);
583 p += bmdata->surface->pitch;
585 break;
587 case 2:
588 for (y = 0; y < msg->height; y++) {
589 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
590 for (x = 0; x < msg->width; x++) {
591 if (srcline[x] != 0)
592 PUTPIXEL16(&(((Uint16 *) p)[x]), fg);
594 p += bmdata->surface->pitch;
596 break;
598 case 3:
599 for (y = 0; y < msg->height; y++) {
600 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
601 for (x = 0; x < msg->width; x++) {
602 if (srcline[x] != 0)
603 PUTPIXEL24(&(((Uint32 *) p)[x]), fg);
605 p += bmdata->surface->pitch;
607 break;
609 case 4:
610 for (y = 0; y < msg->height; y++) {
611 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
612 for (x = 0; x < msg->width; x++) {
613 if (srcline[x] != 0)
614 PUTPIXEL32(&(((Uint32 *) p)[x]), fg);
616 p += bmdata->surface->pitch;
618 break;
621 break;
624 case vHidd_GC_ColExp_Opaque:
625 D(bug("[sdl] opaque colour expansion, fg 0x%08x bg %08x\n", fg, bg));
627 switch (bytesperpixel) {
629 case 1:
630 for (y = 0; y < msg->height; y++) {
631 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
632 for (x = 0; x < msg->width; x++)
633 PUTPIXEL8(&p[x], srcline[x] != 0 ? fg : bg);
634 p += bmdata->surface->pitch;
636 break;
638 case 2:
639 for (y = 0; y < msg->height; y++) {
640 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcY, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
641 for (x = 0; x < msg->width; x++)
642 PUTPIXEL16(&(((Uint16 *) p)[x]), srcline[x] != 0 ? fg : bg);
643 p += bmdata->surface->pitch;
645 break;
647 case 3:
648 for (y = 0; y < msg->height; y++) {
649 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
650 for (x = 0; x < msg->width; x++)
651 PUTPIXEL24(&(((Uint32 *) p)[x]), srcline[x] != 0 ? fg : bg);
652 p += bmdata->surface->pitch;
654 break;
656 case 4:
657 for (y = 0; y < msg->height; y++) {
658 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *)srcline, msg->width * sizeof(ULONG), msg->srcX, msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
659 for (x = 0; x < msg->width; x++)
660 PUTPIXEL32(&(((Uint32 *) p)[x]), srcline[x] != 0 ? fg : bg);
661 p += bmdata->surface->pitch;
663 break;
666 break;
669 UNLOCK(bmdata->surface);
671 FreeMem(srcline, msg->width * sizeof(ULONG));
674 VOID SDLBitMap__Hidd_BitMap__PutAlphaImage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutAlphaImage *msg) {
675 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
676 SDL_Surface *s;
677 SDL_Rect srect, drect;
679 D(bug("[sdl] SDLBitMap::PutAlphaImage\n"));
681 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
682 s = SP(SDL_CreateRGBSurfaceFrom, msg->pixels, msg->width, msg->height, 32, msg->modulo, 0xff0000, 0xff00, 0xff, 0xff000000);
683 #else
684 s = SP(SDL_CreateRGBSurfaceFrom, msg->pixels, msg->width, msg->height, 32, msg->modulo, 0xff00, 0xff0000, 0xff000000, 0xff);
685 #endif
687 srect.x = 0;
688 srect.y = 0;
689 srect.w = msg->width;
690 srect.h = msg->height;
692 drect.x = msg->x;
693 drect.y = msg->y;
695 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));
697 S(SDL_BlitSurface, s, &srect, bmdata->surface, &drect);
699 SV(SDL_FreeSurface, s);
702 VOID SDLBitMap__Hidd_BitMap__PutTemplate(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutTemplate *msg) {
703 struct bmdata *bmdata = OOP_INST_DATA(cl, o);
705 D(bug("[sdl] SDLBitMap::PutTemplate\n"));
707 LOCK(bmdata->surface);
709 switch (bmdata->surface->format->BytesPerPixel) {
710 case 1:
711 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);
712 break;
714 case 2:
715 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);
716 break;
718 case 3:
719 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);
720 break;
722 case 4:
723 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);
724 break;
727 UNLOCK(bmdata->surface);
730 static struct OOP_MethodDescr SDLBitMap_Root_descr[] = {
731 {(OOP_MethodFunc)SDLBitMap__Root__New, moRoot_New},
732 {(OOP_MethodFunc)SDLBitMap__Root__Dispose, moRoot_Dispose},
733 {(OOP_MethodFunc)SDLBitMap__Root__Get, moRoot_Get},
734 {(OOP_MethodFunc)SDLBitMap__Root__Set, moRoot_Set},
735 {NULL, 0}
737 #define NUM_SDLBitMap_Root_METHODS 4
739 static struct OOP_MethodDescr SDLBitMap_Hidd_BitMap_descr[] = {
740 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__SetColors, moHidd_BitMap_SetColors},
741 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__PutPixel, moHidd_BitMap_PutPixel},
742 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__GetPixel, moHidd_BitMap_GetPixel},
743 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__UpdateRect, moHidd_BitMap_UpdateRect},
744 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__PutImage, moHidd_BitMap_PutImage},
745 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__GetImage, moHidd_BitMap_GetImage},
746 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__FillRect, moHidd_BitMap_FillRect},
747 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__Clear, moHidd_BitMap_Clear},
748 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__BlitColorExpansion, moHidd_BitMap_BlitColorExpansion},
749 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__PutAlphaImage, moHidd_BitMap_PutAlphaImage},
750 {(OOP_MethodFunc)SDLBitMap__Hidd_BitMap__PutTemplate, moHidd_BitMap_PutTemplate},
751 {NULL, 0}
753 #define NUM_SDLBitMap_Hidd_BitMap_METHODS 11
755 struct OOP_InterfaceDescr SDLBitMap_ifdescr[] = {
756 {SDLBitMap_Root_descr , IID_Root , NUM_SDLBitMap_Root_METHODS },
757 {SDLBitMap_Hidd_BitMap_descr, IID_Hidd_BitMap, NUM_SDLBitMap_Hidd_BitMap_METHODS},
758 {NULL , NULL }