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 Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
33 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
34 struct chunkybm_data
*data
;
36 IPTR bytesperrow
, bytesperpixel
;
38 OOP_MethodID dispose_mid
;
40 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
44 /* Initialize the instance data to 0 */
45 data
= OOP_INST_DATA(cl
, o
);
46 memset(data
, 0, sizeof (*data
));
48 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (APTR
)&pf
);
49 OOP_GetAttr(o
, aHidd_BitMap_GfxHidd
, (APTR
)&data
->gfxhidd
);
50 /* Get some dimensions of the bitmap */
51 OOP_GetAttr(o
, aHidd_BitMap_BytesPerRow
, &bytesperrow
);
52 OOP_GetAttr(pf
, aHidd_PixFmt_BytesPerPixel
, &bytesperpixel
);
54 data
->bytesperpixel
= bytesperpixel
;
55 data
->bytesperrow
= bytesperrow
;
57 tag
= FindTagItem(aHidd_ChunkyBM_Buffer
, msg
->attrList
);
61 * NULL user-supplied buffer is valid.
62 * In this case we create a bitmap with no buffer. We can attach it later.
64 data
->own_buffer
= FALSE
;
65 data
->buffer
= (APTR
)tag
->ti_Data
;
73 OOP_GetAttr(o
, aHidd_BitMap_Height
, &height
);
75 data
->own_buffer
= TRUE
;
76 data
->buffer
= AllocVec(height
* bytesperrow
, MEMF_ANY
| MEMF_CLEAR
);
82 /* free all on error */
83 dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
85 OOP_CoerceMethod(cl
, o
, (OOP_Msg
)&dispose_mid
);
89 /****************************************************************************************/
91 void CBM__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
93 struct chunkybm_data
*data
;
95 data
= OOP_INST_DATA(cl
, o
);
98 FreeVec(data
->buffer
);
100 OOP_DoSuperMethod(cl
, o
, msg
);
105 /****************************************************************************************/
107 VOID
CBM__Hidd_BitMap__PutPixel(OOP_Class
*cl
, OOP_Object
*o
,
108 struct pHidd_BitMap_PutPixel
*msg
)
112 struct chunkybm_data
*data
;
114 data
= OOP_INST_DATA(cl
, o
);
116 /* bitmap in chunky-mode */
117 dest
= data
->buffer
+ msg
->x
* data
->bytesperpixel
+ msg
->y
* data
->bytesperrow
;
119 switch(data
->bytesperpixel
)
122 *((UBYTE
*) dest
) = (UBYTE
) msg
->pixel
;
126 *((UWORD
*) dest
) = (UWORD
) msg
->pixel
;
131 dest
[0] = (UBYTE
)(msg
->pixel
>> 16) & 0x000000FF;
132 dest
[1] = (UBYTE
)(msg
->pixel
>> 8) & 0x000000FF;
133 dest
[2] = (UBYTE
)msg
->pixel
& 0x000000FF;
135 dest
[0] = (UBYTE
)msg
->pixel
& 0x000000FF;
136 dest
[1] = (UBYTE
)(msg
->pixel
>> 8) & 0x000000FF;
137 dest
[2] = (UBYTE
)(msg
->pixel
>> 16) & 0x000000FF;
141 /* if (1 == ( ((IPTR)dest) & 1) )
143 *((UBYTE *) dest++) = (UBYTE) msg->pixel >> 16;
144 *((UWORD *) dest ) = (UWORD) msg->pixel;
148 *((UWORD *) dest++) = (UWORD) msg->pixel >> 8;
149 *((UBYTE *) dest ) = (UBYTE) msg->pixel;
154 *((ULONG
*) dest
) = (ULONG
) msg
->pixel
;
160 /****************************************************************************************/
162 ULONG
CBM__Hidd_BitMap__GetPixel(OOP_Class
*cl
, OOP_Object
*o
,
163 struct pHidd_BitMap_GetPixel
*msg
)
165 HIDDT_Pixel retval
= 0;
167 struct chunkybm_data
*data
;
169 data
= OOP_INST_DATA(cl
, o
);
171 src
= data
->buffer
+ msg
->x
* data
->bytesperpixel
+ msg
->y
* data
->bytesperrow
;
173 switch(data
->bytesperpixel
)
176 retval
= (HIDDT_Pixel
) *((UBYTE
*) src
);
180 retval
= (HIDDT_Pixel
) *((UWORD
*) src
);
185 retval
= (HIDDT_Pixel
) (src
[0] << 16) + (src
[1] << 8) + src
[2];
187 retval
= (HIDDT_Pixel
) (src
[2] << 16) + (src
[1] << 8) + src
[0];
191 //(*((UBYTE *) src++) << 16) | *((UWORD *) src));
195 retval
= ((ULONG
) *((ULONG
*) src
));
202 /****************************************************************************************/
204 VOID
CBM__Hidd_BitMap__FillRect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawRect
*msg
)
206 struct chunkybm_data
*data
=OOP_INST_DATA(cl
, o
);
207 HIDDT_Pixel fg
= GC_FG(msg
->gc
);
208 HIDDT_DrawMode mode
= GC_DRMD(msg
->gc
);
211 mod
= data
->bytesperrow
;
215 case vHidd_GC_DrawMode_Copy
:
216 switch(data
->bytesperpixel
)
219 HIDD_BM_FillMemRect8(o
,
230 HIDD_BM_FillMemRect16(o
,
241 HIDD_BM_FillMemRect24(o
,
252 HIDD_BM_FillMemRect32(o
,
265 case vHidd_GC_DrawMode_Invert
:
266 HIDD_BM_InvertMemRect(o
,
268 msg
->minX
* data
->bytesperpixel
,
270 msg
->maxX
* data
->bytesperpixel
+ data
->bytesperpixel
- 1,
276 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
283 /****************************************************************************************/
285 VOID
CBM__Hidd_BitMap__PutImage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImage
*msg
)
287 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
288 APTR dst_pixels
, src_pixels
;
293 case vHidd_StdPixFmt_Native
:
294 switch(data
->bytesperpixel
)
297 HIDD_BM_CopyMemBox8(o
,
311 HIDD_BM_CopyMemBox16(o
,
325 HIDD_BM_CopyMemBox24(o
,
339 HIDD_BM_CopyMemBox32(o
,
352 } /* switch(data->bytesperpixel) */
355 case vHidd_StdPixFmt_Native32
:
356 switch(data
->bytesperpixel
)
359 HIDD_BM_PutMem32Image8(o
,
371 HIDD_BM_PutMem32Image16(o
,
383 HIDD_BM_PutMem32Image24(o
,
395 HIDD_BM_CopyMemBox32(o
,
408 } /* switch(data->bytesperpixel) */
412 src_pixels
= msg
->pixels
;
413 dst_pixels
= data
->buffer
+ msg
->y
* data
->bytesperrow
414 + msg
->x
* data
->bytesperpixel
;
415 srcpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
417 HIDD_BM_ConvertPixels(o
, &src_pixels
,
418 (HIDDT_PixelFormat
*)srcpf
, msg
->modulo
, &dst_pixels
,
419 BM_PIXFMT(o
), data
->bytesperrow
, msg
->width
, msg
->height
,
422 } /* switch(msg->pixFmt) */
426 /**************************************************************************/
429 __attribute__((always_inline
, const)) do_alpha(int a
, int v
)
432 return (tmp
+ (tmp
>> 8) + 0x80) >> 8;
435 VOID
CBM__Hidd_BitMap__PutAlphaImage(OOP_Class
*cl
, OOP_Object
*o
,
436 struct pHidd_BitMap_PutAlphaImage
*msg
)
438 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
439 HIDDT_StdPixFmt pixFmt
= BM_PIXFMT(o
)->stdpixfmt
;
440 WORD x
, y
, src_step
, dst_step
;
442 UBYTE src_red
, src_green
, src_blue
, src_alpha
;
443 UBYTE dst_red
, dst_green
, dst_blue
;
447 case vHidd_StdPixFmt_BGR032
:
450 q
= data
->buffer
+ msg
->y
* data
->bytesperrow
451 + msg
->x
* data
->bytesperpixel
;
452 src_step
= msg
->modulo
- msg
->width
* 4;
453 dst_step
= data
->bytesperrow
- data
->bytesperpixel
* msg
->width
;
455 for(y
= 0; y
< msg
->height
; y
++)
457 for(x
= 0; x
< msg
->width
; x
++)
479 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
483 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
487 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
498 case vHidd_StdPixFmt_RGB16_LE
:
501 q
= data
->buffer
+ msg
->y
* data
->bytesperrow
502 + msg
->x
* data
->bytesperpixel
;
503 src_step
= msg
->modulo
- msg
->width
* 4;
504 dst_step
= data
->bytesperrow
- data
->bytesperpixel
* msg
->width
;
506 for(y
= 0; y
< msg
->height
; y
++)
508 for(x
= 0; x
< msg
->width
; x
++)
522 *q
++ = (src_green
<< 3) & 0xe0 | src_blue
>> 3;
523 *q
++ = src_red
& 0xf8 | src_green
>> 5;
529 dst_green
= dst_red
<< 5 | dst_blue
>> 3 & 0x1c;
533 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
534 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
535 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
537 *q
++ = (dst_green
<< 3) & 0xe0 | dst_blue
>> 3;
538 *q
++ = dst_red
& 0xf8 | dst_green
>> 5;
547 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
552 /****************************************************************************************/
554 VOID
CBM__Hidd_BitMap__GetImage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetImage
*msg
)
556 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
557 APTR src_pixels
, dst_pixels
;
562 case vHidd_StdPixFmt_Native
:
563 switch(data
->bytesperpixel
)
566 HIDD_BM_CopyMemBox8(o
,
580 HIDD_BM_CopyMemBox16(o
,
594 HIDD_BM_CopyMemBox24(o
,
608 HIDD_BM_CopyMemBox32(o
,
621 } /* switch(data->bytesperpix) */
624 case vHidd_StdPixFmt_Native32
:
625 switch(data
->bytesperpixel
)
628 HIDD_BM_GetMem32Image8(o
,
640 HIDD_BM_GetMem32Image16(o
,
652 HIDD_BM_GetMem32Image24(o
,
664 HIDD_BM_CopyMemBox32(o
,
677 } /* switch(data->bytesperpixel) */
681 src_pixels
= data
->buffer
+ msg
->y
* data
->bytesperrow
682 + msg
->x
* data
->bytesperpixel
;
683 dst_pixels
= msg
->pixels
;
684 dstpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
686 HIDD_BM_ConvertPixels(o
, &src_pixels
, BM_PIXFMT(o
),
687 data
->bytesperrow
, &dst_pixels
, (HIDDT_PixelFormat
*)dstpf
,
688 msg
->modulo
, msg
->width
, msg
->height
, NULL
);
690 } /* switch(msg->pixFmt) */
694 /****************************************************************************************/
696 VOID
CBM__Hidd_BitMap__PutImageLUT(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImageLUT
*msg
)
698 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
700 switch(data
->bytesperpixel
)
703 HIDD_BM_CopyLUTMemBox16(o
,
718 HIDD_BM_CopyLUTMemBox24(o
,
733 HIDD_BM_CopyLUTMemBox32(o
,
748 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
750 } /* switch(data->bytesperpixel) */
754 /****************************************************************************************/
756 VOID
CBM__Hidd_BitMap__PutTemplate(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutTemplate
*msg
)
758 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
760 switch(data
->bytesperpixel
)
763 HIDD_BM_PutMemTemplate8(o
,
774 msg
->inverttemplate
);
778 HIDD_BM_PutMemTemplate16(o
,
789 msg
->inverttemplate
);
793 HIDD_BM_PutMemTemplate24(o
,
804 msg
->inverttemplate
);
808 HIDD_BM_PutMemTemplate32(o
,
819 msg
->inverttemplate
);
823 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
826 } /* switch(data->bytesperpixel) */
830 /****************************************************************************************/
832 VOID
CBM__Hidd_BitMap__PutPattern(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutPattern
*msg
)
834 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
836 switch(data
->bytesperpixel
)
839 HIDD_BM_PutMemPattern8(o
,
860 HIDD_BM_PutMemPattern16(o
,
881 HIDD_BM_PutMemPattern24(o
,
902 HIDD_BM_PutMemPattern32(o
,
923 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
926 } /* switch(data->bytesperpixel) */
930 /****************************************************************************************/
932 BOOL
CBM__Hidd_BitMap__ObtainDirectAccess(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_ObtainDirectAccess
*msg
)
934 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
935 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
939 OOP_GetAttr(o
, aHidd_BitMap_Width
, &width
);
940 OOP_GetAttr(o
, aHidd_BitMap_Height
, &height
);
942 *msg
->addressReturn
= data
->buffer
;
943 *msg
->widthReturn
= width
;
944 *msg
->heightReturn
= height
;
945 *msg
->bankSizeReturn
= *msg
->memSizeReturn
= data
->bytesperrow
* height
;
950 /****************************************************************************************/
952 VOID
CBM__Hidd_BitMap__ReleaseDirectAccess(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_ReleaseDirectAccess
*msg
)
956 /****************************************************************************************/
958 VOID
CBM__Root__Get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
960 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
963 EnterFunc(bug("BitMap::Get() attrID: %i storage: %p\n", msg
->attrID
, msg
->storage
));
965 if (IS_CHUNKYBM_ATTR(msg
->attrID
, idx
))
969 case aoHidd_ChunkyBM_Buffer
:
970 *msg
->storage
= (IPTR
)data
->buffer
;
975 OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
978 /****************************************************************************************/
980 VOID
CBM__Root__Set(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Set
*msg
)
982 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
983 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
984 struct TagItem
*tag
, *tstate
;
987 tstate
= msg
->attrList
;
988 while((tag
= NextTagItem(&tstate
)))
990 if(IS_CHUNKYBM_ATTR(tag
->ti_Tag
, idx
))
994 case aoHidd_ChunkyBM_Buffer
:
995 if (data
->own_buffer
)
997 FreeVec(data
->buffer
);
998 data
->own_buffer
= FALSE
;
1000 data
->buffer
= (UBYTE
*)tag
->ti_Data
;
1001 D(bug("[CBM] New buffer now 0x%p\n", data
->buffer
));
1007 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);