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