home *** CD-ROM | disk | FTP | other *** search
- /*
- * BLITTER.c
- *
- * PROGRAMMER : Gregg A. Tavares
- * VERSION : 00.002
- * CREATED : 08/22/89
- * MODIFIED : 10/25/89
- *
- * DESCRIPTION
- * various BLITTER routines for manipulating graphic images.
- *
- * NOTES
- * Set ClipLeft, ClipTop, ClipWidth and ClipHeight to the
- * maximum area you want effected in your destination BitMap.
- *
- * This code was written with Manx C68k 3.6a with the +l option
- * (32 bit ints) I don't know what if anything you'll have to
- * change to use it with out that option or with another compiler.
- *
- * You must also add -L100 to compile with Manx.
- *
- * COPYWRONG
- * I hereby place this code IN THE PUBLIC DOMAIN. Use it, Sell it,
- * burn it, frame it, worship it, whatever makes your pants smoke :-)
- *
- * DISCLAIMER
- * If this code causes you or any one you know any problems don't
- * come crying to me! ;-)
- *
- * HISTORY
- * 9/6/89 Wednesday
- * Made CopyBitMap work non-distructively when copying on the same
- * BitMap.
- *
- */
-
- short ClipLeft = 0;
- short ClipTop = 0;
- short ClipHeight = 320;
- short ClipWidth = 200;
-
- #include <exec/types.h>
- #include <hardware/blit.h>
- #include <hardware/dmabits.h>
- #include <hardware/custom.h>
- #include <graphics/gfx.h>
-
- /* remove the following macros if they are standard in your 'C' */
-
- #ifndef OKAY
- #define OKAY 1
- #endif
-
- #ifndef NULL
- #define NULL 0L
- #endif
-
- #ifndef FALSE
- #define FALSE 0L
- #endif
-
- #ifndef TRUE
- #define TRUE (!FALSE)
- #endif
-
- #ifndef abs
- #define abs(value) (((value) < 0) ? -(value) : (value))
- #endif
-
- #ifndef min
- #define min(a,b) (((a) < (b)) ? (a) : (b))
- #endif
-
- #ifndef max
- #define max(a,b) (((a) > (b)) ? (a) : (b))
- #endif
-
- #ifndef sign
- #define sign(value) (((value) > 0) - ((value) < 0))
- #endif
-
- #define WAITFORBLITTER while(custom.dmaconr & DMAF_BLTDONE);
-
- /*
- #define DEBUG 1
- */
-
- #if DEBUG
- typedef struct {
- UWORD bltddat;
- UWORD bltcon0;
- UWORD bltcon1;
- UWORD bltafwm;
- UWORD bltalwm;
- APTR bltcpt;
- APTR bltbpt;
- APTR bltapt;
- APTR bltdpt;
- UWORD bltsize;
- UWORD bltcmod;
- UWORD bltbmod;
- UWORD bltamod;
- UWORD bltdmod;
- UWORD bltcdat;
- UWORD bltbdat;
- UWORD bltadat;
- } BLITTER;
- #else
- typedef struct Custom BLITTER;
- #endif
-
- #if DEBUG
- void dorealblit (hardware)
- BLITTER *hardware;
- {
- OwnBlitter ();
-
- WAITFORBLITTER
-
- custom.bltddat = hardware->bltddat;
- custom.bltcon0 = hardware->bltcon0;
- custom.bltcon1 = hardware->bltcon1;
- custom.bltafwm = hardware->bltafwm;
- custom.bltalwm = hardware->bltalwm;
- custom.bltcpt = hardware->bltcpt;
- custom.bltbpt = hardware->bltbpt;
- custom.bltapt = hardware->bltapt;
- custom.bltdpt = hardware->bltdpt;
- custom.bltcmod = hardware->bltcmod;
- custom.bltbmod = hardware->bltbmod;
- custom.bltamod = hardware->bltamod;
- custom.bltdmod = hardware->bltdmod;
- custom.bltcdat = hardware->bltcdat;
- custom.bltbdat = hardware->bltbdat;
- custom.bltadat = hardware->bltadat;
- custom.bltsize = hardware->bltsize;
-
- DisownBlitter ();
- }
- #endif
-
- #if 0
- if (!mask && !tsbit && !tebit && !fsbit && !febit) {
- /*
- * Use Special Quick Blit.
- */
- } else if (!mask) {
- } else {
- #endif
- /**************************************************************************
- *
- * CopyMaskBitMap
- *
- * SYNOPSIS
- * void CopyMaskBitMap (
- * struct BitMap *frombm,
- * int fromleft,
- * int fromtop,
- * struct BitMap *tobm,
- * int toleft,
- * int totop,
- * int width,
- * int height,
- * UBYTE planemask,
- * UBYTE *mask
- * );
- *
- * FUNCTION
- * Use the blitter to copy from one bitmap to another using a mask
- * for transparency. As far as I can tell if you are blitting from
- * a one word source into a two word destination (example: pixels
- * 10<->13 to 14<->17) you must use two blits (yech!) in the generic
- * case. If are always blitting entire shape clipped to word boundries
- * then use ShapeBlit().
- *
- * INPUTS
- * frombm = pointer to bitmap to copy from
- * fromleft = x position to start copying from
- * fromtop = y position to start copying from
- * tobm = pointer to bitmap to copy to
- * toleft = x position to start copying to
- * totop = y position to start copying to
- * width = width in pixels of area to copy
- * height = height in pixels of area to copy
- * planemask = bitmask of planes to effect, bit0 = plane 0, bit1 = plane1...
- * mask = optional pointer to a mask bitplane of same size as a
- * bitplane in frombm->Planes[0].
- *
- * BUGS
- * NOTE: If you copy from LEFT to RIGHT or TOP to BOTTOM from a bitmap
- * to the SAME bitmap and the areas overlap the area will be trashed
- * (or smeared)
- *
- * HISTORY
- *
- *
- * SEE ALSO
- * ShapeBlit (), CopyBitMap ()
- */
-
- void CopyMaskBitMap (
- frombm,
- fromleft,
- fromtop,
- tobm,
- toleft,
- totop,
- inwidth,
- inheight,
- planemask,
- mask
- )
- struct BitMap *frombm;
- int fromleft;
- int fromtop;
- struct BitMap *tobm;
- int toleft;
- int totop;
- int inwidth;
- int inheight;
- UBYTE planemask;
- UBYTE *mask;
- {
- register ULONG fromoffset;
- register ULONG tooffset;
- BLITTER h;
- register BLITTER *hardware =
- #if DEBUG
- &h;
- #else
- (struct Custom *)0x0DFF000;
- #endif
- UWORD fsword;
- UWORD tsword;
- UWORD newwidth;
- UWORD fend;
- UWORD tend;
- UWORD fsbit;
- UWORD tsbit;
- UWORD febit;
- UWORD tebit;
- UWORD frommod;
- UWORD tomod;
- UWORD shift;
- UWORD bltshift;
- UWORD fbwidth;
- UWORD tbwidth;
- UWORD bltwidth;
- ULONG toptr;
- UWORD size;
- UWORD firstmask;
- UWORD lastmask;
- UWORD othermask;
- UWORD ndx;
- UWORD depth;
- UWORD more;
- UBYTE tempmask;
-
- /* --------------------------------------------------------------------- */
- int width = inwidth;
- int height = inheight;
-
- if (toleft < ClipLeft) {
- width = inwidth - (ClipLeft - toleft);
- toleft = ClipLeft;
- fromleft += inwidth - width;
- } else if (toleft > ClipLeft + ClipWidth - inwidth) {
- width = (ClipLeft + ClipWidth) - toleft;
- }
-
- if (totop < ClipTop) {
- height = inheight - (ClipTop - totop);
- totop = ClipTop;
- fromtop += inheight - height;
- } else if (totop > ClipTop + ClipHeight - inheight) {
- height = (ClipTop + ClipHeight) - totop;
- }
-
- if (width <= 0 || height <= 0) {
- return;
- }
- /* --------------------------------------------------------------------- */
-
- #ifndef DEBUG
- OwnBlitter ();
- #endif
- more = FALSE;
- othermask = 0xFFFF;
-
- tempmask = planemask;
-
- depth = min (frombm->Depth, tobm->Depth);
-
- fsword = fromleft >> 4;
- tsword = toleft >> 4;
-
- newwidth = width - 1;
- fend = fromleft + newwidth;
- tend = toleft + newwidth;
-
- fromoffset = fromtop * frombm->BytesPerRow + (fsword << 1);
- tooffset = totop * tobm->BytesPerRow + (tsword << 1);
-
- fsbit = fromleft & 0x0F;
- tsbit = toleft & 0x0F;
-
- febit = fend & 0x0F;
- tebit = tend & 0x0F;
-
- fbwidth = (fend >> 4) - fsword + 1;
- tbwidth = (tend >> 4) - tsword + 1;
-
- bltwidth = fbwidth;
- shift = (tsbit - fsbit);
- if (shift > 15) {
- bltwidth += 1;
- shift &= 0x0F;
- tooffset -= 2;
- othermask = 0x0000;
- }
-
- firstmask = 0xFFFF >> fsbit;
-
- if (tbwidth > fbwidth) {
- more = TRUE;
- lastmask = 0xFFFF << shift;
- } else {
- lastmask = 0xFFFF << (15 - febit);
- }
-
- frommod = frombm->BytesPerRow - (bltwidth << 1);
- tomod = tobm->BytesPerRow - (bltwidth << 1);
-
- bltshift = shift << 12;
- size = (height << 6) | bltwidth;
-
- mask += fromoffset;
-
- #ifndef DEBUG
- WAITFORBLITTER
- #endif
-
- hardware->bltcon0 = bltshift | 0x0FCA;
- hardware->bltcon1 = bltshift;
- hardware->bltafwm = firstmask;
- hardware->bltalwm = lastmask & othermask;
- hardware->bltamod = frommod;
- hardware->bltbmod = frommod;
- hardware->bltcmod = tomod;
- hardware->bltdmod = tomod;
-
- for (ndx = 0; ndx < depth; ndx++) {
- if (planemask & 0x01) {
- toptr = (ULONG)tobm->Planes[ndx] + (ULONG)tooffset;
- #ifndef DEBUG
- WAITFORBLITTER
- #endif
-
- hardware->bltapt = (APTR)mask;
- hardware->bltbpt = (APTR)((ULONG)frombm->Planes[ndx] + fromoffset);
- hardware->bltcpt = (APTR)toptr;
- hardware->bltdpt = (APTR)toptr;
- hardware->bltsize = size;
-
- #if DEBUG
- dorealblit (hardware);
- #endif
-
- }
- planemask >>= 1;
- }
-
- if (more) {
- bltwidth <<= 1;
- newwidth = bltwidth - 2;
- fromoffset += newwidth;
- mask += newwidth;
- tooffset += newwidth;
-
- frommod = frombm->BytesPerRow - (2 << 1);
- tomod = tobm->BytesPerRow - (2 << 1);
-
- size = (height << 6) | 2;
-
- firstmask = 0xFFFF << (15 - febit);
- lastmask = 0xFFFF >> (((15 - shift) + 1) & 0x0F);
- #ifndef DEBUG
- WAITFORBLITTER
- #endif
-
- hardware->bltafwm = lastmask & firstmask;
- hardware->bltalwm = 0x0000;
- hardware->bltbmod = frommod;
- hardware->bltamod = frommod;
- hardware->bltcmod = tomod;
- hardware->bltdmod = tomod;
-
- for (ndx = 0; ndx < depth; ndx++) {
- if (tempmask & 0x01) {
- toptr = (ULONG)tobm->Planes[ndx] + (ULONG)tooffset;
- #ifndef DEBUG
- WAITFORBLITTER
- #endif
-
- hardware->bltapt = (APTR)mask;
- hardware->bltbpt = (APTR)((ULONG)frombm->Planes[ndx] + fromoffset);
- hardware->bltcpt = (APTR)toptr;
- hardware->bltdpt = (APTR)toptr;
- hardware->bltsize = size;
-
- #if DEBUG
- dorealblit (hardware);
- #endif
-
- }
- tempmask >>= 1;
- }
-
- }
-
-
- #ifndef DEBUG
- DisownBlitter ();
- #endif
-
- }
-
- /**************************************************************************
- *
- * CopyBitMap
- *
- * SYNOPSIS
- * void CopyBitMap (
- * struct BitMap *frombm,
- * int fromleft,
- * int fromtop,
- * struct BitMap *tobm,
- * int toleft,
- * int totop,
- * int width,
- * int height,
- * UBYTE planemask,
- * );
- *
- * FUNCTION
- * Use the blitter to copy from one bitmap to another. If the blit
- * is word aligned (ie. First pixel is the first bit of the first
- * word and last pixel is last bit of the last word) and the same is
- * true for both the source and the destination then this routine will
- * use a special blit (D=A) which is twice as fast as the normal
- * 'clipped' blit (D=AB+~AC).
- *
- * INPUTS
- * frombm = pointer to bitmap to copy from
- * fromleft = x position to start copying from
- * fromtop = y position to start copying from
- * tobm = pointer to bitmap to copy to
- * toleft = x position to start copying to
- * totop = y position to start copying to
- * width = width in pixels of area to copy
- * height = height in pixels of area to copy
- * planemask = bitmask of planes to effect, bit0 = plane 0, bit1 = plane1...
- *
- * HISTORY
- *
- *
- * SEE ALSO
- * ShapeBlit (), CopyMaskBitMap ()
- */
- void CopyBitMap (
- frombm,
- fromleft,
- fromtop,
- tobm,
- toleft,
- totop,
- inwidth,
- inheight,
- planemask,
- )
- struct BitMap *frombm;
- int fromleft;
- int fromtop;
- struct BitMap *tobm;
- int toleft;
- int totop;
- int inwidth;
- int inheight;
- UBYTE planemask;
- {
- register ULONG fromoffset;
- register ULONG tooffset;
- BLITTER h;
- register BLITTER *hardware =
- #if DEBUG
- &h;
- #else
- (struct Custom *)0x0DFF000;
- #endif
- register ULONG newoffset;
- UWORD fsword;
- UWORD tsword;
- UWORD newwidth;
- UWORD fend;
- UWORD tend;
- UWORD fsbit;
- UWORD tsbit;
- UWORD febit;
- UWORD tebit;
- UWORD frommod;
- UWORD tomod;
- UWORD shift;
- UWORD bltshift;
- UWORD fbwidth;
- UWORD tbwidth;
- UWORD bltwidth;
- ULONG toptr;
- UWORD size;
- UWORD firstmask;
- UWORD lastmask;
- UWORD othermask;
- UWORD ndx;
- UWORD depth;
- UWORD control;
-
- /* --------------------------------------------------------------------- */
- int width = inwidth;
- int height = inheight;
-
- if (toleft < ClipLeft) {
- width = inwidth - (ClipLeft - toleft);
- toleft = ClipLeft;
- fromleft += inwidth - width;
- } else if (toleft > ClipLeft + ClipWidth - inwidth) {
- width = (ClipLeft + ClipWidth) - toleft;
- }
-
- if (totop < ClipTop) {
- height = inheight - (ClipTop - totop);
- totop = ClipTop;
- fromtop += inheight - height;
- } else if (totop > ClipTop + ClipHeight - inheight) {
- height = (ClipTop + ClipHeight) - totop;
- }
-
- if (width <= 0 || height <= 0) {
- return;
- }
- /* --------------------------------------------------------------------- */
- depth = min (frombm->Depth, tobm->Depth);
-
- fsword = fromleft >> 4;
- tsword = toleft >> 4;
-
- newwidth = width - 1;
- fend = fromleft + newwidth;
- tend = toleft + newwidth;
-
- fromoffset = fromtop * frombm->BytesPerRow + (fsword << 1);
- tooffset = totop * tobm->BytesPerRow + (tsword << 1);
-
- fsbit = fromleft & 0x0F;
- tsbit = toleft & 0x0F;
-
- febit = fend & 0x0F;
- tebit = tend & 0x0F;
-
- fbwidth = (fend >> 4) - fsword + 1;
- tbwidth = (tend >> 4) - tsword + 1;
- bltwidth = fbwidth;
-
- if (!fsbit && !tsbit && febit == 15 && tebit == 15) {
- frommod = frombm->BytesPerRow - (bltwidth << 1);
- tomod = tobm->BytesPerRow - (bltwidth << 1);
-
- size = (height << 6) | bltwidth;
-
- if (fromoffset < tooffset) {
- control = 0x0002;
- newoffset = (bltwidth - 1) << 1;
- fromoffset += frombm->BytesPerRow * (height - 1) + newoffset;
- tooffset += tobm->BytesPerRow * (height - 1) + newoffset;
- } else {
- control = 0x0000;
- }
-
- #ifndef DEBUG
- OwnBlitter ();
- WAITFORBLITTER
- #endif
-
- hardware->bltcon0 = 0x09F0;
- hardware->bltcon1 = control;
- hardware->bltafwm = 0xFFFF;
- hardware->bltalwm = 0xFFFF;
- hardware->bltamod = frommod;
- hardware->bltdmod = tomod;
-
- for (ndx = 0; ndx < depth; ndx++) {
- if (planemask & 0x01) {
- toptr = (ULONG)tobm->Planes[ndx] + (ULONG)tooffset;
- #ifndef DEBUG
- WAITFORBLITTER
- #endif
-
- hardware->bltapt = (APTR)((ULONG)frombm->Planes[ndx] + fromoffset);
- hardware->bltdpt = (APTR)toptr;
- hardware->bltsize = size;
-
- #if DEBUG
- dorealblit (hardware);
- #endif
-
- }
- planemask >>= 1;
- }
- #ifndef DEBUG
- DisownBlitter ();
- #endif
-
- } else {
-
- BltBitMap (frombm, fromleft, fromtop,
- tobm, toleft, totop,
- width, height, 0xC0, 0xFF, NULL);
-
- #if 0
- shift = (tsbit - fsbit);
-
- if (shift > 15) {
- bltwidth += 1;
- shift &= 0x0F;
- tooffset -= 2;
- othermask = 0x0000;
- }
-
- firstmask = 0xFFFF >> fsbit;
-
- if (tbwidth > fbwidth) {
- more = TRUE;
- lastmask = 0xFFFF << shift;
- } else {
- lastmask = 0xFFFF << (15 - febit);
- }
-
- frommod = frombm->BytesPerRow - (bltwidth << 1);
- tomod = tobm->BytesPerRow - (bltwidth << 1);
-
- bltshift = shift << 12;
- size = (height << 6) | bltwidth;
-
- mask += fromoffset;
-
- #ifndef DEBUG
- WAITFORBLITTER
- #endif
-
- hardware->bltcon0 = bltshift | 0x0FCA;
- hardware->bltcon1 = bltshift;
- hardware->bltafwm = firstmask;
- hardware->bltalwm = lastmask & othermask;
- hardware->bltamod = frommod;
- hardware->bltbmod = frommod;
- hardware->bltcmod = tomod;
- hardware->bltdmod = tomod;
-
- for (ndx = 0; ndx < depth; ndx++) {
- if (planemask & 0x01) {
- toptr = (ULONG)tobm->Planes[ndx] + (ULONG)tooffset;
- #ifndef DEBUG
- WAITFORBLITTER
- #endif
-
- hardware->bltapt = (APTR)mask;
- hardware->bltbpt = (APTR)((ULONG)frombm->Planes[ndx] + fromoffset);
- hardware->bltcpt = (APTR)toptr;
- hardware->bltdpt = (APTR)toptr;
- hardware->bltsize = size;
-
- #if DEBUG
- dorealblit (hardware);
- #endif
-
- }
- planemask >>= 1;
- }
- #endif
- }
- }
-
-