/* show a ball bouncing in a box using curses */ #include #include #include #include #include #include struct ball_s { int ballxold; int ballyold; int ballx; int bally; int ballx_vel; int bally_vel; }; struct parameters_s { int length; struct ball_s * ball; }; void drawStart(WINDOW *win); void drawScreen(WINDOW *win, struct ball_s * one); void cleanUp(); void moveBall(struct ball_s * ball); void moveCursor(WINDOW *win); void* loop(void * parameters); #define MIN_X 11 #define MAX_X 69 #define MIN_Y 5 #define MAX_Y 19 WINDOW *main_window; int main(int argc, char *argv[]) { struct ball_s one; struct ball_s two; pthread_t one_t; pthread_t two_t; pthread_attr_t pthreads_attr; struct parameters_s one_p; struct parameters_s two_p; one_p.ball = &one; two_p.ball = &two; one_p.length = 300000; two_p.length = 1000000; /* initialize curses stuff */ initscr(); main_window = newwin(0,0,0,0); leaveok(main_window,TRUE); curs_set(0); /* turn off cursor */ /* initialize ball */ one.ballx = (MAX_X - MIN_X) / 3 + MIN_X; one.bally = (MAX_Y - MIN_Y) / 3 + MIN_Y; one.ballxold = one.ballx; one.ballyold = one.bally; one.ballx_vel = -1; one.bally_vel = +1; two.ballx = (MAX_X - MIN_X) * 2 / 3 + MIN_X; two.bally = (MAX_Y - MIN_Y) * 2 / 3 + MIN_Y; two.ballxold = two.ballx; two.ballyold = two.bally; two.ballx_vel = -1; two.bally_vel = +1; /* draw starting box */ drawStart(main_window); int err; if ((err = pthread_attr_init(&pthreads_attr)) < 0) { cleanUp(); } if ((err = pthread_create(&one_t, &pthreads_attr, loop, (void *)&one_p))<0){ cleanUp(); } if ((err = pthread_create(&two_t, &pthreads_attr, loop, (void *)&two_p))<0){ cleanUp(); } pthread_join(one_t,NULL); pthread_join(two_t,NULL); } // loop drawing balls. Should use synchronization but forget that for now. void* loop(void * parameters) { struct parameters_s * param = (struct parameters_s *) parameters; int length = param->length; struct ball_s * ball = param->ball; while(1) { usleep(length); //Imagine this is a blocking I/O call moveBall(ball); drawScreen(main_window, ball); } } /* move the ball based on x,y velocity and walls */ void moveBall(struct ball_s * ball) { /* move the ball */ ball->ballxold = ball->ballx; ball->ballyold = ball->bally; ball->ballx = ball->ballx + ball->ballx_vel; ball->bally = ball->bally + ball->bally_vel; /* hit side wall? */ if (ball->ballx == MIN_X || ball->ballx == MAX_X) ball->ballx_vel = ball->ballx_vel * -1; /* hit top/bottom wall? */ if (ball->bally == MAX_Y || ball->bally == MIN_Y) ball->bally_vel = ball->bally_vel * -1; } /* draw the screen */ void drawScreen(WINDOW *win, struct ball_s * one){ mvwaddch(win, one->ballyold, one->ballxold,' '); mvwaddch(win, one->bally, one->ballx, '*'); wrefresh(win); } /* draw the starting box */ void drawStart(WINDOW *win) { int i; /* horizontal bars */ for (i=MIN_X-1; i<=MAX_X+1; i++) { mvwaddch(win, MIN_Y-1, i, '-'); mvwaddch(win, MAX_Y+1, i, '-'); } /* vertical bars */ for (i=MIN_Y-1; i<=MAX_Y+1; i++) { mvwaddch(win, i, MIN_X-1, '|'); mvwaddch(win, i, MAX_X+1, '|'); } wrefresh(win); } /* close curses and exit */ void cleanUp() { endwin(); exit(0); }