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.
9 #define __OOP_NOATTRBASES__
11 #include <aros/symbolsets.h>
13 #include <hidd/hidd.h>
14 #include <hidd/graphics.h>
15 #include <utility/tagitem.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
27 #include <aros/debug.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
},
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
);
55 ADD2INITLIB(sdl_bmclass_init
, 0)
56 ADD2EXPUNGELIB(sdl_bmclass_expunge
, 0)
58 #define UPDATE(bmdata, x, y, w, h) \
60 if (bmdata->is_onscreen) \
61 SV(SDL_UpdateRect, bmdata->surface, x, y, w, h); \
66 if (SDL_MUSTLOCK(s)) \
67 SV(SDL_LockSurface, s); \
72 if (SDL_MUSTLOCK(s)) \
73 SV(SDL_UnlockSurface, s); \
76 static SDL_Surface
*icon
;
77 static void load_icon(LIBBASETYPEPTR SDLGfxBase
) {
78 unsigned char *data
, *pixel
;
81 icon
= S(SDL_CreateRGBSurface
, SDL_SWSURFACE
, icon_width
, icon_height
, 24, icon_red_mask
, icon_green_mask
, icon_blue_mask
, 0);
85 data
= icon_header_data
;
88 for (i
= 0; i
< icon_width
* icon_height
; i
++) {
89 ICON_HEADER_PIXEL(data
, pixel
);
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
;
101 int width
, height
, depth
;
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
);
110 D(bug("[sdl] supermethod failed, bailing out\n"));
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
);
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
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"));
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) |
154 SV(SDL_WM_SetCaption
, "AROS Research Operating System", "AROS");
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
);
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
);
182 bmdata
->is_onscreen
= TRUE
;
184 D(bug("[sdl] created surface: 0x%08x\n", s
));
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
);
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
;
216 case aoHidd_SDLBitMap_IsOnScreen
:
217 *msg
->storage
= (IPTR
) bmdata
->is_onscreen
;
221 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
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
;
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
))
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
));
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) \
271 ((Uint8 *) p)[0] = ((c) >> 16) & 0xff; \
272 ((Uint8 *) p)[1] = ((c) >> 8) & 0xff; \
273 ((Uint8 *) p)[2] = (c) & 0xff; \
275 #define GETPIXEL24(p) (((Uint8 *) p)[0] << 16 | ((Uint8 *) p)[1] << 8 | ((Uint8 *)p)[2])
277 #define PUTPIXEL24(p,c) \
279 ((Uint8 *) p)[0] = (c) & 0xff; \
280 ((Uint8 *) p)[1] = ((c) >> 8) & 0xff; \
281 ((Uint8 *) p)[2] = ((c) >> 16) & 0xff; \
283 #define GETPIXEL24(p) (((Uint8 *) p)[0] | ((Uint8 *) p)[1] << 8 | ((Uint8 *) p)[2] << 16)
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
) {
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
;
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
) {
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
);
360 Uint32 red_mask
, green_mask
, blue_mask
, alpha_mask
;
361 BOOL native32
= FALSE
;
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"));
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
;
384 D(bug("[sdl] pixel format %d, asking the gfxhidd for attributes\n", msg
->pixFmt
));
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
);
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
);
404 D(bug("[sdl] native32 format, setting pixel width to 4 bytes\n"));
405 s
->format
->BytesPerPixel
= 4;
410 srect
.w
= msg
->width
;
411 srect
.h
= msg
->height
;
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
);
428 Uint32 red_mask
, green_mask
, blue_mask
, alpha_mask
;
429 BOOL native32
= FALSE
;
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"));
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
;
452 D(bug("[sdl] pixel format %d, asking the gfxhidd for attributes\n", msg
->pixFmt
));
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
);
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
);
472 D(bug("[sdl] native32 format, setting pixel width to 4 bytes\n"));
473 s
->format
->BytesPerPixel
= 4;
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"));
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
));
507 case vHidd_GC_DrawMode_Copy
:
508 SV(SDL_FillRect
, bmdata
->surface
, &rect
, fg
);
512 case vHidd_GC_DrawMode_Invert
:
513 LOCK(bmdata
->surface
);
515 HIDD_BM_InvertMemRect(o
,
516 bmdata
->surface
->pixels
,
517 msg
->minX
* bytesperpixel
,
519 msg
->maxX
* bytesperpixel
+ bytesperpixel
- 1,
521 bmdata
->surface
->pitch
);
523 UNLOCK(bmdata
->surface
);
528 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
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
);
540 D(bug("[sdl] SDLBitMap::Clear\n"));
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
;
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
));
567 ce
= GC_COLEXP(msg
->gc
);
569 srcline
= AllocMem(msg
->width
* sizeof(ULONG
), 0);
571 LOCK(bmdata
->surface
);
575 case vHidd_GC_ColExp_Transparent
:
576 D(bug("[sdl] transparent colour expansion, fg 0x%08x\n", fg
));
578 switch (bytesperpixel
) {
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
++) {
585 PUTPIXEL8(&p
[x
], fg
);
587 p
+= bmdata
->surface
->pitch
;
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
++) {
596 PUTPIXEL16(&(((Uint16
*) p
)[x
]), fg
);
598 p
+= bmdata
->surface
->pitch
;
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
++) {
607 PUTPIXEL24(&(((Uint32
*) p
)[x
]), fg
);
609 p
+= bmdata
->surface
->pitch
;
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
++) {
618 PUTPIXEL32(&(((Uint32
*) p
)[x
]), fg
);
620 p
+= bmdata
->surface
->pitch
;
628 case vHidd_GC_ColExp_Opaque
:
629 D(bug("[sdl] opaque colour expansion, fg 0x%08x bg %08x\n", fg
, bg
));
631 switch (bytesperpixel
) {
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
;
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
;
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
;
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
;
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
);
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);
690 s
= S(SDL_CreateRGBSurfaceFrom
, msg
->pixels
, msg
->width
, msg
->height
, 32, msg
->modulo
, 0xff00, 0xff0000, 0xff000000, 0xff);
695 srect
.w
= msg
->width
;
696 srect
.h
= msg
->height
;
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
);
714 D(bug("[sdl] SDLBitMap::PutTemplate\n"));
716 LOCK(bmdata
->surface
);
718 switch (bmdata
->surface
->format
->BytesPerPixel
) {
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
);
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
);
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
);
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
);
736 UNLOCK(bmdata
->surface
);
737 SV(SDL_UnlockSurface
, bmdata
->surface
);
739 UPDATE(bmdata
, msg
->x
, msg
->y
, msg
->width
, msg
->height
);