more rendering corrections
[AROS.git] / workbench / hidds / hidd.nvidia / planarbm.c
blobdebd394099f5c9d8ae4bc0a31d4c0436579be086
1 /*
2 Copyright © 1995-2009, 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 "nv.h"
26 #include <string.h>
28 #define DEBUG 1
29 #include <aros/debug.h>
31 /****************************************************************************************/
33 #define _sd (&((LIBBASETYPEPTR)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 HiddNVidiaBitMapAttrBase (_sd->nvBitMapAttrBase)
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 *NVPlanBM__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;
78 o =(OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
79 if (NULL == o)
80 return NULL;
82 data = OOP_INST_DATA(cl, o);
83 memset(data, 0, sizeof (*data));
86 /* Get some data about the dimensions of the bitmap */
88 data->planes_alloced = (BOOL)GetTagData(aHidd_PlanarBM_AllocPlanes, TRUE, msg->attrList);
90 #warning Fix this hack
91 /* Because this class is used to emulate Amiga bitmaps, we
92 have to see if it should have late initalisation
94 if (!data->planes_alloced)
95 return o; /* Late initialization */
98 /* Not late initalization. Get some info on the bitmap */
99 OOP_GetAttr(o, aHidd_BitMap_Width, &width);
100 OOP_GetAttr(o, aHidd_BitMap_Height, &height);
101 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (APTR)&pf);
102 OOP_GetAttr(pf, aHidd_PixFmt_Depth, (APTR)&depth);
104 /* We cache some info */
105 data->bytesperrow = ((width + 31) & ~31) / 8;
106 data->rows = height;
107 data->depth = depth;
109 if (ok)
111 /* Allocate memory for plane array */
112 data->planes = AllocVec(sizeof (ULONG *) * depth, MEMF_ANY|MEMF_CLEAR);
113 if (NULL == data->planes)
114 ok = FALSE;
115 else
117 UBYTE i;
119 data->planebuf_size = depth;
121 /* Allocate all the planes */
122 for ( i = 0; i < depth && ok; i ++)
124 data->planes[i] = AllocVec(height * data->bytesperrow, MEMF_ANY|MEMF_CLEAR);
125 if (NULL == data->planes[i])
126 ok = FALSE;
131 if (!ok)
133 OOP_MethodID dispose_mid;
135 dispose_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
136 OOP_CoerceMethod(cl, o, (OOP_Msg)&dispose_mid);
138 o = NULL;
141 return o;
144 /****************************************************************************************/
146 VOID NVPlanBM__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
148 struct planarbm_data *data;
149 UBYTE i;
151 data = OOP_INST_DATA(cl, o);
153 if (data->planes_alloced)
155 if (NULL != data->planes)
157 for (i = 0; i < data->depth; i ++)
159 if (NULL != data->planes[i])
161 FreeVec(data->planes[i]);
164 FreeVec(data->planes);
168 OOP_DoSuperMethod(cl, o, msg);
170 return;
173 /****************************************************************************************/
175 VOID NVPlanBM__Hidd_BitMap__PutPixel(OOP_Class *cl, OOP_Object *o,
176 struct pHidd_BitMap_PutPixel *msg)
178 UBYTE **plane;
179 struct planarbm_data *data;
180 ULONG offset;
181 ULONG mask;
182 UBYTE pixel, notpixel;
183 UBYTE i;
185 data = OOP_INST_DATA(cl, o);
187 /* bitmap in plane-mode */
188 plane = (UBYTE**)data->planes;
189 offset = msg->x / 8 + msg->y * data->bytesperrow;
190 pixel = 1 << (msg->x % 8); // 128 >>
191 notpixel = ~pixel;
192 mask = 1;
194 for(i = 0; i < data->depth; i++, mask <<=1, plane ++)
196 if ((*plane != NULL) && (*plane != (UBYTE *)-1))
198 if(msg->pixel & mask)
200 *(*plane + offset) = *(*plane + offset) | pixel;
202 else
204 *(*plane + offset) = *(*plane + offset) & notpixel;
210 /****************************************************************************************/
212 ULONG NVPlanBM__Hidd_BitMap__GetPixel(OOP_Class *cl, OOP_Object *o,
213 struct pHidd_BitMap_GetPixel *msg)
215 struct planarbm_data *data;
216 UBYTE **plane;
217 ULONG offset;
218 ULONG i;
219 UBYTE pixel;
220 ULONG retval;
222 data = OOP_INST_DATA(cl, o);
224 plane = (UBYTE**)data->planes;
225 offset = msg->x / 8 + msg->y * data->bytesperrow;
226 pixel = 1 << (msg->x % 8); // 128 >>
227 retval = 0;
229 for(i = 0; i < data->depth; i++, plane ++)
232 if (*plane == (UBYTE *)-1)
234 retval = retval | (1 << i);
236 else if (*plane != NULL)
238 if(*(*plane + offset) & pixel)
240 retval = retval | (1 << i);
245 return retval;
248 /****************************************************************************************/
250 VOID NVPlanBM__Hidd_BitMap__PutImage(OOP_Class *cl, OOP_Object *o,
251 struct pHidd_BitMap_PutImage *msg)
253 WORD x, y, d;
254 UBYTE *pixarray = (UBYTE *)msg->pixels;
255 UBYTE **plane;
256 ULONG planeoffset;
257 struct planarbm_data *data;
259 if ((msg->pixFmt != vHidd_StdPixFmt_Native) &&
260 (msg->pixFmt != vHidd_StdPixFmt_Native32))
262 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
263 return;
266 data = OOP_INST_DATA(cl, o);
268 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
270 for(y = 0; y < msg->height; y++)
272 switch(msg->pixFmt)
274 case vHidd_StdPixFmt_Native:
276 UBYTE *src = pixarray;
278 plane = (UBYTE**)data->planes;
280 for(d = 0; d < data->depth; d++)
282 ULONG dmask = 1L << d;
283 ULONG pmask = 1 << (msg->x & 7); // 0x80 >>
284 UBYTE *pl = *plane;
286 if (pl == (UBYTE *)-1) continue;
287 if (pl == NULL) continue;
289 pl += planeoffset;
291 for(x = 0; x < msg->width; x++)
293 if (src[x] & dmask)
295 *pl |= pmask;
297 else
299 *pl &= ~pmask;
302 if (pmask == 0x80) // 0x1
304 pmask = 1; // 0x80
305 pl++;
307 else
309 pmask <<= 1; // >>=
312 } /* for(x = 0; x < msg->width; x++) */
314 plane++;
316 } /* for(d = 0; d < data->depth; d++) */
318 pixarray += msg->modulo;
319 planeoffset += data->bytesperrow;
321 break;
323 case vHidd_StdPixFmt_Native32:
325 HIDDT_Pixel *src = (HIDDT_Pixel *)pixarray;
327 plane = (UBYTE**)data->planes;
329 for(d = 0; d < data->depth; d++)
331 ULONG dmask = 1L << d;
332 ULONG pmask = 1 << (msg->x & 7); // 0x80 >>
333 UBYTE *pl = *plane;
335 if (pl == (UBYTE *)-1) continue;
336 if (pl == NULL) continue;
338 pl += planeoffset;
340 for(x = 0; x < msg->width; x++)
342 if (src[x] & dmask)
344 *pl |= pmask;
346 else
348 *pl &= ~pmask;
351 if (pmask == 0x80) // 0x01
353 pmask = 0x01; // 0x80
354 pl++;
356 else
358 pmask <<= 1; // >>=
361 } /* for(x = 0; x < msg->width; x++) */
363 plane++;
365 } /* for(d = 0; d < data->depth; d++) */
367 pixarray += msg->modulo;
368 planeoffset += data->bytesperrow;
371 break;
373 } /* switch(msg->pixFmt) */
375 } /* for(y = 0; y < msg->height; y++) */
378 /****************************************************************************************/
380 VOID NVPlanBM__Hidd_BitMap__PutImageLUT(OOP_Class *cl, OOP_Object *o,
381 struct pHidd_BitMap_PutImageLUT *msg)
383 WORD x, y, d;
384 UBYTE *pixarray = (UBYTE *)msg->pixels;
385 UBYTE **plane;
386 ULONG planeoffset;
387 struct planarbm_data *data;
389 data = OOP_INST_DATA(cl, o);
391 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
393 for(y = 0; y < msg->height; y++)
395 UBYTE *src = pixarray;
397 plane = (UBYTE**)data->planes;
399 for(d = 0; d < data->depth; d++)
401 ULONG dmask = 1L << d;
402 ULONG pmask = 1 << (msg->x & 7); // 0x80 >>
403 UBYTE *pl = *plane;
405 if (pl == (UBYTE *)-1) continue;
406 if (pl == NULL) continue;
408 pl += planeoffset;
410 for(x = 0; x < msg->width; x++)
412 if (src[x] & dmask)
414 *pl |= pmask;
416 else
418 *pl &= ~pmask;
421 if (pmask == 0x80) // 0x01
423 pmask = 0x01; // 0x80
424 pl++;
426 else
428 pmask <<= 1; // >>
431 } /* for(x = 0; x < msg->width; x++) */
433 plane++;
435 } /* for(d = 0; d < data->depth; d++) */
437 pixarray += msg->modulo;
438 planeoffset += data->bytesperrow;
440 } /* for(y = 0; y < msg->height; y++) */
443 /****************************************************************************************/
445 VOID NVPlanBM__Hidd_BitMap__GetImageLUT(OOP_Class *cl, OOP_Object *o,
446 struct pHidd_BitMap_GetImageLUT *msg)
448 WORD x, y, d;
449 UBYTE *pixarray = (UBYTE *)msg->pixels;
450 UBYTE **plane;
451 ULONG planeoffset;
452 struct planarbm_data *data;
453 UBYTE prefill;
455 data = OOP_INST_DATA(cl, o);
457 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
459 prefill = 0;
460 for(d = 0; d < data->depth; d++)
462 if (data->planes[d] == (UBYTE *)-1)
464 prefill |= (1L << d);
468 for(y = 0; y < msg->height; y++)
470 UBYTE *dest = pixarray;
472 plane = data->planes;
474 for(x = 0; x < msg->width; x++)
476 dest[x] = prefill;
479 for(d = 0; d < data->depth; d++)
481 ULONG dmask = 1L << d;
482 ULONG pmask = 1 << (msg->x & 7); // 0x80 >>
483 UBYTE *pl = *plane;
485 if (pl == (UBYTE *)-1) continue;
486 if (pl == NULL) continue;
488 pl += planeoffset;
490 for(x = 0; x < msg->width; x++)
492 if (*pl & pmask)
494 dest[x] |= dmask;
496 else
498 dest[x] &= ~dmask;
501 if (pmask == 0x80) // 0x01
503 pmask = 0x01; // 0x80
504 pl++;
506 else
508 pmask <<= 1; // >>
511 } /* for(x = 0; x < msg->width; x++) */
513 plane++;
515 } /* for(d = 0; d < data->depth; d++) */
517 pixarray += msg->modulo;
518 planeoffset += data->bytesperrow;
520 } /* for(y = 0; y < msg->height; y++) */
524 /****************************************************************************************/
526 VOID NVPlanBM__Hidd_BitMap__BlitColorExpansion(OOP_Class *cl, OOP_Object *o,
527 struct pHidd_BitMap_BlitColorExpansion *msg)
529 WORD x, y, d;
530 UBYTE **plane;
531 UBYTE *mask;
532 ULONG planeoffset /*, maskoffset*/;
533 ULONG cemd, fg, bg;
534 BOOL opaque;
535 OOP_Object *gc = msg->gc;
536 struct planarbm_data *data, *maskdata;
538 data = OOP_INST_DATA(cl, o);
540 cemd = GC_COLEXP(gc);
541 fg = GC_FG(gc);
542 bg = GC_BG(gc);
544 opaque = (cemd & vHidd_GC_ColExp_Opaque) ? TRUE : FALSE;
546 planeoffset = msg->destY * data->bytesperrow + msg->destX / 8;
548 if (OOP_OCLASS(msg->srcBitMap) == cl)
550 /* srcBitMap is a planarbm class object */
552 maskdata = OOP_INST_DATA(cl, msg->srcBitMap);
553 mask = maskdata->planes[0];
554 mask += msg->srcY * maskdata->bytesperrow + msg->srcX / 8;
556 for(y = 0; y < msg->height; y++)
558 plane = data->planes;
560 for(d = 0; d < data->depth; d++)
562 ULONG dmask = 1L << d;
563 ULONG pmask = 1 << (msg->destX & 7); // 0x80
564 ULONG mmask = 1 << (msg->srcX & 7); // 0x80
565 BOOL fgset = (fg & dmask) ? TRUE : FALSE;
566 BOOL bgset = (bg & dmask) ? TRUE : FALSE;
568 UBYTE *pl = *plane;
569 UBYTE *msk = mask;
571 if (pl == (UBYTE *)-1) continue;
572 if (pl == NULL) continue;
574 pl += planeoffset;
576 for(x = 0; x < msg->width; x++)
578 if (*msk & mmask)
580 if (fgset)
581 *pl |= pmask;
582 else
583 *pl &= ~pmask;
585 else if (opaque)
587 if (bgset)
588 *pl |= pmask;
589 else
590 *pl &= ~pmask;
593 if (pmask == 0x80) // 0x01
595 pmask = 0x01; // 0x80
596 pl++;
598 else
600 pmask <<= 1; // >>
603 if (mmask == 0x80) // 0x01
605 mmask = 0x01; // 0x80
606 msk++;
608 else
610 mmask <<= 1; // >>
613 } /* for(x = 0; x < msg->width; x++) */
615 plane++;
617 } /* for(d = 0; d < data->depth; d++) */
619 mask += maskdata->bytesperrow;
620 planeoffset += data->bytesperrow;
622 } /* for(y = 0; y < msg->height; y++) */
624 } /* if (OOP_OCLASS(msg->srcBitMap) == cl) */
625 else
627 HIDDT_Pixel *maskline;
629 maskline = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
630 if (!maskline)
632 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
633 return;
636 for(y = 0; y < msg->height; y++)
638 plane = data->planes;
639 struct pHidd_BitMap_GetImage __m = {
640 _sd->mid_GetImage,
641 (UBYTE *)maskline,
643 msg->srcX,
644 msg->srcY + y,
645 msg->width,
647 vHidd_StdPixFmt_Native32
648 }, *m = &__m;
650 OOP_DoMethod(msg->srcBitMap, (OOP_Msg)m);
652 for(d = 0; d < data->depth; d++)
654 ULONG dmask = 1L << d;
655 ULONG pmask = 1 << (msg->destX & 7); // 0x80 >>
656 BOOL fgset = (fg & dmask) ? TRUE : FALSE;
657 BOOL bgset = (bg & dmask) ? TRUE : FALSE;
659 UBYTE *pl = *plane;
661 if (pl == (UBYTE *)-1) continue;
662 if (pl == NULL) continue;
664 pl += planeoffset;
666 for(x = 0; x < msg->width; x++)
668 if (maskline[x])
670 if (fgset)
671 *pl |= pmask;
672 else
673 *pl &= ~pmask;
675 else if (opaque)
677 if (bgset)
678 *pl |= pmask;
679 else
680 *pl &= ~pmask;
683 if (pmask == 0x80) // 0x01
685 pmask = 0x01; // 0x80
686 pl++;
688 else
690 pmask <<= 1; // >>
693 } /* for(x = 0; x < msg->width; x++) */
695 plane++;
697 } /* for(d = 0; d < data->depth; d++) */
699 planeoffset += data->bytesperrow;
701 } /* for(y = 0; y < msg->height; y++) */
703 FreeVec(maskline);
705 } /* if (OOP_OCLASS(msg->srcBitMap) == cl) else ... */
709 /****************************************************************************************/
711 BOOL NVPlanBM__Hidd_PlanarBM__SetBitMap(OOP_Class *cl, OOP_Object *o,
712 struct pHidd_PlanarBM_SetBitMap *msg)
714 struct planarbm_data *data;
715 struct BitMap *bm;
717 struct TagItem pftags[] =
719 { aHidd_PixFmt_Depth , 0UL }, /* 0 */
720 { aHidd_PixFmt_BitsPerPixel , 0UL }, /* 1 */
721 { aHidd_PixFmt_BytesPerPixel, 1UL }, /* 2 */
722 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_Palette }, /* 3 */
723 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Planar }, /* 4 */
724 { aHidd_PixFmt_CLUTShift , 0UL }, /* 5 */
725 { aHidd_PixFmt_CLUTMask , 0x000000FF }, /* 6 */
726 { aHidd_PixFmt_RedMask , 0x00FF0000 }, /* 7 */
727 { aHidd_PixFmt_GreenMask , 0x0000FF00 }, /* 8 */
728 { aHidd_PixFmt_BlueMask , 0x000000FF }, /* 9 */
729 { TAG_DONE , 0UL } /* 7 */
731 struct TagItem bmtags[] =
733 { aHidd_BitMap_Width , 0UL },
734 { aHidd_BitMap_Height , 0UL },
735 { aHidd_BitMap_PixFmtTags , 0UL },
736 { TAG_DONE , 0UL }
739 ULONG i;
741 data = OOP_INST_DATA(cl, o);
742 bm = msg->bitMap;
744 if (data->planes_alloced)
746 D(bug(" !!!!! PlanarBM: Trying to set bitmap in one that allready has planes allocated\n"));
747 return FALSE;
750 /* Check if plane array allready allocated */
751 if (NULL != data->planes)
753 if (bm->Depth > data->planebuf_size)
755 FreeVec(data->planes);
756 data->planes = NULL;
760 if (NULL == data->planes)
762 data->planes = AllocVec(sizeof (UBYTE *) * bm->Depth, MEMF_CLEAR);
764 if (NULL == data->planes)
765 return FALSE;
767 data->planebuf_size = bm->Depth;
771 /* Update the planes */
772 for (i = 0; i < data->planebuf_size; i ++)
774 if (i < bm->Depth)
775 data->planes[i] = bm->Planes[i];
776 else
777 data->planes[i] = NULL;
780 data->depth = bm->Depth;
781 data->bytesperrow = bm->BytesPerRow;
782 data->rows = bm->Rows;
784 pftags[0].ti_Data = bm->Depth; /* PixFmt_Depth */
785 pftags[1].ti_Data = bm->Depth; /* PixFmt_BitsPerPixel */
787 bmtags[0].ti_Data = bm->BytesPerRow * 8;
788 bmtags[1].ti_Data = bm->Rows;
789 bmtags[2].ti_Data = (IPTR)pftags;
791 struct pHidd_BitMap_SetBitMapTags {
792 OOP_MethodID mID;
793 struct TagItem *tags;
794 } __m = {
795 OOP_GetMethodID(IID_Hidd_BitMap, num_Hidd_BitMap_Methods),
796 bmtags
797 }, *m = &__m;
799 /* Call private bitmap method to update superclass */
800 if (!OOP_DoMethod(o, (OOP_Msg)m))
802 ULONG i;
804 for (i = 0; i < data->planebuf_size; i ++)
806 data->planes[i] = NULL;
810 return TRUE;
813 /****************************************************************************************/