Hint added.
[AROS.git] / workbench / hidds / radeon / planarbm.c
blobc43f51dccad479302bba445622c5291849e8d8a4
1 /*
2 Copyright � 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphics planar bitmap class implementation.
6 Lang: english
7 */
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>
17 #include <graphics/gfx.h>
18 #include <oop/oop.h>
20 #include <hidd/graphics.h>
22 #include <string.h>
24 #include "ati.h"
26 #include <string.h>
28 #define DEBUG 0
29 #include <aros/debug.h>
31 /****************************************************************************************/
33 #define _sd (&((struct atibase *)cl->UserData)->sd)
35 #undef HiddPCIDeviceAttrBase
36 #undef HiddGfxAttrBase
37 #undef HiddPixFmtAttrBase
38 #undef HiddSyncAttrBase
39 #undef HiddBitMapAttrBase
40 #define HiddPCIDeviceAttrBase (_sd->pciAttrBase)
41 #define HiddATIBitMapAttrBase (_sd->atiBitMapAttrBase)
42 #define HiddBitMapAttrBase (_sd->bitMapAttrBase)
43 #define HiddPixFmtAttrBase (_sd->pixFmtAttrBase)
44 #define HiddGfxAttrBase (_sd->gfxAttrBase)
45 #define HiddSyncAttrBase (_sd->syncAttrBase)
46 #define __IHidd_PlanarBM (_sd->planarAttrBase)
48 /****************************************************************************************/
50 OOP_Object *ATIPlanBM__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
52 IPTR width, height, depth;
54 BOOL ok = TRUE;
56 #if 0
57 /* Set the bitmaps' pixelformat */
58 struct TagItem pf_tags[] =
60 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_Palette }, /* 0 */
61 { aHidd_PixFmt_Depth , 0 }, /* 1 */
62 { aHidd_PixFmt_BytesPerPixel, 0 }, /* 2 */
63 { aHidd_PixFmt_BitsPerPixel , 0 }, /* 3 */
64 { aHidd_PixFmt_StdPixFmt , 0 }, /* 4 */
65 { aHidd_PixFmt_CLUTShift , 0 }, /* 5 */
66 { aHidd_PixFmt_CLUTMask , 0x000000FF }, /* 6 */
67 { aHidd_PixFmt_RedMask , 0x00FF0000 }, /* 7 */
68 { aHidd_PixFmt_GreenMask , 0x0000FF00 }, /* 8 */
69 { aHidd_PixFmt_BlueMask , 0x000000FF }, /* 9 */
70 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Planar },
71 { TAG_DONE , 0UL }
73 #endif
75 struct planarbm_data *data;
76 OOP_Object *pf;
77 APTR p_pf = &pf;
79 o =(OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
80 if (NULL == o)
81 return NULL;
83 data = OOP_INST_DATA(cl, o);
84 memset(data, 0, sizeof (*data));
87 /* Get some data about the dimensions of the bitmap */
89 data->planes_alloced = (BOOL)GetTagData(aHidd_PlanarBM_AllocPlanes, TRUE, msg->attrList);
91 /* FIXME: Fix this hack */
92 /* Because this class is used to emulate Amiga bitmaps, we
93 have to see if it should have late initalisation
95 if (!data->planes_alloced)
96 return o; /* Late initialization */
99 /* Not late initalization. Get some info on the bitmap */
100 OOP_GetAttr(o, aHidd_BitMap_Width, &width);
101 OOP_GetAttr(o, aHidd_BitMap_Height, &height);
102 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (IPTR *)p_pf);
103 OOP_GetAttr(pf, aHidd_PixFmt_Depth, (IPTR *)&depth);
105 /* We cache some info */
106 data->bytesperrow = ((width + 31) & ~31) / 8;
107 data->rows = height;
108 data->depth = depth;
110 if (ok)
112 /* Allocate memory for plane array */
113 data->planes = AllocVec(sizeof (UBYTE *) * depth, MEMF_ANY|MEMF_CLEAR);
114 if (NULL == data->planes)
115 ok = FALSE;
116 else
118 UBYTE i;
120 data->planebuf_size = depth;
122 /* Allocate all the planes */
123 for ( i = 0; i < depth && ok; i ++)
125 data->planes[i] = AllocVec(height * data->bytesperrow, MEMF_ANY|MEMF_CLEAR);
126 if (NULL == data->planes[i])
127 ok = FALSE;
132 if (!ok)
134 OOP_MethodID dispose_mid;
136 dispose_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
137 OOP_CoerceMethod(cl, o, (OOP_Msg)&dispose_mid);
139 o = NULL;
142 return o;
145 /****************************************************************************************/
147 VOID ATIPlanBM__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
149 struct planarbm_data *data;
150 UBYTE i;
152 data = OOP_INST_DATA(cl, o);
154 if (data->planes_alloced)
156 if (NULL != data->planes)
158 for (i = 0; i < data->depth; i ++)
160 FreeVec(data->planes[i]);
162 FreeVec(data->planes);
166 OOP_DoSuperMethod(cl, o, msg);
168 return;
171 /****************************************************************************************/
173 VOID ATIPlanBM__Hidd_BitMap__PutPixel(OOP_Class *cl, OOP_Object *o,
174 struct pHidd_BitMap_PutPixel *msg)
176 UBYTE **plane;
177 struct planarbm_data *data;
178 ULONG offset;
179 ULONG mask;
180 UBYTE pixel, notpixel;
181 UBYTE i;
183 data = OOP_INST_DATA(cl, o);
185 /* bitmap in plane-mode */
186 plane = data->planes;
187 offset = msg->x / 8 + msg->y * data->bytesperrow;
188 pixel = 128 >> (msg->x % 8);
189 notpixel = ~pixel;
190 mask = 1;
192 for(i = 0; i < data->depth; i++, mask <<=1, plane ++)
194 if ((*plane != NULL) && (*plane != (UBYTE *)-1))
196 if(msg->pixel & mask)
198 *(*plane + offset) = *(*plane + offset) | pixel;
200 else
202 *(*plane + offset) = *(*plane + offset) & notpixel;
208 /****************************************************************************************/
210 ULONG ATIPlanBM__Hidd_BitMap__GetPixel(OOP_Class *cl, OOP_Object *o,
211 struct pHidd_BitMap_GetPixel *msg)
213 struct planarbm_data *data;
214 UBYTE **plane;
215 ULONG offset;
216 ULONG i;
217 UBYTE pixel;
218 ULONG retval;
220 data = OOP_INST_DATA(cl, o);
222 plane = data->planes;
223 offset = msg->x / 8 + msg->y * data->bytesperrow;
224 pixel = 128 >> (msg->x % 8);
225 retval = 0;
227 for(i = 0; i < data->depth; i++, plane ++)
230 if (*plane == (UBYTE *)-1)
232 retval = retval | (1 << i);
234 else if (*plane != NULL)
236 if(*(*plane + offset) & pixel)
238 retval = retval | (1 << i);
243 return retval;
246 /****************************************************************************************/
248 VOID ATIPlanBM__Hidd_BitMap__PutImage(OOP_Class *cl, OOP_Object *o,
249 struct pHidd_BitMap_PutImage *msg)
251 WORD x, y, d;
252 UBYTE *pixarray = (UBYTE *)msg->pixels;
253 UBYTE **plane;
254 ULONG planeoffset;
255 struct planarbm_data *data;
257 if ((msg->pixFmt != vHidd_StdPixFmt_Native) &&
258 (msg->pixFmt != vHidd_StdPixFmt_Native32))
260 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
261 return;
264 data = OOP_INST_DATA(cl, o);
266 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
268 for(y = 0; y < msg->height; y++)
270 switch(msg->pixFmt)
272 case vHidd_StdPixFmt_Native:
274 UBYTE *src = pixarray;
276 plane = data->planes;
278 for(d = 0; d < data->depth; d++)
280 ULONG dmask = 1L << d;
281 ULONG pmask = 0x80 >> (msg->x & 7);
282 UBYTE *pl = *plane;
284 if (pl == (UBYTE *)-1) continue;
285 if (pl == NULL) continue;
287 pl += planeoffset;
289 for(x = 0; x < msg->width; x++)
291 if (src[x] & dmask)
293 *pl |= pmask;
295 else
297 *pl &= ~pmask;
300 if (pmask == 0x1)
302 pmask = 0x80;
303 pl++;
305 else
307 pmask >>= 1;
310 } /* for(x = 0; x < msg->width; x++) */
312 plane++;
314 } /* for(d = 0; d < data->depth; d++) */
316 pixarray += msg->modulo;
317 planeoffset += data->bytesperrow;
319 break;
321 case vHidd_StdPixFmt_Native32:
323 HIDDT_Pixel *src = (HIDDT_Pixel *)pixarray;
325 plane = data->planes;
327 for(d = 0; d < data->depth; d++)
329 ULONG dmask = 1L << d;
330 ULONG pmask = 0x80 >> (msg->x & 7);
331 UBYTE *pl = *plane;
333 if (pl == (UBYTE *)-1) continue;
334 if (pl == NULL) continue;
336 pl += planeoffset;
338 for(x = 0; x < msg->width; x++)
340 if (src[x] & dmask)
342 *pl |= pmask;
344 else
346 *pl &= ~pmask;
349 if (pmask == 0x1)
351 pmask = 0x80;
352 pl++;
354 else
356 pmask >>= 1;
359 } /* for(x = 0; x < msg->width; x++) */
361 plane++;
363 } /* for(d = 0; d < data->depth; d++) */
365 pixarray += msg->modulo;
366 planeoffset += data->bytesperrow;
369 break;
371 } /* switch(msg->pixFmt) */
373 } /* for(y = 0; y < msg->height; y++) */
376 /****************************************************************************************/
378 VOID ATIPlanBM__Hidd_BitMap__PutImageLUT(OOP_Class *cl, OOP_Object *o,
379 struct pHidd_BitMap_PutImageLUT *msg)
381 WORD x, y, d;
382 UBYTE *pixarray = (UBYTE *)msg->pixels;
383 UBYTE **plane;
384 ULONG planeoffset;
385 struct planarbm_data *data;
387 data = OOP_INST_DATA(cl, o);
389 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
391 for(y = 0; y < msg->height; y++)
393 UBYTE *src = pixarray;
395 plane = data->planes;
397 for(d = 0; d < data->depth; d++)
399 ULONG dmask = 1L << d;
400 ULONG pmask = 0x80 >> (msg->x & 7);
401 UBYTE *pl = *plane;
403 if (pl == (UBYTE *)-1) continue;
404 if (pl == NULL) continue;
406 pl += planeoffset;
408 for(x = 0; x < msg->width; x++)
410 if (src[x] & dmask)
412 *pl |= pmask;
414 else
416 *pl &= ~pmask;
419 if (pmask == 0x1)
421 pmask = 0x80;
422 pl++;
424 else
426 pmask >>= 1;
429 } /* for(x = 0; x < msg->width; x++) */
431 plane++;
433 } /* for(d = 0; d < data->depth; d++) */
435 pixarray += msg->modulo;
436 planeoffset += data->bytesperrow;
438 } /* for(y = 0; y < msg->height; y++) */
441 /****************************************************************************************/
443 VOID ATIPlanBM__Hidd_BitMap__GetImageLUT(OOP_Class *cl, OOP_Object *o,
444 struct pHidd_BitMap_GetImageLUT *msg)
446 WORD x, y, d;
447 UBYTE *pixarray = (UBYTE *)msg->pixels;
448 UBYTE **plane;
449 ULONG planeoffset;
450 struct planarbm_data *data;
451 UBYTE prefill;
453 data = OOP_INST_DATA(cl, o);
455 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
457 prefill = 0;
458 for(d = 0; d < data->depth; d++)
460 if (data->planes[d] == (UBYTE *)-1)
462 prefill |= (1L << d);
466 for(y = 0; y < msg->height; y++)
468 UBYTE *dest = pixarray;
470 plane = data->planes;
472 for(x = 0; x < msg->width; x++)
474 dest[x] = prefill;
477 for(d = 0; d < data->depth; d++)
479 ULONG dmask = 1L << d;
480 ULONG pmask = 0x80 >> (msg->x & 7);
481 UBYTE *pl = *plane;
483 if (pl == (UBYTE *)-1) continue;
484 if (pl == NULL) continue;
486 pl += planeoffset;
488 for(x = 0; x < msg->width; x++)
490 if (*pl & pmask)
492 dest[x] |= dmask;
494 else
496 dest[x] &= ~dmask;
499 if (pmask == 0x1)
501 pmask = 0x80;
502 pl++;
504 else
506 pmask >>= 1;
509 } /* for(x = 0; x < msg->width; x++) */
511 plane++;
513 } /* for(d = 0; d < data->depth; d++) */
515 pixarray += msg->modulo;
516 planeoffset += data->bytesperrow;
518 } /* for(y = 0; y < msg->height; y++) */
522 /****************************************************************************************/
524 VOID ATIPlanBM__Hidd_BitMap__BlitColorExpansion(OOP_Class *cl, OOP_Object *o,
525 struct pHidd_BitMap_BlitColorExpansion *msg)
527 WORD x, y, d;
528 UBYTE **plane;
529 UBYTE *mask;
530 ULONG planeoffset /*, maskoffset*/;
531 ULONG cemd, fg, bg;
532 BOOL opaque;
533 OOP_Object *gc = msg->gc;
534 struct planarbm_data *data, *maskdata;
536 data = OOP_INST_DATA(cl, o);
538 cemd = GC_COLEXP(gc);
539 fg = GC_FG(gc);
540 bg = GC_BG(gc);
542 opaque = (cemd & vHidd_GC_ColExp_Opaque) ? TRUE : FALSE;
544 planeoffset = msg->destY * data->bytesperrow + msg->destX / 8;
546 if (OOP_OCLASS(msg->srcBitMap) == cl)
548 /* srcBitMap is a planarbm class object */
550 maskdata = OOP_INST_DATA(cl, msg->srcBitMap);
551 mask = maskdata->planes[0];
552 mask += msg->srcY * maskdata->bytesperrow + msg->srcX / 8;
554 for(y = 0; y < msg->height; y++)
556 plane = data->planes;
558 for(d = 0; d < data->depth; d++)
560 ULONG dmask = 1L << d;
561 ULONG pmask = 0x80 >> (msg->destX & 7);
562 ULONG mmask = 0x80 >> (msg->srcX & 7);
563 BOOL fgset = (fg & dmask) ? TRUE : FALSE;
564 BOOL bgset = (bg & dmask) ? TRUE : FALSE;
566 UBYTE *pl = *plane;
567 UBYTE *msk = mask;
569 if (pl == (UBYTE *)-1) continue;
570 if (pl == NULL) continue;
572 pl += planeoffset;
574 for(x = 0; x < msg->width; x++)
576 if (*msk & mmask)
578 if (fgset)
579 *pl |= pmask;
580 else
581 *pl &= ~pmask;
583 else if (opaque)
585 if (bgset)
586 *pl |= pmask;
587 else
588 *pl &= ~pmask;
591 if (pmask == 0x1)
593 pmask = 0x80;
594 pl++;
596 else
598 pmask >>= 1;
601 if (mmask == 0x1)
603 mmask = 0x80;
604 msk++;
606 else
608 mmask >>= 1;
611 } /* for(x = 0; x < msg->width; x++) */
613 plane++;
615 } /* for(d = 0; d < data->depth; d++) */
617 mask += maskdata->bytesperrow;
618 planeoffset += data->bytesperrow;
620 } /* for(y = 0; y < msg->height; y++) */
622 } /* if (OOP_OCLASS(msg->srcBitMap) == cl) */
623 else
625 HIDDT_Pixel *maskline;
627 maskline = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
628 if (!maskline)
630 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
631 return;
634 for(y = 0; y < msg->height; y++)
636 plane = data->planes;
638 struct pHidd_BitMap_GetImage __m = {
639 _sd->mid_GetImage,
640 (UBYTE *)maskline,
642 msg->srcX,
643 msg->srcY + y,
644 msg->width,
646 vHidd_StdPixFmt_Native32
647 }, *m = &__m;
649 OOP_DoMethod(msg->srcBitMap, (OOP_Msg)m);
651 for(d = 0; d < data->depth; d++)
653 ULONG dmask = 1L << d;
654 ULONG pmask = 0x80 >> (msg->destX & 7);
655 BOOL fgset = (fg & dmask) ? TRUE : FALSE;
656 BOOL bgset = (bg & dmask) ? TRUE : FALSE;
658 UBYTE *pl = *plane;
660 if (pl == (UBYTE *)-1) continue;
661 if (pl == NULL) continue;
663 pl += planeoffset;
665 for(x = 0; x < msg->width; x++)
667 if (maskline[x])
669 if (fgset)
670 *pl |= pmask;
671 else
672 *pl &= ~pmask;
674 else if (opaque)
676 if (bgset)
677 *pl |= pmask;
678 else
679 *pl &= ~pmask;
682 if (pmask == 0x1)
684 pmask = 0x80;
685 pl++;
687 else
689 pmask >>= 1;
692 } /* for(x = 0; x < msg->width; x++) */
694 plane++;
696 } /* for(d = 0; d < data->depth; d++) */
698 planeoffset += data->bytesperrow;
700 } /* for(y = 0; y < msg->height; y++) */
702 FreeVec(maskline);
704 } /* if (OOP_OCLASS(msg->srcBitMap) == cl) else ... */
708 /****************************************************************************************/
710 BOOL ATIPlanBM__Hidd_PlanarBM__SetBitMap(OOP_Class *cl, OOP_Object *o,
711 struct pHidd_PlanarBM_SetBitMap *msg)
713 struct planarbm_data *data;
714 struct BitMap *bm;
716 struct TagItem pftags[] =
718 { aHidd_PixFmt_Depth , 0UL }, /* 0 */
719 { aHidd_PixFmt_BitsPerPixel , 0UL }, /* 1 */
720 { aHidd_PixFmt_BytesPerPixel, 1UL }, /* 2 */
721 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_Palette }, /* 3 */
722 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Planar }, /* 4 */
723 { aHidd_PixFmt_CLUTShift , 0UL }, /* 5 */
724 { aHidd_PixFmt_CLUTMask , 0x000000FF }, /* 6 */
725 { aHidd_PixFmt_RedMask , 0x00FF0000 }, /* 7 */
726 { aHidd_PixFmt_GreenMask , 0x0000FF00 }, /* 8 */
727 { aHidd_PixFmt_BlueMask , 0x000000FF }, /* 9 */
728 { TAG_DONE , 0UL } /* 7 */
730 struct TagItem bmtags[] =
732 { aHidd_BitMap_Width , 0UL },
733 { aHidd_BitMap_Height , 0UL },
734 { TAG_DONE , 0UL }
737 ULONG i;
739 data = OOP_INST_DATA(cl, o);
740 bm = msg->bitMap;
742 if (data->planes_alloced)
744 D(bug(" !!!!! PlanarBM: Trying to set bitmap in one that allready has planes allocated\n"));
745 return FALSE;
748 /* Check if plane array allready allocated */
749 if (NULL != data->planes)
751 if (bm->Depth > data->planebuf_size)
753 FreeVec(data->planes);
754 data->planes = NULL;
758 if (NULL == data->planes)
760 data->planes = AllocVec(sizeof (UBYTE *) * bm->Depth, MEMF_CLEAR);
762 if (NULL == data->planes)
763 return FALSE;
765 data->planebuf_size = bm->Depth;
769 /* Update the planes */
770 for (i = 0; i < data->planebuf_size; i ++)
772 if (i < bm->Depth)
773 data->planes[i] = bm->Planes[i];
774 else
775 data->planes[i] = NULL;
778 data->depth = bm->Depth;
779 data->bytesperrow = bm->BytesPerRow;
780 data->rows = bm->Rows;
782 pftags[0].ti_Data = bm->Depth; /* PixFmt_Depth */
783 pftags[1].ti_Data = bm->Depth; /* PixFmt_BitsPerPixel */
785 bmtags[0].ti_Data = bm->BytesPerRow * 8;
786 bmtags[1].ti_Data = bm->Rows;
787 bmtags[2].ti_Data = (IPTR)pftags;
789 struct pHidd_BitMap_SetBitMapTags {
790 OOP_MethodID mID;
791 struct TagItem *tags;
792 } __m = {
793 OOP_GetMethodID(IID_Hidd_BitMap, num_Hidd_BitMap_Methods),
794 bmtags
795 }, *m = &__m;
797 /* Call private bitmap method to update superclass */
798 if (!OOP_DoMethod(o, (OOP_Msg)m))
800 ULONG i;
802 for (i = 0; i < data->planebuf_size; i ++)
804 data->planes[i] = NULL;
808 return TRUE;
811 /****************************************************************************************/