grub2: bring back build of aros-side grub2 tools
[AROS.git] / rom / hidds / graphics / planarbm.c
blob9adcee520a843b7e7e9ebf526758e6bdf2339e1c
1 /*
2 Copyright © 1995-2011, 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 NAME
34 --background_planarbm--
36 LOCATION
37 hidd.graphics.bitmap.planarbm
39 NOTES
40 This is a class representing a planar Amiga(tm) bitmap in AROS graphics subsystem.
42 When you create an object of this class, an associated planar bitmap will be created.
43 However, it's possible to use this class with pre-existing bitmaps, making them
44 available to the graphics HIDD subsystem.
46 *****************************************************************************************/
48 /*****************************************************************************************
50 NAME
51 aoHidd_PlanarBM_AllocPlanes
53 SYNOPSIS
54 [I..], BOOL
56 LOCATION
57 hidd.graphics.bitmap.planarbm
59 FUNCTION
60 Set this attribute to FALSE if you want to create an empty bitmap object containing
61 no bitmap data. Useful if you want to create an empty object to be associated with
62 existing bitmap later.
64 NOTES
65 This attribute is obsolete. It's equal to supplying aoHidd_PlanarBM_BitMap attribute
66 with a NULL value.
68 EXAMPLE
70 BUGS
72 SEE ALSO
73 aoHidd_PlanarBM_BitMap
75 INTERNALS
77 *****************************************************************************************/
79 /*****************************************************************************************
81 NAME
82 aoHidd_PlanarBM_BitMap
84 SYNOPSIS
85 [ISG], struct BitMap *
87 LOCATION
88 hidd.graphics.bitmap.planarbm
90 FUNCTION
91 Allows to specify or retrieve a raw planar bitmap structure associated with the object.
92 Useful for direct access to the bitmap within subclasses, as well as for associating
93 an object with already existing BitMap structure.
95 It is valid to pass this attribute with a NULL value. In this case the object becomes
96 empty and contains no actual bitmap.
98 NOTES
99 If the object was created with own bitmap data (with no aoHidd_PlanarBM_BitMap specified
100 during creation), this data will be deallocated when you set this attribute.
102 It's up to you to deallocate own bitmaps, set using this attribute. Even if the object
103 is disposed, it won't deallocate user-supplied bitmap.
105 EXAMPLE
107 BUGS
109 SEE ALSO
111 INTERNALS
113 *****************************************************************************************/
115 OOP_Object *PBM__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
117 struct Library *UtilityBase = CSD(cl)->cs_UtilityBase;
118 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
119 IPTR height, bytesperrow;
120 UBYTE depth;
121 IPTR displayable = FALSE;
122 BOOL ok = FALSE;
123 struct planarbm_data *data;
124 struct TagItem *tag;
126 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, &msg->mID);
127 if (NULL == o)
128 return NULL;
130 data = OOP_INST_DATA(cl, o);
132 /* Check if we want to use existing bitmap */
134 tag = FindTagItem(aHidd_PlanarBM_BitMap, msg->attrList);
135 if (tag)
137 /* It's not our own bitmap */
138 data->planes_alloced = FALSE;
139 /* Remember the bitmap. It can be NULL here. */
140 data->bitmap = (struct BitMap *)tag->ti_Data;
142 /* That's all, we are attached to an existing BitMap */
143 return o;
145 else
147 /* Check obsolete attribute now */
148 data->planes_alloced = GetTagData(aHidd_PlanarBM_AllocPlanes, TRUE, msg->attrList);
150 if (!data->planes_alloced)
151 return o; /* Late initialization */
154 /* By default we create 1-plane bitmap */
155 depth = GetTagData(aHidd_BitMap_Depth, 1, msg->attrList);
157 /* Not late initialization. Get some info on the bitmap */
158 OOP_GetAttr(o, aHidd_BitMap_Height, &height);
159 OOP_GetAttr(o, aHidd_BitMap_BytesPerRow, &bytesperrow);
160 OOP_GetAttr(o, aHidd_BitMap_Displayable, &displayable);
162 data->bitmap = AllocMem(sizeof(struct BitMap), MEMF_CLEAR);
163 if (data->bitmap)
165 UBYTE i;
167 ok = TRUE;
169 /* We cache some info */
170 data->bitmap->Rows = height;
171 data->bitmap->BytesPerRow = bytesperrow;
172 data->bitmap->Depth = depth;
173 data->bitmap->Flags = BMF_STANDARD|BMF_MINPLANES; /* CHECKME */
174 if (displayable)
175 data->bitmap->Flags |= BMF_DISPLAYABLE;
177 /* Allocate memory for all the planes. Use chip memory. */
178 for (i = 0; i < depth; i++)
180 data->bitmap->Planes[i] = AllocMem(height * bytesperrow, MEMF_CHIP | MEMF_CLEAR);
182 if (NULL == data->bitmap->Planes[i])
184 ok = FALSE;
185 break;
190 if (!ok)
192 OOP_MethodID dispose_mid;
194 dispose_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
195 OOP_CoerceMethod(cl, o, (OOP_Msg)&dispose_mid);
197 o = NULL;
200 return o;
203 /****************************************************************************************/
205 static void PBM_FreeBitMap(struct planarbm_data *data)
207 if (data->planes_alloced)
209 if (NULL != data->bitmap)
211 UBYTE i;
213 for (i = 0; i < data->bitmap->Depth; i++)
215 if (data->bitmap->Planes[i])
217 FreeMem(data->bitmap->Planes[i], data->bitmap->Rows * data->bitmap->BytesPerRow);
220 FreeMem(data->bitmap, sizeof(struct BitMap));
225 VOID PBM__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
227 struct planarbm_data *data = OOP_INST_DATA(cl, o);
229 PBM_FreeBitMap(data);
230 OOP_DoSuperMethod(cl, o, msg);
233 /****************************************************************************************/
235 VOID PBM__Root__Get(OOP_Class *cl, OOP_Object *obj, struct pRoot_Get *msg)
237 struct planarbm_data *data = OOP_INST_DATA(cl, obj);
239 if (msg->attrID == aHidd_BitMap_Depth)
241 /* Planar bitmaps may have a variable depth. */
242 *msg->storage = data->bitmap ? data->bitmap->Depth : 0;
243 return;
245 else if (msg->attrID == aHidd_PlanarBM_BitMap)
247 *msg->storage = (IPTR)data->bitmap;
248 return;
251 OOP_DoSuperMethod(cl, obj, &msg->mID);
254 /****************************************************************************************/
256 static BOOL PBM_SetBitMap(OOP_Class *cl, OOP_Object *o, struct BitMap *bm)
258 struct TagItem pftags[] =
260 { aHidd_PixFmt_Depth , 0UL }, /* 0 */
261 { aHidd_PixFmt_BitsPerPixel , 0UL }, /* 1 */
262 { aHidd_PixFmt_BytesPerPixel, 1UL }, /* 2 */
263 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_Palette }, /* 3 */
264 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Planar }, /* 4 */
265 { aHidd_PixFmt_CLUTShift , 0UL }, /* 5 */
266 { aHidd_PixFmt_CLUTMask , 0x000000FF }, /* 6 */
267 { aHidd_PixFmt_RedMask , 0x00FF0000 }, /* 7 */
268 { aHidd_PixFmt_GreenMask , 0x0000FF00 }, /* 8 */
269 { aHidd_PixFmt_BlueMask , 0x000000FF }, /* 9 */
270 { aHidd_PixFmt_StdPixFmt , vHidd_StdPixFmt_Plane },
271 { TAG_DONE , 0UL }
273 struct TagItem bmtags[] =
275 { aHidd_BitMap_Width , 0 }, /* 0 */
276 { aHidd_BitMap_Height , 0 }, /* 1 */
277 { aHidd_BitMap_BytesPerRow , 0 }, /* 2 */
278 { TAG_DONE , 0 }
280 struct planarbm_data *data = OOP_INST_DATA(cl, o);
281 OOP_Object *pf;
283 /* First we attempt to register a pixelformat */
284 pftags[0].ti_Data = bm->Depth; /* PixFmt_Depth */
285 pftags[1].ti_Data = bm->Depth; /* PixFmt_BitsPerPixel */
287 pf = GFX__Hidd_Gfx__RegisterPixFmt(CSD(cl)->gfxhiddclass, pftags);
289 if (!pf)
291 /* Fail is pixelformat registration failed */
292 return FALSE;
295 /* Free old bitmap, if it was ours. */
296 PBM_FreeBitMap(data);
298 /* Set the new bitmap. It's not ours. */
299 data->bitmap = bm;
300 data->planes_alloced = FALSE;
302 /* Call private bitmap method to update superclass */
303 bmtags[0].ti_Data = bm->BytesPerRow * 8;
304 bmtags[1].ti_Data = bm->Rows;
305 bmtags[2].ti_Data = bm->BytesPerRow;
307 BM__Hidd_BitMap__SetBitMapTags(CSD(cl)->bitmapclass, o, bmtags);
308 BM__Hidd_BitMap__SetPixFmt(CSD(cl)->bitmapclass, o, pf);
310 return TRUE;
313 VOID PBM__Root__Set(OOP_Class *cl, OOP_Object *obj, struct pRoot_Set *msg)
315 struct Library *UtilityBase = CSD(cl)->cs_UtilityBase;
316 struct TagItem *tag = FindTagItem(aHidd_PlanarBM_BitMap, msg->attrList);
318 if (tag)
321 * TODO: We can't check for failure here. However, since we already
322 * have Depth attribute for the bitmap, may be we shouldn't register
323 * 8 pixelformats? In this case we are unable to fail.
325 PBM_SetBitMap(cl, obj, (struct BitMap *)tag->ti_Data);
328 OOP_DoSuperMethod(cl, obj, &msg->mID);
331 /****************************************************************************************/
333 VOID PBM__Hidd_BitMap__PutPixel(OOP_Class *cl, OOP_Object *o,
334 struct pHidd_BitMap_PutPixel *msg)
336 UBYTE **plane;
337 struct planarbm_data *data;
338 ULONG offset;
339 UWORD mask;
340 UBYTE pixel, notpixel;
341 UBYTE i;
343 data = OOP_INST_DATA(cl, o);
345 if (!data->bitmap)
346 return;
348 /* bitmap in plane-mode */
349 plane = data->bitmap->Planes;
350 offset = msg->x / 8 + msg->y * data->bitmap->BytesPerRow;
351 pixel = 128 >> (msg->x % 8);
352 notpixel = ~pixel;
353 mask = 1;
355 for (i = 0; i < data->bitmap->Depth; i++, mask <<=1, plane ++)
357 if ((*plane != NULL) && (*plane != (UBYTE *)-1))
359 if(msg->pixel & mask)
361 *(*plane + offset) = *(*plane + offset) | pixel;
363 else
365 *(*plane + offset) = *(*plane + offset) & notpixel;
371 /****************************************************************************************/
373 ULONG PBM__Hidd_BitMap__GetPixel(OOP_Class *cl, OOP_Object *o,
374 struct pHidd_BitMap_GetPixel *msg)
376 struct planarbm_data *data;
377 UBYTE **plane;
378 ULONG offset;
379 UWORD i;
380 UBYTE pixel;
381 ULONG retval;
383 data = OOP_INST_DATA(cl, o);
385 if (!data->bitmap)
386 return 0;
388 plane = data->bitmap->Planes;
389 offset = msg->x / 8 + msg->y * data->bitmap->BytesPerRow;
390 pixel = 128 >> (msg->x % 8);
391 retval = 0;
393 for (i = 0; i < data->bitmap->Depth; i++, plane ++)
395 if (*plane == (UBYTE *)-1)
397 retval = retval | (1 << i);
399 else if (*plane != NULL)
401 if(*(*plane + offset) & pixel)
403 retval = retval | (1 << i);
408 return retval;
411 /****************************************************************************************/
414 * In fact these two routines are implementations of C2P algorighm. The first one takes chunky
415 * array of 8-bit values, the second one - 32-bit one.
417 static void PBM_PutImage_Native(UBYTE *src, ULONG modulo, struct BitMap *data, UWORD startx, UWORD starty, UWORD width, UWORD height)
419 ULONG planeoffset = starty * data->BytesPerRow + startx / 8;
420 UWORD x, y, d;
422 startx &= 7;
424 for (y = 0; y < height; y++)
426 UBYTE **plane = data->Planes;
428 for (d = 0; d < data->Depth; d++)
430 UWORD dmask = 1L << d;
431 UWORD pmask = 0x80 >> startx;
432 UBYTE *pl = *plane;
434 if (pl == (UBYTE *)-1) continue;
435 if (pl == NULL) continue;
437 pl += planeoffset;
439 for (x = 0; x < width; x++)
441 if (src[x] & dmask)
443 *pl |= pmask;
445 else
447 *pl &= ~pmask;
450 if (pmask == 0x1)
452 pmask = 0x80;
453 pl++;
455 else
457 pmask >>= 1;
459 } /* for (x = 0; x < msg->width; x++) */
461 plane++;
463 } /* for (d = 0; d < data->depth; d++) */
465 src += modulo;
466 planeoffset += data->BytesPerRow;
467 } /* for (y = 0; y < msg->height; y++) */
470 static void PBM_PutImage_Native32(HIDDT_Pixel *src, ULONG modulo, struct BitMap *data, UWORD startx, UWORD starty, UWORD width, UWORD height)
472 ULONG planeoffset = starty * data->BytesPerRow + startx / 8;
473 UWORD x, y, d;
475 startx &= 7;
477 for (y = 0; y < height; y++)
479 UBYTE **plane = data->Planes;
481 for (d = 0; d < data->Depth; d++)
483 UWORD dmask = 1L << d;
484 UWORD pmask = 0x80 >> startx;
485 UBYTE *pl = *plane;
487 if (pl == (UBYTE *)-1) continue;
488 if (pl == NULL) continue;
490 pl += planeoffset;
492 for (x = 0; x < width; x++)
494 if (src[x] & dmask)
496 *pl |= pmask;
498 else
500 *pl &= ~pmask;
503 if (pmask == 0x1)
505 pmask = 0x80;
506 pl++;
508 else
510 pmask >>= 1;
512 } /* for (x = 0; x < msg->width; x++) */
514 plane++;
516 } /* for (d = 0; d < data->depth; d++) */
518 src = ((APTR)src + modulo);
519 planeoffset += data->BytesPerRow;
520 } /* for (y = 0; y < msg->height; y++) */
523 VOID PBM__Hidd_BitMap__PutImage(OOP_Class *cl, OOP_Object *o,
524 struct pHidd_BitMap_PutImage *msg)
526 struct planarbm_data *data = OOP_INST_DATA(cl, o);
528 if (!data->bitmap)
529 return;
531 if ((msg->pixFmt != vHidd_StdPixFmt_Native) &&
532 (msg->pixFmt != vHidd_StdPixFmt_Native32))
534 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
535 return;
538 switch(msg->pixFmt)
540 case vHidd_StdPixFmt_Native:
541 PBM_PutImage_Native(msg->pixels, msg->modulo, data->bitmap, msg->x, msg->y, msg->width, msg->height);
542 break;
544 case vHidd_StdPixFmt_Native32:
545 PBM_PutImage_Native32((HIDDT_Pixel *)msg->pixels, msg->modulo, data->bitmap, msg->x, msg->y, msg->width, msg->height);
546 break;
551 /****************************************************************************************/
553 VOID PBM__Hidd_BitMap__PutImageLUT(OOP_Class *cl, OOP_Object *o,
554 struct pHidd_BitMap_PutImageLUT *msg)
556 struct planarbm_data *data = OOP_INST_DATA(cl, o);
558 if (!data->bitmap)
559 return;
561 /* This is the same as PutImage() with vHidd_StdPixFmt_Native format */
562 PBM_PutImage_Native(msg->pixels, msg->modulo, data->bitmap, msg->x, msg->y, msg->width, msg->height);
565 /****************************************************************************************/
567 VOID PBM__Hidd_BitMap__GetImageLUT(OOP_Class *cl, OOP_Object *o,
568 struct pHidd_BitMap_GetImageLUT *msg)
570 WORD x, y, d;
571 UBYTE *pixarray = (UBYTE *)msg->pixels;
572 UBYTE **plane;
573 ULONG planeoffset;
574 struct planarbm_data *data;
575 UBYTE prefill;
577 data = OOP_INST_DATA(cl, o);
579 if (!data->bitmap)
580 return;
582 planeoffset = msg->y * data->bitmap->BytesPerRow + msg->x / 8;
584 prefill = 0;
585 for (d = 0; d < data->bitmap->Depth; d++)
587 if (data->bitmap->Planes[d] == (UBYTE *)-1)
589 prefill |= (1L << d);
593 for (y = 0; y < msg->height; y++)
595 UBYTE *dest = pixarray;
597 plane = data->bitmap->Planes;
598 for(x = 0; x < msg->width; x++)
600 dest[x] = prefill;
603 for (d = 0; d < data->bitmap->Depth; d++)
605 UWORD dmask = 1L << d;
606 UWORD pmask = 0x80 >> (msg->x & 7);
607 UBYTE *pl = *plane;
609 if (pl == (UBYTE *)-1) continue;
610 if (pl == NULL) continue;
612 pl += planeoffset;
614 for (x = 0; x < msg->width; x++)
616 if (*pl & pmask)
618 dest[x] |= dmask;
620 else
622 dest[x] &= ~dmask;
625 if (pmask == 0x1)
627 pmask = 0x80;
628 pl++;
630 else
632 pmask >>= 1;
635 } /* for(x = 0; x < msg->width; x++) */
637 plane++;
639 } /* for(d = 0; d < data->depth; d++) */
641 pixarray += msg->modulo;
642 planeoffset += data->bitmap->BytesPerRow;
644 } /* for(y = 0; y < msg->height; y++) */
648 /****************************************************************************************/
650 BOOL PBM__Hidd_PlanarBM__SetBitMap(OOP_Class *cl, OOP_Object *o,
651 struct pHidd_PlanarBM_SetBitMap *msg)
653 return PBM_SetBitMap(cl, o, msg->bitMap);
656 /****************************************************************************************/
658 BOOL PBM__Hidd_PlanarBM__GetBitMap(OOP_Class *cl, OOP_Object *o,
659 struct pHidd_PlanarBM_GetBitMap *msg)
661 struct planarbm_data *data = OOP_INST_DATA(cl, o);
663 if (!data->bitmap)
664 return FALSE;
667 * Totally obsolete and deprecated.
668 * Just get aoHidd_PlanarBM_BitMap value instead.
670 CopyMem(data->bitmap, msg->bitMap, sizeof(struct BitMap));
671 return TRUE;