/************************************************************************/ /* GUN! Version 1.4 */ /* ---- */ /* Use a Mattel PowerGlove and a silicon graphics Personal Iris */ /* to shoot at multiple moving targets on the screen (2d version). */ /* User can input the number, size, speed, and randomisity of */ /* the targets. The PowerGlove is used as a virtual GUN. To make */ /* a gun position put first finger straight out and two and */ /* three fingers all the way in. To fire a bullet quickly jerk */ /* in your first finger. [modified.. only 1st finger triggers] */ /* Keeping the first finger in will */ /* provoke a machine-gun like mode (very bad for your hit percentage) */ /* Making 'the bird' (middle finger up, one and three down) will */ /* clear all bullet holes on screen. At anytime press ESC to quit. */ /* */ /* send any correspondence concering this program to: */ /* dbarberi@sunsite.unc.edu */ /* COPYRIGHT (C) 1993, 1991 by David Barberi */ /**z*********************************************************************/ #include #include #include #include #include #include #include #define PORT_ID "/dev/ttyd2" /* serial port were the glove is */ #define MAXBULLETS 100 #define MAXTARGETS 25 long signed int x, y, z, thumb, one, two, three, twist; /* actual glove data */ long int correct_x, correct_y; /* correct x,y screen postions */ long int loop, loop1, loop2, i; long int bullet_x[MAXBULLETS], bullet_y[MAXBULLETS]; long int target_x[MAXTARGETS], target_y[MAXTARGETS], t_size; /* target size */ long int speed=8, bullet_count=0, total_bullet_count=0; /* defaults */ long int old_bullet_count; /* memory of last count */ long int duration[MAXTARGETS], direction[MAXTARGETS]; /* Randomosity */ long int countdown[MAXTARGETS]; long int level, percentage, clicks; /* score values */ long int target_center_x[MAXTARGETS], target_center_y[MAXTARGETS]; long int number_of_hits=0; long int pick_target, number_of_targets; char char_number_of_hits[50]; /* can only print out strings */ char char_bullet_count[50]; /* with the charstr() command */ char char_percentage[50]; char char_total_bullet_count[50], char_clicks[999]; int file_id; /* low level powerglove stuff */ extern char *sys_errlist[]; int sleepval = 8; /* default delay of VERY FAST: dangerous to go lower */ /****************************************************************/ /* Da Main Loop */ /****************************************************************/ main(argc, argv) int argc; char *argv[]; { /* use argument for delay time, else use default */ if (argc > 1) sleepval = atoi(argv[1]); /* Initialize graphics and powerglove */ initialize(); /* Main loop: */ while(!getbutton(ESCKEY)) { color(BLUE); clear(); query_glove(); shoot_bullets(); draw_target(); draw_crosshair(); check_for_clear(); check_for_gun(); write_score(); swapbuffers(); clicks++; } /* cleanup and go */ curson(); gexit(); final_score(); } final_score() { printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); printf(" FINAL SCORE\n\n"); printf(" Hit Percantage= %d # of Hits= %d # of Shots= %d Clicks= %d\n", percentage, number_of_hits, total_bullet_count, clicks); printf("\n\n\nThanks for Playing GUN!\n\n\n"); } /************ check_for_clear() ***************************/ check_for_clear() { if((one>=2)&&(two==0)&&(three>=2)) { /* if the bird is made */ bullet_count=0; /* then clear all the */ } /* bullets from the screen */ } /************** check_for_gun() ****************/ check_for_gun() { /* if((two>=2)&&(three>=2)) { */ /* if gun position */ if(one>=2) { /* if trigger pulled */ bullet_count++; bullet_x[bullet_count] = correct_x; bullet_y[bullet_count] = correct_y; check_for_hit(); } } /********************** draw_crosshair *********************/ draw_crosshair() { linewidth(3); color(BLACK); circi(correct_x, correct_y, 40); circi(correct_x, correct_y, 20); color(GREEN); circi(correct_x, correct_y, 7); color(BLACK); move2((correct_x - 5), correct_y); draw2((correct_x - 50), correct_y); move2((correct_x + 5), correct_y); draw2((correct_x + 50), correct_y); move2(correct_x, (correct_y - 5)); draw2(correct_x, (correct_y - 50)); move2(correct_x, (correct_y + 5)); draw2(correct_x, (correct_y +50)); linewidth(1); } /************************ shoot_bullets() *****************/ shoot_bullets() { old_bullet_count = bullet_count; color(BLACK); for(i=0; i<=bullet_count; i++) { cmov2(bullet_x[i], bullet_y[i]); charstr("X"); /* circfi(bullet_x[i], bullet_y[i], 5); */ /* for some odd reason the circfi command slows down the program */ /* A LOT when the number of bullets get over 15 or so..!?! */ } if(bullet_count > MAXBULLETS) bullet_count =0; } /************** draw_target() ****************************/ draw_target() { for(loop=0; loop duration[loop]) /* see if duration is expired */ get_new_direction(loop); if(direction[loop]==0) { target_x[loop]=target_x[loop]+speed; } if(direction[loop]==1) { target_x[loop]=target_x[loop]+speed; /* pick the right */ target_y[loop]=target_y[loop]+speed; /* direction to go */ } if(direction[loop]==2) { target_y[loop]=target_y[loop]+speed; } if(direction[loop]==3) { target_x[loop]=target_x[loop]-speed; target_y[loop]=target_y[loop]+speed; } if(direction[loop]==4) { target_x[loop]=target_x[loop]+speed; } if(direction[loop]==5) { target_x[loop]=target_x[loop]-speed; target_y[loop]=target_y[loop]-speed; } if(direction[loop]==6) { target_y[loop]=target_y[loop]-speed; } if(direction[loop]==7) { target_x[loop]=target_x[loop]+speed; target_y[loop]=target_y[loop]-speed; } if(target_x[loop] > 1280) target_x[loop] = 0; if(target_x[loop] < 0) /* check if on border of screen */ target_x[loop] = 1280; /* could add better jumps that */ if(target_y[loop] < 0) /* take t_size into consideration */ target_y[loop] = 1024; if(target_y[loop] > 1024) target_y[loop] = 0; target_center_x[loop] =(target_x[loop] + (0.5 * t_size)); target_center_y[loop] =(target_y[loop] + (0.5 * t_size)); color(WHITE); rectf(target_x[loop], target_y[loop], (target_x[loop]+t_size), (target_y[loop]+t_size)); color(BLACK); circf(target_center_x[loop], target_center_y[loop], /* draw it */ (t_size-(t_size*0.55))); color(CYAN); circf(target_center_x[loop], target_center_y[loop], (t_size-(t_size*0.7))); color(YELLOW); circf(target_center_x[loop], target_center_y[loop], (t_size-(t_size*0.9))); } } /*************** check_for_hit ***************************/ check_for_hit() { for(loop=0; loop bullet_x[bullet_count]) && (target_y[loop] < bullet_y[bullet_count]) && ((target_y[loop]+t_size) > bullet_y[bullet_count]) ) hit_it(loop); } } /* for(loop1=target_x[loop]; loop1<=(target_x[loop]+t_size); loop1++) { if( loop1==bullet_x[bullet_count] ) { for(loop2=target_y[loop]; loop2<=(target_y[loop]+t_size); loop2++) { if( loop2==bullet_y[bullet_count] ) { hit_it(loop); } } } }} */ /**************** hit_it() *******************************/ hit_it(long int pick_target) { setbell(1); ringbell(); speed = speed + 2; number_of_hits++; for(i=0; i<1; i++) { color(BLACK); clear(); swapbuffers(); color(RED); clear(); swapbuffers(); color(YELLOW); clear(); swapbuffers(); } bullet_count = 0; /* last target = current target; erase last target */ /* if you don't do this then when you shoot at a target */ /* it may not dissapear.. giving you an easy picking for */ /* repetitive hits... not very sportsman of us! */ target_x[pick_target]=target_x[number_of_targets]; target_y[pick_target]=target_y[number_of_targets]; number_of_targets--; if(number_of_targets==0) you_win(); } /******************* you_win() *****************************/ you_win() { for(i=0; i<15; i++) { color(BLACK); clear(); write_win(); swapbuffers(); color(GREEN); clear(); write_win(); swapbuffers(); color(YELLOW); clear(); write_win(); swapbuffers(); } curson(); while(1) { if(getbutton(SPACEKEY)) { gexit(); printf("Too Bad, you can't play again.. Pfffft!\n\n"); final_score(); exit(1); /*gexit(); initialize(); */ } if(getbutton(QKEY)) { gexit(); final_score(); exit(0); } } } /******************** write_win() **************************/ write_win() { pushmatrix(); ortho2(0.0,1280.0,0.0,1024.0); color(BLACK); cmov(500.0, 500.0); charstr("YOU WIN!!!!!"); cmov(500.0, 300.0); charstr("Press SPACEBAR to play again or Q to quit"); popmatrix(); write_score(); } /******************* get_new_direction() *******************/ get_new_direction(long int pick_target) { duration[pick_target]=( (rand()%30) + level); direction[pick_target]=( rand()%8 ); countdown[pick_target]=0; } /* level is user inputed randomosity factor */ /******************** get_new_location() ********************/ get_new_location(long int pick_target) { target_x[pick_target] = (rand()%1280); target_y[pick_target] = (rand()%1024); } /***************** write_score() *************************/ write_score() { if(old_bullet_count != bullet_count) total_bullet_count++; /* to get accurate total count */ sprintf(char_total_bullet_count,"%d", total_bullet_count); sprintf(char_number_of_hits,"%d", number_of_hits); sprintf(char_bullet_count, "%d", bullet_count); sprintf(char_clicks, "%d", clicks); if(total_bullet_count>0) { percentage= ((number_of_hits*100) / total_bullet_count); sprintf(char_percentage, "%d", percentage); } pushmatrix(); ortho2(0.0,1280.0,0.0,1024.0); color(MAGENTA); /* cmov2(500.0, 930.0); */ cmov2(500.0, 999.0); charstr("GUN! by David Barberi"); color(BLACK); /* cmov2(10.0,150.0); */ cmov2(10.0, 40.0); charstr(" # of Hits = "); color(WHITE); charstr(char_number_of_hits); color(BLACK); charstr(" # of recent shots = "); color(WHITE); charstr(char_bullet_count); color(BLACK); charstr(" # of Total shots = "); color(WHITE); charstr(char_total_bullet_count); color(BLACK); charstr(" Hit Percentage = %"); color(WHITE); charstr(char_percentage); color(BLACK); charstr(" Clicks = "); color(WHITE); charstr(char_clicks); popmatrix(); } /****************************************************************/ /* Get glove and user ready; flush data from glove buffer */ /****************************************************************/ initialize() { if (initPort() != 0) fprintf(stderr,"Could not initialize port\n"); get_values(); /* Initialize graphics */ ginit(); doublebuffer(); gconfig(); cursoff(); color(BLUE); clear(); /* Wait until the user is ready */ while(!getbutton(SPACEKEY)) { color(BLUE); clear(); pushmatrix(); ortho2(0.0,1280.0,0.0,1024.0); cmov2(500.0, 500.0); color(WHITE); charstr("WELCOME TO "); color(RED); charstr("GUN!"); cmov2(500.0, 400.0); color(YELLOW); charstr("Press the SPACEBAR to play!"); popmatrix(); swapbuffers(); query_glove(); } for(i=0; i 3) && (buf[0] == (0x81 - 127)) && (buf[1] == (0xDE - 127)) && (buf[2] == (0xDE - 127))) parse(buf); else fprintf(stderr,"Bad data: %d %d %d %d %d %d %d %d %d %d %d\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13]); /* get_position(); get correct_x and correct_y */ /* Sleep until next query to glove (absolute min. 1/30th second */ /* For the IRIS, 100 ticks is approx one second. */ sginap(sleepval); return(0); } /*********************** get_position() *****************************/ /* translate the x and y glove data into correct screen positions */ /********************************************************************/ get_position() { correct_x = ((x+127) * 5); /* not exact.. ~5.1? */ correct_y = ((y+127) * 4); } /****************************************************************/ /* Open and initialize the serial port connection to PowerGlove */ /****************************************************************/ initPort() { struct termios tbuf; int rslt; file_id = open(PORT_ID, O_RDWR,0); if (file_id == -1) { printf("Error on open call\n"); perror(*sys_errlist); exit(1); } /* structure for characteristics of port */ tbuf.c_iflag = 0; tbuf.c_oflag = 0; tbuf.c_lflag = 0; tbuf.c_cflag = B9600 | CS8 | CLOCAL | CREAD; rslt = ioctl(file_id, TCSETA, &tbuf); if (rslt == -1) { fprintf(stderr, "ioctl failed\n"); perror(*sys_errlist); exit(1); } return(0); } /****************************************************************/ /* Routine to parse input received from PowerGlove port */ /****************************************************************/ parse(input) char *input; { int temp; x = input[3]; y = input[4]; z = input[5]; /* Query the first bit for sign */ if (x > 127) x -= 256; if (y > 127) y -= 256; if (z > 127) z -= 256; twist = input[6]; temp = input[7]; three = temp & 3; temp = temp >> 2; two = temp & 3; temp = temp >> 2; one = temp & 3; temp = temp >> 2; thumb = temp & 3; get_position(); } /** Dis be the end **/