the famous "crabs" program ported

Bill Carpenter wjc at ho5cad.ATT.COM
Tue Nov 14 05:22:24 AEST 1989


Attached below is the source for the famous "crabs" program, ported to
run on the UNIXpc (with or without the Botton "vidpal" video ram
access hardware mod).  See the simple compile instructions in the
comments near the top of the code.

If you have the video access hardware mod (or are thinking of getting
it), you will also want the source for "blitlib.a" to do direct memory
raster operations (instead of via a system call).  Watch for that in a
separate posting in these groups within a day or two.

BTW, this was posted to comp.sources.games earlier this year.  The
code still works on 5620 and 630 terminals.  The email address of the
original author is "gwyn at smoke.brl.mil".  I also recommend that you
find the cited article in Scientific American (*after* you've seen
this running).
--
   Bill Carpenter att!ho5cad!wjc or attmail!bill

-------------------------------< crabs.c >---------------------------------
/*
    crabs -- see September 1985 Scientific American pages 18..23

    last edit:    89/02/25    D A Gwyn

    SCCS ID:    @(#)crabs.c    1.3    for 5620 DMD and 630 MTG

To compile:
    $ dmdcc -o crabs.m crabs.c    # -g -O also recommended

To run:
    $ dmdld crabs.m            # runs only in mpx mode
or
    $ dmdld crabs.m -        # for invisible crabs
*/
#if defined(unixpc)
/*
**
** UNIXpc version, mods by Bill Carpenter, Oct/Nov '89
**                         att!ho5cad!wjc  william_j_carpenter at att.com
**                         attmail!bill
**
**   cc -O -c -Dunixpc crabs.c
**   ld -s /lib/crt0s.o /lib/shlib.ifile -o crabs crabs.o
**
**   cc -O -c -Dunixpc -Dvidpal crabs.c
**   ld -s /lib/crt0s.o /lib/shlib.ifile -o crabs crabs.o blitlib.a
**
** The second version works with both normal machines and those with the
** "vidpal" video ram access modification.  It determines at run time if
** you have it.  If you have it, it will run on screen memory directly;
** else, it will operate within the confines of the window from which it
** is called using the kernel-based raster stuff.
**
** For the second form, you need blitlib.a.  That's the bitblit library
** from the "mgr" window manager.  Posted a while back to
** comp.sources.unix.  You also need bitmap.h from that library.
**
** There are at least a couple variations on blitlib.a.  In the "mgr"
** source posted to c.s.unix, there were 68020 assembler and
** machine-independent C versions.  The latter runs on the UNIXpc, but it
** draws things incorrectly (I think due to byte ordering and alignment
** differences from sun2's).  In later versions of "mgr" (which include a
** port to DEC3100), there is a new portable version of blitlib.a.  Out
** of the box, it needs some configuration for the UNIXpc (and perhaps a
** few minor bugfixes?).
**
** If you have some other bitblit routine available to you, you shouldn't
** have too much trouble getting this code to work with it.  There are
** only a couple different of bitblit operations used in this program.
**
** All of the code specific to the UNIXpc port is identified by
**
**    #if defined(unixpc)
**
** Code specific to use of the VIDPAL hardware mod (including the
** autodetection that you don't have it) if identified by
**
**    #if defined(vidpal)
**
** and is a subset of the UNIXpc mods.
*/
#endif /* unixpc */

#ifndef lint
static char    SCCS_ID[] = "@(#)crabs.c    1.3 89/02/25";    /* for "what"
 utility */
#endif

#ifdef unixpc
#  include <stdio.h>
#  include <sys/signal.h>
#  include <sys/window.h>
#  ifdef vidpal
#    include "bitmap.h"
#  endif
#  define XMIN    0
#  define YMIN    12  /* to keep from being completely annoying */
#else
#  define XMIN    0
#  define YMIN    0
#endif

short xmin = XMIN;
short ymin = YMIN;

#ifdef unixpc
#  define XMAX  720
#  define YMAX  348

/*
** The scheme for detecting if you have the vidpal board is to try to
** access video memory.  This forces either a bus error or a segmentation
** violation (not sure which) if you don't have it, since it's a
** privileged address.  But, since you might want to compile without the
** vidpal option even if you have the board, I #ifdef'd it to another
** address that is equally illegal.
*/
#    ifdef vidpal
#      define UNIXPC_VIDEO ((unsigned short *)0x420000)
#    else
#      define UNIXPC_VIDEO ((unsigned short *)0x41ffff)
#    endif

  int single_window_fd = -1;
  typedef struct {unsigned short us[16];} Texture16;
  typedef unsigned short Word;
  typedef struct {short x; short y} Point;
  typedef struct {Point origin; Point corner} Rectangle;
  typedef struct
  {
	Word *base;
	unsigned short width;
	Rectangle rect;
  } Bitmap;

  /* warning "Pt" and "Rect" use overlaid static space in these definitions */
  Point
  Pt(x,y)
  short x,y;
  {
	static Point scratch;
	scratch.x = x;
	scratch.y = y;
	return (scratch);
  };
  Rectangle
  Rect(ox,oy,cx,cy)
  short ox,oy,cx,cy;
  {
	static Rectangle scratch;
	scratch.origin.x = ox;
	scratch.origin.y = oy;
	scratch.corner.x = cx;
	scratch.corner.y = cy;
	return (scratch);
  };

#  define F_STORE  DSTSRC
#  define F_XOR    DSTXOR
#  define WORDSIZE 16
#  define display crabs_physical

#else /* below is !unixpc */
#  include    <dmd.h>
#endif

#ifdef DMD630

#define    texture16    texture
#define    crabs_T_background  T_background
#define    crabs_physical  physical

#else

static Texture16    crabs_T_background =        /* background texture */
    {
#if defined(unixpc)  /* this difference due to bit order within words */
    0x2222, 0x8888, 0x2222, 0x8888,
    0x2222, 0x8888, 0x2222, 0x8888,
    0x2222, 0x8888, 0x2222, 0x8888,
    0x2222, 0x8888, 0x2222, 0x8888
#else
    0x1111, 0x4444, 0x1111, 0x4444,
    0x1111, 0x4444, 0x1111, 0x4444,
    0x1111, 0x4444, 0x1111, 0x4444,
    0x1111, 0x4444, 0x1111, 0x4444
#endif
    };

static Bitmap    crabs_physical =        /* full screen definition */
    {
#ifdef unixpc
    (Word *)UNIXPC_VIDEO,     /* without hardware mod, this dumps core */
    (XMAX + 15) / 16,        /* bitmap width in 16-bit Words */
#else
    (Word *)0x700000L,        /* DMD screen image base address */
    (XMAX + 31) / 32,        /* bitmap width in 32-bit Words */
#endif
    0, 0, XMAX, YMAX        /* screen rectangle within bitmap */
    };

#endif

#define    NCRABS   32            /* total number of crabs (1..32) */

#define    MAXVEL    8            /* abs. bound on velocity component */

#define    PERIOD    2            /* sleep time (ticks) per cycle */


typedef int    bool;            /* Boolean data type */
#define    false    0
#define    true    1


static bool    visible;        /* true if crabs are to be shown */

static struct
    {
    Point    ulc;            /* upper left corner screen coords */
    Point    vel;            /* velocity (pixels/cycle) */
    }    crab[NCRABS];        /* keeps track of crabs' state */
/* We rely on this forcing the following arrays to be Word-aligned! */

/* There are 4 possible crab orientations, each of which
   has 4 possible relationships with the grey background.
   (Scientific American article says 8, but it's wrong.) */

/* Crab images XORed with grey background texture at various offsets: */

static short    upcrab[] =        /* facing up */
    {
    0x6E4C, 0x2A66,
    0xB377, 0xE6D5,
    0x8081, 0x8101,
    0xB935, 0xAC9D,
    0x6E5C, 0x3A76,
    0x3A76, 0x6E5C,
    0xAC9D, 0xB935,
    0x0242, 0x4240
    };

static short    downcrab[] =        /* facing down */
    {
    0x4240, 0x0242,
    0xB935, 0xAC9D,
    0x6E5C, 0x3A76,
    0x3A76, 0x6E5C,
    0xAC9D, 0xB935,
    0x8101, 0x8081,
    0xEECD, 0xAB67,
    0x3276, 0x6654
    };

static short    rightcrab[] =        /* facing right */
    {
    0x4E4C, 0x0A46,
    0xB333, 0xA291,
    0x6A59, 0x3B73,
    0x3A72, 0x6A58,
    0x6859, 0x3971,
    0x3B73, 0x6A59,
    0xA291, 0xB333,
    0x0A46, 0x4E4C
    };

static short    leftcrab[] =        /* facing left */
    {
    0x6250, 0x3272,
    0x8945, 0xCCCD,
    0xCEDC, 0x9A56,
    0x9A16, 0x8E9C,
    0x4E5C, 0x1A56,
    0x9A56, 0xCEDC,
    0xCCCD, 0x8945,
    0x3272, 0x6250
    };

/* The bitmaps for the four orientations: */

static Bitmap    upmap = { (Word *)upcrab, 32/WORDSIZE, 0, 0, 32, 8 };
static Bitmap    downmap = { (Word *)downcrab, 32/WORDSIZE, 0, 0, 32, 8 };
static Bitmap    rightmap = { (Word *)rightcrab, 32/WORDSIZE, 0, 0, 32, 8 };
static Bitmap    leftmap = { (Word *)leftcrab, 32/WORDSIZE, 0, 0, 32, 8 };

/* Crab "vicinities" are recorded in the following
   global map; see Collide() and Draw() for details: */

static long    vicinity[(XMAX + 31) / 32 + 2][(YMAX + 31) / 32 + 2];
                    /* includes margins all around */

static void    Cycle(), DrawCrab(), HideCrabs(), Init(), ModVel(), NewVel();
static int    RandInt();
static long    Collide();

#ifdef unixpc
  core_dump_catcher(ziggy)
  int ziggy;
  {
	/*
	** Caught what would normally be a core cump due to an invalid memory
	** reference.  That means we should revert to single-window mode and
	** use ioctl(WIOCRASTOP) for bitblits.
	**
	** Set crabs_physical.base = 0 to make blits window-relative.  Set ymin = 0
	** to start with the very top scan line (instead of specially
	** protecting the very top line of characters [usually done in
	** full-screen mode].)
	**
	** Set the file descriptor to use standard input as the window
	** descriptor for the ioctl().  Having this variable non-negative is
	** also the runtime flag that that's what we want instead of direct
	** memory writes.
	**
	** We leave the XMAX,YMAX to be the size of the full display.  We
	** could make them variables (they are #define constants now) and
	** reset them here to the bounds of the actual windows.  We could
	** also catch SIGWIND and change them accordingly on window reshapes.
	** I didn't do it because single-window mode isn't nearly as exciting
	** as full-screen mode in the first place.
	*/
	single_window_fd = 0;
	crabs_physical.base = 0;
	ymin = 0;
	signal(ziggy, core_dump_catcher);
  }
#endif
main( argc, argv )
    int    argc;
    char    *argv[];
    {
#ifdef unixpc
		/*
		** Force autodetection of vidpal board by referencing video
		** memory.  Notice that if your compiler optimizes out this
		** otherwise pointless reference, the reset won't take place
		** until the first round of legit bitblits.  I'm not sure what
		** kind of mischief that causes.  If you haven't used the
		** -Dvidpal compile option, we just unconditionally force
		** detection of a standard machine.
		*/
		int fdex;
#ifdef vidpal
		signal(SIGSEGV, core_dump_catcher);
		signal(SIGBUS, core_dump_catcher);
		fdex = *UNIXPC_VIDEO; /* don't optimize me out of existence */
#else
		core_dump_catcher(SIGBUS);
#endif
		/*
		** Close all the file descriptors so that you can run this in the
		** background and exit without leaving the window hanging around.
		*/
		for (fdex=80; fdex<80; ++fdex)
		{
			if (fdex != single_window_fd) close(fdex);
		}
		nice(19);
#endif
#ifdef DMD630
    local();
#endif
    Init( argc, argv );        /* set up initial grey crab layer */

    for ( ; ; )            /* no way out! */
        {
#ifndef unixpc
        /*
        ** On the UNIXpc, sleep is in units of one second, much too big
        ** for crabs.  Also, we don't have the resource contention
        ** situation that the 5620/630's have.  So, skip the sleep and
        ** just "nice()" it (see above).
        */
        sleep( PERIOD );    /* relinquish the processor */
#endif

        Cycle();        /* move the crabs */
        }
    /*NOTREACHED*/
    }


static void
Init( argc, argv )            /* set up initial crab layer */
    int    argc;
    char    *argv[];
    {
    int    i;            /* crab # */

    visible = argc <= 1;        /* default is to show crabs */

#ifndef unixpc
    /*
    ** This pre-eats the window from which the crabs are downloaded on
    ** the 5620/630.  Since we're treating that as the whole screen or
    ** the whole single-window for the UNIXpc, that means that the entire
    ** interesting area is done at startup.  Much less interesting than
    ** on the DMDs.
    */
    texture16( &display, display.rect, &crabs_T_background, F_STORE );
                    /* crab layer */
#endif

    /* Create initial set of crabs: */

    for ( i = 0; i < NCRABS; ++i )
        {
        /* Assign random position within "crabs" layer: */

        crab[i].ulc.x = RandInt( display.rect.origin.x,
                     display.rect.corner.x - 8
                       );
        crab[i].ulc.y = RandInt( display.rect.origin.y,
                     display.rect.corner.y - 8
                       );

        /* Assign random velocity: */

        NewVel( i );

        /* Draw crab at initial position (within "crabs" layer): */

        if ( visible )
            DrawCrab( i );
        }


#ifndef unixpc
    /*
    ** For the equivalent on the UNIXpc, just run nohup'd and in the
    ** background.
    */
    display.rect.corner = display.rect.origin;    /* make unpickable */
#endif
    }


static void
Cycle()                    /* one motion cycle for all crabs */
    {
    static long    old[8];        /* old contents of new crab position */
    static Bitmap    oldmap = { (Word *)old, 32/WORDSIZE, 0, 0, 8, 8 };
    Point        p;        /* new crab upper left corner */
    Rectangle    r;        /* new crab area */
    long        syndrome;    /* crab collision mask */
    int        i;        /* crab # */
    int        w;        /* index for old[.] */

    for ( i = 0; i < NCRABS; ++i )
        {
        DrawCrab( i );        /* erase crab from previous position */

        for ( ; ; )        /* determine a new position */
            {
            p.x = crab[i].ulc.x + crab[i].vel.x;    /* motion */
            p.y = crab[i].ulc.y + crab[i].vel.y;

            if ( p.x >= xmin && p.x < XMAX - 8
              && p.y >= ymin && p.y < YMAX - 8
               )
                break;    /* on-screen, proceed */

            /* Bounce off edge of screen: */

            NewVel( i );    /* assign new velocity */
            }

        r.origin = p;
        r.corner.x = p.x + 8;
        r.corner.y = p.y + 8;

        /* Check for collision with other crabs;
           if you don't worry about this, you get
           crud left behind from crab collisions
           (visible in Scientific American article).
           (Note that crab # i has been removed.) */

        /* The strategy is: only undraw possibly colliding crabs.
           The obvious alternative, not showing any crabs until
           all locations have been painted, would probably cause
           the set of crabs to flicker or to appear too faint. */

        if ( (syndrome = Collide( p )) != 0L )
            HideCrabs( syndrome );    /* save from following code */

        /* Save old contents of new crab location: */

        bitblt( &crabs_physical, r, &oldmap, Pt( 0, 0 ), F_STORE );

        /* Paint the new location grey: */

        texture16( &crabs_physical, r, &crabs_T_background, F_STORE );

        /* Determine if new location used to be grey: */

        bitblt( &crabs_physical, r, &oldmap, Pt( 0, 0 ), F_XOR );

        for ( w = 0; w < 8; ++w )
            if ( old[w] != 0L )
                {    /* this location has been nibbled */
                p = crab[i].ulc;    /* reset position */

                NewVel( i );    /* bounce away from bite */

                break;
                }

        if ( syndrome != 0L )
            HideCrabs( syndrome );    /* bring them back */

        /* Draw the crab in its new position: */

        crab[i].ulc = p;

        ModVel( i );        /* randomly alter crab velocity */

        DrawCrab( i );
        }
    }


static long
Collide( p )                /* return syndrome for crab collision */
    Point    p;            /* crab upper left corner */
    {
    long    syndrome;        /* accumulate syndrome here */
    bool    right = p.x % 32 > 32 - 8,
        down = p.y % 32 > 32 - 8;    /* more than one vicinity? */
    int    x32 = p.x / 32,
        y32 = p.y / 32;        /* vicinity array indices */

    /* "Or" in crabs from overlapping vicinities: */

    syndrome = vicinity[x32 + 1][y32 + 1];
    if ( right )
        syndrome |= vicinity[x32 + 1 + 1][y32 + 1];
    if ( down )
        syndrome |= vicinity[x32 + 1][y32 + 1 + 1];
    if ( right && down )
        syndrome |= vicinity[x32 + 1 + 1][y32 + 1 + 1];

    return syndrome;
    }


static void
HideCrabs( syndrome )            /* draw crabs contained in syndrome */
    long    syndrome;        /* syndrome (crab bit flags) */
    {
    int    i;            /* indexes crab[.] */
    long    m;            /* bit mask for crab # i */

    for ( m = 1L, i = 0; i < NCRABS; m <<= 1, ++i )
        if ( (m & syndrome) != 0L )    /* crab contained in syndrome */
            DrawCrab( i );    /* toggle crab */
    }


static void
DrawCrab( i )                /* draw specified crab */
    int    i;            /* crab # (0..NCRABS-1) */
    {
    Point    p;            /* upper left corner for crab image */
    Point    v;            /* crab velocity */
    Bitmap    *whichmap;        /* -> 1 of 4 possible orientations */
    int    index;            /* selects 1 of 4 offsets wrt grey */
    int    x32, y32;        /* vicinity array indices */
    bool    right, down;        /* more than one vicinity? */
    long    syn_bit;        /* crab possible-occupancy bit */

    if ( visible )
        {
        p = crab[i].ulc;
        v = crab[i].vel;

        if ( abs( v.x ) >= abs( v.y ) )
            if ( v.x > 0 )
                whichmap = &upmap;
            else
                whichmap = &downmap;
        else
            if ( v.y > 0 )
                whichmap = &rightmap;
            else
                whichmap = &leftmap;

        index = (p.x + p.y * 2) % 4 * 8;
        bitblt( whichmap,
            Rect( index, 0, index + 8, 8 ),
            &crabs_physical,
            p,
            F_XOR
              );

        /* A crab's vicinities are the disjoint 32x32 regions
           that contain any piece of the crab's 8x8 square.
           On the average, 9 out of 16 crabs occupy just 1
           vicinity; 6 out of 16 crabs occupy 2 vicinities,
           and 1 out of every 16 crabs occupies 4 vicinities. */

        x32 = p.x / 32;
        y32 = p.y / 32;        /* coords for upper left vicinity */

        right = p.x % 32 > 32 - 8;    /* also next vicinity right? */
        down = p.y % 32 > 32 - 8;    /* also next vicinty down? */

        /* Toggle crab's occupancy bit in all occupied vicinities: */

        syn_bit = i == 0 ? 1L : 1L << i;

        vicinity[x32 + 1][y32 + 1] ^= syn_bit;
        if ( right )
            vicinity[x32 + 1 + 1][y32 + 1] ^= syn_bit;
        if ( down )
            vicinity[x32 + 1][y32 + 1 + 1] ^= syn_bit;
        if ( right && down )
            vicinity[x32 + 1 + 1][y32 + 1 + 1] ^= syn_bit;
        }
    /* else nibble away but don't show crabs */
    }


static void
NewVel( i )                /* assign new velocity to crab */
    int    i;            /* crab # */
    {
    crab[i].vel.x = RandInt( 1 - MAXVEL, MAXVEL );
    crab[i].vel.y = RandInt( 1 - MAXVEL, MAXVEL );

    /* Velocity (0,0) is okay since we repeatedly modify all velocities. */
    }


static void
ModVel( i )                /* randomly modify crab velocity */
    int    i;            /* crab # */
    {
    int    d;            /* increment */

    if ( crab[i].vel.x >= MAXVEL - 1 )
        d = RandInt( -1, 1 );
    else if ( crab[i].vel.x <= 1 - MAXVEL )
        d = RandInt( 0, 2 );
    else
        d = RandInt( -1, 2 );

    crab[i].vel.x += d;

    if ( crab[i].vel.y >= MAXVEL - 1 )
        d = RandInt( -1, 1 );
    else if ( crab[i].vel.y <= 1 - MAXVEL )
        d = RandInt( 0, 2 );
    else
        d = RandInt( -1, 2 );

    crab[i].vel.y += d;
    }


static int
RandInt( lo, hi )            /* generate random integer in range */
    int    lo, hi;            /* range lo..hi-1 */
    {
    return lo + (int)((long)(hi - lo) * (long)(rand() & 0x7FFF) / 32768L);
    }



#ifdef unixpc

int
texture16(dest, inner, pattern, operation)
Bitmap *dest;
Rectangle inner;
Texture16 *pattern;
int operation;
{
	/*
	** Paint the inner rectangle with the pattern.  We take advantage of
	** the fact that we know the operation will always be a straight
	** STORE.
	*/
	if (single_window_fd >= 0)
	{
		struct urdata ww;
		ww.ur_srcbase	= dest->base;
		ww.ur_srcwidth	= dest->width * 2;
		ww.ur_dstbase	= dest->base;
		ww.ur_dstwidth	= dest->width * 2;
		ww.ur_srcx		= inner.origin.x;
		ww.ur_srcy		= inner.origin.y;
		ww.ur_dstx		= inner.origin.x;
		ww.ur_dstx		= inner.origin.x;
		ww.ur_dsty		= inner.origin.y;
		ww.ur_width		= inner.corner.x - inner.origin.x;
		ww.ur_height	= inner.corner.y - inner.origin.y;
		ww.ur_srcop		= SRCPAT;
		ww.ur_dstop		= DSTSRC;
		ww.ur_pattern	= pattern->us;
		ioctl(single_window_fd, WIOCRASTOP, &ww);
	}
#ifdef vidpal
	else
	{
		/*
		** These mod 8's work because we need alignment of the pattern
		** stuff (which repeats %4 horizontal and %2 veritical).  We know
		** from the semantics of the program that the rectangle we're
		** moving is always 8x8.  Using %8 gives the least multiword
		** blits while leaving some flexibility to modify the pattern
		** later without clobbering this.
		*/
		int ax = inner.origin.x % 8;
		int ay = inner.origin.y % 8;
		int mgrblit_operation;
		BITMAP mgrblit_s, mgrblit_d;
		if (operation == F_STORE)
		{
			mgrblit_operation = BIT_SRC;
		}
		else if (operation == F_XOR)
		{
			mgrblit_operation = BIT_XOR;
		}
		mgrblit_s.data = pattern->us;
		mgrblit_d.data = dest->base;
		mgrblit_s.primary = &mgrblit_s;
		mgrblit_d.primary = &mgrblit_d;
		mgrblit_s.x0 = 0;
		mgrblit_d.x0 = 0;
		mgrblit_s.y0 = 0;
		mgrblit_d.y0 = 0;
		mgrblit_s.wide = 16;
		mgrblit_d.wide = dest->width * 16;
		mgrblit_s.high = 16;
		mgrblit_d.high = dest->rect.corner.y   - dest->rect.origin.y;
		mgrblit_s.type = _STATIC;
		mgrblit_d.type = _STATIC;
		bit_blit(&mgrblit_d, inner.origin.x, inner.origin.y,
		         inner.corner.x - inner.origin.x, inner.corner.y - inner.origin.y,
		         mgrblit_operation,
				 &mgrblit_s, ax, ay);
	}
#endif
	return (0);
}

int
bitblt(source, mvrect, dest, destorigin, operation)
Bitmap *source;
Bitmap *dest;
Point destorigin;
int operation;
Rectangle mvrect;
{
	if (single_window_fd >= 0)
	{
		struct urdata ww;
		ww.ur_srcbase	= source->base;
		ww.ur_srcwidth	= source->width * 2;
		ww.ur_dstbase	= dest->base;
		ww.ur_dstwidth	= dest->width * 2;
		ww.ur_srcx		= mvrect.origin.x;
		ww.ur_srcy		= mvrect.origin.y;
		ww.ur_dstx		= destorigin.x;
		ww.ur_dsty		= destorigin.y;
		ww.ur_width		= mvrect.corner.x - mvrect.origin.x;
		ww.ur_height	= mvrect.corner.y - mvrect.origin.y;
		ww.ur_srcop		= SRCSRC;
		ww.ur_dstop		= operation;
		ww.ur_pattern	= 0;
		ioctl(single_window_fd, WIOCRASTOP, &ww);
	}
#ifdef vidpal
	else
	{
		int mgrblit_operation;
		BITMAP mgrblit_s, mgrblit_d;
		if (operation == F_STORE)
		{
			mgrblit_operation = BIT_SRC;
		}
		else if (operation == F_XOR)
		{
			mgrblit_operation = BIT_XOR;
		}
		mgrblit_s.data = source->base;
		mgrblit_d.data = dest->base;
		mgrblit_s.primary = &mgrblit_s;
		mgrblit_d.primary = &mgrblit_d;
		mgrblit_s.x0 = 0;
		mgrblit_d.x0 = 0;
		mgrblit_s.y0 = 0;
		mgrblit_d.y0 = 0;
		mgrblit_s.wide = source->rect.corner.x - source->rect.origin.x;
		mgrblit_d.wide = dest->rect.corner.x   - dest->rect.origin.x;
		mgrblit_s.wide = source->width * 16;
		mgrblit_d.wide = dest->width * 16;
		mgrblit_s.high = source->rect.corner.y - source->rect.origin.y;
		mgrblit_d.high = dest->rect.corner.y   - dest->rect.origin.y;
		mgrblit_s.type = _STATIC;
		mgrblit_d.type = _STATIC;
		bit_blit(&mgrblit_d, destorigin.x, destorigin.y,
		         mvrect.corner.x - mvrect.origin.x, mvrect.corner.y - mvrect.origin.y,
		         mgrblit_operation,
				 &mgrblit_s, mvrect.origin.x, mvrect.origin.y);
	}
#endif
	return (0);
}
#endif



More information about the Unix-pc.sources mailing list