Fixed out-by-one error in previous commit.
[AROS.git] / workbench / hidds / hidd.radeon / planarbm.c
blobe5367bf68045f2f64062ab9c83dca742b84df46f
1 /*
2 Copyright � 1995-2001, 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 if (NULL != data->planes[i])
162 FreeVec(data->planes[i]);
165 FreeVec(data->planes);
169 OOP_DoSuperMethod(cl, o, msg);
171 return;
174 /****************************************************************************************/
176 VOID ATIPlanBM__Hidd_BitMap__PutPixel(OOP_Class *cl, OOP_Object *o,
177 struct pHidd_BitMap_PutPixel *msg)
179 UBYTE **plane;
180 struct planarbm_data *data;
181 ULONG offset;
182 ULONG mask;
183 UBYTE pixel, notpixel;
184 UBYTE i;
186 data = OOP_INST_DATA(cl, o);
188 /* bitmap in plane-mode */
189 plane = data->planes;
190 offset = msg->x / 8 + msg->y * data->bytesperrow;
191 pixel = 128 >> (msg->x % 8);
192 notpixel = ~pixel;
193 mask = 1;
195 for(i = 0; i < data->depth; i++, mask <<=1, plane ++)
197 if ((*plane != NULL) && (*plane != (UBYTE *)-1))
199 if(msg->pixel & mask)
201 *(*plane + offset) = *(*plane + offset) | pixel;
203 else
205 *(*plane + offset) = *(*plane + offset) & notpixel;
211 /****************************************************************************************/
213 ULONG ATIPlanBM__Hidd_BitMap__GetPixel(OOP_Class *cl, OOP_Object *o,
214 struct pHidd_BitMap_GetPixel *msg)
216 struct planarbm_data *data;
217 UBYTE **plane;
218 ULONG offset;
219 ULONG i;
220 UBYTE pixel;
221 ULONG retval;
223 data = OOP_INST_DATA(cl, o);
225 plane = data->planes;
226 offset = msg->x / 8 + msg->y * data->bytesperrow;
227 pixel = 128 >> (msg->x % 8);
228 retval = 0;
230 for(i = 0; i < data->depth; i++, plane ++)
233 if (*plane == (UBYTE *)-1)
235 retval = retval | (1 << i);
237 else if (*plane != NULL)
239 if(*(*plane + offset) & pixel)
241 retval = retval | (1 << i);
246 return retval;
249 /****************************************************************************************/
251 VOID ATIPlanBM__Hidd_BitMap__PutImage(OOP_Class *cl, OOP_Object *o,
252 struct pHidd_BitMap_PutImage *msg)
254 WORD x, y, d;
255 UBYTE *pixarray = (UBYTE *)msg->pixels;
256 UBYTE **plane;
257 ULONG planeoffset;
258 struct planarbm_data *data;
260 if ((msg->pixFmt != vHidd_StdPixFmt_Native) &&
261 (msg->pixFmt != vHidd_StdPixFmt_Native32))
263 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
264 return;
267 data = OOP_INST_DATA(cl, o);
269 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
271 for(y = 0; y < msg->height; y++)
273 switch(msg->pixFmt)
275 case vHidd_StdPixFmt_Native:
277 UBYTE *src = pixarray;
279 plane = data->planes;
281 for(d = 0; d < data->depth; d++)
283 ULONG dmask = 1L << d;
284 ULONG pmask = 0x80 >> (msg->x & 7);
285 UBYTE *pl = *plane;
287 if (pl == (UBYTE *)-1) continue;
288 if (pl == NULL) continue;
290 pl += planeoffset;
292 for(x = 0; x < msg->width; x++)
294 if (src[x] & dmask)
296 *pl |= pmask;
298 else
300 *pl &= ~pmask;
303 if (pmask == 0x1)
305 pmask = 0x80;
306 pl++;
308 else
310 pmask >>= 1;
313 } /* for(x = 0; x < msg->width; x++) */
315 plane++;
317 } /* for(d = 0; d < data->depth; d++) */
319 pixarray += msg->modulo;
320 planeoffset += data->bytesperrow;
322 break;
324 case vHidd_StdPixFmt_Native32:
326 HIDDT_Pixel *src = (HIDDT_Pixel *)pixarray;
328 plane = data->planes;
330 for(d = 0; d < data->depth; d++)
332 ULONG dmask = 1L << d;
333 ULONG pmask = 0x80 >> (msg->x & 7);
334 UBYTE *pl = *plane;
336 if (pl == (UBYTE *)-1) continue;
337 if (pl == NULL) continue;
339 pl += planeoffset;
341 for(x = 0; x < msg->width; x++)
343 if (src[x] & dmask)
345 *pl |= pmask;
347 else
349 *pl &= ~pmask;
352 if (pmask == 0x1)
354 pmask = 0x80;
355 pl++;
357 else
359 pmask >>= 1;
362 } /* for(x = 0; x < msg->width; x++) */
364 plane++;
366 } /* for(d = 0; d < data->depth; d++) */
368 pixarray += msg->modulo;
369 planeoffset += data->bytesperrow;
372 break;
374 } /* switch(msg->pixFmt) */
376 } /* for(y = 0; y < msg->height; y++) */
379 /****************************************************************************************/
381 VOID ATIPlanBM__Hidd_BitMap__PutImageLUT(OOP_Class *cl, OOP_Object *o,
382 struct pHidd_BitMap_PutImageLUT *msg)
384 WORD x, y, d;
385 UBYTE *pixarray = (UBYTE *)msg->pixels;
386 UBYTE **plane;
387 ULONG planeoffset;
388 struct planarbm_data *data;
390 data = OOP_INST_DATA(cl, o);
392 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
394 for(y = 0; y < msg->height; y++)
396 UBYTE *src = pixarray;
398 plane = data->planes;
400 for(d = 0; d < data->depth; d++)
402 ULONG dmask = 1L << d;
403 ULONG pmask = 0x80 >> (msg->x & 7);
404 UBYTE *pl = *plane;
406 if (pl == (UBYTE *)-1) continue;
407 if (pl == NULL) continue;
409 pl += planeoffset;
411 for(x = 0; x < msg->width; x++)
413 if (src[x] & dmask)
415 *pl |= pmask;
417 else
419 *pl &= ~pmask;
422 if (pmask == 0x1)
424 pmask = 0x80;
425 pl++;
427 else
429 pmask >>= 1;
432 } /* for(x = 0; x < msg->width; x++) */
434 plane++;
436 } /* for(d = 0; d < data->depth; d++) */
438 pixarray += msg->modulo;
439 planeoffset += data->bytesperrow;
441 } /* for(y = 0; y < msg->height; y++) */
444 /****************************************************************************************/
446 VOID ATIPlanBM__Hidd_BitMap__GetImageLUT(OOP_Class *cl, OOP_Object *o,
447 struct pHidd_BitMap_GetImageLUT *msg)
449 WORD x, y, d;
450 UBYTE *pixarray = (UBYTE *)msg->pixels;
451 UBYTE **plane;
452 ULONG planeoffset;
453 struct planarbm_data *data;
454 UBYTE prefill;
456 data = OOP_INST_DATA(cl, o);
458 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
460 prefill = 0;
461 for(d = 0; d < data->depth; d++)
463 if (data->planes[d] == (UBYTE *)-1)
465 prefill |= (1L << d);
469 for(y = 0; y < msg->height; y++)
471 UBYTE *dest = pixarray;
473 plane = data->planes;
475 for(x = 0; x < msg->width; x++)
477 dest[x] = prefill;
480 for(d = 0; d < data->depth; d++)
482 ULONG dmask = 1L << d;
483 ULONG pmask = 0x80 >> (msg->x & 7);
484 UBYTE *pl = *plane;
486 if (pl == (UBYTE *)-1) continue;
487 if (pl == NULL) continue;
489 pl += planeoffset;
491 for(x = 0; x < msg->width; x++)
493 if (*pl & pmask)
495 dest[x] |= dmask;
497 else
499 dest[x] &= ~dmask;
502 if (pmask == 0x1)
504 pmask = 0x80;
505 pl++;
507 else
509 pmask >>= 1;
512 } /* for(x = 0; x < msg->width; x++) */
514 plane++;
516 } /* for(d = 0; d < data->depth; d++) */
518 pixarray += msg->modulo;
519 planeoffset += data->bytesperrow;
521 } /* for(y = 0; y < msg->height; y++) */
525 /****************************************************************************************/
527 VOID ATIPlanBM__Hidd_BitMap__BlitColorExpansion(OOP_Class *cl, OOP_Object *o,
528 struct pHidd_BitMap_BlitColorExpansion *msg)
530 WORD x, y, d;
531 UBYTE **plane;
532 UBYTE *mask;
533 ULONG planeoffset /*, maskoffset*/;
534 ULONG cemd, fg, bg;
535 BOOL opaque;
536 OOP_Object *gc = msg->gc;
537 struct planarbm_data *data, *maskdata;
539 data = OOP_INST_DATA(cl, o);
541 cemd = GC_COLEXP(gc);
542 fg = GC_FG(gc);
543 bg = GC_BG(gc);
545 opaque = (cemd & vHidd_GC_ColExp_Opaque) ? TRUE : FALSE;
547 planeoffset = msg->destY * data->bytesperrow + msg->destX / 8;
549 if (OOP_OCLASS(msg->srcBitMap) == cl)
551 /* srcBitMap is a planarbm class object */
553 maskdata = OOP_INST_DATA(cl, msg->srcBitMap);
554 mask = maskdata->planes[0];
555 mask += msg->srcY * maskdata->bytesperrow + msg->srcX / 8;
557 for(y = 0; y < msg->height; y++)
559 plane = data->planes;
561 for(d = 0; d < data->depth; d++)
563 ULONG dmask = 1L << d;
564 ULONG pmask = 0x80 >> (msg->destX & 7);
565 ULONG mmask = 0x80 >> (msg->srcX & 7);
566 BOOL fgset = (fg & dmask) ? TRUE : FALSE;
567 BOOL bgset = (bg & dmask) ? TRUE : FALSE;
569 UBYTE *pl = *plane;
570 UBYTE *msk = mask;
572 if (pl == (UBYTE *)-1) continue;
573 if (pl == NULL) continue;
575 pl += planeoffset;
577 for(x = 0; x < msg->width; x++)
579 if (*msk & mmask)
581 if (fgset)
582 *pl |= pmask;
583 else
584 *pl &= ~pmask;
586 else if (opaque)
588 if (bgset)
589 *pl |= pmask;
590 else
591 *pl &= ~pmask;
594 if (pmask == 0x1)
596 pmask = 0x80;
597 pl++;
599 else
601 pmask >>= 1;
604 if (mmask == 0x1)
606 mmask = 0x80;
607 msk++;
609 else
611 mmask >>= 1;
614 } /* for(x = 0; x < msg->width; x++) */
616 plane++;
618 } /* for(d = 0; d < data->depth; d++) */
620 mask += maskdata->bytesperrow;
621 planeoffset += data->bytesperrow;
623 } /* for(y = 0; y < msg->height; y++) */
625 } /* if (OOP_OCLASS(msg->srcBitMap) == cl) */
626 else
628 HIDDT_Pixel *maskline;
630 maskline = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
631 if (!maskline)
633 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
634 return;
637 for(y = 0; y < msg->height; y++)
639 plane = data->planes;
641 struct pHidd_BitMap_GetImage __m = {
642 _sd->mid_GetImage,
643 (UBYTE *)maskline,
645 msg->srcX,
646 msg->srcY + y,
647 msg->width,
649 vHidd_StdPixFmt_Native32
650 }, *m = &__m;
652 OOP_DoMethod(msg->srcBitMap, (OOP_Msg)m);
654 for(d = 0; d < data->depth; d++)
656 ULONG dmask = 1L << d;
657 ULONG pmask = 0x80 >> (msg->destX & 7);
658 BOOL fgset = (fg & dmask) ? TRUE : FALSE;
659 BOOL bgset = (bg & dmask) ? TRUE : FALSE;
661 UBYTE *pl = *plane;
663 if (pl == (UBYTE *)-1) continue;
664 if (pl == NULL) continue;
666 pl += planeoffset;
668 for(x = 0; x < msg->width; x++)
670 if (maskline[x])
672 if (fgset)
673 *pl |= pmask;
674 else
675 *pl &= ~pmask;
677 else if (opaque)
679 if (bgset)
680 *pl |= pmask;
681 else
682 *pl &= ~pmask;
685 if (pmask == 0x1)
687 pmask = 0x80;
688 pl++;
690 else
692 pmask >>= 1;
695 } /* for(x = 0; x < msg->width; x++) */
697 plane++;
699 } /* for(d = 0; d < data->depth; d++) */
701 planeoffset += data->bytesperrow;
703 } /* for(y = 0; y < msg->height; y++) */
705 FreeVec(maskline);
707 } /* if (OOP_OCLASS(msg->srcBitMap) == cl) else ... */
711 /****************************************************************************************/
713 BOOL ATIPlanBM__Hidd_PlanarBM__SetBitMap(OOP_Class *cl, OOP_Object *o,
714 struct pHidd_PlanarBM_SetBitMap *msg)
716 struct planarbm_data *data;
717 struct BitMap *bm;
719 struct TagItem pftags[] =
721 { aHidd_PixFmt_Depth , 0UL }, /* 0 */
722 { aHidd_PixFmt_BitsPerPixel , 0UL }, /* 1 */
723 { aHidd_PixFmt_BytesPerPixel, 1UL }, /* 2 */
724 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_Palette }, /* 3 */
725 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Planar }, /* 4 */
726 { aHidd_PixFmt_CLUTShift , 0UL }, /* 5 */
727 { aHidd_PixFmt_CLUTMask , 0x000000FF }, /* 6 */
728 { aHidd_PixFmt_RedMask , 0x00FF0000 }, /* 7 */
729 { aHidd_PixFmt_GreenMask , 0x0000FF00 }, /* 8 */
730 { aHidd_PixFmt_BlueMask , 0x000000FF }, /* 9 */
731 { TAG_DONE , 0UL } /* 7 */
733 struct TagItem bmtags[] =
735 { aHidd_BitMap_Width , 0UL },
736 { aHidd_BitMap_Height , 0UL },
737 { TAG_DONE , 0UL }
740 ULONG i;
742 data = OOP_INST_DATA(cl, o);
743 bm = msg->bitMap;
745 if (data->planes_alloced)
747 D(bug(" !!!!! PlanarBM: Trying to set bitmap in one that allready has planes allocated\n"));
748 return FALSE;
751 /* Check if plane array allready allocated */
752 if (NULL != data->planes)
754 if (bm->Depth > data->planebuf_size)
756 FreeVec(data->planes);
757 data->planes = NULL;
761 if (NULL == data->planes)
763 data->planes = AllocVec(sizeof (UBYTE *) * bm->Depth, MEMF_CLEAR);
765 if (NULL == data->planes)
766 return FALSE;
768 data->planebuf_size = bm->Depth;
772 /* Update the planes */
773 for (i = 0; i < data->planebuf_size; i ++)
775 if (i < bm->Depth)
776 data->planes[i] = bm->Planes[i];
777 else
778 data->planes[i] = NULL;
781 data->depth = bm->Depth;
782 data->bytesperrow = bm->BytesPerRow;
783 data->rows = bm->Rows;
785 pftags[0].ti_Data = bm->Depth; /* PixFmt_Depth */
786 pftags[1].ti_Data = bm->Depth; /* PixFmt_BitsPerPixel */
788 bmtags[0].ti_Data = bm->BytesPerRow * 8;
789 bmtags[1].ti_Data = bm->Rows;
790 bmtags[2].ti_Data = (IPTR)pftags;
792 struct pHidd_BitMap_SetBitMapTags {
793 OOP_MethodID mID;
794 struct TagItem *tags;
795 } __m = {
796 OOP_GetMethodID(IID_Hidd_BitMap, num_Hidd_BitMap_Methods),
797 bmtags
798 }, *m = &__m;
800 /* Call private bitmap method to update superclass */
801 if (!OOP_DoMethod(o, (OOP_Msg)m))
803 ULONG i;
805 for (i = 0; i < data->planebuf_size; i ++)
807 data->planes[i] = NULL;
811 return TRUE;
814 /****************************************************************************************/