#define SOUND #include #include #include #include #ifdef SOUND #include "vssClient.h" #endif /* function prototypes */ float randomspeed(); void constrainmotion(chtype ch); void moveball(); void drawframe(); void drawgizmos(); void drawdata(); int readkeyboard(); int initsound(int argc, char** argv); void termsound(); void sendaudiodata(); int frame; void main(int argc, char** argv) { if (!initsound(argc, argv)) /* AUDIO */ return; drawframe(); drawgizmos(); for (frame = 1; readkeyboard(); frame++) { moveball(); drawdata(); refresh(); sginap(3L); sendaudiodata(); /* AUDIO */ } endwin(); termsound(); /* AUDIO */ } float dy=0.; /* (initial) vertical speed of ball */ float dx=.01; /* (initial) horiz. speed of ball */ float vBall = 0.; /* net speed of ball */ static float by=2., bx=2.; /* (initial) ball position */ #define cy (lines - 6) int fHitBumperPrev = 0; /* did ball hit a bumper recently? */ int fHitAcceleratorPrev = 0; int fHitRandomizerPrev = 0; int fHitBumper = 0; /* is ball hitting a bumper now? */ int fHitAccelerator = 0; int fHitRandomizer = 0; float randomspeed() /* return a value between -1 and 1 */ { static int _=0; if (++_ >= 300) _ = 0; return drand48() * ((_<150) ? -1 : 1); } void constrainmotion(chtype ch) /* keep the ball under control */ { fHitBumperPrev = fHitBumper; fHitAcceleratorPrev = fHitAccelerator; fHitRandomizerPrev = fHitRandomizer; if (fHitBumper) fHitBumper--; if (fHitAccelerator) fHitAccelerator--; if (fHitRandomizer) fHitRandomizer--; /* don't let us skip over a cell in the character grid */ if (dx < -1) dx = -.99; else if (dx > 1) dx = .99; if (dy < -1) dy = -.99; else if (dy > 1) dy = .99; /* walls */ if (ch == '-') { fHitBumper+=4; dy *= -1.02; } if (ch == '|') { fHitBumper+=4; dx *= -1.06; } if (ch == '+') { fHitBumper+=4; dx *= -1; dy *= -1; } /* randomizers */ if (ch == '?') { float v = sqrt(dx*dx + dy*dy); float v2; dx = randomspeed(); dy = randomspeed(); v2 = sqrt(dx*dx + dy*dy); dx *= v/v2; dy *= v/v2; fHitRandomizer+=3; } /* accelerators */ if (ch == 'X') { fHitAccelerator+=3; dx *= 1.22; dy *= 1.12; } /* don't let us skip over a character */ if (dx < -1) dx = -.99; else if (dx > 1) dx = .99; if (dy < -1) dy = -.99; else if (dy > 1) dy = .99; /* recompute net speed of ball */ vBall = sqrt(dx*dx + dy*dy); /* but put an upper bound on it -- handy for mapping to audio */ if (vBall > .8) { dx *= .8/vBall; dy *= .8/vBall; vBall = .8; } } void moveball() /* do inertia, gravity and friction */ { static chtype chPrev = ' '; move((int)by, (int)bx); addch(chPrev); constrainmotion(chPrev); by += dy; bx += dx; /* stay in bounds */ if (bx < 0) { bx=0; } else if (bx > 78) { bx=78; } if (by < 0) { by=0; } else if (by > cy) { by=cy; } dy += 0.0021; /* gravity */ dx *= .998; dy *= .9977; /* friction */ move((int)by, (int)bx); /* these are "curses" functions */ chPrev = inwch(); attron(A_BOLD); move((int)by, (int)bx); /* in case someone else used stdout */ addch('O'); attroff(A_BOLD); } void drawframe() /* draw the border of the playing field */ { int i; initscr(); cbreak(); nodelay(stdscr, TRUE); nonl(); noecho(); intrflush(stdscr,FALSE); keypad(stdscr,TRUE); move(0, 0); addstr("+-----------------------------------------------------------------------------+"); for (i=1; i threshhold)" blocks AUDupdates which * have little impact. It's a good idea to not send gazillions * of AUDupdate()'s to the sound server. */ if (fabs(vBall - vBallPrev) > .04 || fabs(by - byPrev) > .25 || fabs(dy - dyPrev) > .06) { float ballArray[7]; float beatsPerSecond; ballArray[0] = by/cy; /* rescale 0..cy to 0..1 */ ballArray[0] = 900. - ballArray[0] * 800.; /* rescale to Hz */ ballArray[1] = fabs(dy); /* rescale -1..1 to 1..0..1 */ ballArray[1] *= 5.; /* rescale to index of modulation */ ballArray[2] = .01 + vBall*.12; /* rescale 0-1.414 to 0-.1 */ ballArray[3] = .3 + vBall * 3.; /* rescale 0-1.414 to .3-5 */ ballArray[4] = 1 + vBall * .24; /* rescale 0-1.414 to 1-1.4 */ ballArray[5] = 1300. - (by/cy) * 700.; /* rescale to Hz */ beatsPerSecond = 2 + vBall * 3; /* rescale 0-1.414 to 2-6.5 */ ballArray[6] = ballArray[5] + beatsPerSecond; /* make lower notes louder */ ballArray[2] *= 1. + 2.*(by/cy); AUDupdateSimple("mBall", 7, ballArray); vBallPrev = vBall; byPrev = by; dyPrev = dy; } } #else /********************************************************************/ int initsound(int argc, char** argv) { return 1; } void termsound() {} void sendaudiodata() {} #endif /*******************************************************************/