#include #include #include #include #include #define PI 3.14159265359879323846 const int FRAMERATE = 2000; /* frame rate in microseconds */ const int SCREEN_ROWS = 24; const int SCREEN_COLS = 80; const int MAX_ROW = SCREEN_ROWS-5; const int MAX_COL = SCREEN_COLS-9; const double THETA = PI/4; const double T = .01; double X0 = 0; double Y0 = 13; double V0 = 1.3; double F = .1; double g = -2.98; bool end = false; bool sound = false; void beep(); void erase_all(); void position (int row,int column); int u_sleep(unsigned int usec); /* sleep for specified number of microsecs */ void print_ball(int row, int col); void find_position(int& row, int& col, double& t); int main (int argc, char *argv[]) { extern int optind; extern int opterr; optarg = NULL; int opt; int errflg = 0; int count = 0; double t = 0; int row, col; if (argc > 1) { while ((opt = getopt(argc, argv, "v:b")) != EOF) { switch (opt) { case 'v': V0 = atof(optarg); if (V0 < 0 || V0 > 10.0) { fprintf (stderr, "Please specify a velocity between 0 and 10.0\n"); exit(2); } break; case 'b': sound = true; break; default: errflg++; } } if (errflg) { fprintf (stderr, "Usage: ball [-b][-v velocity]\n"); exit (2); } } for ( ; optind < argc; optind++) { count++; if (count > 0) { printf ("ball: Too many arguments.\n"); exit (2); } } while (!end) { erase_all(); find_position(row, col, t); print_ball(row, col); u_sleep(FRAMERATE); t+=T; } } void find_position(int& row, int& col, double& t) { static double px = X0; static double py = Y0; static double vy = V0*sin(THETA); static double vx = V0*cos(THETA); vy = vy + g*T; px = px + vx; py = py + vy; row = (int) py; col = (int) px; if (py <= 0 || py >= MAX_ROW) { if (vy != 0) { if (vy < F && vy > -F) { vy = 0; } else { vy = vy > 0 ? vy-F : vy+F; vy = -vy; } } } if (px <= 0 || px >= MAX_COL) { if (vx != 0) { if (vx < F && vx > -F) { vx = 0; } else { vx = vx > 0 ? vx-F : vx+F; vx = -vx; } } } if (px > MAX_COL) { px = MAX_COL; } else if (px < 0) { px = 0; } if (py > MAX_ROW) { py = MAX_ROW; } else if (py < 0) { py = 0; } /* if (row <= 0 || row >=MAX_ROW) { vy-=F; if (vy != 0) { if (vx >= .001) { vx-=.001; } else { vx = 0; } vy = -vy; } */ } void print_ball(int row, int col) { static int stationary = 0; int i; col = col % SCREEN_COLS + 1; if (row<=0) { stationary++; if (stationary > 10) { end = true; } if (stationary==1 && sound) { beep(); } } else { stationary = 0; } if (row < 0) { row = 0; } if (row > MAX_ROW) { row = MAX_ROW; } row = MAX_ROW-row; position(row, col); printf(" .LLII:.\n"); position(row+1, col); printf(" ANEFLI::.\n"); position(row+2, col); printf(" NMARYLLI:\n"); position(row+3, col); printf(" VWWNNHEF+\n"); position(row+4, col); printf(" `VWWWV'\n"); position(SCREEN_ROWS, 0); for (i=0; i < SCREEN_COLS; i++) { printf("-"); } printf("\n"); } int u_sleep(unsigned int usec) { static int subtotal = 0; int msec; struct pollfd foo; subtotal += usec; if (subtotal < 1000) return (0); msec = subtotal/1000; subtotal = subtotal%1000; return poll(&foo,(unsigned long)0, msec); } void position (int row,int column) { printf("\033[H\033[%d;%dH", row, column); } void erase_all() { printf("\033[2J"); } void beep() { printf("\007"); }