2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Graphics chunky bitmap class implementation.
9 /****************************************************************************************/
11 #include <proto/exec.h>
12 #include <proto/utility.h>
13 #include <proto/oop.h>
15 #include <exec/memory.h>
16 #include <utility/tagitem.h>
19 #include <hidd/graphics.h>
21 #include "graphics_intern.h"
26 #include <aros/debug.h>
28 /****************************************************************************************/
30 OOP_Object
*CBM__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
32 struct chunkybm_data
*data
;
34 IPTR bytesperrow
, bytesperpixel
;
36 OOP_MethodID dispose_mid
;
38 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
42 /* Initialize the instance data to 0 */
43 data
= OOP_INST_DATA(cl
, o
);
44 memset(data
, 0, sizeof (*data
));
46 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (APTR
)&pf
);
47 OOP_GetAttr(o
, aHidd_BitMap_GfxHidd
, (APTR
)&data
->gfxhidd
);
48 /* Get some dimensions of the bitmap */
49 OOP_GetAttr(o
, aHidd_BitMap_BytesPerRow
, &bytesperrow
);
50 OOP_GetAttr(pf
, aHidd_PixFmt_BytesPerPixel
, &bytesperpixel
);
52 data
->bytesperpixel
= bytesperpixel
;
53 data
->bytesperrow
= bytesperrow
;
55 tag
= FindTagItem(aHidd_ChunkyBM_Buffer
, msg
->attrList
);
59 * NULL user-supplied buffer is valid.
60 * In this case we create a bitmap with no buffer. We can attach it later.
62 data
->own_buffer
= FALSE
;
63 data
->buffer
= (APTR
)tag
->ti_Data
;
71 OOP_GetAttr(o
, aHidd_BitMap_Height
, &height
);
73 data
->own_buffer
= TRUE
;
74 data
->buffer
= AllocVec(height
* bytesperrow
, MEMF_ANY
| MEMF_CLEAR
);
80 /* free all on error */
81 dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
83 OOP_CoerceMethod(cl
, o
, (OOP_Msg
)&dispose_mid
);
87 /****************************************************************************************/
89 void CBM__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
91 struct chunkybm_data
*data
;
93 data
= OOP_INST_DATA(cl
, o
);
96 FreeVec(data
->buffer
);
98 OOP_DoSuperMethod(cl
, o
, msg
);
103 /****************************************************************************************/
105 VOID
CBM__Hidd_BitMap__PutPixel(OOP_Class
*cl
, OOP_Object
*o
,
106 struct pHidd_BitMap_PutPixel
*msg
)
110 struct chunkybm_data
*data
;
112 data
= OOP_INST_DATA(cl
, o
);
114 /* bitmap in chunky-mode */
115 dest
= data
->buffer
+ msg
->x
* data
->bytesperpixel
+ msg
->y
* data
->bytesperrow
;
117 switch(data
->bytesperpixel
)
120 *((UBYTE
*) dest
) = (UBYTE
) msg
->pixel
;
124 *((UWORD
*) dest
) = (UWORD
) msg
->pixel
;
129 dest
[0] = (UBYTE
)(msg
->pixel
>> 16) & 0x000000FF;
130 dest
[1] = (UBYTE
)(msg
->pixel
>> 8) & 0x000000FF;
131 dest
[2] = (UBYTE
)msg
->pixel
& 0x000000FF;
133 dest
[0] = (UBYTE
)msg
->pixel
& 0x000000FF;
134 dest
[1] = (UBYTE
)(msg
->pixel
>> 8) & 0x000000FF;
135 dest
[2] = (UBYTE
)(msg
->pixel
>> 16) & 0x000000FF;
139 /* if (1 == ( ((IPTR)dest) & 1) )
141 *((UBYTE *) dest++) = (UBYTE) msg->pixel >> 16;
142 *((UWORD *) dest ) = (UWORD) msg->pixel;
146 *((UWORD *) dest++) = (UWORD) msg->pixel >> 8;
147 *((UBYTE *) dest ) = (UBYTE) msg->pixel;
152 *((ULONG
*) dest
) = (ULONG
) msg
->pixel
;
158 /****************************************************************************************/
160 ULONG
CBM__Hidd_BitMap__GetPixel(OOP_Class
*cl
, OOP_Object
*o
,
161 struct pHidd_BitMap_GetPixel
*msg
)
163 HIDDT_Pixel retval
= 0;
165 struct chunkybm_data
*data
;
167 data
= OOP_INST_DATA(cl
, o
);
169 src
= data
->buffer
+ msg
->x
* data
->bytesperpixel
+ msg
->y
* data
->bytesperrow
;
171 switch(data
->bytesperpixel
)
174 retval
= (HIDDT_Pixel
) *((UBYTE
*) src
);
178 retval
= (HIDDT_Pixel
) *((UWORD
*) src
);
183 retval
= (HIDDT_Pixel
) (src
[0] << 16) + (src
[1] << 8) + src
[2];
185 retval
= (HIDDT_Pixel
) (src
[2] << 16) + (src
[1] << 8) + src
[0];
189 //(*((UBYTE *) src++) << 16) | *((UWORD *) src));
193 retval
= ((ULONG
) *((ULONG
*) src
));
200 /****************************************************************************************/
202 VOID
CBM__Hidd_BitMap__FillRect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawRect
*msg
)
204 struct chunkybm_data
*data
=OOP_INST_DATA(cl
, o
);
205 HIDDT_Pixel fg
= GC_FG(msg
->gc
);
206 HIDDT_DrawMode mode
= GC_DRMD(msg
->gc
);
209 mod
= data
->bytesperrow
;
213 case vHidd_GC_DrawMode_Copy
:
214 switch(data
->bytesperpixel
)
217 HIDD_BM_FillMemRect8(o
,
228 HIDD_BM_FillMemRect16(o
,
239 HIDD_BM_FillMemRect24(o
,
250 HIDD_BM_FillMemRect32(o
,
263 case vHidd_GC_DrawMode_Invert
:
264 HIDD_BM_InvertMemRect(o
,
266 msg
->minX
* data
->bytesperpixel
,
268 msg
->maxX
* data
->bytesperpixel
+ data
->bytesperpixel
- 1,
274 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
281 /****************************************************************************************/
283 VOID
CBM__Hidd_BitMap__PutImage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImage
*msg
)
285 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
286 APTR dst_pixels
, src_pixels
;
291 case vHidd_StdPixFmt_Native
:
292 switch(data
->bytesperpixel
)
295 HIDD_BM_CopyMemBox8(o
,
309 HIDD_BM_CopyMemBox16(o
,
323 HIDD_BM_CopyMemBox24(o
,
337 HIDD_BM_CopyMemBox32(o
,
350 } /* switch(data->bytesperpixel) */
353 case vHidd_StdPixFmt_Native32
:
354 switch(data
->bytesperpixel
)
357 HIDD_BM_PutMem32Image8(o
,
369 HIDD_BM_PutMem32Image16(o
,
381 HIDD_BM_PutMem32Image24(o
,
393 HIDD_BM_CopyMemBox32(o
,
406 } /* switch(data->bytesperpixel) */
410 src_pixels
= msg
->pixels
;
411 dst_pixels
= data
->buffer
+ msg
->y
* data
->bytesperrow
412 + msg
->x
* data
->bytesperpixel
;
413 srcpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
415 HIDD_BM_ConvertPixels(o
, &src_pixels
,
416 (HIDDT_PixelFormat
*)srcpf
, msg
->modulo
, &dst_pixels
,
417 BM_PIXFMT(o
), data
->bytesperrow
, msg
->width
, msg
->height
,
420 } /* switch(msg->pixFmt) */
424 /**************************************************************************/
427 __attribute__((always_inline
, const)) do_alpha(int a
, int v
)
430 return (tmp
+ (tmp
>> 8) + 0x80) >> 8;
433 VOID
CBM__Hidd_BitMap__PutAlphaImage(OOP_Class
*cl
, OOP_Object
*o
,
434 struct pHidd_BitMap_PutAlphaImage
*msg
)
436 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
437 HIDDT_StdPixFmt pixFmt
= BM_PIXFMT(o
)->stdpixfmt
;
438 WORD x
, y
, src_step
, dst_step
;
440 UBYTE src_red
, src_green
, src_blue
, src_alpha
;
441 UBYTE dst_red
, dst_green
, dst_blue
;
445 case vHidd_StdPixFmt_BGR032
:
448 q
= data
->buffer
+ msg
->y
* data
->bytesperrow
449 + msg
->x
* data
->bytesperpixel
;
450 src_step
= msg
->modulo
- msg
->width
* 4;
451 dst_step
= data
->bytesperrow
- data
->bytesperpixel
* msg
->width
;
453 for(y
= 0; y
< msg
->height
; y
++)
455 for(x
= 0; x
< msg
->width
; x
++)
477 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
481 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
485 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
496 case vHidd_StdPixFmt_RGB16_LE
:
499 q
= data
->buffer
+ msg
->y
* data
->bytesperrow
500 + msg
->x
* data
->bytesperpixel
;
501 src_step
= msg
->modulo
- msg
->width
* 4;
502 dst_step
= data
->bytesperrow
- data
->bytesperpixel
* msg
->width
;
504 for(y
= 0; y
< msg
->height
; y
++)
506 for(x
= 0; x
< msg
->width
; x
++)
520 *q
++ = (src_green
<< 3) & 0xe0 | src_blue
>> 3;
521 *q
++ = src_red
& 0xf8 | src_green
>> 5;
527 dst_green
= dst_red
<< 5 | dst_blue
>> 3 & 0x1c;
531 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
532 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
533 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
535 *q
++ = (dst_green
<< 3) & 0xe0 | dst_blue
>> 3;
536 *q
++ = dst_red
& 0xf8 | dst_green
>> 5;
545 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
550 /****************************************************************************************/
552 VOID
CBM__Hidd_BitMap__GetImage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetImage
*msg
)
554 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
555 APTR src_pixels
, dst_pixels
;
560 case vHidd_StdPixFmt_Native
:
561 switch(data
->bytesperpixel
)
564 HIDD_BM_CopyMemBox8(o
,
578 HIDD_BM_CopyMemBox16(o
,
592 HIDD_BM_CopyMemBox24(o
,
606 HIDD_BM_CopyMemBox32(o
,
619 } /* switch(data->bytesperpix) */
622 case vHidd_StdPixFmt_Native32
:
623 switch(data
->bytesperpixel
)
626 HIDD_BM_GetMem32Image8(o
,
638 HIDD_BM_GetMem32Image16(o
,
650 HIDD_BM_GetMem32Image24(o
,
662 HIDD_BM_CopyMemBox32(o
,
675 } /* switch(data->bytesperpixel) */
679 src_pixels
= data
->buffer
+ msg
->y
* data
->bytesperrow
680 + msg
->x
* data
->bytesperpixel
;
681 dst_pixels
= msg
->pixels
;
682 dstpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
684 HIDD_BM_ConvertPixels(o
, &src_pixels
, BM_PIXFMT(o
),
685 data
->bytesperrow
, &dst_pixels
, (HIDDT_PixelFormat
*)dstpf
,
686 msg
->modulo
, msg
->width
, msg
->height
, NULL
);
688 } /* switch(msg->pixFmt) */
692 /****************************************************************************************/
694 VOID
CBM__Hidd_BitMap__PutImageLUT(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImageLUT
*msg
)
696 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
698 switch(data
->bytesperpixel
)
701 HIDD_BM_CopyLUTMemBox16(o
,
716 HIDD_BM_CopyLUTMemBox24(o
,
731 HIDD_BM_CopyLUTMemBox32(o
,
746 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
748 } /* switch(data->bytesperpixel) */
752 /****************************************************************************************/
754 VOID
CBM__Hidd_BitMap__PutTemplate(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutTemplate
*msg
)
756 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
758 switch(data
->bytesperpixel
)
761 HIDD_BM_PutMemTemplate8(o
,
772 msg
->inverttemplate
);
776 HIDD_BM_PutMemTemplate16(o
,
787 msg
->inverttemplate
);
791 HIDD_BM_PutMemTemplate24(o
,
802 msg
->inverttemplate
);
806 HIDD_BM_PutMemTemplate32(o
,
817 msg
->inverttemplate
);
821 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
824 } /* switch(data->bytesperpixel) */
828 /****************************************************************************************/
830 VOID
CBM__Hidd_BitMap__PutPattern(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutPattern
*msg
)
832 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
834 switch(data
->bytesperpixel
)
837 HIDD_BM_PutMemPattern8(o
,
858 HIDD_BM_PutMemPattern16(o
,
879 HIDD_BM_PutMemPattern24(o
,
900 HIDD_BM_PutMemPattern32(o
,
921 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
924 } /* switch(data->bytesperpixel) */
928 /****************************************************************************************/
930 VOID
CBM__Root__Get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
932 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
935 EnterFunc(bug("BitMap::Get() attrID: %i storage: %p\n", msg
->attrID
, msg
->storage
));
937 if (IS_CHUNKYBM_ATTR(msg
->attrID
, idx
))
941 case aoHidd_ChunkyBM_Buffer
:
942 *msg
->storage
= (IPTR
)data
->buffer
;
947 OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
950 /****************************************************************************************/
952 VOID
CBM__Root__Set(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Set
*msg
)
954 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
955 struct TagItem
*tag
, *tstate
;
958 tstate
= msg
->attrList
;
959 while((tag
= NextTagItem((const struct TagItem
**)&tstate
)))
961 if(IS_CHUNKYBM_ATTR(tag
->ti_Tag
, idx
))
965 case aoHidd_ChunkyBM_Buffer
:
966 if (data
->own_buffer
)
968 FreeVec(data
->buffer
);
969 data
->own_buffer
= FALSE
;
971 data
->buffer
= (UBYTE
*)tag
->ti_Data
;
972 D(bug("[CBM] New buffer now 0x%p\n", data
->buffer
));
978 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);