[net.sources.mac] source to rae demo

sdh@joevax.UUCP (The Doctor) (08/22/86)

/* rae.c */
/* this is the demo "rae" originally written for blit terminals
 * converted to the Macintosh in Aztec C version 1.06H
 * Steve Hawley 8/22/86
 *
 * I can't vouch for the code for rae. It was copied directly.
 * I only changed the system commands and initialization sequence.
 */
#include <quickdraw.h>
#include <event.h>
#include <osutil.h>

#define HEIGHT  16
#define WIDTH   16
#define XMIN    0
#define YMIN    0
#define XMAX    511
#define YMAX    341
#define TOP     YMIN
#define BOT     (YMAX-1)

int     GND[128];
int     xpos;

GrafPort myPort;

/* This is the bits for the face that gets bounced around.
 * the original rae used just circles.
 */
static unsigned char facebits[32] = {
	0x07, 0xe0, 0x18, 0x18, 0x20, 0x04, 0x42, 0x42, 0x42, 0x42,
	0x82, 0x41, 0x80, 0x01, 0x80, 0x01, 0x84, 0x21, 0x88, 0x11,
	0x94, 0x29, 0x43, 0xc2, 0x40, 0x02, 0x20, 0x04, 0x18, 0x18,
	0x07, 0xe0
};

struct BitMap face;

main ()
{
	Rect myRect, trect;

	register i;
	register time;
	int x, xx, y, yy, xvel, yvel, xacc, yacc, ypos, offset;
	long waste;


	InitGraf(&thePort);
	OpenPort(&myPort); /* create my own port so I don't need */
		           /* windows and can blacken the whole screen */
	
	HideCursor();
	SetRect(&myRect, 0, 0, XMAX+1, YMAX+1);
	PenPat(black);
	PaintRect(&myRect); /* clear screen to black */
	
	face.baseAddr = &facebits[0]; /* set up bitmap parameters */
	face.rowBytes = 2;
	SetRect(&face.bounds, 0, 0, 16, 16);
	
Again:
	PenPat(white);
	MoveTo(XMIN, YMIN); 
	LineTo(XMIN, YMAX);
	MoveTo(XMIN, YMAX); 
	LineTo(XMAX, YMAX);
	MoveTo(XMAX, YMAX);
	LineTo(XMAX, YMIN);
	PenPat(black);

	for (i=0; i<128; i++) {
		x = i<<3;
		if (x <= XMIN+8 || x >= XMAX-8)
			GND[i] = 0;
		else {
			GND[i] = BOT - 9;
			if (i&01)
				if (GND[i-1]==0)
					GND[i] = 0;
				else
					GND[i] -= 7;
		}
	}
	while (!Button()) { /* was a readkey command */
		xpos = Random() & 0177;
		if (GND[xpos] <= TOP) {
			Delay(1L, &waste); /* was a sleep() call. Waits 1/60 second */
			continue;
		}
		x = xpos << 3;
		xvel = 4 - ((Random()|01)&07);
		yacc = 1;
		yvel = 0;
		y = TOP;
		for (time = 0;; time++) {
			if (Button()) /* was a read key command */
				return;
			drawit(x,y);
			xx = x; 
			yy = y;         /* save x and y */
			yvel += yacc;
			y += yvel;
			x += xvel;
			if (y > GND[x>>3]) {	/* bounce? */
				if (yvel>5) {
					drawit(xx, yy);
					drawit(x, y);
					Delay(1L, &waste);
					drawit(x, y);
					drawit(xx, yy);
				}
				if (y <= GND[xx>>3]) { /* side collision? */
					x = xx;
					xvel = -xvel;
				} else if (yy <= GND[x>>3]) { /*bottom? */
					y = yy;
					yvel = -yvel;
				} else {	/* corner */
					x = xx;
					y = yy;
					xvel = -xvel;
					yvel = -yvel;
				}
				if ((time & 017)==0)
					xvel = decay(xvel);
				if (xvel == 0) {
					xpos = x>>3;
					if (GND[xpos-1]<GND[xpos]
					 && GND[xpos]<GND[xpos+1])
						xvel = 1;
					/* roll left */
					else if (GND[xpos-1]>GND[xpos]
					      && GND[xpos]>GND[xpos+1])
						xvel = -1;
					/* on hilltop */
					else if (GND[xpos-1]>GND[xpos]
					      && GND[xpos]<GND[xpos+1]) {
						if (Random() & 01)
							xvel = 1;
						else
							xvel = -1;
					}
				}
				yvel = decay(yvel);
			}
			Delay(1L, &waste);
			drawit(xx,yy);
			if (xvel==0 && yvel==0 && y > GND[x>>3]-4)
				break;
		}
		for (;;) {
			/* find stable position */
			if (GND[xpos-1]<GND[xpos] && GND[xpos]>GND[xpos+1]) {
				drawit(xpos<<3, GND[xpos]);
				GND[xpos] -= 21;
				if (GND[xpos-1]<=0)
					GND[xpos] -= 7;
				GND[xpos+1] -= 7;
				break;
			}
			/* roll right */
			if (GND[xpos-1]<GND[xpos] && GND[xpos]<GND[xpos+1]) {
				xpos++;
				continue;
			}
			/* roll left */
			if (GND[xpos-1]>GND[xpos] && GND[xpos]>GND[xpos+1]) {
				xpos--;
				continue;
			}
			/* on hilltop, choose at Random */
			if (GND[xpos-1]>GND[xpos] && GND[xpos]<GND[xpos+1]) {
				if (Random() & 01)
					xpos++;
				else
					xpos--;
				continue;
			}
			/* else botch */
			drawit(xpos<<3, GND[xpos]);
			PaintRect(&myRect); /* was a call to f_rect() */
			break;
		}
	}
}

drawit(x,y)
int x,y;
{       
	int i;
	Rect trect;

	if (x<XMIN)
		x = XMIN+8;
	if (y<TOP)
		y = TOP+8;
	if (x>XMAX)
		x = XMAX-8;
	xpos = x>>3;
	if (y>GND[xpos])
		y = GND[xpos];
	/* was a call to bitblt() */
	SetRect(&trect, x-12, y-8, x+4, y+8);
	CopyBits(&face, &myPort.portBits, &face.bounds, &trect, srcXor, 0L);
}

decay(v)
register v;
{
	if (v==0)
		return(v);
	if (v > 0)
		return(v-1-(v>>3));
	return(v+1-(v>>3));
}