/* * Glove Doodle Version 1.4 * * by David Barberi Spring 1993, 02/24/92 08/19/91 * dbarberi@sunsite.unc.edu * * Use PowerGlove to Make boxes and lines. * */ #include #include #include #include #include #include #include #define PORT_ID "/dev/ttyd2" #define MAXBOXES 100 #define MAXPOINTS 9999 #define MAXLINES 999 #define IN_BOX 0 /* for box_mode */ #define NOT_IN_BOX 1 #define STRANGE 0 #define OPEN_HAND 1 /* for hand_mode */ #define FIST 2 #define POINTING 3 #define BIRD 4 #define NOTHING 0 #define BOX 1 /* for control_mode */ #define DOODLE 2 #define CIRCLE 3 #define COLOR 4 #define LINE_WIDTH 5 long signed int x, y, z, thumb, one, two, three, twist; long int correct_x, correct_y; /* correct x,y screen postions */ long int number_of_boxes; long int loop, loop1,loop2,i,ss; long int box_x[MAXBOXES], box_y[MAXBOXES]; long int box_x2[MAXBOXES], box_y2[MAXBOXES]; long int hand_mode, box_mode[MAXBOXES]; long int change_in_x, change_in_y, old_x, old_y; long int color_val[MAXBOXES], color_loop; long int create, temp, clicks; long int control_mode, control_box_mode, old_control_mode; long int control_box_x, control_box_x2, control_box_y, control_box_y2; long int point_x[MAXLINES][MAXPOINTS], point_y[MAXLINES][MAXPOINTS]; long int line_count=0, point_count=0; long int BOX_control_x, BOX_control_x2, BOX_control_y, BOX_control_y2; long int DOODLE_control_x, DOODLE_control_x2, DOODLE_control_y, DOODLE_control_y2; char char_num_boxes[10]; char char_clicks[50]; int file_id; extern char *sys_errlist[]; int sleepval = 8; /* default delay of FAST */ /****************************************************************/ /* 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(); check_status_box(); do_action(); draw_box(); draw_line(); draw_status_box(); write_score(); draw_hand(); swapbuffers(); clicks++; } /* cleanup and go */ curson(); gexit(); } /***********/ check_status_box() { old_control_mode = control_mode; control_box_mode = NOT_IN_BOX; control_mode = NOTHING; if( (correct_x > control_box_x) && (correct_x < control_box_x2) && (correct_y > control_box_y) && (correct_y < control_box_y2) ) { color(BLACK); linewidth(8); rect(control_box_x-15, control_box_y-15, control_box_x2-15, control_box_y2-15); control_box_mode = IN_BOX; if( (correct_x > BOX_control_x) && (correct_x < BOX_control_x2) && (correct_y > BOX_control_y) && (correct_y < BOX_control_y2) && (hand_mode == FIST) ) { if( control_mode == BOX) control_mode = NOTHING; else control_mode = BOX; } if( (correct_x > DOODLE_control_x) && (correct_x < DOODLE_control_x2) && (correct_y > DOODLE_control_y) && (correct_y < DOODLE_control_y2) && (hand_mode == FIST) ) { if( control_mode == DOODLE) control_mode = NOTHING; else control_mode = DOODLE; } } } /*********/ draw_status_box() { control_box_x = 0; control_box_x2 = 1280; control_box_y = 0; control_box_y2 = 150; color(WHITE); rectf(control_box_x, control_box_y, control_box_x2, control_box_y2); BOX_control_x = 100; BOX_control_x2 = 300; BOX_control_y = control_box_y + 5; BOX_control_y2 = control_box_y2 - 5; if(control_mode==BOX) color(MAGENTA); else color(BLUE); rectf(BOX_control_x, BOX_control_y, BOX_control_x2, BOX_control_y2); color(BLACK); linewidth(3); rect(BOX_control_x, BOX_control_y, BOX_control_x2, BOX_control_y2); DOODLE_control_x = 500; DOODLE_control_x2 = 700; DOODLE_control_y = control_box_y +5; DOODLE_control_y2 = control_box_y2 -5; if(control_mode==DOODLE) color(MAGENTA); else color(BLUE); rectf(DOODLE_control_x, DOODLE_control_y, DOODLE_control_x2, DOODLE_control_y2); color(BLACK); linewidth(3); rect(DOODLE_control_x, DOODLE_control_y, DOODLE_control_x2, DOODLE_control_y2); } /************************** do_action() ***************************/ do_action() { control_mode = BOX; if( (control_mode==BOX) && (hand_mode==FIST) ) { if(number_of_boxes==0) { create_box(); return(0); } for(loop=number_of_boxes; loop>=0; loop--) { if( box_mode[loop]==IN_BOX ) { move_box(loop); return(0); } } create_box(); } /* if( (control_mode==DOODLE) && (hand_mode==FIST) ) line_doodle(); */ if(hand_mode==BIRD) { number_of_boxes=0; line_count=0; } } /*************** check_if_inside_box() ***************************/ check_if_inside_box() /* called from draw_box */ { if(number_of_boxes==0) { return(1); } for(loop=0; loop<=(number_of_boxes+1); loop++) box_mode[loop]=NOT_IN_BOX; for(loop=number_of_boxes; loop>=0; loop--) { if( ( box_x[loop] > correct_x) && ( box_x2[loop] < correct_x) && ( box_y[loop] > correct_y) && ( box_y2[loop] < correct_y) ) { box_mode[loop]=IN_BOX; return(0); } } } /************************** draw_box() *****************************/ draw_box() { /* if(number_of_boxes==0) {return(1); } */ for(loop=0; loop<=number_of_boxes; loop++) { color(color_val[loop]); rectf(box_x[loop], box_y[loop], box_x2[loop], box_y2[loop]); } check_if_inside_box(); if(box_mode[loop]==IN_BOX) { linewidth(5); color(BLACK); rect(box_x[loop], box_y[loop], box_x2[loop], box_y2[loop]); linewidth(1); } } /*************************** move_box() ************************/ move_box(long int box) { while(hand_mode==FIST) { color(BLUE); clear(); /* ?????? */ old_x = correct_x; old_y = correct_y; query_glove(); change_in_x = correct_x - old_x; change_in_y = correct_y - old_y; box_x[box]+=change_in_x; box_y[box]+=change_in_y; box_x2[box]+=change_in_x; box_y2[box]+=change_in_y; mini_main(); linewidth(5); color(BLACK); circ(box_x[number_of_boxes], box_y[number_of_boxes], 5); circ(box_x2[number_of_boxes], box_y2[number_of_boxes], 10); linewidth(1); swapbuffers(); } swapbuffers(); } /********************** mini_main() *************************/ mini_main() { /* called from create_box and move_box */ draw_box(); draw_line(); draw_status_box(); draw_hand(); write_score(); clicks++; } /************************* create_box() *****************************/ create_box() { if(number_of_boxes > MAXBOXES) { printf("...ABORT..Too many boxes already, can't create more\n"); return(1); } color_loop++; if(color_loop==7) color_loop=1; color_val[number_of_boxes]=color_loop; box_x[number_of_boxes] = correct_x; box_y[number_of_boxes] = correct_y; while(hand_mode==FIST) { color(BLUE); clear(); query_glove(); box_x2[number_of_boxes]=correct_x; box_y2[number_of_boxes]=correct_y; mini_main(); linewidth(5); color(BLACK); circ(box_x[number_of_boxes], box_y[number_of_boxes], 5); circ(box_x2[number_of_boxes], box_y2[number_of_boxes], 10); swapbuffers(); } /* switch corners for easier checking in IN_BOX that's a laugh*/ if(box_x2[number_of_boxes] > box_x[number_of_boxes]) { temp = box_x[number_of_boxes]; box_x[number_of_boxes] = box_x2[number_of_boxes]; box_x2[number_of_boxes] = temp; } if(box_y2[number_of_boxes] > box_y[number_of_boxes]) { temp = box_y[number_of_boxes]; box_y[number_of_boxes] = box_y2[number_of_boxes]; box_y2[number_of_boxes] = temp; } number_of_boxes++; } /***************************************************************/ line_doodle() { /*printf("control_mode =%i _old=%i \n", control_mode, old_control_mode);*/ if(old_control_mode != DOODLE) { line_count++; point_count=0; } if(line_count==0) return(-1); point_x[line_count][point_count]= correct_x; point_y[line_count][point_count]= correct_y; point_count++; /* printf(" line_count=%i point_count=%i \n", line_count, point_count);*/ } /*******************************************/ draw_line() { /* really really messed up */ linewidth(2); color(BLACK); for(loop1=1; loop1<=line_count; loop1++) { /* printf("loop1 = %i\n", loop1); */ for(loop2=1; loop2<=point_count; loop2++) { /* printf(" loop2 = %i", loop2); */ move(point_x[loop1][loop2], point_y[loop1][loop2]); ss = loop2 + 1; /* printf(" ss= %i\n", ss); */ draw(point_x[loop1][ss], point_y[loop1][ss]); } } } /********************** draw_hand() ********************/ draw_hand() { linewidth(2); if(hand_mode==FIST) { color(BLACK); circi(correct_x, correct_y, 30); color(GREEN); circi(correct_x, correct_y, 10); } else /* if(hand_mode==OPEN_HAND) */ { color(BLACK); circi(correct_x, correct_y, 40); circi(correct_x, correct_y, 20); color(YELLOW); circi(correct_x, correct_y, 7); color(RED); 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)); } } /***************** write_score() *************************/ write_score() { pushmatrix(); color(MAGENTA); cmov2(500.0, 1000.0); charstr("2D Glove Doodle by David Barberi"); cmov2(900, 10.0); color(RED); charstr("hand_mode = "); color(BLACK); if(hand_mode==FIST) charstr("FIST"); else if(hand_mode==OPEN_HAND) charstr("OPEN_HAND"); else if(hand_mode==POINTING) charstr("POINTING"); else if(hand_mode==BIRD) charstr("BIRD"); else charstr("STRANGE"); /* cmov2(250.0, 10.0); color(BLACK); charstr("number_of_boxes = "); sprintf(char_num_boxes, "%d", number_of_boxes); color(WHITE); charstr(char_num_boxes); */ cmov2(850, 10.0); sprintf(char_clicks, "%d", clicks); color(RED); charstr(" clicks = "); color(BLACK); charstr(char_clicks); cmov2( ((BOX_control_x2 - BOX_control_x) /2), ((BOX_control_y2 - BOX_control_y) /2) +50 ); if(control_mode==BOX) { color(WHITE); charstr("*DRAWING BOX*"); } else { color(RED); charstr("BOX"); } /* cmov2( ((DOODLE_control_x2 - DOODLE_control_x) /2), ((DOODLE_control_y2 - DOODLE_control_y) /2) ); if(control_mode==DOODLE) { color(WHITE); charstr("*DOODLING*"); } else { color(RED); charstr("dood"); } */ popmatrix(); } /****************************************************************/ /* Get glove and user ready; flush data from glove buffer */ /****************************************************************/ initialize() { if (initPort() != 0) fprintf(stderr,"Could not initialize port\n"); /* Initialize graphics */ ginit(); doublebuffer(); gconfig(); cursoff(); color(BLUE); clear(); swapbuffers(); clear(); /*** Defaults ***/ number_of_boxes=0; clicks=0; control_mode = BOX; line_count=0; point_count=0; /* Wait until the user is ready */ while(!getbutton(SPACEKEY)) { pushmatrix(); ortho2(0.0,1280.0,0.0,1024.0); cmov2(500.0, 500.0); color(WHITE); charstr("WELCOME TO "); color(RED); charstr("2D GLOVE DOODLE"); cmov2(500.0, 400.0); color(YELLOW); charstr("Press the SPACEBAR to play!"); popmatrix(); swapbuffers(); query_glove(); } } /********** get_modes(); ***************************/ get_modes() { /* check_if_inside_box(); */ if ((one<=1)&&(two<=1)&&(three<=1)) { /* OPEN HAND */ hand_mode= OPEN_HAND; return(0); /*printf("hand_mode=OPEN_HAND\n"); */ } else if ((one==3)&&(two>=2)&&(three>=2)) { /* FIST */ hand_mode = FIST; return(0); /* printf("hand_mode=FIST\n"); */ } else if ((one==0)&&(two>=2)&&(three>=2)) { hand_mode = POINTING; return(0); } else if ((one==3)&&(two==0)&&(three==3)) { hand_mode = BIRD; return(0); } else hand_mode = STRANGE; } /***** END get_modes(); *********/ /****************************************************************/ /* Get glove data */ /****************************************************************/ query_glove() { char buf[BUFSIZ]; char command[BUFSIZ]; int ret; /* disable buffering for stdout */ setbuf(stdout,NULL); /* Ask for data */ command[0] = 2; write(file_id,command,1); ret = read(file_id,buf,14); if ((ret > 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]); /* 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() ************************/ get_position() { correct_x = ((x+127) * 5.1); /* 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(); get_modes(); } /*** Dis be da end ***/