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));
}