added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / workbench / hidds / graphics / planarbm.c
blob0d717bf9cb768fb08a35069c15f22292828cd020
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 "graphics_intern.h"
26 #include <string.h>
28 #define DEBUG 0
29 #include <aros/debug.h>
31 /****************************************************************************************/
33 OOP_Object *PBM__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
35 IPTR width, height, depth;
37 BOOL ok = TRUE;
39 #if 0
40 /* Set the bitmaps' pixelformat */
41 struct TagItem pf_tags[] =
43 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_Palette }, /* 0 */
44 { aHidd_PixFmt_Depth , 0 }, /* 1 */
45 { aHidd_PixFmt_BytesPerPixel, 0 }, /* 2 */
46 { aHidd_PixFmt_BitsPerPixel , 0 }, /* 3 */
47 { aHidd_PixFmt_StdPixFmt , 0 }, /* 4 */
48 { aHidd_PixFmt_CLUTShift , 0 }, /* 5 */
49 { aHidd_PixFmt_CLUTMask , 0x000000FF }, /* 6 */
50 { aHidd_PixFmt_RedMask , 0x00FF0000 }, /* 7 */
51 { aHidd_PixFmt_GreenMask , 0x0000FF00 }, /* 8 */
52 { aHidd_PixFmt_BlueMask , 0x000000FF }, /* 9 */
53 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Planar },
54 { TAG_DONE , 0UL }
56 #endif
58 struct planarbm_data *data;
59 OOP_Object *pf;
60 APTR p_pf = &pf;
62 o =(OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
63 if (NULL == o)
64 return NULL;
66 data = OOP_INST_DATA(cl, o);
67 memset(data, 0, sizeof (*data));
70 /* Get some data about the dimensions of the bitmap */
72 data->planes_alloced = (BOOL)GetTagData(aHidd_PlanarBM_AllocPlanes, TRUE, msg->attrList);
74 #warning Fix this hack
75 /* Because this class is used to emulate Amiga bitmaps, we
76 have to see if it should have late initalisation
78 if (!data->planes_alloced)
79 return o; /* Late initialization */
82 /* Not late initalization. Get some info on the bitmap */
83 OOP_GetAttr(o, aHidd_BitMap_Width, &width);
84 OOP_GetAttr(o, aHidd_BitMap_Height, &height);
85 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (IPTR *)p_pf);
86 OOP_GetAttr(pf, aHidd_PixFmt_Depth, (IPTR *)&depth);
88 /* We cache some info */
89 data->bytesperrow = ((width + 15) & ~15) / 8;
90 data->rows = height;
91 data->depth = depth;
93 if (ok)
95 /* Allocate memory for plane array */
96 data->planes = AllocVec(sizeof (UBYTE *) * depth, MEMF_ANY|MEMF_CLEAR);
97 if (NULL == data->planes)
98 ok = FALSE;
99 else
101 UBYTE i;
103 data->planebuf_size = depth;
105 /* Allocate all the planes */
106 for ( i = 0; i < depth && ok; i ++)
108 data->planes[i] = AllocVec(height * data->bytesperrow, MEMF_ANY|MEMF_CLEAR);
109 if (NULL == data->planes[i])
110 ok = FALSE;
115 if (!ok)
117 OOP_MethodID dispose_mid;
119 dispose_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
120 OOP_CoerceMethod(cl, o, (OOP_Msg)&dispose_mid);
122 o = NULL;
125 return o;
128 /****************************************************************************************/
130 VOID PBM__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
132 struct planarbm_data *data;
133 UBYTE i;
135 data = OOP_INST_DATA(cl, o);
137 if (data->planes_alloced)
139 if (NULL != data->planes)
141 for (i = 0; i < data->depth; i ++)
143 if (NULL != data->planes[i])
145 FreeVec(data->planes[i]);
148 FreeVec(data->planes);
152 OOP_DoSuperMethod(cl, o, msg);
154 return;
157 /****************************************************************************************/
159 VOID PBM__Hidd_BitMap__PutPixel(OOP_Class *cl, OOP_Object *o,
160 struct pHidd_BitMap_PutPixel *msg)
162 UBYTE **plane;
163 struct planarbm_data *data;
164 ULONG offset;
165 ULONG mask;
166 UBYTE pixel, notpixel;
167 UBYTE i;
169 data = OOP_INST_DATA(cl, o);
171 /* bitmap in plane-mode */
172 plane = data->planes;
173 offset = msg->x / 8 + msg->y * data->bytesperrow;
174 pixel = 128 >> (msg->x % 8);
175 notpixel = ~pixel;
176 mask = 1;
178 for(i = 0; i < data->depth; i++, mask <<=1, plane ++)
180 if ((*plane != NULL) && (*plane != (UBYTE *)-1))
182 if(msg->pixel & mask)
184 *(*plane + offset) = *(*plane + offset) | pixel;
186 else
188 *(*plane + offset) = *(*plane + offset) & notpixel;
194 /****************************************************************************************/
196 ULONG PBM__Hidd_BitMap__GetPixel(OOP_Class *cl, OOP_Object *o,
197 struct pHidd_BitMap_GetPixel *msg)
199 struct planarbm_data *data;
200 UBYTE **plane;
201 ULONG offset;
202 ULONG i;
203 UBYTE pixel;
204 ULONG retval;
206 data = OOP_INST_DATA(cl, o);
208 plane = data->planes;
209 offset = msg->x / 8 + msg->y * data->bytesperrow;
210 pixel = 128 >> (msg->x % 8);
211 retval = 0;
213 for(i = 0; i < data->depth; i++, plane ++)
216 if (*plane == (UBYTE *)-1)
218 retval = retval | (1 << i);
220 else if (*plane != NULL)
222 if(*(*plane + offset) & pixel)
224 retval = retval | (1 << i);
229 return retval;
232 /****************************************************************************************/
234 VOID PBM__Hidd_BitMap__PutImage(OOP_Class *cl, OOP_Object *o,
235 struct pHidd_BitMap_PutImage *msg)
237 WORD x, y, d;
238 UBYTE *pixarray = (UBYTE *)msg->pixels;
239 UBYTE **plane;
240 ULONG planeoffset;
241 struct planarbm_data *data;
243 if ((msg->pixFmt != vHidd_StdPixFmt_Native) &&
244 (msg->pixFmt != vHidd_StdPixFmt_Native32))
246 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
247 return;
250 data = OOP_INST_DATA(cl, o);
252 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
254 for(y = 0; y < msg->height; y++)
256 switch(msg->pixFmt)
258 case vHidd_StdPixFmt_Native:
260 UBYTE *src = pixarray;
262 plane = data->planes;
264 for(d = 0; d < data->depth; d++)
266 ULONG dmask = 1L << d;
267 ULONG pmask = 0x80 >> (msg->x & 7);
268 UBYTE *pl = *plane;
270 if (pl == (UBYTE *)-1) continue;
271 if (pl == NULL) continue;
273 pl += planeoffset;
275 for(x = 0; x < msg->width; x++)
277 if (src[x] & dmask)
279 *pl |= pmask;
281 else
283 *pl &= ~pmask;
286 if (pmask == 0x1)
288 pmask = 0x80;
289 pl++;
291 else
293 pmask >>= 1;
296 } /* for(x = 0; x < msg->width; x++) */
298 plane++;
300 } /* for(d = 0; d < data->depth; d++) */
302 pixarray += msg->modulo;
303 planeoffset += data->bytesperrow;
305 break;
307 case vHidd_StdPixFmt_Native32:
309 HIDDT_Pixel *src = (HIDDT_Pixel *)pixarray;
311 plane = data->planes;
313 for(d = 0; d < data->depth; d++)
315 ULONG dmask = 1L << d;
316 ULONG pmask = 0x80 >> (msg->x & 7);
317 UBYTE *pl = *plane;
319 if (pl == (UBYTE *)-1) continue;
320 if (pl == NULL) continue;
322 pl += planeoffset;
324 for(x = 0; x < msg->width; x++)
326 if (src[x] & dmask)
328 *pl |= pmask;
330 else
332 *pl &= ~pmask;
335 if (pmask == 0x1)
337 pmask = 0x80;
338 pl++;
340 else
342 pmask >>= 1;
345 } /* for(x = 0; x < msg->width; x++) */
347 plane++;
349 } /* for(d = 0; d < data->depth; d++) */
351 pixarray += msg->modulo;
352 planeoffset += data->bytesperrow;
355 break;
357 } /* switch(msg->pixFmt) */
359 } /* for(y = 0; y < msg->height; y++) */
362 /****************************************************************************************/
364 VOID PBM__Hidd_BitMap__PutImageLUT(OOP_Class *cl, OOP_Object *o,
365 struct pHidd_BitMap_PutImageLUT *msg)
367 WORD x, y, d;
368 UBYTE *pixarray = (UBYTE *)msg->pixels;
369 UBYTE **plane;
370 ULONG planeoffset;
371 struct planarbm_data *data;
373 data = OOP_INST_DATA(cl, o);
375 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
377 for(y = 0; y < msg->height; y++)
379 UBYTE *src = pixarray;
381 plane = data->planes;
383 for(d = 0; d < data->depth; d++)
385 ULONG dmask = 1L << d;
386 ULONG pmask = 0x80 >> (msg->x & 7);
387 UBYTE *pl = *plane;
389 if (pl == (UBYTE *)-1) continue;
390 if (pl == NULL) continue;
392 pl += planeoffset;
394 for(x = 0; x < msg->width; x++)
396 if (src[x] & dmask)
398 *pl |= pmask;
400 else
402 *pl &= ~pmask;
405 if (pmask == 0x1)
407 pmask = 0x80;
408 pl++;
410 else
412 pmask >>= 1;
415 } /* for(x = 0; x < msg->width; x++) */
417 plane++;
419 } /* for(d = 0; d < data->depth; d++) */
421 pixarray += msg->modulo;
422 planeoffset += data->bytesperrow;
424 } /* for(y = 0; y < msg->height; y++) */
427 /****************************************************************************************/
429 VOID PBM__Hidd_BitMap__GetImageLUT(OOP_Class *cl, OOP_Object *o,
430 struct pHidd_BitMap_GetImageLUT *msg)
432 WORD x, y, d;
433 UBYTE *pixarray = (UBYTE *)msg->pixels;
434 UBYTE **plane;
435 ULONG planeoffset;
436 struct planarbm_data *data;
437 UBYTE prefill;
439 data = OOP_INST_DATA(cl, o);
441 planeoffset = msg->y * data->bytesperrow + msg->x / 8;
443 prefill = 0;
444 for(d = 0; d < data->depth; d++)
446 if (data->planes[d] == (UBYTE *)-1)
448 prefill |= (1L << d);
452 for(y = 0; y < msg->height; y++)
454 UBYTE *dest = pixarray;
456 plane = data->planes;
458 for(x = 0; x < msg->width; x++)
460 dest[x] = prefill;
463 for(d = 0; d < data->depth; d++)
465 ULONG dmask = 1L << d;
466 ULONG pmask = 0x80 >> (msg->x & 7);
467 UBYTE *pl = *plane;
469 if (pl == (UBYTE *)-1) continue;
470 if (pl == NULL) continue;
472 pl += planeoffset;
474 for(x = 0; x < msg->width; x++)
476 if (*pl & pmask)
478 dest[x] |= dmask;
480 else
482 dest[x] &= ~dmask;
485 if (pmask == 0x1)
487 pmask = 0x80;
488 pl++;
490 else
492 pmask >>= 1;
495 } /* for(x = 0; x < msg->width; x++) */
497 plane++;
499 } /* for(d = 0; d < data->depth; d++) */
501 pixarray += msg->modulo;
502 planeoffset += data->bytesperrow;
504 } /* for(y = 0; y < msg->height; y++) */
508 /****************************************************************************************/
510 VOID PBM__Hidd_BitMap__BlitColorExpansion(OOP_Class *cl, OOP_Object *o,
511 struct pHidd_BitMap_BlitColorExpansion *msg)
513 WORD x, y, d;
514 UBYTE **plane;
515 UBYTE *mask;
516 ULONG planeoffset /*, maskoffset*/;
517 ULONG cemd, fg, bg;
518 BOOL opaque;
519 OOP_Object *gc = msg->gc;
520 struct planarbm_data *data, *maskdata;
522 data = OOP_INST_DATA(cl, o);
524 cemd = GC_COLEXP(gc);
525 fg = GC_FG(gc);
526 bg = GC_BG(gc);
528 opaque = (cemd & vHidd_GC_ColExp_Opaque) ? TRUE : FALSE;
530 planeoffset = msg->destY * data->bytesperrow + msg->destX / 8;
532 if (OOP_OCLASS(msg->srcBitMap) == cl)
534 /* srcBitMap is a planarbm class object */
536 maskdata = OOP_INST_DATA(cl, msg->srcBitMap);
537 mask = maskdata->planes[0];
538 mask += msg->srcY * maskdata->bytesperrow + msg->srcX / 8;
540 for(y = 0; y < msg->height; y++)
542 plane = data->planes;
544 for(d = 0; d < data->depth; d++)
546 ULONG dmask = 1L << d;
547 ULONG pmask = 0x80 >> (msg->destX & 7);
548 ULONG mmask = 0x80 >> (msg->srcX & 7);
549 BOOL fgset = (fg & dmask) ? TRUE : FALSE;
550 BOOL bgset = (bg & dmask) ? TRUE : FALSE;
552 UBYTE *pl = *plane;
553 UBYTE *msk = mask;
555 if (pl == (UBYTE *)-1) continue;
556 if (pl == NULL) continue;
558 pl += planeoffset;
560 for(x = 0; x < msg->width; x++)
562 if (*msk & mmask)
564 if (fgset)
565 *pl |= pmask;
566 else
567 *pl &= ~pmask;
569 else if (opaque)
571 if (bgset)
572 *pl |= pmask;
573 else
574 *pl &= ~pmask;
577 if (pmask == 0x1)
579 pmask = 0x80;
580 pl++;
582 else
584 pmask >>= 1;
587 if (mmask == 0x1)
589 mmask = 0x80;
590 msk++;
592 else
594 mmask >>= 1;
597 } /* for(x = 0; x < msg->width; x++) */
599 plane++;
601 } /* for(d = 0; d < data->depth; d++) */
603 mask += maskdata->bytesperrow;
604 planeoffset += data->bytesperrow;
606 } /* for(y = 0; y < msg->height; y++) */
608 } /* if (OOP_OCLASS(msg->srcBitMap) == cl) */
609 else
611 HIDDT_Pixel *maskline;
613 maskline = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
614 if (!maskline)
616 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
617 return;
620 for(y = 0; y < msg->height; y++)
622 plane = data->planes;
624 HIDD_BM_GetImage(msg->srcBitMap,
625 (UBYTE *)maskline,
627 msg->srcX,
628 msg->srcY + y,
629 msg->width,
631 vHidd_StdPixFmt_Native32);
633 for(d = 0; d < data->depth; d++)
635 ULONG dmask = 1L << d;
636 ULONG pmask = 0x80 >> (msg->destX & 7);
637 BOOL fgset = (fg & dmask) ? TRUE : FALSE;
638 BOOL bgset = (bg & dmask) ? TRUE : FALSE;
640 UBYTE *pl = *plane;
642 if (pl == (UBYTE *)-1) continue;
643 if (pl == NULL) continue;
645 pl += planeoffset;
647 for(x = 0; x < msg->width; x++)
649 if (maskline[x])
651 if (fgset)
652 *pl |= pmask;
653 else
654 *pl &= ~pmask;
656 else if (opaque)
658 if (bgset)
659 *pl |= pmask;
660 else
661 *pl &= ~pmask;
664 if (pmask == 0x1)
666 pmask = 0x80;
667 pl++;
669 else
671 pmask >>= 1;
674 } /* for(x = 0; x < msg->width; x++) */
676 plane++;
678 } /* for(d = 0; d < data->depth; d++) */
680 planeoffset += data->bytesperrow;
682 } /* for(y = 0; y < msg->height; y++) */
684 FreeVec(maskline);
686 } /* if (OOP_OCLASS(msg->srcBitMap) == cl) else ... */
690 /****************************************************************************************/
692 BOOL PBM__Hidd_PlanarBM__SetBitMap(OOP_Class *cl, OOP_Object *o,
693 struct pHidd_PlanarBM_SetBitMap *msg)
695 struct planarbm_data *data;
696 struct BitMap *bm;
698 struct TagItem pftags[] =
700 { aHidd_PixFmt_Depth , 0UL }, /* 0 */
701 { aHidd_PixFmt_BitsPerPixel , 0UL }, /* 1 */
702 { aHidd_PixFmt_BytesPerPixel, 1UL }, /* 2 */
703 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_Palette }, /* 3 */
704 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Planar }, /* 4 */
705 { aHidd_PixFmt_CLUTShift , 0UL }, /* 5 */
706 { aHidd_PixFmt_CLUTMask , 0x000000FF }, /* 6 */
707 { aHidd_PixFmt_RedMask , 0x00FF0000 }, /* 7 */
708 { aHidd_PixFmt_GreenMask , 0x0000FF00 }, /* 8 */
709 { aHidd_PixFmt_BlueMask , 0x000000FF }, /* 9 */
710 { TAG_DONE , 0UL } /* 7 */
712 struct TagItem bmtags[] =
714 { aHidd_BitMap_Width , 0UL },
715 { aHidd_BitMap_Height , 0UL },
716 { aHidd_BitMap_PixFmtTags , 0UL },
717 { TAG_DONE , 0UL }
720 ULONG i;
722 data = OOP_INST_DATA(cl, o);
723 bm = msg->bitMap;
725 if (data->planes_alloced)
727 D(bug(" !!!!! PlanarBM: Trying to set bitmap in one that allready has planes allocated\n"));
728 return FALSE;
731 /* Check if plane array allready allocated */
732 if (NULL != data->planes)
734 if (bm->Depth > data->planebuf_size)
736 FreeVec(data->planes);
737 data->planes = NULL;
741 if (NULL == data->planes)
743 data->planes = AllocVec(sizeof (UBYTE *) * bm->Depth, MEMF_CLEAR);
745 if (NULL == data->planes)
746 return FALSE;
748 data->planebuf_size = bm->Depth;
752 /* Update the planes */
753 for (i = 0; i < data->planebuf_size; i ++)
755 if (i < bm->Depth)
756 data->planes[i] = bm->Planes[i];
757 else
758 data->planes[i] = NULL;
761 data->depth = bm->Depth;
762 data->bytesperrow = bm->BytesPerRow;
763 data->rows = bm->Rows;
765 pftags[0].ti_Data = bm->Depth; /* PixFmt_Depth */
766 pftags[1].ti_Data = bm->Depth; /* PixFmt_BitsPerPixel */
768 bmtags[0].ti_Data = bm->BytesPerRow * 8;
769 bmtags[1].ti_Data = bm->Rows;
770 bmtags[2].ti_Data = (IPTR)pftags;
772 /* Call private bitmap method to update superclass */
773 if (!HIDD_BitMap_SetBitMapTags(o, bmtags))
775 ULONG i;
777 for (i = 0; i < data->planebuf_size; i ++)
779 data->planes[i] = NULL;
783 return TRUE;
786 /****************************************************************************************/