Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / hidds / nvidia / planarbm.c
blobf8a198b23273fdf311ee22acaceb2ce0a11a3f93
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 "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 /* TODO: 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 FreeVec(data->planes[i]);
161 FreeVec(data->planes);
165 OOP_DoSuperMethod(cl, o, msg);
167 return;
170 /****************************************************************************************/
172 VOID NVPlanBM__Hidd_BitMap__PutPixel(OOP_Class *cl, OOP_Object *o,
173 struct pHidd_BitMap_PutPixel *msg)
175 UBYTE **plane;
176 struct planarbm_data *data;
177 ULONG offset;
178 ULONG mask;
179 UBYTE pixel, notpixel;
180 UBYTE i;
182 data = OOP_INST_DATA(cl, o);
184 /* bitmap in plane-mode */
185 plane = (UBYTE**)data->planes;
186 offset = msg->x / 8 + msg->y * data->bytesperrow;
187 pixel = 1 << (msg->x % 8); // 128 >>
188 notpixel = ~pixel;
189 mask = 1;
191 for(i = 0; i < data->depth; i++, mask <<=1, plane ++)
193 if ((*plane != NULL) && (*plane != (UBYTE *)-1))
195 if(msg->pixel & mask)
197 *(*plane + offset) = *(*plane + offset) | pixel;
199 else
201 *(*plane + offset) = *(*plane + offset) & notpixel;
207 /****************************************************************************************/
209 ULONG NVPlanBM__Hidd_BitMap__GetPixel(OOP_Class *cl, OOP_Object *o,
210 struct pHidd_BitMap_GetPixel *msg)
212 struct planarbm_data *data;
213 UBYTE **plane;
214 ULONG offset;
215 ULONG i;
216 UBYTE pixel;
217 ULONG retval;
219 data = OOP_INST_DATA(cl, o);
221 plane = (UBYTE**)data->planes;
222 offset = msg->x / 8 + msg->y * data->bytesperrow;
223 pixel = 1 << (msg->x % 8); // 128 >>
224 retval = 0;
226 for(i = 0; i < data->depth; i++, plane ++)
229 if (*plane == (UBYTE *)-1)
231 retval = retval | (1 << i);
233 else if (*plane != NULL)
235 if(*(*plane + offset) & pixel)
237 retval = retval | (1 << i);
242 return retval;
245 /****************************************************************************************/
247 VOID NVPlanBM__Hidd_BitMap__PutImage(OOP_Class *cl, OOP_Object *o,
248 struct pHidd_BitMap_PutImage *msg)
250 WORD x, y, d;
251 UBYTE *pixarray = (UBYTE *)msg->pixels;
252 UBYTE **plane;
253 ULONG planeoffset;
254 struct planarbm_data *data;
256 if ((msg->pixFmt != vHidd_StdPixFmt_Native) &&
257 (msg->pixFmt != vHidd_StdPixFmt_Native32))
259 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
260 return;
263 data = OOP_INST_DATA(cl, o);
265 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
267 for(y = 0; y < msg->height; y++)
269 switch(msg->pixFmt)
271 case vHidd_StdPixFmt_Native:
273 UBYTE *src = pixarray;
275 plane = (UBYTE**)data->planes;
277 for(d = 0; d < data->depth; d++)
279 ULONG dmask = 1L << d;
280 ULONG pmask = 1 << (msg->x & 7); // 0x80 >>
281 UBYTE *pl = *plane;
283 if (pl == (UBYTE *)-1) continue;
284 if (pl == NULL) continue;
286 pl += planeoffset;
288 for(x = 0; x < msg->width; x++)
290 if (src[x] & dmask)
292 *pl |= pmask;
294 else
296 *pl &= ~pmask;
299 if (pmask == 0x80) // 0x1
301 pmask = 1; // 0x80
302 pl++;
304 else
306 pmask <<= 1; // >>=
309 } /* for(x = 0; x < msg->width; x++) */
311 plane++;
313 } /* for(d = 0; d < data->depth; d++) */
315 pixarray += msg->modulo;
316 planeoffset += data->bytesperrow;
318 break;
320 case vHidd_StdPixFmt_Native32:
322 HIDDT_Pixel *src = (HIDDT_Pixel *)pixarray;
324 plane = (UBYTE**)data->planes;
326 for(d = 0; d < data->depth; d++)
328 ULONG dmask = 1L << d;
329 ULONG pmask = 1 << (msg->x & 7); // 0x80 >>
330 UBYTE *pl = *plane;
332 if (pl == (UBYTE *)-1) continue;
333 if (pl == NULL) continue;
335 pl += planeoffset;
337 for(x = 0; x < msg->width; x++)
339 if (src[x] & dmask)
341 *pl |= pmask;
343 else
345 *pl &= ~pmask;
348 if (pmask == 0x80) // 0x01
350 pmask = 0x01; // 0x80
351 pl++;
353 else
355 pmask <<= 1; // >>=
358 } /* for(x = 0; x < msg->width; x++) */
360 plane++;
362 } /* for(d = 0; d < data->depth; d++) */
364 pixarray += msg->modulo;
365 planeoffset += data->bytesperrow;
368 break;
370 } /* switch(msg->pixFmt) */
372 } /* for(y = 0; y < msg->height; y++) */
375 /****************************************************************************************/
377 VOID NVPlanBM__Hidd_BitMap__PutImageLUT(OOP_Class *cl, OOP_Object *o,
378 struct pHidd_BitMap_PutImageLUT *msg)
380 WORD x, y, d;
381 UBYTE *pixarray = (UBYTE *)msg->pixels;
382 UBYTE **plane;
383 ULONG planeoffset;
384 struct planarbm_data *data;
386 data = OOP_INST_DATA(cl, o);
388 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
390 for(y = 0; y < msg->height; y++)
392 UBYTE *src = pixarray;
394 plane = (UBYTE**)data->planes;
396 for(d = 0; d < data->depth; d++)
398 ULONG dmask = 1L << d;
399 ULONG pmask = 1 << (msg->x & 7); // 0x80 >>
400 UBYTE *pl = *plane;
402 if (pl == (UBYTE *)-1) continue;
403 if (pl == NULL) continue;
405 pl += planeoffset;
407 for(x = 0; x < msg->width; x++)
409 if (src[x] & dmask)
411 *pl |= pmask;
413 else
415 *pl &= ~pmask;
418 if (pmask == 0x80) // 0x01
420 pmask = 0x01; // 0x80
421 pl++;
423 else
425 pmask <<= 1; // >>
428 } /* for(x = 0; x < msg->width; x++) */
430 plane++;
432 } /* for(d = 0; d < data->depth; d++) */
434 pixarray += msg->modulo;
435 planeoffset += data->bytesperrow;
437 } /* for(y = 0; y < msg->height; y++) */
440 /****************************************************************************************/
442 VOID NVPlanBM__Hidd_BitMap__GetImageLUT(OOP_Class *cl, OOP_Object *o,
443 struct pHidd_BitMap_GetImageLUT *msg)
445 WORD x, y, d;
446 UBYTE *pixarray = (UBYTE *)msg->pixels;
447 UBYTE **plane;
448 ULONG planeoffset;
449 struct planarbm_data *data;
450 UBYTE prefill;
452 data = OOP_INST_DATA(cl, o);
454 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
456 prefill = 0;
457 for(d = 0; d < data->depth; d++)
459 if (data->planes[d] == (UBYTE *)-1)
461 prefill |= (1L << d);
465 for(y = 0; y < msg->height; y++)
467 UBYTE *dest = pixarray;
469 plane = data->planes;
471 for(x = 0; x < msg->width; x++)
473 dest[x] = prefill;
476 for(d = 0; d < data->depth; d++)
478 ULONG dmask = 1L << d;
479 ULONG pmask = 1 << (msg->x & 7); // 0x80 >>
480 UBYTE *pl = *plane;
482 if (pl == (UBYTE *)-1) continue;
483 if (pl == NULL) continue;
485 pl += planeoffset;
487 for(x = 0; x < msg->width; x++)
489 if (*pl & pmask)
491 dest[x] |= dmask;
493 else
495 dest[x] &= ~dmask;
498 if (pmask == 0x80) // 0x01
500 pmask = 0x01; // 0x80
501 pl++;
503 else
505 pmask <<= 1; // >>
508 } /* for(x = 0; x < msg->width; x++) */
510 plane++;
512 } /* for(d = 0; d < data->depth; d++) */
514 pixarray += msg->modulo;
515 planeoffset += data->bytesperrow;
517 } /* for(y = 0; y < msg->height; y++) */
521 /****************************************************************************************/
523 VOID NVPlanBM__Hidd_BitMap__BlitColorExpansion(OOP_Class *cl, OOP_Object *o,
524 struct pHidd_BitMap_BlitColorExpansion *msg)
526 WORD x, y, d;
527 UBYTE **plane;
528 UBYTE *mask;
529 ULONG planeoffset /*, maskoffset*/;
530 ULONG cemd, fg, bg;
531 BOOL opaque;
532 OOP_Object *gc = msg->gc;
533 struct planarbm_data *data, *maskdata;
535 data = OOP_INST_DATA(cl, o);
537 cemd = GC_COLEXP(gc);
538 fg = GC_FG(gc);
539 bg = GC_BG(gc);
541 opaque = (cemd & vHidd_GC_ColExp_Opaque) ? TRUE : FALSE;
543 planeoffset = msg->destY * data->bytesperrow + msg->destX / 8;
545 if (OOP_OCLASS(msg->srcBitMap) == cl)
547 /* srcBitMap is a planarbm class object */
549 maskdata = OOP_INST_DATA(cl, msg->srcBitMap);
550 mask = maskdata->planes[0];
551 mask += msg->srcY * maskdata->bytesperrow + msg->srcX / 8;
553 for(y = 0; y < msg->height; y++)
555 plane = data->planes;
557 for(d = 0; d < data->depth; d++)
559 ULONG dmask = 1L << d;
560 ULONG pmask = 1 << (msg->destX & 7); // 0x80
561 ULONG mmask = 1 << (msg->srcX & 7); // 0x80
562 BOOL fgset = (fg & dmask) ? TRUE : FALSE;
563 BOOL bgset = (bg & dmask) ? TRUE : FALSE;
565 UBYTE *pl = *plane;
566 UBYTE *msk = mask;
568 if (pl == (UBYTE *)-1) continue;
569 if (pl == NULL) continue;
571 pl += planeoffset;
573 for(x = 0; x < msg->width; x++)
575 if (*msk & mmask)
577 if (fgset)
578 *pl |= pmask;
579 else
580 *pl &= ~pmask;
582 else if (opaque)
584 if (bgset)
585 *pl |= pmask;
586 else
587 *pl &= ~pmask;
590 if (pmask == 0x80) // 0x01
592 pmask = 0x01; // 0x80
593 pl++;
595 else
597 pmask <<= 1; // >>
600 if (mmask == 0x80) // 0x01
602 mmask = 0x01; // 0x80
603 msk++;
605 else
607 mmask <<= 1; // >>
610 } /* for(x = 0; x < msg->width; x++) */
612 plane++;
614 } /* for(d = 0; d < data->depth; d++) */
616 mask += maskdata->bytesperrow;
617 planeoffset += data->bytesperrow;
619 } /* for(y = 0; y < msg->height; y++) */
621 } /* if (OOP_OCLASS(msg->srcBitMap) == cl) */
622 else
624 HIDDT_Pixel *maskline;
626 maskline = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
627 if (!maskline)
629 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
630 return;
633 for(y = 0; y < msg->height; y++)
635 plane = data->planes;
636 struct pHidd_BitMap_GetImage __m = {
637 _sd->mid_GetImage,
638 (UBYTE *)maskline,
640 msg->srcX,
641 msg->srcY + y,
642 msg->width,
644 vHidd_StdPixFmt_Native32
645 }, *m = &__m;
647 OOP_DoMethod(msg->srcBitMap, (OOP_Msg)m);
649 for(d = 0; d < data->depth; d++)
651 ULONG dmask = 1L << d;
652 ULONG pmask = 1 << (msg->destX & 7); // 0x80 >>
653 BOOL fgset = (fg & dmask) ? TRUE : FALSE;
654 BOOL bgset = (bg & dmask) ? TRUE : FALSE;
656 UBYTE *pl = *plane;
658 if (pl == (UBYTE *)-1) continue;
659 if (pl == NULL) continue;
661 pl += planeoffset;
663 for(x = 0; x < msg->width; x++)
665 if (maskline[x])
667 if (fgset)
668 *pl |= pmask;
669 else
670 *pl &= ~pmask;
672 else if (opaque)
674 if (bgset)
675 *pl |= pmask;
676 else
677 *pl &= ~pmask;
680 if (pmask == 0x80) // 0x01
682 pmask = 0x01; // 0x80
683 pl++;
685 else
687 pmask <<= 1; // >>
690 } /* for(x = 0; x < msg->width; x++) */
692 plane++;
694 } /* for(d = 0; d < data->depth; d++) */
696 planeoffset += data->bytesperrow;
698 } /* for(y = 0; y < msg->height; y++) */
700 FreeVec(maskline);
702 } /* if (OOP_OCLASS(msg->srcBitMap) == cl) else ... */
706 /****************************************************************************************/
708 BOOL NVPlanBM__Hidd_PlanarBM__SetBitMap(OOP_Class *cl, OOP_Object *o,
709 struct pHidd_PlanarBM_SetBitMap *msg)
711 struct planarbm_data *data;
712 struct BitMap *bm;
714 struct TagItem pftags[] =
716 { aHidd_PixFmt_Depth , 0UL }, /* 0 */
717 { aHidd_PixFmt_BitsPerPixel , 0UL }, /* 1 */
718 { aHidd_PixFmt_BytesPerPixel, 1UL }, /* 2 */
719 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_Palette }, /* 3 */
720 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Planar }, /* 4 */
721 { aHidd_PixFmt_CLUTShift , 0UL }, /* 5 */
722 { aHidd_PixFmt_CLUTMask , 0x000000FF }, /* 6 */
723 { aHidd_PixFmt_RedMask , 0x00FF0000 }, /* 7 */
724 { aHidd_PixFmt_GreenMask , 0x0000FF00 }, /* 8 */
725 { aHidd_PixFmt_BlueMask , 0x000000FF }, /* 9 */
726 { TAG_DONE , 0UL } /* 7 */
728 struct TagItem bmtags[] =
730 { aHidd_BitMap_Width , 0UL },
731 { aHidd_BitMap_Height , 0UL },
732 { TAG_DONE , 0UL }
735 ULONG i;
737 data = OOP_INST_DATA(cl, o);
738 bm = msg->bitMap;
740 if (data->planes_alloced)
742 D(bug(" !!!!! PlanarBM: Trying to set bitmap in one that allready has planes allocated\n"));
743 return FALSE;
746 /* Check if plane array allready allocated */
747 if (NULL != data->planes)
749 if (bm->Depth > data->planebuf_size)
751 FreeVec(data->planes);
752 data->planes = NULL;
756 if (NULL == data->planes)
758 data->planes = AllocVec(sizeof (UBYTE *) * bm->Depth, MEMF_CLEAR);
760 if (NULL == data->planes)
761 return FALSE;
763 data->planebuf_size = bm->Depth;
767 /* Update the planes */
768 for (i = 0; i < data->planebuf_size; i ++)
770 if (i < bm->Depth)
771 data->planes[i] = bm->Planes[i];
772 else
773 data->planes[i] = NULL;
776 data->depth = bm->Depth;
777 data->bytesperrow = bm->BytesPerRow;
778 data->rows = bm->Rows;
780 pftags[0].ti_Data = bm->Depth; /* PixFmt_Depth */
781 pftags[1].ti_Data = bm->Depth; /* PixFmt_BitsPerPixel */
783 bmtags[0].ti_Data = bm->BytesPerRow * 8;
784 bmtags[1].ti_Data = bm->Rows;
785 bmtags[2].ti_Data = (IPTR)pftags;
787 struct pHidd_BitMap_SetBitMapTags {
788 OOP_MethodID mID;
789 struct TagItem *tags;
790 } __m = {
791 OOP_GetMethodID(IID_Hidd_BitMap, num_Hidd_BitMap_Methods),
792 bmtags
793 }, *m = &__m;
795 /* Call private bitmap method to update superclass */
796 if (!OOP_DoMethod(o, (OOP_Msg)m))
798 ULONG i;
800 for (i = 0; i < data->planebuf_size; i ++)
802 data->planes[i] = NULL;
806 return TRUE;
809 /****************************************************************************************/