Fixed missing fprintf argument.
[AROS.git] / rom / graphics / gfxfuncsupport.c
blobbdbd4ca5537d5040d0b6de9fbe665ce041d3ee7b
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /* !!!! ONLY USE THE BELOW MACROS IF YOU ARE 100% SURE
7 THAT IT IS A HIDD BITMAP AND NOT ONE THE USER
8 HAS CREATED BY HAND !!!. You can use IS_HIDD_BM(bitmap) to test
9 if it is a HIDD bitmap
12 /****************************************************************************************/
14 #include <cybergraphx/cybergraphics.h>
15 #include <graphics/rpattr.h>
16 #include <proto/exec.h>
17 #include <proto/graphics.h>
18 #include <proto/layers.h>
19 #include <proto/cybergraphics.h>
20 #include <proto/oop.h>
21 #include <clib/macros.h>
23 #include "graphics_intern.h"
24 #include "objcache.h"
25 #include "intregions.h"
26 #include "gfxfuncsupport.h"
28 #define DEBUG 0
29 #include <aros/debug.h>
31 /****************************************************************************************/
33 OOP_Object *get_planarbm_object(struct BitMap *bitmap, struct GfxBase *GfxBase)
35 OOP_Object *pbm_obj;
37 D(bug("get_planarbm_object()\n"));
38 pbm_obj = obtain_cache_object(SDD(GfxBase)->planarbm_cache, GfxBase);
40 if (NULL != pbm_obj)
43 D(bug("Got cache object %p, class=%s, domethod=%p, instoffset=%d\n"
44 , pbm_obj
45 , OOP_OCLASS(pbm_obj)->ClassNode.ln_Name
46 , OOP_OCLASS(pbm_obj)->DoMethod
47 , OOP_OCLASS(pbm_obj)->InstOffset
48 ));
50 if (!HIDD_PlanarBM_SetBitMap(pbm_obj, bitmap))
52 D(bug("!!! get_planarbm_object: HIDD_PlanarBM_SetBitMap FAILED !!!\n"));
53 release_cache_object(SDD(GfxBase)->planarbm_cache, pbm_obj, GfxBase);
54 pbm_obj = NULL;
58 else
60 D(bug("!!! get_planarbm_object: obtain_cache_object FAILED !!!\n"));
63 return pbm_obj;
66 /****************************************************************************************/
68 ULONG do_render_func(struct RastPort *rp
69 , Point *src
70 , struct Rectangle *rr
71 , ULONG (*render_func)(APTR, LONG, LONG, OOP_Object *, OOP_Object *, LONG, LONG, LONG, LONG, struct GfxBase *)
72 , APTR funcdata
73 , BOOL get_special_info
74 , struct GfxBase *GfxBase)
77 struct BitMap *bm = rp->BitMap;
78 struct Layer *L = rp->Layer;
79 OOP_Object *gc;
80 struct Rectangle rp_clip_rectangle;
81 BOOL have_rp_cliprectangle;
82 ULONG width, height;
83 LONG srcx, srcy;
84 LONG pixwritten = 0;
86 gc = GetDriverData(rp)->dd_GC;
88 width = rr->MaxX - rr->MinX + 1;
89 height = rr->MaxY - rr->MinY + 1;
91 if (NULL != src)
93 srcx = src->x;
94 srcy = src->y;
95 } else
97 srcx = 0;
98 srcy = 0;
101 if (NULL == L)
103 /* No layer, probably a screen, but may be a user inited bitmap */
104 OOP_Object *bm_obj;
106 bm_obj = OBTAIN_HIDD_BM(bm);
107 if (NULL == bm_obj)
108 return 0;
110 if (get_special_info)
112 RSI(funcdata)->curbm = rp->BitMap;
113 RSI(funcdata)->onscreen = TRUE;
114 RSI(funcdata)->layer_rel_srcx = srcx;
115 RSI(funcdata)->layer_rel_srcy = srcy;
118 pixwritten = render_func(funcdata
119 , srcx, srcy
120 , bm_obj, gc
121 , rr->MinX, rr->MinY
122 , rr->MaxX, rr->MaxY
123 , GfxBase
126 RELEASE_HIDD_BM(bm_obj, bm);
129 else
131 struct ClipRect *CR;
132 WORD xrel;
133 WORD yrel;
134 struct Rectangle torender, intersect;
136 LockLayerRom(L);
138 have_rp_cliprectangle = GetRPClipRectangleForLayer(rp, L, &rp_clip_rectangle, GfxBase);
140 xrel = L->bounds.MinX;
141 yrel = L->bounds.MinY;
143 torender.MinX = rr->MinX + xrel - L->Scroll_X;
144 torender.MinY = rr->MinY + yrel - L->Scroll_Y;
145 torender.MaxX = rr->MaxX + xrel - L->Scroll_X;
146 torender.MaxY = rr->MaxY + yrel - L->Scroll_Y;
149 CR = L->ClipRect;
151 for (;NULL != CR; CR = CR->Next)
153 D(bug("Cliprect (%d, %d, %d, %d), lobs=%p\n",
154 CR->bounds.MinX, CR->bounds.MinY, CR->bounds.MaxX, CR->bounds.MaxY,
155 CR->lobs));
157 /* Does this cliprect intersect with area to rectfill ? */
158 if (_AndRectRect(&CR->bounds, &torender, &intersect))
160 if (!have_rp_cliprectangle || _AndRectRect(&rp_clip_rectangle, &intersect, &intersect))
162 LONG xoffset, yoffset;
164 xoffset = intersect.MinX - torender.MinX;
165 yoffset = intersect.MinY - torender.MinY;
167 if (get_special_info) {
168 RSI(funcdata)->layer_rel_srcx = intersect.MinX - L->bounds.MinX + L->Scroll_X;
169 RSI(funcdata)->layer_rel_srcy = intersect.MinY - L->bounds.MinY + L->Scroll_Y;
172 if (NULL == CR->lobs)
174 if (get_special_info)
176 RSI(funcdata)->curbm = bm;
177 RSI(funcdata)->onscreen = TRUE;
180 pixwritten += render_func(funcdata
181 , srcx + xoffset
182 , srcy + yoffset
183 , HIDD_BM_OBJ(bm)
184 , gc
185 , intersect.MinX
186 , intersect.MinY
187 , intersect.MaxX
188 , intersect.MaxY
189 , GfxBase
194 else
196 /* Render into offscreen cliprect bitmap */
197 if (L->Flags & LAYERSIMPLE)
198 continue;
199 else if (L->Flags & LAYERSUPER)
201 D(bug("do_render_func(): Superbitmap not handled yet\n"));
203 else
206 if (get_special_info)
208 RSI(funcdata)->curbm = CR->BitMap;
209 RSI(funcdata)->onscreen = FALSE;
211 pixwritten += render_func(funcdata
212 , srcx + xoffset, srcy + yoffset
213 , HIDD_BM_OBJ(CR->BitMap)
214 , gc
215 , intersect.MinX - CR->bounds.MinX + ALIGN_OFFSET(CR->bounds.MinX)
216 , intersect.MinY - CR->bounds.MinY
217 , intersect.MaxX - CR->bounds.MinX + ALIGN_OFFSET(CR->bounds.MinX)
218 , intersect.MaxY - CR->bounds.MinY
219 , GfxBase
223 } /* if (CR->lobs == NULL) */
225 } /* if it also intersects with possible rastport clip rectangle */
227 } /* if (cliprect intersects with area to render into) */
229 } /* for (each cliprect in the layer) */
231 UnlockLayerRom(L);
232 } /* if (rp->Layer) */
235 return pixwritten;
239 /****************************************************************************************/
241 ULONG do_pixel_func(struct RastPort *rp
242 , LONG x, LONG y
243 , LONG (*render_func)(APTR, OOP_Object *, OOP_Object *, LONG, LONG, struct GfxBase *)
244 , APTR funcdata
245 , struct GfxBase *GfxBase)
247 struct BitMap *bm = rp->BitMap;
248 struct Layer *L = rp->Layer;
249 OOP_Object *gc;
250 struct Rectangle rp_clip_rectangle;
251 BOOL have_rp_cliprectangle;
252 ULONG retval = -1;
254 gc = GetDriverData(rp)->dd_GC;
256 if (NULL == L)
258 OOP_Object *bm_obj;
259 ULONG width, height;
261 bm_obj = OBTAIN_HIDD_BM(bm);
262 if (NULL == bm_obj)
263 return -1;
265 OOP_GetAttr(bm_obj, aHidd_BitMap_Width, &width);
266 OOP_GetAttr(bm_obj, aHidd_BitMap_Height, &height);
268 /* Check whether we it is inside the rastport */
269 if ( x < 0
270 || x >= width
271 || y < 0
272 || y >= height)
275 RELEASE_HIDD_BM(bm_obj, bm);
276 return -1;
280 /* This is a screen */
281 retval = render_func(funcdata, bm_obj, gc, x, y, GfxBase);
283 RELEASE_HIDD_BM(bm_obj, bm);
286 else
288 struct ClipRect *CR;
289 LONG absx, absy;
291 LockLayerRom( L );
293 have_rp_cliprectangle = GetRPClipRectangleForLayer(rp, L, &rp_clip_rectangle, GfxBase);
295 CR = L->ClipRect;
297 absx = x + L->bounds.MinX - L->Scroll_X;
298 absy = y + L->bounds.MinY - L->Scroll_Y;
300 for (;NULL != CR; CR = CR->Next)
303 if ( absx >= CR->bounds.MinX
304 && absy >= CR->bounds.MinY
305 && absx <= CR->bounds.MaxX
306 && absy <= CR->bounds.MaxY )
309 if (!have_rp_cliprectangle || _IsPointInRect(&rp_clip_rectangle, absx, absy))
311 if (NULL == CR->lobs)
313 retval = render_func(funcdata
314 , HIDD_BM_OBJ(bm), gc
315 , absx, absy
316 , GfxBase
319 else
321 /* This is the tricky one: render into offscreen cliprect bitmap */
322 if (L->Flags & LAYERSIMPLE)
324 /* We cannot do anything */
325 retval = 0;
328 else if (L->Flags & LAYERSUPER)
330 D(bug("driver_WriteRGBPixel(): Superbitmap not handled yet\n"));
332 else
334 retval = render_func(funcdata
335 , HIDD_BM_OBJ(CR->BitMap), gc
336 , absx - CR->bounds.MinX + ALIGN_OFFSET(CR->bounds.MinX)
337 , absy - CR->bounds.MinY
338 , GfxBase
342 } /* If (SMARTREFRESH cliprect) */
345 } /* if (intersecton inside hidden cliprect) */
347 } /* if point is also inside possible rastport clip rectangle */
349 /* The pixel was found and put inside one of the cliprects, just exit */
350 break;
352 } /* if (cliprect intersects with area we want to draw to) */
354 } /* while (cliprects to examine) */
356 UnlockLayerRom( L );
360 return retval;
363 /****************************************************************************************/
365 static ULONG fillrect_render(APTR funcdata, LONG srcx, LONG srcy,
366 OOP_Object *dstbm_obj, OOP_Object *dst_gc,
367 LONG x1, LONG y1, LONG x2, LONG y2,
368 struct GfxBase *GfxBase)
371 HIDD_BM_FillRect(dstbm_obj, dst_gc, x1, y1, x2, y2);
373 return (x2 - x1 + 1) * (y2 - y1 + 1);
376 /****************************************************************************************/
378 LONG fillrect_pendrmd(struct RastPort *rp, LONG x1, LONG y1, LONG x2, LONG y2,
379 HIDDT_Pixel pix, HIDDT_DrawMode drmd, struct GfxBase *GfxBase)
381 LONG pixwritten = 0;
383 HIDDT_DrawMode old_drmd;
384 HIDDT_Pixel old_fg;
385 OOP_Object *gc;
386 struct Rectangle rr;
388 struct TagItem gc_tags[] =
390 { aHidd_GC_DrawMode , drmd },
391 { aHidd_GC_Foreground , pix },
392 { TAG_DONE }
396 if (!OBTAIN_DRIVERDATA(rp, GfxBase))
397 return 0;
399 gc = GetDriverData(rp)->dd_GC;
401 OOP_GetAttr(gc, aHidd_GC_DrawMode, (IPTR *)&old_drmd);
402 OOP_GetAttr(gc, aHidd_GC_Foreground,(IPTR *)&old_fg);
404 OOP_SetAttrs(gc, gc_tags);
406 rr.MinX = x1;
407 rr.MinY = y1;
408 rr.MaxX = x2;
409 rr.MaxY = y2;
411 pixwritten = do_render_func(rp, NULL, &rr, fillrect_render, NULL, FALSE, GfxBase);
413 /* Restore old GC values */
414 gc_tags[0].ti_Data = (IPTR)old_drmd;
415 gc_tags[1].ti_Data = (IPTR)old_fg;
416 OOP_SetAttrs(gc, gc_tags);
418 RELEASE_DRIVERDATA(rp, GfxBase);
420 return pixwritten;
423 /****************************************************************************************/
425 BOOL int_bltbitmap(struct BitMap *srcBitMap, OOP_Object *srcbm_obj, LONG xSrc, LONG ySrc,
426 struct BitMap *dstBitMap, OOP_Object *dstbm_obj, LONG xDest, LONG yDest,
427 LONG xSize, LONG ySize, ULONG minterm, OOP_Object *gc, struct GfxBase *GfxBase)
429 HIDDT_DrawMode drmd;
431 ULONG srcflags = 0;
432 ULONG dstflags = 0;
434 BOOL src_colmap_set = FALSE;
435 BOOL dst_colmap_set = FALSE;
436 BOOL success = TRUE;
437 BOOL colmaps_ok = TRUE;
439 drmd = MINTERM_TO_GCDRMD(minterm);
441 /* We must lock any HIDD_BM_SetColorMap calls */
442 LOCK_BLIT
444 /* Try to get a CLUT for the bitmaps */
445 if (IS_HIDD_BM(srcBitMap))
447 //bug("driver_intbltbitmap: source is hidd bitmap\n");
448 if (NULL != HIDD_BM_COLMAP(srcBitMap))
450 //bug("driver_intbltbitmap: source has colormap\n");
451 srcflags |= FLG_HASCOLMAP;
453 srcflags |= GET_COLMOD_FLAGS(srcBitMap);
455 else
457 //bug("driver_intbltbitmap: source is amiga bitmap\n");
458 /* Amiga BM */
459 srcflags |= FLG_PALETTE;
462 if (IS_HIDD_BM(dstBitMap))
464 //bug("driver_intbltbitmap: dest is hidd bitmap\n");
465 if (NULL != HIDD_BM_COLMAP(dstBitMap))
467 //bug("driver_intbltbitmap: dest has colormap\n");
468 dstflags |= FLG_HASCOLMAP;
470 dstflags |= GET_COLMOD_FLAGS(dstBitMap);
472 else
474 //bug("driver_intbltbitmap: dest is amiga bitmap\n");
475 /* Amiga BM */
476 dstflags |= FLG_PALETTE;
479 if ( (srcflags == FLG_PALETTE || srcflags == FLG_STATICPALETTE))
481 /* palettized with no colmap. Neew to get a colmap from dest*/
482 if (dstflags == FLG_TRUECOLOR)
485 D(bug("!!! NO WAY GETTING PALETTE FOR src IN BltBitMap\n"));
486 colmaps_ok = FALSE;
487 success = FALSE;
490 else if (dstflags == (FLG_TRUECOLOR | FLG_HASCOLMAP))
493 /* Use the dest colmap for src */
494 HIDD_BM_SetColorMap(srcbm_obj, HIDD_BM_COLMAP(dstBitMap));
496 src_colmap_set = TRUE;
499 bug("Colormap:\n");
501 ULONG idx;
502 for (idx = 0; idx < 256; idx ++)
503 bug("[%d]=%d ", idx, HIDD_CM_GetPixel(HIDD_BM_COLMAP(dstBitMap), idx));
509 if ( (dstflags == FLG_PALETTE || dstflags == FLG_STATICPALETTE))
511 /* palettized with no pixtab. Nees to get a pixtab from dest*/
512 if (srcflags == FLG_TRUECOLOR)
514 D(bug("!!! NO WAY GETTING PALETTE FOR dst IN BltBitMap\n"));
515 colmaps_ok = FALSE;
516 success = FALSE;
519 else if (srcflags == (FLG_TRUECOLOR | FLG_HASCOLMAP))
522 /* Use the src colmap for dst */
523 HIDD_BM_SetColorMap(dstbm_obj, HIDD_BM_COLMAP(srcBitMap));
525 dst_colmap_set = TRUE;
529 if (colmaps_ok)
531 /* We need special treatment with drawmode Clear and
532 truecolor bitmaps, in order to set it to
533 colormap[0] instead of just 0
535 if ( (drmd == vHidd_GC_DrawMode_Clear)
536 && ( (dstflags & (FLG_TRUECOLOR | FLG_HASCOLMAP)) == (FLG_TRUECOLOR | FLG_HASCOLMAP) ))
539 HIDDT_DrawMode old_drmd;
540 HIDDT_Pixel old_fg;
542 struct TagItem frtags[] =
544 { aHidd_GC_Foreground , 0 },
545 { aHidd_GC_DrawMode , vHidd_GC_DrawMode_Copy },
546 { TAG_DONE }
549 OOP_GetAttr(gc, aHidd_GC_DrawMode, &old_drmd);
550 OOP_GetAttr(gc, aHidd_GC_Foreground, &old_fg);
552 frtags[0].ti_Data = HIDD_BM_PIXTAB(dstBitMap)[0];
553 frtags[1].ti_Data = vHidd_GC_DrawMode_Copy;
555 OOP_SetAttrs(gc, frtags);
557 HIDD_BM_FillRect(dstbm_obj, gc
558 , xDest, yDest
559 , xDest + xSize - 1
560 , yDest + ySize - 1
563 frtags[0].ti_Data = old_fg;
564 frtags[1].ti_Data = old_drmd;
567 else
569 HIDDT_DrawMode old_drmd;
571 struct TagItem cbtags[] =
573 { aHidd_GC_DrawMode, 0 },
574 { TAG_DONE }
577 OOP_GetAttr(gc, aHidd_GC_DrawMode, &old_drmd);
579 cbtags[0].ti_Data = drmd;
581 OOP_SetAttrs(gc, cbtags);
582 HIDD_Gfx_CopyBox(SDD(GfxBase)->gfxhidd
583 , srcbm_obj
584 , xSrc, ySrc
585 , dstbm_obj
586 , xDest, yDest
587 , xSize, ySize
588 , gc
591 cbtags[0].ti_Data = drmd;
592 OOP_SetAttrs(gc, cbtags);
595 } /* if (colmaps_ok) */
597 if (src_colmap_set)
598 HIDD_BM_SetColorMap(srcbm_obj, NULL);
600 if (dst_colmap_set)
601 HIDD_BM_SetColorMap(dstbm_obj, NULL);
603 ULOCK_BLIT
605 return success;
609 /****************************************************************************************/
611 struct wp8_render_data
613 UBYTE *array;
614 ULONG modulo;
615 HIDDT_PixelLUT *pixlut;
618 static ULONG wp8_render(APTR wp8r_data, LONG srcx, LONG srcy, OOP_Object *dstbm_obj,
619 OOP_Object *dst_gc, LONG x1, LONG y1, LONG x2, LONG y2,
620 struct GfxBase *GfxBase)
622 struct wp8_render_data *wp8rd;
623 ULONG width, height;
625 wp8rd = (struct wp8_render_data *)wp8r_data;
627 width = x2 - x1 + 1;
628 height = y2 - y1 + 1;
630 HIDD_BM_PutImageLUT(dstbm_obj
631 , dst_gc
632 , wp8rd->array + CHUNKY8_COORD_TO_BYTEIDX(srcx, srcy, wp8rd->modulo)
633 , wp8rd->modulo
634 , x1, y1
635 , width, height
636 , wp8rd->pixlut
639 return width * height;
641 /****************************************************************************************/
643 LONG write_pixels_8(struct RastPort *rp, UBYTE *array, ULONG modulo,
644 LONG xstart, LONG ystart, LONG xstop, LONG ystop,
645 HIDDT_PixelLUT *pixlut, struct GfxBase *GfxBase)
648 LONG pixwritten = 0;
650 struct wp8_render_data wp8rd;
651 struct Rectangle rr;
653 OOP_Object *gc;
654 HIDDT_DrawMode old_drmd;
656 struct TagItem gc_tags[] =
658 { aHidd_GC_DrawMode, vHidd_GC_DrawMode_Copy},
659 { TAG_DONE, 0}
663 if (!OBTAIN_DRIVERDATA(rp, GfxBase))
664 return 0;
666 gc = GetDriverData(rp)->dd_GC;
668 OOP_GetAttr(gc, aHidd_GC_DrawMode, &old_drmd);
669 OOP_SetAttrs(gc, gc_tags);
671 wp8rd.modulo = modulo;
672 wp8rd.array = array;
673 wp8rd.pixlut = pixlut;
675 rr.MinX = xstart;
676 rr.MinY = ystart;
677 rr.MaxX = xstop;
678 rr.MaxY = ystop;
680 pixwritten = do_render_func(rp, NULL, &rr, wp8_render, &wp8rd, FALSE, GfxBase);
682 /* Reset to preserved drawmode */
683 gc_tags[0].ti_Data = old_drmd;
684 OOP_SetAttrs(gc, gc_tags);
686 RELEASE_DRIVERDATA(rp, GfxBase);
688 return pixwritten;
692 /****************************************************************************************/
695 ** General functions for moving blocks of data to or from HIDDs, be it pixelarrays
696 ** or bitmaps. They use a callback-function to get data from amiga/put data to amiga
697 ** bitmaps/pixelarrays
700 /****************************************************************************************/
702 #if 0
704 void amiga2hidd_fast(APTR src_info, OOP_Object *hidd_gc, LONG x_src , LONG y_src,
705 struct BitMap *hidd_bm, LONG x_dest, LONG y_dest,
706 ULONG xsize, ULONG ysize, VOID (*fillbuf_hook)(),
707 struct GfxBase * GfxBase)
711 ULONG tocopy_w,
712 tocopy_h;
714 LONG pixels_left_to_process = xsize * ysize;
716 LONG current_x, current_y, next_x, next_y;
717 OOP_Object *bm_obj;
719 next_x = 0;
720 next_y = 0;
722 bm_obj = OBTAIN_HIDD_BM(hidd_bm);
723 if (NULL == bm_obj)
724 return;
726 LOCK_PIXBUF
728 while (pixels_left_to_process)
731 /* Get some more pixels from the HIDD */
733 current_x = next_x;
734 current_y = next_y;
736 if (NUMPIX < xsize)
738 /* buffer can't hold a single horizontal line, and must
739 divide each line into several copy-operations */
740 tocopy_w = xsize - current_x;
741 if (tocopy_w > NUMPIX)
743 /* Not quite finished with current horizontal pixel line */
744 tocopy_w = NUMPIX;
745 next_x += NUMPIX;
747 else
748 { /* Start at a new line */
749 next_x = 0;
750 next_y ++;
752 tocopy_h = 1;
755 else /* We can copy one or several whole horizontal lines at a time */
757 tocopy_h = MIN(NUMPIX / xsize, ysize - current_y);
759 tocopy_w = xsize;
761 next_x = 0;
762 next_y += tocopy_h;
768 /* Get data */
769 fillbuf_hook(src_info
770 , current_x + x_src
771 , current_y + y_src
772 , current_x + x_dest
773 , current_y + y_dest
774 , tocopy_w, tocopy_h
775 , PrivGBase(GfxBase)->pixel_buf
776 , bm_obj
777 , IS_HIDD_BM(hidd_bm) ? HIDD_BM_PIXTAB(hidd_bm) : NULL
778 , GfxBase
781 /* Put it to the HIDD */
782 D(bug("Putting box\n"));
784 HIDD_BM_PutImage(bm_obj
785 , hidd_gc
786 , (UBYTE*)PrivGBase(GfxBase)->pixel_buf
787 , tocopy_w * sizeof (HIDDT_Pixel)
788 , x_dest + current_x
789 , y_dest + current_y
790 , tocopy_w, tocopy_h
791 , vHidd_StdPixFmt_Native32
794 D(bug("Box put\n"));
796 pixels_left_to_process -= (tocopy_w * tocopy_h);
799 } /* while (pixels left to copy) */
801 ULOCK_PIXBUF
803 RELEASE_HIDD_BM(bm_obj, hidd_bm);
805 return;
809 #endif
811 /****************************************************************************************/
813 void hidd2buf_fast(struct BitMap *hidd_bm, LONG x_src , LONG y_src, APTR dest_info,
814 LONG x_dest, LONG y_dest, ULONG xsize, ULONG ysize, VOID (*putbuf_hook)(),
815 struct GfxBase * GfxBase)
818 ULONG tocopy_w, tocopy_h;
820 LONG pixels_left_to_process = xsize * ysize;
821 ULONG current_x, current_y, next_x, next_y;
823 #warning Src bitmap migh be user initialized so we should not use HIDD_BM_PIXTAB() below
825 OOP_Object *bm_obj;
827 next_x = 0;
828 next_y = 0;
830 bm_obj = OBTAIN_HIDD_BM(hidd_bm);
831 if (NULL == bm_obj)
832 return;
834 LOCK_PIXBUF
836 while (pixels_left_to_process)
839 current_x = next_x;
840 current_y = next_y;
842 if (NUMPIX < xsize)
844 /* buffer cant hold a single horizontal line, and must
845 divide each line into copies */
846 tocopy_w = xsize - current_x;
847 if (tocopy_w > NUMPIX)
849 /* Not quite finished with current horizontal pixel line */
850 tocopy_w = NUMPIX;
851 next_x += NUMPIX;
853 else
854 { /* Start at a new line */
856 next_x = 0;
857 next_y ++;
859 tocopy_h = 1;
862 else
864 tocopy_h = MIN(NUMPIX / xsize, ysize - current_y);
865 tocopy_w = xsize;
867 next_x = 0;
868 next_y += tocopy_h;
873 /* Get some more pixels from the HIDD */
874 HIDD_BM_GetImage(bm_obj
875 , (UBYTE *)PrivGBase(GfxBase)->pixel_buf
876 , tocopy_w
877 , x_src + current_x
878 , y_src + current_y
879 , tocopy_w, tocopy_h
880 , vHidd_StdPixFmt_Native32);
883 /* Write pixels to the destination */
884 putbuf_hook(dest_info
885 , current_x + x_src
886 , current_y + y_src
887 , current_x + x_dest
888 , current_y + y_dest
889 , tocopy_w, tocopy_h
890 , (HIDDT_Pixel *)PrivGBase(GfxBase)->pixel_buf
891 , bm_obj
892 , IS_HIDD_BM(hidd_bm) ? HIDD_BM_PIXTAB(hidd_bm) : NULL
895 pixels_left_to_process -= (tocopy_w * tocopy_h);
899 ULOCK_PIXBUF
901 RELEASE_HIDD_BM(bm_obj, hidd_bm);
903 return;
907 /****************************************************************************************/
909 UWORD hidd2cyber_pixfmt(HIDDT_StdPixFmt stdpf, struct GfxBase *GfxBase)
911 UWORD cpf = (UWORD)-1;
913 bug("hidd2cyber stdpf = %d [%d]\n", stdpf, vHidd_StdPixFmt_BGR032);
915 switch (stdpf)
917 case vHidd_StdPixFmt_RGB15:
918 cpf = PIXFMT_RGB15;
919 break;
921 case vHidd_StdPixFmt_RGB15_LE:
922 cpf = PIXFMT_RGB15PC;
923 break;
925 case vHidd_StdPixFmt_BGR15:
926 cpf = PIXFMT_BGR15;
927 break;
929 case vHidd_StdPixFmt_BGR15_LE:
930 cpf = PIXFMT_BGR15PC;
931 break;
933 case vHidd_StdPixFmt_RGB16:
934 cpf = PIXFMT_RGB16;
935 break;
937 case vHidd_StdPixFmt_RGB16_LE:
938 cpf = PIXFMT_RGB16PC;
939 break;
941 case vHidd_StdPixFmt_BGR16:
942 cpf = PIXFMT_BGR16;
943 break;
945 case vHidd_StdPixFmt_BGR16_LE:
946 cpf = PIXFMT_BGR16PC;
947 break;
949 case vHidd_StdPixFmt_RGB24:
950 cpf = PIXFMT_RGB24;
951 break;
953 case vHidd_StdPixFmt_BGR24:
954 cpf = PIXFMT_BGR24;
955 break;
957 case vHidd_StdPixFmt_0RGB32:
958 case vHidd_StdPixFmt_ARGB32:
959 cpf = PIXFMT_ARGB32;
960 break;
962 case vHidd_StdPixFmt_RGB032:
963 case vHidd_StdPixFmt_RGBA32:
964 cpf = PIXFMT_RGBA32;
965 break;
967 case vHidd_StdPixFmt_BGRA32:
968 case vHidd_StdPixFmt_BGR032:
969 cpf = PIXFMT_BGRA32;
970 break;
972 case vHidd_StdPixFmt_ABGR32:
973 case vHidd_StdPixFmt_0BGR32:
974 cpf = PIXFMT_ABGR32;
975 break;
977 case vHidd_StdPixFmt_LUT8:
978 cpf = PIXFMT_LUT8;
979 break;
981 default:
982 D(bug("UNKNOWN CYBERGRAPHICS PIXFMT IN cyber2hidd_pixfmt\n"));
983 break;
987 return cpf;
991 /****************************************************************************************/
993 HIDDT_StdPixFmt cyber2hidd_pixfmt(UWORD cpf, struct GfxBase *GfxBase)
995 HIDDT_StdPixFmt stdpf = vHidd_StdPixFmt_Unknown;
997 switch (cpf)
999 case PIXFMT_RGB15:
1000 stdpf = vHidd_StdPixFmt_RGB15;
1001 break;
1003 case PIXFMT_RGB15PC:
1004 stdpf = vHidd_StdPixFmt_RGB15_LE;
1005 break;
1007 case PIXFMT_BGR15:
1008 stdpf = vHidd_StdPixFmt_BGR15;
1009 break;
1011 case PIXFMT_BGR15PC:
1012 stdpf = vHidd_StdPixFmt_BGR15_LE;
1013 break;
1015 case PIXFMT_RGB16:
1016 stdpf = vHidd_StdPixFmt_RGB16;
1017 break;
1019 case PIXFMT_RGB16PC:
1020 stdpf = vHidd_StdPixFmt_RGB16_LE;
1021 break;
1023 case PIXFMT_BGR16:
1024 stdpf = vHidd_StdPixFmt_BGR16;
1025 break;
1027 case PIXFMT_BGR16PC:
1028 stdpf = vHidd_StdPixFmt_BGR16_LE;
1029 break;
1031 case PIXFMT_RGB24:
1032 stdpf = vHidd_StdPixFmt_RGB24;
1033 break;
1035 case PIXFMT_BGR24:
1036 stdpf = vHidd_StdPixFmt_BGR24;
1037 break;
1039 case PIXFMT_ARGB32:
1040 stdpf = vHidd_StdPixFmt_ARGB32;
1041 break;
1043 case PIXFMT_RGBA32:
1044 stdpf = vHidd_StdPixFmt_RGBA32;
1045 break;
1047 case PIXFMT_BGRA32:
1048 stdpf = vHidd_StdPixFmt_BGRA32;
1049 break;
1051 case PIXFMT_ABGR32:
1052 stdpf = vHidd_StdPixFmt_ABGR32;
1053 break;
1055 case PIXFMT_LUT8:
1056 stdpf = vHidd_StdPixFmt_LUT8;
1057 break;
1059 default:
1060 D(bug("UNKNOWN CYBERGRAPHICS PIXFMT IN cyber2hidd_pixfmt\n"));
1061 break;
1064 return stdpf;
1067 /****************************************************************************************/
1069 #define ENABLE_PROFILING 0
1070 #define USE_OLD_MoveRaster 0
1072 #define rdtscll(val) \
1073 __asm__ __volatile__("rdtsc" : "=A" (val))
1075 #if ENABLE_PROFILING && defined(__i386__)
1078 #define AROS_BEGIN_PROFILING(context) \
1080 unsigned long long _time1, _time2; \
1081 char *_text = #context; \
1082 rdtscll(_time1); \
1085 #define AROS_END_PROFILING \
1087 rdtscll(_time2); \
1088 kprintf("%s: Ticks count: %u\n", _text, (unsigned long)(_time2 - _time1)); \
1091 #else
1093 #define AROS_BEGIN_PROFILING(context)
1094 #define AROS_END_PROFILING
1096 #endif
1098 BOOL MoveRaster (struct RastPort * rp, LONG dx, LONG dy, LONG x1, LONG y1,
1099 LONG x2, LONG y2, BOOL UpdateDamageList, struct GfxBase * GfxBase)
1101 struct Layer *L = rp->Layer;
1102 struct Rectangle ScrollRect;
1103 struct Rectangle Rect;
1105 if (0 == dx && 0 == dy)
1106 return TRUE;
1108 if (!OBTAIN_DRIVERDATA(rp, GfxBase))
1109 return FALSE;
1111 ScrollRect.MinX = x1;
1112 ScrollRect.MinY = y1;
1113 ScrollRect.MaxX = x2;
1114 ScrollRect.MaxY = y2;
1116 if (!L)
1118 Rect = ScrollRect;
1119 TranslateRect(&Rect, -dx, -dy);
1120 if (_AndRectRect(&ScrollRect, &Rect, &Rect))
1122 BltBitMap(rp->BitMap,
1123 Rect.MinX + dx,
1124 Rect.MinY + dy,
1125 rp->BitMap,
1126 Rect.MinX,
1127 Rect.MinY,
1128 Rect.MaxX - Rect.MinX + 1,
1129 Rect.MaxY - Rect.MinY + 1,
1130 0xc0, /* copy */
1131 0xff,
1132 NULL );
1135 else
1137 struct ClipRect *SrcCR;
1139 LockLayerRom(L);
1141 if (L->Flags & LAYERSIMPLE && UpdateDamageList)
1143 /* Scroll the old damagelist within the scroll area */
1144 ScrollRegion(L->DamageList, &ScrollRect, -dx, -dy);
1147 /* The scrolling area is relative to the Layer, so make it relative to the screen */
1148 TranslateRect(&ScrollRect, MinX(L), MinY(L));
1150 /* The damage list will be formed by the now hidden layer's parts that will become visible due
1151 to the scrolling procedure, thus we procede this way:
1153 1) Calculate the invisible region out of the visible one, subtracting it from the
1154 scrolling area
1156 2) Scroll the invisible region by (-dx, -dy) and then subtract from it the not scrolled equivalent
1158 The regions that we obtain after (2) is the new damage list
1161 if (L->Flags & LAYERSIMPLE && UpdateDamageList)
1163 Rect = ScrollRect;
1164 TranslateRect(&Rect, dx, dy);
1166 if (_AndRectRect(&ScrollRect, &Rect, &Rect))
1168 struct Region *Damage;
1170 Damage = NewRectRegion(Rect.MinX, Rect.MinY, Rect.MaxX, Rect.MaxY);
1171 if (Damage)
1175 ClearRegionRegion(L->VisibleRegion, Damage)
1177 Damage->RegionRectangle
1180 struct Region Tmp;
1182 We play sort of dirty here, by making assumptions about the internals of the
1183 Region structure and the region handling functions, but we are allowed to do that,
1184 aren't we? ;-)
1187 Tmp = *Damage;
1189 TranslateRect(Bounds(Damage), -dx, -dy);
1193 ClearRegionRegion(&Tmp, Damage)
1195 Damage->RegionRectangle
1198 /* Join the new damage list with the old one */
1199 TranslateRect(Bounds(Damage), -MinX(L), -MinY(L));
1200 OrRegionRegion(Damage, L->DamageList);
1202 L->Flags |= LAYERREFRESH;
1206 DisposeRegion(Damage);
1211 AROS_BEGIN_PROFILING(SortLayerCR)
1213 #define LayersBase (struct LayersBase *)(GfxBase->gb_LayersBase)
1214 SortLayerCR(L, dx, dy);
1215 #undef LayersBase
1217 AROS_END_PROFILING
1219 AROS_BEGIN_PROFILING(Blitting loop)
1221 #if USE_OLDMoveRaster
1224 struct ClipRect *LastHiddenCR;
1226 for (LastHiddenCR = NULL, SrcCR = L->ClipRect; SrcCR; SrcCR = SrcCR->Next)
1228 SrcCR->_p1 = LastHiddenCR;
1230 if (SrcCR->lobs)
1231 LastHiddenCR = SrcCR;
1236 for (SrcCR = L->ClipRect; SrcCR; SrcCR = SrcCR->Next)
1238 int cando = 0;
1240 if (SrcCR->lobs && (L->Flags & LAYERSIMPLE))
1242 continue;
1245 if (_AndRectRect(&ScrollRect, Bounds(SrcCR), &Rect))
1247 TranslateRect(&Rect, -dx, -dy);
1249 if (_AndRectRect(&ScrollRect, &Rect, &Rect))
1250 cando = 1;
1253 if (cando)
1255 /* Rect.Min(X|Y) are the coordinates to wich the rectangle has to be moved
1256 Rect.Max(X|Y) - Rect.Max(X|Y) - 1 are the dimensions of this rectangle */
1257 if (!SrcCR->_p1 && !SrcCR->lobs)
1259 /* there are no hidden/obscured rectangles this recrtangle has to deal with*/
1260 BltBitMap
1262 rp->BitMap,
1263 Rect.MinX + dx,
1264 Rect.MinY + dy,
1265 rp->BitMap,
1266 Rect.MinX,
1267 Rect.MinY,
1268 Rect.MaxX - Rect.MinX + 1,
1269 Rect.MaxY - Rect.MinY + 1,
1270 0xc0, /* copy */
1271 0xff,
1272 NULL
1275 else
1277 struct BitMap *srcbm;
1278 struct RegionRectangle *rr;
1279 struct Region *RectRegion;
1280 struct Rectangle Tmp;
1281 struct ClipRect *HiddCR;
1282 WORD corrsrcx, corrsrcy;
1283 BOOL dosrcsrc;
1285 RectRegion = NewRectRegion(Rect.MinX, Rect.MinY, Rect.MaxX, Rect.MaxY);
1286 if (!RectRegion)
1287 goto failexit;
1289 if (SrcCR->lobs)
1291 if (L->Flags & LAYERSUPER)
1293 corrsrcx = - MinX(L) - L->Scroll_X;
1294 corrsrcy = - MinY(L) - L->Scroll_Y;
1296 else
1298 corrsrcx = - MinX(SrcCR) + ALIGN_OFFSET(MinX(SrcCR));
1299 corrsrcy = - MinY(SrcCR);
1301 srcbm = SrcCR->BitMap;
1303 else
1305 corrsrcx = 0;
1306 corrsrcy = 0;
1307 srcbm = rp->BitMap;
1310 for (HiddCR = SrcCR->_p1; HiddCR; HiddCR = HiddCR->_p1)
1312 if (_AndRectRect(Bounds(RectRegion), Bounds(HiddCR), &Tmp))
1314 if (!(L->Flags & LAYERSIMPLE))
1316 WORD corrdstx, corrdsty;
1318 if (L->Flags & LAYERSUPER)
1320 corrdstx = - MinX(L) - L->Scroll_X;
1321 corrdsty = - MinY(L) - L->Scroll_Y;
1323 else
1325 /* Smart layer */
1326 corrdstx = - MinX(HiddCR) + ALIGN_OFFSET(MinX(HiddCR));
1327 corrdsty = - MinY(HiddCR);
1331 BltBitMap
1333 srcbm,
1334 Tmp.MinX + corrsrcx + dx,
1335 Tmp.MinY + corrsrcy + dy,
1336 HiddCR->BitMap,
1337 Tmp.MinX + corrdstx,
1338 Tmp.MinY + corrdsty,
1339 Tmp.MaxX - Tmp.MinX + 1,
1340 Tmp.MaxY - Tmp.MinY + 1,
1341 0xc0, /* copy */
1342 0xff,
1343 NULL
1347 if (!ClearRectRegion(RectRegion, &Tmp))
1349 DisposeRegion(RectRegion);
1350 goto failexit;
1355 if ((dosrcsrc = _AndRectRect(Bounds(SrcCR), &Rect, &Tmp)))
1357 if (!ClearRectRegion(RectRegion, &Tmp))
1359 DisposeRegion(RectRegion);
1360 goto failexit;
1364 for (rr = RectRegion->RegionRectangle; rr; rr = rr->Next)
1366 BltBitMap
1368 srcbm,
1369 MinX(rr) + MinX(RectRegion) + corrsrcx + dx,
1370 MinY(rr) + MinY(RectRegion) + corrsrcy + dy,
1371 rp->BitMap,
1372 MinX(rr) + MinX(RectRegion),
1373 MinY(rr) + MinY(RectRegion),
1374 Width(rr),
1375 Height(rr),
1376 0xc0, /* copy */
1377 0xff,
1378 NULL
1382 if (dosrcsrc)
1384 BltBitMap
1386 srcbm,
1387 Tmp.MinX + corrsrcx + dx,
1388 Tmp.MinY + corrsrcy + dy,
1389 srcbm,
1390 Tmp.MinX + corrsrcx,
1391 Tmp.MinY + corrsrcy,
1392 Tmp.MaxX - Tmp.MinX + 1,
1393 Tmp.MaxY - Tmp.MinY + 1,
1394 0xc0, /* copy */
1395 0xff,
1396 NULL
1401 DisposeRegion(RectRegion);
1406 #else
1408 for (SrcCR = L->ClipRect; SrcCR; SrcCR = SrcCR->Next)
1410 if (_AndRectRect(&ScrollRect, Bounds(SrcCR), &Rect))
1412 TranslateRect(&Rect, -dx, -dy);
1414 if (_AndRectRect(&ScrollRect, &Rect, &Rect))
1416 struct BitMap *srcbm;
1417 struct ClipRect *DstCR;
1418 LONG corrsrcx, corrsrcy;
1419 ULONG area;
1421 if (SrcCR->lobs)
1423 if (L->Flags & LAYERSIMPLE) continue;
1425 if (L->Flags & LAYERSUPER)
1427 corrsrcx = - MinX(L) - L->Scroll_X;
1428 corrsrcy = - MinY(L) - L->Scroll_Y;
1430 else
1432 corrsrcx = - MinX(SrcCR) + ALIGN_OFFSET(MinX(SrcCR));
1433 corrsrcy = - MinY(SrcCR);
1435 srcbm = SrcCR->BitMap;
1437 else
1439 corrsrcx = 0;
1440 corrsrcy = 0;
1441 srcbm = rp->BitMap;
1444 area = (ULONG)(Rect.MaxX - Rect.MinX + 1) * (ULONG)(Rect.MaxY - Rect.MinY + 1);
1446 for (DstCR = L->ClipRect ; area && DstCR; DstCR = DstCR->Next)
1448 struct Rectangle Rect2;
1450 if (_AndRectRect(Bounds(DstCR), &Rect, &Rect2))
1452 struct BitMap *dstbm;
1453 LONG corrdstx, corrdsty;
1455 area -= (ULONG)(Rect2.MaxX - Rect2.MinX + 1) * (ULONG)(Rect2.MaxY - Rect2.MinY + 1);
1457 if (DstCR->lobs)
1459 if (L->Flags & LAYERSIMPLE) continue;
1461 if (L->Flags & LAYERSUPER)
1463 corrdstx = - MinX(L) - L->Scroll_X;
1464 corrdsty = - MinY(L) - L->Scroll_Y;
1466 else
1468 corrdstx = - MinX(DstCR) + ALIGN_OFFSET(MinX(DstCR));
1469 corrdsty = - MinY(DstCR);
1471 dstbm = DstCR->BitMap;
1473 else
1475 corrdstx = 0;
1476 corrdsty = 0;
1477 dstbm = rp->BitMap;
1480 BltBitMap
1482 srcbm,
1483 Rect2.MinX + corrsrcx + dx,
1484 Rect2.MinY + corrsrcy + dy,
1485 dstbm,
1486 Rect2.MinX + corrdstx,
1487 Rect2.MinY + corrdsty,
1488 Rect2.MaxX - Rect2.MinX + 1,
1489 Rect2.MaxY - Rect2.MinY + 1,
1490 0xC0,
1491 0xFF,
1492 NULL
1499 #endif
1500 AROS_END_PROFILING
1502 UnlockLayerRom(L);
1505 RELEASE_DRIVERDATA(rp, GfxBase);
1507 return TRUE;
1510 /****************************************************************************************/
1512 BOOL GetRPClipRectangleForLayer(struct RastPort *rp, struct Layer *lay,
1513 struct Rectangle *r, struct GfxBase *GfxBase)
1515 (void)GfxBase;
1517 if (RP_DRIVERDATA(rp)->dd_ClipRectangleFlags & RPCRF_VALID)
1519 *r = RP_DRIVERDATA(rp)->dd_ClipRectangle;
1521 if (RP_DRIVERDATA(rp)->dd_ClipRectangleFlags & RPCRF_RELRIGHT)
1523 r->MaxX += (lay->bounds.MaxX - lay->bounds.MinX + 1) - 1;
1526 if (RP_DRIVERDATA(rp)->dd_ClipRectangleFlags & RPCRF_RELBOTTOM)
1528 r->MaxY += (lay->bounds.MaxY - lay->bounds.MinY + 1) - 1;
1531 r->MinX += lay->bounds.MinX;
1532 r->MinY += lay->bounds.MinY;
1533 r->MaxX += lay->bounds.MinX;
1534 r->MaxY += lay->bounds.MinY;
1536 return TRUE;
1539 return FALSE;
1542 /****************************************************************************************/
1544 BOOL GetRPClipRectangleForBitMap(struct RastPort *rp, struct BitMap *bm,
1545 struct Rectangle *r, struct GfxBase *GfxBase)
1547 if (RP_DRIVERDATA(rp)->dd_ClipRectangleFlags & RPCRF_VALID)
1550 *r = RP_DRIVERDATA(rp)->dd_ClipRectangle;
1552 if (RP_DRIVERDATA(rp)->dd_ClipRectangleFlags & RPCRF_RELRIGHT)
1554 LONG width = GetBitMapAttr(bm, BMA_WIDTH);
1556 r->MaxX += width - 1;
1559 if (RP_DRIVERDATA(rp)->dd_ClipRectangleFlags & RPCRF_RELBOTTOM)
1561 LONG height = GetBitMapAttr(bm, BMA_HEIGHT);
1563 r->MaxY += height - 1;
1566 return TRUE;
1569 return FALSE;
1572 /****************************************************************************************/