Updated PCI IDs to latest snapshot.
[tangerine.git] / rom / graphics / bltbitmap.c
blobe65fa08dc2985fc35ae79a1a1d1b0a9841c269c8
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Copy a rectangle in a bitmap to another place or another bitmap.
6 Lang: english
7 */
8 #include <aros/debug.h>
9 #include <string.h>
10 #include <exec/memory.h>
11 #include <graphics/gfx.h>
12 #include <proto/exec.h>
13 #include "graphics_intern.h"
14 #include "gfxfuncsupport.h"
15 #include "objcache.h"
17 static void copyonepixel (PLANEPTR src, ULONG xsrc, PLANEPTR dest,
18 ULONG xdest, ULONG minterm);
20 /*****************************************************************************
22 NAME */
23 #include <graphics/gfx.h>
24 #include <proto/graphics.h>
26 AROS_LH11(LONG, BltBitMap,
28 /* SYNOPSIS */
29 AROS_LHA(struct BitMap *, srcBitMap, A0),
30 AROS_LHA(LONG , xSrc, D0),
31 AROS_LHA(LONG , ySrc, D1),
32 AROS_LHA(struct BitMap *, destBitMap, A1),
33 AROS_LHA(LONG , xDest, D2),
34 AROS_LHA(LONG , yDest, D3),
35 AROS_LHA(LONG , xSize, D4),
36 AROS_LHA(LONG , ySize, D5),
37 AROS_LHA(ULONG , minterm, D6),
38 AROS_LHA(ULONG , mask, D7),
39 AROS_LHA(PLANEPTR , tempA, A2),
41 /* LOCATION */
42 struct GfxBase *, GfxBase, 5, Graphics)
44 /* FUNCTION
45 Moves a part of a bitmap around or into another bitmaps.
47 INPUTS
48 srcBitMap - Copy from this bitmap.
49 xSrc, ySrc - This is the upper left corner of the area to copy.
50 destBitMap - Copy to this bitmap. May be the same as srcBitMap.
51 xDest, yDest - Upper left corner where to place the copy
52 xSize, ySize - The size of the area to copy
53 minterm - How to copy. Most useful values are 0x00C0 for a vanilla
54 copy, 0x0030 to invert the source and then copy or 0x0050
55 to ignore the source and just invert the destination. If
56 you want to calculate other values, then you must know that
57 channel A is set, if you are inside the rectangle, channel
58 B is the source and channel C is the destination of the
59 rectangle.
61 Bit ABC
62 0 000
63 1 001
64 2 010
65 3 011
66 4 100
67 5 101
68 6 110
69 7 111
71 So 0x00C0 means: D is set if one is inside the rectangle
72 (A is set) and B (the source) is set and cleared otherwise.
74 To fill the rectangle, you would want to set D when A is
75 set, so the value is 0x00F0.
77 mask - Which planes should be copied. Typically, you should set
78 this to ~0L.
79 tempA - If the copy overlaps exactly to the left or right (i.e. the
80 scan line addresses overlap), and tempA is non-zero, it
81 points to enough chip accessible memory to hold a line of a
82 source for the blit (i.e. CHIP RAM). BltBitMap will allocate
83 (and free) the needed TempA if none is provided and one is
84 needed. Blit overlap is determined from the relation of
85 the first non-masked planes in the source and destination
86 bit maps.
88 RESULT
89 The number of planes actually involved in the blit.
91 NOTES
92 If a special hardware is available, this function will use it.
94 As a special case, plane pointers of destBitMap can contain NULL
95 or -1, which will act as if the plane was filled with 0's or 1's,
96 respectively.
98 EXAMPLE
100 BUGS
102 SEE ALSO
103 ClipBlit(), BltBitMapRastPort()
105 INTERNALS
107 HISTORY
109 *****************************************************************************/
111 AROS_LIBFUNC_INIT
112 LONG planecnt;
114 FIX_GFXCOORD(xSrc);
115 FIX_GFXCOORD(ySrc);
116 FIX_GFXCOORD(xDest);
117 FIX_GFXCOORD(yDest);
119 /* nlorentz: Also check for BMF_AROS_DISPLAYED flag which if set tells
120 that this is a HIDD bitmap and should be handled by the driver */
122 if ( srcBitMap->pad != 0 || destBitMap->pad != 0
123 || srcBitMap->Flags & BMF_AROS_HIDD || destBitMap->Flags & BMF_AROS_HIDD)
125 ULONG wSrc, wDest;
126 ULONG x;
127 ULONG depth;
129 OOP_Object *tmp_gc;
131 EnterFunc(bug("driver_BltBitMap()\n"));
133 /* bug("BltBitMap(%p, %d, %d, %p, %d, %d, %d, %d, %x)\n"
134 ,srcBitMap, xSrc, ySrc, destBitMap, xDest, yDest, xSize, ySize, minterm);
138 wSrc = GetBitMapAttr( srcBitMap, BMA_WIDTH);
139 wDest = GetBitMapAttr(destBitMap, BMA_WIDTH);
141 /* Clip all blits */
143 depth = GetBitMapAttr ( srcBitMap, BMA_DEPTH);
144 x = GetBitMapAttr (destBitMap, BMA_DEPTH);
146 if (x < depth) depth = x;
148 /* Clip X and Y */
149 if (xSrc < 0)
151 xDest += -xSrc;
152 xSize -= -xSrc;
153 xSrc = 0;
156 if (ySrc < 0)
158 yDest += -ySrc;
159 ySize -= -ySrc;
160 ySrc = 0;
163 /* Clip width and height for source and dest */
164 if (ySrc + ySize > srcBitMap->Rows)
166 ySize = srcBitMap->Rows - ySrc;
169 if (yDest + ySize > destBitMap->Rows)
171 ySize = destBitMap->Rows - yDest;
174 if ((ULONG)(xSrc + xSize) >= wSrc)
176 xSize = wSrc - xSrc;
179 if ((ULONG)(xDest + xSize) >= wDest)
181 xSize = wDest - xDest;
184 /* If the size is illegal or we need not copy anything, return */
185 if (ySize <= 0 || xSize <= 0 || !mask) return 0;
187 tmp_gc = obtain_cache_object(SDD(GfxBase)->gc_cache, GfxBase);
188 if (NULL != tmp_gc)
190 OOP_Object *srcbm_obj;
192 srcbm_obj = OBTAIN_HIDD_BM(srcBitMap);
193 if (NULL != srcbm_obj)
195 OOP_Object *dstbm_obj;
197 dstbm_obj = OBTAIN_HIDD_BM(destBitMap);
198 if (NULL != dstbm_obj)
201 int_bltbitmap(srcBitMap, srcbm_obj
202 , xSrc, ySrc
203 , destBitMap, dstbm_obj
204 , xDest, yDest
205 , xSize, ySize
206 , minterm
207 , tmp_gc
208 , GfxBase);
210 RELEASE_HIDD_BM(dstbm_obj, destBitMap);
213 RELEASE_HIDD_BM(srcbm_obj, srcBitMap);
215 release_cache_object(SDD(GfxBase)->gc_cache, tmp_gc, GfxBase);
218 #warning: dummy return value
219 planecnt = 8;
222 else
224 ULONG wSrc, wDest;
225 ULONG x, y, plane;
226 ULONG depth;
227 PLANEPTR src, dest, temp;
229 wSrc = GetBitMapAttr( srcBitMap, BMA_WIDTH);
230 wDest = GetBitMapAttr(destBitMap, BMA_WIDTH);
231 temp = NULL;
233 depth = GetBitMapAttr ( srcBitMap, BMA_DEPTH);
234 x = GetBitMapAttr (destBitMap, BMA_DEPTH);
235 if (x < depth)
236 depth = x;
238 /* Clip X and Y */
239 if (xSrc < 0)
241 xDest += -xSrc;
242 xSize -= -xSrc;
243 xSrc = 0;
246 if (ySrc < 0)
248 yDest += -ySrc;
249 ySize -= -ySrc;
250 ySrc = 0;
253 /* Clip width and height for source and dest */
254 if (ySrc + ySize > srcBitMap->Rows)
256 ySize = srcBitMap->Rows - ySrc;
259 if (yDest + ySize > destBitMap->Rows)
261 ySize = destBitMap->Rows - yDest;
264 if ((ULONG)(xSrc + xSize) >= wSrc)
266 xSize = wSrc - xSrc;
269 if ((ULONG)(xDest + xSize) >= wDest)
271 xSize = wDest - xDest;
274 /* If the size is illegal or we need not copy anything, return */
275 if (ySize <= 0 || xSize <= 0 || !mask)
276 return 0;
278 planecnt = 0;
280 /* For all planes */
281 for (plane=0; plane<depth; plane ++)
283 /* Don't do anything if destination planeptr is NULL (means treat like
284 a plane with all zeros) or -1 (means treat like a plane with all ones) */
286 if ((destBitMap->Planes[plane] != NULL) && (destBitMap->Planes[plane] != (PLANEPTR)-1))
288 /* Copy this plane ? */
289 if ((1L << plane) & mask)
292 planecnt ++; /* count it */
294 for (y=0; y<(ULONG)ySize; y++)
296 src = srcBitMap->Planes[plane] + (y+ySrc) * srcBitMap->BytesPerRow;
297 dest = destBitMap->Planes[plane] + (y+yDest)*destBitMap->BytesPerRow;
300 If the source address is less or equal to
301 the destination address
303 if ((src <= dest && src+srcBitMap->BytesPerRow > dest)
304 || (dest <= src && dest+destBitMap->BytesPerRow > src)
307 if (!temp)
309 if (tempA)
310 temp = tempA;
311 else
312 temp = AllocMem (srcBitMap->BytesPerRow, MEMF_ANY);
314 if (!temp)
315 return 0;
318 memmove (temp, src, srcBitMap->BytesPerRow);
320 for (x=0; x<(ULONG)xSize; x++)
321 copyonepixel (temp, x+xSrc, dest, x+xDest, minterm);
323 else
325 for (x=0; x<(ULONG)xSize; x++)
326 copyonepixel (src, x+xSrc, dest, x+xDest, minterm);
329 } /* for (y=0; y<ySize; y++) */
331 } /* if ((1L << plane) & mask) */
333 } /* if dest plane != NULL and dest plane != -1 */
335 } /* for (plane=0; plane<depth; plane ++) */
337 if (temp && !tempA)
338 FreeMem (temp, srcBitMap->BytesPerRow);
341 return planecnt;
343 AROS_LIBFUNC_EXIT
345 } /* BltBitMap */
347 /****************************************************************************************/
349 static void copyonepixel (PLANEPTR src, ULONG xsrc, PLANEPTR dest, ULONG xdest,
350 ULONG minterm)
352 ULONG sByte, sSet;
353 ULONG dByte, dSet;
354 UBYTE sBit;
355 UBYTE dBit;
356 BOOL set;
358 if (src == NULL)
360 sSet = FALSE;
361 } else if (src == (PLANEPTR)-1)
363 sSet = TRUE;
364 } else {
365 sByte = xsrc >> 3;
366 sBit = 1L << (7 - (xsrc & 0x07));
367 sSet = (src[sByte] & sBit) != 0;
370 /* dest PLANEPTR here will never be NULL or -1 */
371 dByte = xdest >> 3;
372 dBit = 1L << (7 - (xdest & 0x07));
373 dSet = (dest[dByte] & dBit) != 0;
375 set = 0;
377 if (minterm & 0x0010)
379 if (!sSet && !dSet)
380 set = 1;
382 if (minterm & 0x0020)
384 if (!sSet && dSet)
385 set = 1;
387 if (minterm & 0x0040)
389 if (sSet && !dSet)
390 set = 1;
392 if (minterm & 0x0080)
394 if (sSet && dSet)
395 set = 1;
398 if (set)
399 dest[dByte] |= dBit;
400 else
401 dest[dByte] &= ~dBit;
404 /****************************************************************************************/