more rendering corrections
[AROS.git] / workbench / hidds / hidd.nouveau / planarbm.c
blobc0c62c0a7ca7266c16a7dcc91a2d8bae94252502
1 /*
2 Copyright © 2010, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /****************************************************************************************/
8 #include <proto/exec.h>
9 #include <proto/utility.h>
10 #include <proto/oop.h>
12 #include <exec/memory.h>
13 #include <utility/tagitem.h>
14 #include <graphics/gfx.h>
15 #include <oop/oop.h>
17 #include <hidd/graphics.h>
19 #include <string.h>
21 #include "nouveau_intern.h"
23 #include <string.h>
25 #define DEBUG 0
26 #include <aros/debug.h>
28 /****************************************************************************************/
30 #define moHidd_BitMap_SetBitMapTags num_Hidd_BitMap_Methods
32 #undef HiddPixFmtAttrBase
33 #undef HiddBitMapAttrBase
34 #undef HiddPlanarBMAttrBase
35 #define HiddPixFmtAttrBase (SD(cl)->pixFmtAttrBase)
36 #define HiddBitMapAttrBase (SD(cl)->bitMapAttrBase)
37 #define HiddPlanarBMAttrBase (SD(cl)->planarAttrBase)
39 /****************************************************************************************/
41 OOP_Object * METHOD(NouveauPlanarBitMap, Root, New)
43 IPTR width, height, depth;
45 BOOL ok = TRUE;
47 #if 0
48 /* Set the bitmaps' pixelformat */
49 struct TagItem pf_tags[] =
51 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_Palette}, /* 0 */
52 { aHidd_PixFmt_Depth , 0}, /* 1 */
53 { aHidd_PixFmt_BytesPerPixel, 0}, /* 2 */
54 { aHidd_PixFmt_BitsPerPixel , 0}, /* 3 */
55 { aHidd_PixFmt_StdPixFmt , 0}, /* 4 */
56 { aHidd_PixFmt_CLUTShift , 0}, /* 5 */
57 { aHidd_PixFmt_CLUTMask , 0x000000FF}, /* 6 */
58 { aHidd_PixFmt_RedMask , 0x00FF0000}, /* 7 */
59 { aHidd_PixFmt_GreenMask , 0x0000FF00}, /* 8 */
60 { aHidd_PixFmt_BlueMask , 0x000000FF}, /* 9 */
61 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Planar},
62 { TAG_DONE , 0UL}
64 #endif
66 struct planarbm_data *data;
67 OOP_Object *pf;
69 o = (OOP_Object *) OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
70 if (NULL == o)
71 return NULL;
73 data = OOP_INST_DATA(cl, o);
74 memset(data, 0, sizeof(*data));
76 /* Get some data about the dimensions of the bitmap */
78 data->planes_alloced = (BOOL) GetTagData(aHidd_PlanarBM_AllocPlanes, TRUE,
79 msg->attrList);
81 #warning Fix this hack
82 /* Because this class is used to emulate Amiga bitmaps, we
83 have to see if it should have late initalisation
85 if (!data->planes_alloced)
86 return o; /* Late initialization */
88 /* Not late initalization. Get some info on the bitmap */
89 OOP_GetAttr(o, aHidd_BitMap_Width, &width);
90 OOP_GetAttr(o, aHidd_BitMap_Height, &height);
91 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (APTR) & pf);
92 OOP_GetAttr(pf, aHidd_PixFmt_Depth, (APTR) & depth);
94 /* We cache some info */
95 data->bytesperrow = ((width + 31) & ~31) / 8;
96 data->rows = height;
97 data->depth = depth;
99 if (ok)
101 /* Allocate memory for plane array */
102 data->planes = AllocVec(sizeof(UBYTE *) * depth, MEMF_ANY | MEMF_CLEAR);
103 if (NULL == data->planes)
104 ok = FALSE;
105 else
107 UBYTE i;
109 data->planebuf_size = depth;
111 /* Allocate all the planes */
112 for (i = 0; i < depth && ok; i++)
114 data->planes[i] = AllocVec(height * data->bytesperrow, MEMF_ANY
115 | MEMF_CLEAR);
116 if (NULL == data->planes[i])
117 ok = FALSE;
122 if (!ok)
124 OOP_MethodID dispose_mid;
126 dispose_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
127 OOP_CoerceMethod(cl, o, (OOP_Msg) & dispose_mid);
129 o = NULL;
132 return o;
135 /****************************************************************************************/
137 VOID NouveauPlanarBitMap__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
139 struct planarbm_data *data;
140 UBYTE i;
142 data = OOP_INST_DATA(cl, o);
144 if (data->planes_alloced)
146 if (NULL != data->planes)
148 for (i = 0; i < data->depth; i++)
150 if (NULL != data->planes[i])
152 FreeVec(data->planes[i]);
155 FreeVec(data->planes);
159 OOP_DoSuperMethod(cl, o, msg);
161 return;
164 /****************************************************************************************/
166 VOID METHOD(NouveauPlanarBitMap, Hidd_BitMap, PutPixel)
168 UBYTE **plane;
169 struct planarbm_data *data;
170 ULONG offset;
171 ULONG mask;
172 UBYTE pixel, notpixel;
173 UBYTE i;
175 data = OOP_INST_DATA(cl, o);
177 /* bitmap in plane-mode */
178 plane = (UBYTE**) data->planes;
179 offset = msg->x / 8 + msg->y * data->bytesperrow;
180 pixel = 1 << (msg->x % 8); // 128 >>
181 notpixel = ~pixel;
182 mask = 1;
184 for (i = 0; i < data->depth; i++, mask <<= 1, plane++)
186 if ((*plane != NULL) && (*plane != (UBYTE *) -1))
188 if (msg->pixel & mask)
190 *(*plane + offset) = *(*plane + offset) | pixel;
192 else
194 *(*plane + offset) = *(*plane + offset) & notpixel;
200 /****************************************************************************************/
202 ULONG METHOD(NouveauPlanarBitMap, Hidd_BitMap, GetPixel)
204 struct planarbm_data *data;
205 UBYTE **plane;
206 ULONG offset;
207 ULONG i;
208 UBYTE pixel;
209 ULONG retval;
211 data = OOP_INST_DATA(cl, o);
213 plane = (UBYTE**) data->planes;
214 offset = msg->x / 8 + msg->y * data->bytesperrow;
215 pixel = 1 << (msg->x % 8); // 128 >>
216 retval = 0;
218 for (i = 0; i < data->depth; i++, plane++)
221 if (*plane == (UBYTE *) -1)
223 retval = retval | (1 << i);
225 else if (*plane != NULL)
227 if (*(*plane + offset) & pixel)
229 retval = retval | (1 << i);
234 return retval;
237 /****************************************************************************************/
239 VOID METHOD(NouveauPlanarBitMap, Hidd_BitMap, PutImage)
241 WORD x, y, d;
242 UBYTE *pixarray = (UBYTE *) msg->pixels;
243 UBYTE **plane;
244 ULONG planeoffset;
245 struct planarbm_data *data;
247 if ((msg->pixFmt != vHidd_StdPixFmt_Native) && (msg->pixFmt
248 != vHidd_StdPixFmt_Native32))
250 OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
251 return;
254 data = OOP_INST_DATA(cl, o);
256 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
258 for (y = 0; y < msg->height; y++)
260 switch (msg->pixFmt)
262 case vHidd_StdPixFmt_Native:
264 UBYTE *src = pixarray;
266 plane = (UBYTE**) data->planes;
268 for (d = 0; d < data->depth; d++)
270 ULONG dmask = 1L << d;
271 ULONG pmask = 1 << (msg->x & 7); // 0x80 >>
272 UBYTE *pl = *plane;
274 if (pl == (UBYTE *) -1)
275 continue;
276 if (pl == NULL)
277 continue;
279 pl += planeoffset;
281 for (x = 0; x < msg->width; x++)
283 if (src[x] & dmask)
285 *pl |= pmask;
287 else
289 *pl &= ~pmask;
292 if (pmask == 0x80) // 0x1
294 pmask = 1; // 0x80
295 pl++;
297 else
299 pmask <<= 1; // >>=
302 } /* for(x = 0; x < msg->width; x++) */
304 plane++;
306 } /* for(d = 0; d < data->depth; d++) */
308 pixarray += msg->modulo;
309 planeoffset += data->bytesperrow;
311 break;
313 case vHidd_StdPixFmt_Native32:
315 HIDDT_Pixel *src = (HIDDT_Pixel *) pixarray;
317 plane = (UBYTE**) data->planes;
319 for (d = 0; d < data->depth; d++)
321 ULONG dmask = 1L << d;
322 ULONG pmask = 1 << (msg->x & 7); // 0x80 >>
323 UBYTE *pl = *plane;
325 if (pl == (UBYTE *) -1)
326 continue;
327 if (pl == NULL)
328 continue;
330 pl += planeoffset;
332 for (x = 0; x < msg->width; x++)
334 if (src[x] & dmask)
336 *pl |= pmask;
338 else
340 *pl &= ~pmask;
343 if (pmask == 0x80) // 0x01
345 pmask = 0x01; // 0x80
346 pl++;
348 else
350 pmask <<= 1; // >>=
353 } /* for(x = 0; x < msg->width; x++) */
355 plane++;
357 } /* for(d = 0; d < data->depth; d++) */
359 pixarray += msg->modulo;
360 planeoffset += data->bytesperrow;
363 break;
365 } /* switch(msg->pixFmt) */
367 } /* for(y = 0; y < msg->height; y++) */
370 /****************************************************************************************/
372 VOID METHOD(NouveauPlanarBitMap, Hidd_BitMap, PutImageLUT)
374 WORD x, y, d;
375 UBYTE *pixarray = (UBYTE *) msg->pixels;
376 UBYTE **plane;
377 ULONG planeoffset;
378 struct planarbm_data *data;
380 data = OOP_INST_DATA(cl, o);
382 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
384 for (y = 0; y < msg->height; y++)
386 UBYTE *src = pixarray;
388 plane = (UBYTE**) data->planes;
390 for (d = 0; d < data->depth; d++)
392 ULONG dmask = 1L << d;
393 ULONG pmask = 1 << (msg->x & 7); // 0x80 >>
394 UBYTE *pl = *plane;
396 if (pl == (UBYTE *) -1)
397 continue;
398 if (pl == NULL)
399 continue;
401 pl += planeoffset;
403 for (x = 0; x < msg->width; x++)
405 if (src[x] & dmask)
407 *pl |= pmask;
409 else
411 *pl &= ~pmask;
414 if (pmask == 0x80) // 0x01
416 pmask = 0x01; // 0x80
417 pl++;
419 else
421 pmask <<= 1; // >>
424 } /* for(x = 0; x < msg->width; x++) */
426 plane++;
428 } /* for(d = 0; d < data->depth; d++) */
430 pixarray += msg->modulo;
431 planeoffset += data->bytesperrow;
433 } /* for(y = 0; y < msg->height; y++) */
436 /****************************************************************************************/
438 VOID METHOD(NouveauPlanarBitMap, Hidd_BitMap, GetImageLUT)
440 WORD x, y, d;
441 UBYTE *pixarray = (UBYTE *) msg->pixels;
442 UBYTE **plane;
443 ULONG planeoffset;
444 struct planarbm_data *data;
445 UBYTE prefill;
447 data = OOP_INST_DATA(cl, o);
449 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
451 prefill = 0;
452 for (d = 0; d < data->depth; d++)
454 if (data->planes[d] == (UBYTE *) -1)
456 prefill |= (1L << d);
460 for (y = 0; y < msg->height; y++)
462 UBYTE *dest = pixarray;
464 plane = data->planes;
466 for (x = 0; x < msg->width; x++)
468 dest[x] = prefill;
471 for (d = 0; d < data->depth; d++)
473 ULONG dmask = 1L << d;
474 ULONG pmask = 1 << (msg->x & 7); // 0x80 >>
475 UBYTE *pl = *plane;
477 if (pl == (UBYTE *) -1)
478 continue;
479 if (pl == NULL)
480 continue;
482 pl += planeoffset;
484 for (x = 0; x < msg->width; x++)
486 if (*pl & pmask)
488 dest[x] |= dmask;
490 else
492 dest[x] &= ~dmask;
495 if (pmask == 0x80) // 0x01
497 pmask = 0x01; // 0x80
498 pl++;
500 else
502 pmask <<= 1; // >>
505 } /* for(x = 0; x < msg->width; x++) */
507 plane++;
509 } /* for(d = 0; d < data->depth; d++) */
511 pixarray += msg->modulo;
512 planeoffset += data->bytesperrow;
514 } /* for(y = 0; y < msg->height; y++) */
518 /****************************************************************************************/
520 VOID METHOD(NouveauPlanarBitMap, Hidd_BitMap, BlitColorExpansion)
522 WORD x, y, d;
523 UBYTE **plane;
524 UBYTE *mask;
525 ULONG planeoffset /*, maskoffset*/;
526 ULONG cemd, fg, bg;
527 BOOL opaque;
528 OOP_Object *gc = msg->gc;
529 struct planarbm_data *data, *maskdata;
531 data = OOP_INST_DATA(cl, o);
533 cemd = GC_COLEXP(gc);
534 fg = GC_FG(gc);
535 bg = GC_BG(gc);
537 opaque = (cemd & vHidd_GC_ColExp_Opaque) ? TRUE : FALSE;
539 planeoffset = msg->destY * data->bytesperrow + msg->destX / 8;
541 if (OOP_OCLASS(msg->srcBitMap) == cl)
543 /* srcBitMap is a planarbm class object */
545 maskdata = OOP_INST_DATA(cl, msg->srcBitMap);
546 mask = maskdata->planes[0];
547 mask += msg->srcY * maskdata->bytesperrow + msg->srcX / 8;
549 for (y = 0; y < msg->height; y++)
551 plane = data->planes;
553 for (d = 0; d < data->depth; d++)
555 ULONG dmask = 1L << d;
556 ULONG pmask = 1 << (msg->destX & 7); // 0x80
557 ULONG mmask = 1 << (msg->srcX & 7); // 0x80
558 BOOL fgset = (fg & dmask) ? TRUE : FALSE;
559 BOOL bgset = (bg & dmask) ? TRUE : FALSE;
561 UBYTE *pl = *plane;
562 UBYTE *msk = mask;
564 if (pl == (UBYTE *) -1)
565 continue;
566 if (pl == NULL)
567 continue;
569 pl += planeoffset;
571 for (x = 0; x < msg->width; x++)
573 if (*msk & mmask)
575 if (fgset)
576 *pl |= pmask;
577 else
578 *pl &= ~pmask;
580 else if (opaque)
582 if (bgset)
583 *pl |= pmask;
584 else
585 *pl &= ~pmask;
588 if (pmask == 0x80) // 0x01
590 pmask = 0x01; // 0x80
591 pl++;
593 else
595 pmask <<= 1; // >>
598 if (mmask == 0x80) // 0x01
600 mmask = 0x01; // 0x80
601 msk++;
603 else
605 mmask <<= 1; // >>
608 } /* for(x = 0; x < msg->width; x++) */
610 plane++;
612 } /* for(d = 0; d < data->depth; d++) */
614 mask += maskdata->bytesperrow;
615 planeoffset += data->bytesperrow;
617 } /* for(y = 0; y < msg->height; y++) */
619 } /* if (OOP_OCLASS(msg->srcBitMap) == cl) */
620 else
622 HIDDT_Pixel *maskline;
624 maskline = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
625 if (!maskline)
627 OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
628 return;
631 for (y = 0; y < msg->height; y++)
633 plane = data->planes;
635 HIDD_BM_GetImage(msg->srcBitMap, (UBYTE *) maskline, 0, msg->srcX,
636 msg->srcY + y, msg->width, 1, vHidd_StdPixFmt_Native32);
638 for (d = 0; d < data->depth; d++)
640 ULONG dmask = 1L << d;
641 ULONG pmask = 1 << (msg->destX & 7); // 0x80 >>
642 BOOL fgset = (fg & dmask) ? TRUE : FALSE;
643 BOOL bgset = (bg & dmask) ? TRUE : FALSE;
645 UBYTE *pl = *plane;
647 if (pl == (UBYTE *) -1)
648 continue;
649 if (pl == NULL)
650 continue;
652 pl += planeoffset;
654 for (x = 0; x < msg->width; x++)
656 if (maskline[x])
658 if (fgset)
659 *pl |= pmask;
660 else
661 *pl &= ~pmask;
663 else if (opaque)
665 if (bgset)
666 *pl |= pmask;
667 else
668 *pl &= ~pmask;
671 if (pmask == 0x80) // 0x01
673 pmask = 0x01; // 0x80
674 pl++;
676 else
678 pmask <<= 1; // >>
681 } /* for(x = 0; x < msg->width; x++) */
683 plane++;
685 } /* for(d = 0; d < data->depth; d++) */
687 planeoffset += data->bytesperrow;
689 } /* for(y = 0; y < msg->height; y++) */
691 FreeVec(maskline);
693 } /* if (OOP_OCLASS(msg->srcBitMap) == cl) else ... */
696 /****************************************************************************************/
698 BOOL METHOD(NouveauPlanarBitMap, Hidd_PlanarBM, SetBitMap)
700 struct planarbm_data *data;
701 struct BitMap *bm;
703 struct TagItem pftags[] =
705 { aHidd_PixFmt_Depth, 0UL }, /* 0 */
706 { aHidd_PixFmt_BitsPerPixel, 0UL }, /* 1 */
707 { aHidd_PixFmt_BytesPerPixel, 1UL }, /* 2 */
708 { aHidd_PixFmt_ColorModel, vHidd_ColorModel_Palette }, /* 3 */
709 { aHidd_PixFmt_BitMapType, vHidd_BitMapType_Planar }, /* 4 */
710 { aHidd_PixFmt_CLUTShift, 0UL }, /* 5 */
711 { aHidd_PixFmt_CLUTMask, 0x000000FF }, /* 6 */
712 { aHidd_PixFmt_RedMask, 0x00FF0000 }, /* 7 */
713 { aHidd_PixFmt_GreenMask, 0x0000FF00 }, /* 8 */
714 { aHidd_PixFmt_BlueMask, 0x000000FF }, /* 9 */
715 { TAG_DONE, 0UL } /* 7 */
717 struct TagItem bmtags[] =
719 { aHidd_BitMap_Width, 0UL },
720 { aHidd_BitMap_Height, 0UL },
721 { aHidd_BitMap_PixFmtTags, 0UL },
722 { TAG_DONE, 0UL } };
724 ULONG i;
726 data = OOP_INST_DATA(cl, o);
727 bm = msg->bitMap;
729 if (data->planes_alloced)
732 bug(
733 " !!!!! PlanarBM: Trying to set bitmap in one that allready has planes allocated\n"));
734 return FALSE;
737 /* Check if plane array allready allocated */
738 if (NULL != data->planes)
740 if (bm->Depth > data->planebuf_size)
742 FreeVec(data->planes);
743 data->planes = NULL;
747 if (NULL == data->planes)
749 data->planes = AllocVec(sizeof(UBYTE *) * bm->Depth, MEMF_CLEAR);
751 if (NULL == data->planes)
752 return FALSE;
754 data->planebuf_size = bm->Depth;
757 /* Update the planes */
758 for (i = 0; i < data->planebuf_size; i++)
760 if (i < bm->Depth)
761 data->planes[i] = bm->Planes[i];
762 else
763 data->planes[i] = NULL;
766 data->depth = bm->Depth;
767 data->bytesperrow = bm->BytesPerRow;
768 data->rows = bm->Rows;
770 pftags[0].ti_Data = bm->Depth; /* PixFmt_Depth */
771 pftags[1].ti_Data = bm->Depth; /* PixFmt_BitsPerPixel */
773 bmtags[0].ti_Data = bm->BytesPerRow * 8;
774 bmtags[1].ti_Data = bm->Rows;
775 bmtags[2].ti_Data = (IPTR) pftags;
777 struct pHidd_BitMap_SetBitMapTags
779 OOP_MethodID mID;
780 struct TagItem *tags;
781 } __m =
782 { OOP_GetMethodID(IID_Hidd_BitMap, moHidd_BitMap_SetBitMapTags), bmtags },
783 *m = &__m;
785 /* Call private bitmap method to update superclass */
786 if (!OOP_DoMethod(o, (OOP_Msg) m))
788 ULONG i;
790 for (i = 0; i < data->planebuf_size; i++)
792 data->planes[i] = NULL;
796 return TRUE;
799 /****************************************************************************************/
800 BOOL METHOD(NouveauPlanarBitMap, Hidd_PlanarBM, GetBitMap)
802 struct planarbm_data *data = OOP_INST_DATA(cl, o);
803 ULONG i;
805 msg->bitMap->Depth = data->depth;
806 msg->bitMap->BytesPerRow = data->bytesperrow;
807 msg->bitMap->Rows = data->rows;
808 msg->bitMap->Flags = BMF_STANDARD | BMF_MINPLANES; /* CHECKME */
809 msg->bitMap->pad = 0;
811 for (i = 0; i < data->planebuf_size; i++)
812 msg->bitMap->Planes[i] = data->planes[i];
814 return TRUE;