2 Copyright 1995-2010, The AROS Development Team. All rights reserved.
5 Desc: Bitmap class for native Amiga chipset.
10 /****************************************************************************************/
16 #include <proto/oop.h>
17 #include <proto/utility.h>
18 #include <exec/alerts.h>
19 #include <aros/macros.h>
20 #include <exec/memory.h>
21 #include <exec/lists.h>
22 #include <graphics/rastport.h>
23 #include <graphics/gfx.h>
25 #include <hidd/graphics.h>
26 #include <aros/symbolsets.h>
28 #define CMDDEBUGUNIMP(x) ;
29 #define CMDDEBUGPIXEL(x) ;
31 #include <aros/debug.h>
33 #include LC_LIBDEFS_FILE
35 #include "amigavideogfx.h"
36 #include "amigavideobitmap.h"
41 /****************************************************************************************/
43 #define AO(x) (aoHidd_BitMap_ ## x)
44 #define GOT_BM_ATTR(code) GOT_ATTR(code, aoHidd_BitMap, bitmap)
46 /****************************************************************************************/
48 static void setrtg(struct amigavideo_staticdata
*csd
, BOOL showrtg
)
52 OOP_Object
*AmigaVideoBM__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
54 struct amigavideo_staticdata
*csd
= CSD(cl
);
55 struct Library
*OOPBase
= csd
->cs_OOPBase
;
56 IPTR width
, height
, depth
, disp
;
58 struct amigabm_data
*data
;
59 struct BitMap
*pbm
= NULL
;
60 struct pRoot_New mymsg
= *msg
;
61 struct TagItem tags
[] = {
62 { aHidd_BitMap_Align
, csd
->aga
? 64 : 16 },
63 { TAG_MORE
, (IPTR
) msg
->attrList
},
67 DB2(bug("AmigaVideoBM__Root__New\n"));
69 mymsg
.attrList
= tags
;
70 o
=(OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)&mymsg
);
74 data
= OOP_INST_DATA(cl
, o
);
75 memset(data
, 0, sizeof (*data
));
77 data
->align
= csd
->aga
? 64 : 16; // AGA 64-bit fetchmode needs 8-byte alignment
79 /* Get some data about the dimensions of the bitmap */
80 OOP_GetAttr(o
, aHidd_BitMap_Width
, &width
);
81 OOP_GetAttr(o
, aHidd_BitMap_Height
, &height
);
82 OOP_GetAttr(o
, aHidd_BitMap_Depth
, &depth
);
83 OOP_GetAttr(o
, aHidd_BitMap_Displayable
, &disp
);
84 OOP_GetAttr(o
, aHidd_PlanarBM_BitMap
, &pbm
);
86 DB2(bug("%dx%dx%d\n", width
, height
, depth
));
88 /* We cache some info */
90 data
->bytesperrow
= ((width
+ data
->align
- 1) & ~(data
->align
- 1)) / 8;
91 data
->height
= height
;
93 data
->pixelcacheoffset
= -1;
97 OOP_MethodID dispose_mid
;
99 dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
100 OOP_CoerceMethod(cl
, o
, (OOP_Msg
)&dispose_mid
);
105 DB2(bug("ret=%x bm=%x\n", o
, data
));
110 VOID
AmigaVideoBM__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
112 struct amigabm_data
*data
;
114 data
= OOP_INST_DATA(cl
, o
);
116 DB2(bug("AmigaVideoBM__Root__Dispose %x bm=%x\n", o
, data
));
118 DB2(bug("removing displayed bitmap?!\n"));
121 OOP_DoSuperMethod(cl
, o
, msg
);
127 VOID
AmigaVideoBM__Root__Set(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Set
*msg
)
129 struct amigavideo_staticdata
*csd
= CSD(cl
);
130 struct Library
*UtilityBase
= csd
->cs_UtilityBase
;
131 struct amigabm_data
*data
= OOP_INST_DATA(cl
, o
);
132 struct TagItem
*tag
, *tstate
;
136 DB2(bug("AmigaVideoBM__Root__Set\n"));
137 tstate
= msg
->attrList
;
138 while((tag
= NextTagItem(&tstate
)))
140 DB2(bug("%d/%d\n", tag
->ti_Tag
, tag
->ti_Data
));
141 if(IS_BITMAP_ATTR(tag
->ti_Tag
, idx
))
143 DB2(bug("->%d\n", idx
));
146 case aoHidd_BitMap_Visible
:
147 data
->disp
= tag
->ti_Data
;
150 setbitmap(csd
, data
);
156 case aoHidd_BitMap_LeftEdge
:
157 if (data
->leftedge
!= tag
->ti_Data
) {
158 data
->leftedge
= tag
->ti_Data
;
162 case aoHidd_BitMap_TopEdge
:
163 if (data
->topedge
!= tag
->ti_Data
) {
164 data
->topedge
= tag
->ti_Data
;
165 if (data
->topedge
< 0)
167 if (data
->topedge
>= data
->height
)
168 data
->topedge
= data
->height
- 1;
175 DB2(bug("AmigaVideoBM__Root__Set Exit\n"));
176 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
177 if (moved
&& csd
->disp
== data
)
178 setscroll(csd
, data
);
181 VOID
AmigaVideoBM__Root__Get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
183 struct amigavideo_staticdata
*csd
= CSD(cl
);
184 struct Library
*OOPBase
= csd
->cs_OOPBase
;
185 struct amigabm_data
*data
= OOP_INST_DATA(cl
, o
);
188 DB2(bug("AmigaVideoBM__Root__Get %d, Attr=%d AmigaVideoBitmap=%d\n", msg
->attrID
, __IHidd_Attr
, __IHidd_AmigaVideoBitmap
));
189 if (IS_AmigaVideoBM_ATTR(msg
->attrID
, idx
)) {
190 DB2(bug("AVBM=%d\n", idx
));
193 case aoHidd_AmigaVideoBitMap_Drawable
:
194 *msg
->storage
= TRUE
;
197 } else if (IS_BITMAP_ATTR(msg
->attrID
, idx
)) {
198 DB2(bug("BM=%d\n", idx
));
201 case aoHidd_BitMap_LeftEdge
:
202 *msg
->storage
= data
->leftedge
;
204 case aoHidd_BitMap_TopEdge
:
205 *msg
->storage
= data
->topedge
;
207 case aoHidd_BitMap_Visible
:
208 *msg
->storage
= data
->disp
;
210 case aoHidd_BitMap_Align
:
211 *msg
->storage
= csd
->aga
? 64 : 16;
213 case aoHidd_BitMap_BytesPerRow
:
214 if (data
->bytesperrow
== 0) {
216 IPTR align
= csd
->aga
? 64 : 16;
217 OOP_GetAttr(o
, aHidd_BitMap_Width
, &width
);
218 *msg
->storage
= ((width
+ align
- 1) & ~(align
- 1)) / 8;
220 *msg
->storage
= data
->bytesperrow
;
225 DB2(bug("AmigaVideoBM__Root__Get Exit\n"));
226 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
229 /****************************************************************************************/
231 static int AmigaVideoBM_Init(LIBBASETYPEPTR LIBBASE
)
233 D(bug("AmigaVideoBM_Init\n"));
234 return TRUE
; //return OOP_ObtainAttrBases(attrbases);
237 /****************************************************************************************/
239 static int AmigaVideoBM_Expunge(LIBBASETYPEPTR LIBBASE
)
241 D(bug("AmigaVideoBM_Expunge\n"));
242 //OOP_ReleaseAttrBases(attrbases);
246 /****************************************************************************************/
248 ADD2INITLIB(AmigaVideoBM_Init
, 0);
249 ADD2EXPUNGELIB(AmigaVideoBM_Expunge
, 0);
251 /****************************************************************************************/
253 BOOL
AmigaVideoBM__Hidd_BitMap__SetColors(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_SetColors
*msg
)
255 struct amigabm_data
*data
= OOP_INST_DATA(cl
, o
);
256 struct amigavideo_staticdata
*csd
= CSD(cl
);
258 if (!OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
))
260 return setcolors(csd
, msg
, data
->disp
);
263 /****************************************************************************************/
265 #define CLEARCACHE flushpixelcache(data)
266 /* Better than nothing but m68k assembly C2P still needed for best performance */
267 static void flushpixelcache(struct amigabm_data
*data
)
270 ULONG offset
= data
->pixelcacheoffset
;
271 struct BitMap
*bm
= data
->pbm
;
272 UBYTE
**plane
= bm
->Planes
;
274 if (data
->writemask
) {
276 ULONG pixel
, notpixel
, wmask
;
277 if (~data
->writemask
) {
278 for (i
= 0; i
< bm
->Depth
; i
++) {
279 if (plane
[i
] == (UBYTE
*)-1)
280 tmpplanes
[i
] = 0xffffffff;
281 else if (plane
[i
] == NULL
)
282 tmpplanes
[i
] = 0x00000000;
284 tmpplanes
[i
] = *((ULONG
*)(plane
[i
] + offset
));
289 for (x
= 0; pixel
; x
++, pixel
>>= 1, wmask
<<= 1) {
290 if (data
->writemask
& wmask
) {
291 UBYTE c
= data
->pixelcache
[x
];
294 for (i
= 0; i
< data
->depth
; i
++, mask
<<= 1) {
295 if (plane
[i
] != NULL
&& plane
[i
] != (UBYTE
*)-1) {
297 tmpplanes
[i
] |= pixel
;
299 tmpplanes
[i
] &= notpixel
;
304 for (i
= 0; i
< data
->depth
; i
++) {
305 if (plane
[i
] != NULL
&& plane
[i
] != (UBYTE
*)-1)
306 *((ULONG
*)(plane
[i
] + offset
)) = tmpplanes
[i
];
309 data
->pixelcacheoffset
= -1;
313 VOID
AmigaVideoBM__Hidd_BitMap__PutPixel(OOP_Class
*cl
, OOP_Object
*o
,
314 struct pHidd_BitMap_PutPixel
*msg
)
316 struct amigabm_data
*data
;
320 data
= OOP_INST_DATA(cl
, o
);
322 offset
= msg
->x
/ 8 + msg
->y
* data
->bytesperrow
;
323 if ((offset
& ~3) != data
->pixelcacheoffset
) {
325 data
->pixelcacheoffset
= offset
& ~3;
327 bit
= (offset
- data
->pixelcacheoffset
) * 8 + (msg
->x
& 7);
328 data
->pixelcache
[bit
] = msg
->pixel
;
329 data
->writemask
|= 1 << bit
;
331 CMDDEBUGPIXEL(bug("PutPixel: %dx%d %x\n", msg
->x
, msg
->y
, msg
->pixel
));
334 /****************************************************************************************/
336 ULONG
AmigaVideoBM__Hidd_BitMap__GetPixel(OOP_Class
*cl
, OOP_Object
*o
,
337 struct pHidd_BitMap_GetPixel
*msg
)
339 struct amigabm_data
*data
;
343 data
= OOP_INST_DATA(cl
, o
);
344 offset
= msg
->x
/ 8 + msg
->y
* data
->bytesperrow
;
346 if ((offset
& ~3) != data
->pixelcacheoffset
) {
347 ULONG tmpplanes
[8], mask
;
349 UBYTE
**plane
= data
->pbm
->Planes
;
352 data
->pixelcacheoffset
= offset
& ~3;
353 for (i
= 0; i
< data
->depth
; i
++) {
354 if (plane
[i
] == (UBYTE
*)-1)
355 tmpplanes
[i
] = 0xffffffff;
356 else if (plane
[i
] == NULL
)
357 tmpplanes
[i
] = 0x00000000;
359 tmpplanes
[i
] = *((ULONG
*)(plane
[i
] + data
->pixelcacheoffset
));
362 for (x
= 0; mask
; x
++, mask
>>= 1) {
363 UBYTE c
= 0, pixel
= 1;
364 for(i
= 0; i
< data
->depth
; i
++, pixel
<<= 1) {
365 if (tmpplanes
[i
] & mask
)
368 data
->pixelcache
[x
] = c
;
371 bit
= (offset
- data
->pixelcacheoffset
) * 8 + (msg
->x
& 7);
372 c
= data
->pixelcache
[bit
];
373 CMDDEBUGPIXEL(bug("GetPixel: %dx%d %x\n", msg
->x
, msg
->y
, c
));
377 /****************************************************************************************/
379 VOID
AmigaVideoBM__Hidd_BitMap__DrawLine(OOP_Class
*cl
, OOP_Object
*o
,
380 struct pHidd_BitMap_DrawLine
*msg
)
382 OOP_Object
*gc
= msg
->gc
;
383 HIDDT_Pixel fg
= GC_FG(gc
);
384 HIDDT_DrawMode mode
= GC_DRMD(gc
);
385 struct amigavideo_staticdata
*csd
= CSD(cl
);
386 struct amigabm_data
*data
= OOP_INST_DATA(cl
, o
);
387 APTR doclip
= GC_DOCLIP(gc
);
388 WORD linepatmask
= (1 << GC_LINEPATCNT(gc
)) - 1;
391 if ((linepatmask
& GC_LINEPAT(gc
)) != linepatmask
) {
392 // TODO: blitter pattern support
393 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
396 if (msg
->x1
== msg
->x2
|| msg
->y1
== msg
->y2
) {
397 WORD x1
= msg
->x1
, x2
= msg
->x2
;
398 WORD y1
= msg
->y1
, y2
= msg
->y2
;
409 if (doclip
&& (x1
> GC_CLIPX2(gc
)
410 || x2
< GC_CLIPX1(gc
)
411 || y1
> GC_CLIPY2(gc
)
412 || y2
< GC_CLIPY1(gc
)))
419 if (x1
>= data
->width
)
421 if (y1
>= data
->height
)
427 if (x2
>= data
->width
)
428 x2
= data
->width
- 1;
429 if (y2
>= data
->height
)
430 y2
= data
->height
- 1;
434 if (y1
< GC_CLIPY1(gc
))
436 if (y2
> GC_CLIPY2(gc
))
439 if (x1
< GC_CLIPX1(gc
))
441 else if (x2
> GC_CLIPX2(gc
))
446 if (!blit_fillrect(csd
, data
->pbm
, x1
, y1
, x2
, y2
, fg
, mode
))
447 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
449 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
450 CMDDEBUGUNIMP(bug("DrawLine\n"));
454 /****************************************************************************************/
456 VOID
AmigaVideoBM__Hidd_BitMap__PutPattern(OOP_Class
*cl
, OOP_Object
*o
,
457 struct pHidd_BitMap_PutPattern
*msg
)
459 struct amigavideo_staticdata
*csd
= CSD(cl
);
460 struct amigabm_data
*data
= OOP_INST_DATA(cl
, o
);
463 D(bug("PutPattern(%dx%d,%dx%d,mask=%x,mod=%d,masksrcx=%d)\n(%x,%dx%d,h=%d,d=%d,lut=%x,inv=%d)(fg=%d,bg=%d,colexp=%d,drmd=%d)\n",
464 msg
->x
, msg
->y
, msg
->width
, msg
->height
,
465 msg
->mask
, msg
->maskmodulo
, msg
->masksrcx
,
466 msg
->pattern
, msg
->patternsrcx
, msg
->patternsrcy
, msg
->patternheight
, msg
->patterndepth
, msg
->patternlut
, msg
->invertpattern
,
467 GC_FG(msg
->gc
), GC_BG(msg
->gc
), GC_COLEXP(msg
->gc
), GC_DRMD(msg
->gc
)));
469 if (!blit_putpattern(csd
, data
->pbm
, msg
))
470 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
474 /****************************************************************************************/
476 VOID
AmigaVideoBM__Hidd_BitMap__PutImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
477 struct pHidd_BitMap_PutImageLUT
*msg
)
480 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
483 struct amigabm_data
*data
;
485 CMDDEBUGUNIMP(bug("PutImageLUT\n"));
487 data
= OOP_INST_DATA(cl
, o
);
490 planeoffset
= msg
->y
* data
->bytesperrow
+ msg
->x
/ 8;
492 for(y
= 0; y
< msg
->height
; y
++)
494 UBYTE
*src
= pixarray
;
496 plane
= data
->pbm
->Planes
;
498 for(d
= 0; d
< data
->depth
; d
++)
500 ULONG dmask
= 1L << d
;
501 ULONG pmask
= 0x80 >> (msg
->x
& 7);
504 if (pl
== (UBYTE
*)-1) continue;
505 if (pl
== NULL
) continue;
509 for(x
= 0; x
< msg
->width
; x
++)
530 } /* for(x = 0; x < msg->width; x++) */
534 } /* for(d = 0; d < data->depth; d++) */
536 pixarray
+= msg
->modulo
;
537 planeoffset
+= data
->bytesperrow
;
539 } /* for(y = 0; y < msg->height; y++) */
542 /****************************************************************************************/
544 VOID
AmigaVideoBM__Hidd_BitMap__GetImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
545 struct pHidd_BitMap_GetImageLUT
*msg
)
548 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
551 struct amigabm_data
*data
;
554 data
= OOP_INST_DATA(cl
, o
);
556 D(bug("[%s] Get %dx%d to %dx%d from %d planes to buffer at %p\n", __func__
, msg
->x
, msg
->y
, msg
->x
+ msg
->width
- 1, msg
->y
+ msg
->height
- 1, data
->depth
, msg
->pixels
));
558 planeoffset
= msg
->y
* data
->bytesperrow
+ msg
->x
/ 8;
561 for (d
= 0; d
< data
->depth
; d
++)
563 if (data
->pbm
->Planes
[d
] == (UBYTE
*)-1)
565 prefill
|= (1L << d
);
569 for (y
= 0; y
< msg
->height
; y
++)
571 UBYTE
*dest
= pixarray
;
573 plane
= data
->pbm
->Planes
;
574 for(x
= 0; x
< msg
->width
; x
++)
579 for (d
= 0; d
< data
->depth
; d
++)
581 ULONG dmask
= 1L << d
;
582 ULONG pmask
= 0x80 >> (msg
->x
& 7);
585 if (pl
== (UBYTE
*)-1) continue;
586 if (pl
== NULL
) continue;
590 for (x
= 0; x
< msg
->width
; x
++)
611 } /* for(x = 0; x < msg->width; x++) */
615 } /* for(d = 0; d < data->depth; d++) */
617 pixarray
+= msg
->modulo
;
618 planeoffset
+= data
->bytesperrow
;
620 } /* for(y = 0; y < msg->height; y++) */
622 D(bug("[%s] Got %d\n", __func__
, *(UBYTE
*)msg
->pixels
));
626 /****************************************************************************************/
628 VOID
AmigaVideoBM__Hidd_BitMap__PutImage(OOP_Class
*cl
, OOP_Object
*o
,
629 struct pHidd_BitMap_PutImage
*msg
)
632 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
635 struct amigabm_data
*data
= OOP_INST_DATA(cl
, o
);
639 if ((msg
->pixFmt
!= vHidd_StdPixFmt_Native
) &&
640 (msg
->pixFmt
!= vHidd_StdPixFmt_Native32
))
642 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
645 CMDDEBUGUNIMP(bug("PutImage\n"));
647 planeoffset
= msg
->y
* data
->bytesperrow
+ msg
->x
/ 8;
649 for(y
= 0; y
< msg
->height
; y
++)
653 case vHidd_StdPixFmt_Native
:
655 UBYTE
*src
= pixarray
;
657 plane
= data
->pbm
->Planes
;
659 for(d
= 0; d
< data
->depth
; d
++)
661 ULONG dmask
= 1L << d
;
662 ULONG pmask
= 0x80 >> (msg
->x
& 7);
665 if (pl
== (UBYTE
*)-1) continue;
666 if (pl
== NULL
) continue;
670 for(x
= 0; x
< msg
->width
; x
++)
691 } /* for(x = 0; x < msg->width; x++) */
695 } /* for(d = 0; d < data->depth; d++) */
697 pixarray
+= msg
->modulo
;
698 planeoffset
+= data
->bytesperrow
;
702 case vHidd_StdPixFmt_Native32
:
704 HIDDT_Pixel
*src
= (HIDDT_Pixel
*)pixarray
;
706 plane
= data
->pbm
->Planes
;
708 for(d
= 0; d
< data
->depth
; d
++)
710 ULONG dmask
= 1L << d
;
711 ULONG pmask
= 0x80 >> (msg
->x
& 7);
714 if (pl
== (UBYTE
*)-1) continue;
715 if (pl
== NULL
) continue;
719 for(x
= 0; x
< msg
->width
; x
++)
740 } /* for(x = 0; x < msg->width; x++) */
744 } /* for(d = 0; d < data->depth; d++) */
746 pixarray
+= msg
->modulo
;
747 planeoffset
+= data
->bytesperrow
;
752 } /* switch(msg->pixFmt) */
754 } /* for(y = 0; y < msg->height; y++) */
757 /****************************************************************************************/
759 VOID
AmigaVideoBM__Hidd_BitMap__FillRect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawRect
*msg
)
761 HIDDT_Pixel fg
= GC_FG(msg
->gc
);
762 HIDDT_DrawMode mode
= GC_DRMD(msg
->gc
);
763 struct amigavideo_staticdata
*csd
= CSD(cl
);
764 struct amigabm_data
*data
= OOP_INST_DATA(cl
, o
);
767 if (!blit_fillrect(csd
, data
->pbm
, msg
->minX
, msg
->minY
, msg
->maxX
, msg
->maxY
, fg
, mode
)) {
768 CMDDEBUGUNIMP(bug("FillRect\n"));
769 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
773 /****************************************************************************************/
775 VOID
AmigaVideoBM__Hidd_BitMap__PutTemplate(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutTemplate
*msg
)
777 struct amigavideo_staticdata
*csd
= CSD(cl
);
778 struct amigabm_data
*data
= OOP_INST_DATA(cl
, o
);
781 if (!blit_puttemplate(csd
, data
->pbm
, msg
)) {
782 CMDDEBUGUNIMP(bug("PutTemplate: %x x=%d y=%d w=%d h=%d srcx=%d modulo=%d invert=%d\n",
783 msg
->masktemplate
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, msg
->srcx
, msg
->inverttemplate
));
784 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
789 /****************************************************************************************/
791 VOID
AmigaVideoBM__Hidd_BitMap__UpdateRect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_UpdateRect
*msg
)
795 /****************************************************************************************/
797 BOOL
AmigaVideoBM__Hidd_PlanarBM__SetBitMap(OOP_Class
*cl
, OOP_Object
*o
,
798 struct pHidd_PlanarBM_SetBitMap
*msg
)
800 CMDDEBUGUNIMP(bug("SetBitMap\n"));
801 return OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
804 /****************************************************************************************/
806 BOOL
AmigaVideoBM__Hidd_PlanarBM__GetBitMap(OOP_Class
*cl
, OOP_Object
*o
,
807 struct pHidd_PlanarBM_GetBitMap
*msg
)
809 CMDDEBUGUNIMP(bug("GetBitMap\n"));
810 return OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);