/* * * GloveNet Pong Client Version 1.5 * By David Barberi 1/25/91 * dbarberi@sunsite.unc.edu */ #include #include #include "glove.h" /* #define DEBUG 1 */ #define X 0 #define Y 1 /* size of paddles */ #define LENGTH 35 #define WIDTH 90 #define WORLD_X_LOW 15 #define WORLD_X_HIGH 1240 #define WORLD_Y_LOW 15 #define WORLD_Y_HIGH 815 #define FORWARD 0 #define BACKWARD 1 typedef struct { /* multiple windows */ int gid; } wrecord; wrecord wins[3]; /* leave 0th spot empty */ int PongWindow, DataWindow; /* names of windows */ /*** colors ***/ int background[3] = {5,5,5}; int text[3] = {123,255,255}; int highlight[3] = {255,250,2}; int paddle1[3] = {3,255,139 }; int paddle2[3] = {123,5,140 }; int paddle3[3] = {255,231,223 }; int paddle4[3] = {251,1,13 }; int white[3] = {255,255,255}; int black[3] = {0,0,0}; int red[3] = {255,0,0}; int purple[3] = {255,0,255}; int yellow[3] = {255,255,0}; int left_court[3] = { 50, 24, 2}; int mid_court[3] = { 90, 90, 90}; int right_court[3] = { 4, 24, 50}; int correct_x, correct_y; char char_x[10], char_y[10], char_z[10]; char char_gesture[12], char_key[12]; char char_thumb[5], char_one[5], char_two[5], char_three[5], char_twist[5]; char char_key1[5], char_key2[5], char_key3[5], char_key4[5]; char char_ball_x[5], char_ball_y[5]; int pad1[2], pad2[2], pad3[2], pad4[2]; int pad_x_max, pad_x_min, pad_y_max, pad_y_min; float ball_size; int ball_x, ball_y; int ball_x_slope, ball_y_slope; int glove, mouse; int x_direction, y_direction; /*******************************************************************/ main() { init(); while(!getbutton(ESCKEY)) { winset(PongWindow); input(); draw_playing_field(); if(glove) query_glove(file_id, &pglove); if(mouse) get_mouse(); draw_glove(); do_ball(); swapbuffers(); do_data(); } } /************************************************************/ input() { if(getbutton(MKEY)) { mouse= TRUE; glove= FALSE; } if(getbutton(GKEY)) { glove= TRUE; mouse= FALSE; } } /************************************************************/ draw_playing_field() { int court1[2], court2[2], court3[2], court4[2]; int half_court1[2], half_court2[2]; c3i(background); clear(); court1[X] = WORLD_X_HIGH; court1[Y] = WORLD_Y_LOW; court2[X] = WORLD_X_HIGH; court2[Y] = WORLD_Y_HIGH; court3[X] = WORLD_X_LOW; court3[Y] = WORLD_Y_HIGH; court4[X] = WORLD_X_LOW; court4[Y] = WORLD_Y_LOW; half_court1[X] = ( (WORLD_X_HIGH - WORLD_X_LOW) / 2); half_court1[Y] = WORLD_Y_HIGH; half_court2[X] = half_court1[X]; half_court2[Y] = WORLD_Y_LOW; bgnpolygon(); c3i(right_court); v2i(court1); v2i(court2); c3i(mid_court); v2i(half_court1); v2i(half_court2); endpolygon(); bgnpolygon(); c3i(mid_court); v2i(half_court1); v2i(half_court2); c3i(left_court); v2i(court4); v2i(court3); endpolygon(); bgnline(); c3i(white); v2i(half_court1); v2i(half_court2); endline(); bgnclosedline(); c3i(red); linewidth(3); v2i(court1); v2i(court2); v2i(court3); v2i(court4); endclosedline(); } /************************************************************/ get_mouse() { correct_x = getvaluator(MOUSEX); correct_y = getvaluator(MOUSEY); } /***********************************************************/ /**** do_ball() ***/ /***********************************************************/ do_ball() { ball_x += ball_x_slope; ball_y += ball_y_slope; if(ball_x_slope > 0) x_direction = FORWARD; else x_direction = BACKWARD; if(ball_y_slope > 0) y_direction = FORWARD; else y_direction = BACKWARD; /* if it hits a wall, bounce */ if( ( ball_x > WORLD_X_HIGH ) || ( ball_x < WORLD_X_LOW ) ) { ball_x_slope *= -1; } if( ( ball_y > WORLD_Y_HIGH ) || ( ball_y < WORLD_Y_LOW) ) { ball_y_slope *= -1; } /* if hits paddle, bouce */ /* if( x_direction == FORWARD ) { */ if ( ( ball_x < pad_x_max) && ( ball_x > pad_x_min) && ( ball_y < pad_y_max) && ( ball_y > pad_y_min) ) { get_new_slopes(); } draw_ball(); } /*******************************************************************/ get_new_slopes() { if(ball_x_slope < 0 ) ball_x_slope = 10 + (rand()%20); else ball_x_slope = 0 - ( 10+(rand()%20)); if(ball_y_slope > 0 ) ball_y_slope = 10 + (rand()%20); else ball_y_slope = 0 - ( 10+(rand()%20)); } /*******************************************************************/ draw_ball() { /* actually draw ball */ linewidth(2); c3i(yellow); circ( ball_x, ball_y, ( ball_size / 2.5 ) ); linewidth(3); c3i(white); circ( ball_x, ball_y, ( ball_size / 2 ) ); linewidth(4); c3i(purple); circ( ball_x, ball_y, ( ball_size / 1.5) ); linewidth(5); c3i(red); circ( ball_x, ball_y, ball_size); } /*******************************************************************/ draw_glove() { /* if(glove) get_correct_position(); needed????? */ pad_x_max = correct_x + LENGTH; pad_y_max = correct_y + WIDTH; pad_x_min = correct_x - LENGTH; pad_y_min = correct_y - WIDTH; pad1[X] = correct_x + LENGTH; pad1[Y] = correct_y - WIDTH; pad2[X] = correct_x + LENGTH; pad2[Y] = correct_y + WIDTH; pad3[X] = correct_x - LENGTH; pad3[Y] = correct_y + WIDTH; pad4[X] = correct_x - LENGTH; pad4[Y] = correct_y - WIDTH; bgnpolygon(); c3i(paddle1); v2i(pad1); c3i(paddle2); v2i(pad2); c3i(paddle3); v2i(pad3); c3i(paddle4); v2i(pad4); endpolygon(); } /*********************** get_position() ************************/ get_correct_position() { correct_x = ((pglove.x+127) * 5.1); /* not exact.. ~5.1? */ correct_y = ((pglove.y+127) * 4); } /*******************************************************************/ init() { file_id = init_glove(); /*** Initialize graphics ****/ /* open PongWindow */ keepaspect(1,1); prefposition(9, 1270, 169, 996); wins[1].gid = winopen("Pong"); PongWindow = wins[1].gid; doublebuffer(); RGBmode(); gconfig(); /* Open DataWindow */ keepaspect(1,1); prefposition(9, 1270, 8, 130); wins[2].gid = winopen("Data"); DataWindow = wins[2].gid; doublebuffer(); RGBmode(); gconfig(); /* some more variables */ glove = 0; mouse = 1; ball_size = 20.0; ball_x = ball_y = 400; ball_x_slope = 14; ball_y_slope = 19; } /***********************************************************/ /**** do_data() ***/ /***********************************************************/ do_data() { sprintf(char_x, "%i", pglove.x); sprintf(char_y, "%i", pglove.y); sprintf(char_z, "%i", pglove.z); sprintf(char_ball_x, "%i", ball_x); sprintf(char_ball_y, "%i", ball_y); /* sprintf(char_thumb, "%i", pglove.thumb); sprintf(char_one, "%i", pglove.one); sprintf(char_two, "%i", pglove.two); sprintf(char_three, "%i", pglove.three); sprintf(char_twist, "%i", pglove.twist); sprintf(char_key1, "%i", pglove.key1); sprintf(char_key2, "%i", pglove.key2); sprintf(char_key3, "%i", pglove.key3); sprintf(char_key4, "%i", pglove.key4); */ winset(DataWindow); pushmatrix(); ortho2(0.0, 1000.0, 0.0, 10.0); c3i(background); clear(); cmov2(5, 8); c3i(text); charstr("x="); c3i(highlight); charstr(char_x); cmov2(5, 6); c3i(text); charstr("y="); c3i(highlight); charstr(char_y); cmov2(5, 4); c3i(text); charstr("z="); c3i(highlight); charstr(char_z); cmov2(55, 8); c3i(text); charstr("ball_x="); c3i(highlight); charstr(char_ball_x); cmov2(55, 6); c3i(text); charstr("ball_y="); c3i(highlight); charstr(char_ball_y); cmov2(105, 4); c3i(text); if(mouse) charstr("Mouse Control"); if(glove) charstr("Glove Control"); cmov2(300, 4); c3i(text); charstr("x_dir="); c3i(highlight); if(x_direction == FORWARD) charstr("FORWARD"); else charstr("BACKWARD"); cmov2(300, 6); c3i(text); charstr("y_dir="); c3i(highlight); if(y_direction == FORWARD) charstr("FORWARD"); else charstr("BACKWARD"); swapbuffers(); popmatrix(); } /* * FOR GLOVENET PONG CLIENT * * * POWERGLOVE ROUTINES Version 2.9 * * 12/02/91 * * * Syracuse University Virtual Reality Lab * * * use file_id = init_glove(); to set up the glove * * use query_glove(file_id, &pglove); to get the glove data * and pglove.gesture * and pglove.key * * * If you have any questions, please contact: * * David Barberi * dbarberi@sugrfx.acs.syr.edu * dbarberi@sunrise.acs.syr.edu * * * Output format: * * Data Time_stamp gesture key x y z thumb one two three twist key1 key2 key3 key4 * | * 1= GOOD * 0= CORRUPT */ /*******************************************************************/ /* This program will open a connection to the Mattel PowerGlove */ /* via the serial port. It then reads data from the port and */ /* writes to standard output. */ /* Written for the Personal Iris by Greg Newby, Bob Zeh, */ /* Bill Tarolli, and David Barberi */ /* This program is supplied "as is." No warranty is implied. */ /* For additional information, contact Greg Newby at Syracuse */ /* University (gbnewby@rodan.acs.syr.edu or */ /* gbnewby@alexia.lis.uiuc.edu). */ /* 8/07/91. All Rights Etc. */ /*******************************************************************/ /* #include "powerglove.h" */ /* This include is very important.. contains glove structure */ /* the Port definition, and #defines */ int sleepval = 70; /*******************************************************************/ /* Routine to initialize the serial port */ /*******************************************************************/ int init_glove() /* returns the file_id for the open file */ { extern char *sys_errlist[]; int rslt; struct termios tbuf; file_id = open(PORT_ID, O_RDWR, 0); if (file_id == -1) { printf("Error on open call to %s as Glove port, must be read/writable\n", PORT_ID); perror(*sys_errlist); return(1); } else printf(" %s is the Glove port\n", PORT_ID); tbuf.c_iflag = 0; tbuf.c_oflag = 0; tbuf.c_lflag = 0; tbuf.c_cflag = B9600 | CS8 | CLOCAL | CREAD; /* new timewait */ tbuf.c_cc[VMIN] = 0; /* Return read even if no chars */ tbuf.c_cc[VTIME] = 0; /* Return without waiting */ rslt = ioctl(file_id, TCSETA, &tbuf); if (rslt == -1) { fprintf(stderr, "ioctl failed\n"); perror(*sys_errlist); return(1); } ioctl(file_id, TCFLSH,2); /* flush the port */ return(file_id); } /******************************************************************* New Time sleep commands by Jan, ih3e@wilbury.cs.Virginia.EDU *******************************************************************/ void t_sleep(wait) unsigned int wait; { static struct timeval timeout; if ( wait < 1000 ) { timeout.tv_sec = 0; timeout.tv_usec = wait * 1000; } else { /* integral seconds */ timeout.tv_sec = wait / 1000; /* get millisecond part and * 1000 for usecs */ timeout.tv_usec = (wait % 1000) * 1000; } select(0, 0, 0, 0, &timeout); } /* t_sleep */ /*******************************************************************/ /* Puts current glove data in the structure */ /*******************************************************************/ int query_glove(file_id, pglove) pglove_data *pglove; int file_id; { int ret, temp, data; char buf[BUFSIZ]; char command[BUFSIZ]; /* 0x01 = Constand Upload (default) 0x02 = Upload only on Command 0x04 = Send Default Template (reset) 0x07 = Reset to Defaults 0x08 = Rotation Filter ON (default) 0x09 = Rotation Filter OFF */ command[0] = 2; write(file_id,command,1); t_sleep(sleepval); ret = read(file_id,buf,14); /* Check header bytes to see if the data is good, if bad return a 0 */ if (!((ret > 3) && (buf[0] == (0x81 - 127)) && (buf[1] == (0xDE - 127)) && (buf[2] == (0xDE - 127)))) { return(0); } /* Assign X, Y, and Z (need to query 1st bit for sign on Iris) */ pglove->x = buf[3]; if (buf[3] > 127) pglove->x -= 256; pglove->y = buf[4]; if (buf[4] > 127) pglove->y -= 256; pglove->z = buf[5]; if (buf[5] > 127) pglove->z -= 256; /* Assign rotation and (bit-shifted) rotation values */ pglove->twist = buf[6]; temp = buf[7]; pglove->three = temp & 3; temp = temp >> 2; pglove->two = temp & 3; temp = temp >> 2; pglove->one = temp & 3; temp = temp >> 2; pglove->thumb = temp & 3; /* This is data for the Keypad buttons on the glove */ temp = buf[8]; pglove->key1 = temp & 3; temp = temp >> 2; pglove->key2 = temp & 3; temp = temp >> 2; pglove->key3 = temp & 3; temp = temp >> 2; pglove->key4 = temp & 3; get_modes(); get_correct_position(); return(1); } /******************************************************************************/ /** Defines pglove.gesture and pglove.key for easier programming **/ /******************************************************************************/ get_modes() { pglove.gesture = STRANGE; pglove.key = BAD; get_hand_mode(); get_key_mode(); } /********************* assign pglove.gesture *************************/ /*** Gesture Recognition ***/ /*** May have to be modified for each person ***/ /**********************************************************************/ get_hand_mode() { if( (pglove.one==0) && (pglove.two==0) && (pglove.three==0) ) { pglove.gesture = OPEN; return(0); } if( (pglove.one==3) && (pglove.two==3) && (pglove.three==3) ) { pglove.gesture = FIST; return(0); } /* if( (pglove.one>=2) && (pglove.two>=2) && (pglove.three>=2) ) { pglove.gesture = FIST; return(0); } */ if( (pglove.one==0) && (pglove.two>=2) && (pglove.three>=2) ) { pglove.gesture = POINT; return(0); } if( (pglove.one==0) && (pglove.two==0) && (pglove.three>=2) ) { pglove.gesture = BIGPOINT; return(0); } if( (pglove.one==3) && (pglove.two==0) && (pglove.three==3) ) { pglove.gesture = BIRD; return(0); } /* if( (pglove.one>=2) && (pglove.two==0) && (pglove.three>=2) ) { pglove.gesture = BIRD; return(0); } */ if( (pglove.thumb >=1) && (pglove.one>=2) && (pglove.two==0) && (pglove.three==0) ) { pglove.gesture = AOK; return(0); } if( (pglove.one>=2) && (pglove.two==0) && (pglove.three==0) ) { pglove.gesture = ONEDOWN; return(0); } if( (pglove.one==0) && (pglove.two==3) && (pglove.three==0) ) { pglove.gesture = TWODOWN; return(0); } if( (pglove.one==0) && (pglove.two==0) && (pglove.three==3) ) { pglove.gesture = THREEDOWN; return(0); } if( (pglove.one==3) && (pglove.two==3) && (pglove.three<=1) ) { pglove.gesture = THREEUP; return(0); } } /********************** pglove.key **********************/ get_key_mode() { if( (pglove.key1==3) && (pglove.key2==3) && (pglove.key3==3) && (pglove.key4==3) ) { pglove.key = NO_KEY; return(0); } if( (pglove.key1==0) && (pglove.key2==0) && (pglove.key2==0) && (pglove.key4==0) ) { pglove.key = CENTER; return(0); } if( (pglove.key1==3) && (pglove.key2==0) && (pglove.key3==0) && (pglove.key4==2) ) { pglove.key = SELECT; return(0); } if( (pglove.key1==2) && (pglove.key2==0) && (pglove.key3==0) && (pglove.key4==2) ) { pglove.key = START; return(0); } if( (pglove.key1==0) && (pglove.key2==0) && (pglove.key3==0) && (pglove.key4==2) ) { pglove.key = ENTER; return(0); } if( (pglove.key1==1) && (pglove.key2==0) ) pglove.key = ONE; if( (pglove.key1==2) && (pglove.key2==0) ) pglove.key = TWO; if( (pglove.key1==3) && (pglove.key2==0) ) pglove.key = THREE; if( (pglove.key1==0) && (pglove.key2==1) ) pglove.key = FOUR; if( (pglove.key1==1) && (pglove.key2==1) ) pglove.key = FIVE; if( (pglove.key1==2) && (pglove.key2==1) ) pglove.key = SIX; if( (pglove.key1==3) && (pglove.key2==1) ) pglove.key = SEVEN; if( (pglove.key1==0) && (pglove.key2==2) ) pglove.key = EIGHT; if( (pglove.key1==1) && (pglove.key2==2) ) pglove.key = NINE; if( (pglove.key1==1) && (pglove.key2==3) ) pglove.key = UP; /* for now UP is towards to red LED light */ if( (pglove.key1==2) && (pglove.key2==3) ) pglove.key = DOWN; if( (pglove.key1==3) && (pglove.key2==3) ) pglove.key = RIGHT; if( (pglove.key1==0) && (pglove.key2==3) ) pglove.key = LEFT; if( (pglove.key1==2) && (pglove.key2==2) ) pglove.key = A; if( (pglove.key1==3) && (pglove.key2==2) ) pglove.key = B; /* how to read the data from the keypad key4 key4 key3 | key3 | key2 | | key2 | | key1 | | | key1 | | | | | | | | | | | NO_KEY 3 3 3 3 0 0 0 0 0 UP 1 3 0 0 1 1 0 0 0 DOWN 2 3 0 0 2 2 0 0 0 LEFT 0 3 0 0 3 3 0 0 0 RIGHT 3 3 0 0 4 0 1 0 0 A 2 2 0 0 5 1 1 0 0 B 3 2 0 0 6 2 1 0 0 SELECT 3 0 0 2 7 3 1 0 0 START 2 0 0 2 8 0 2 0 0 CENTER 0 0 0 0 9 1 2 0 0 PROG ? ? ? ? ENTER 0 0 0 2 ?BAD? 0 0 0 1 */ } /******************/ print_modes() { printf(" gesture= "); /* 9 chars */ if(pglove.gesture==OPEN) printf("OPEN "); if(pglove.gesture==FIST) printf("FIST "); if(pglove.gesture==POINT) printf("POINT "); if(pglove.gesture==BIGPOINT) printf("BIGPOINT "); if(pglove.gesture==BIRD) printf("BIRD "); if(pglove.gesture==AOK) printf("AOK "); if(pglove.gesture==ONEDOWN) printf("ONEDOWN "); if(pglove.gesture==TWODOWN) printf("TWODOWN "); if(pglove.gesture==THREEDOWN) printf("THREEDOWN"); if(pglove.gesture==THREEUP) printf("THREEUP "); if(pglove.gesture==STRANGE) printf("STRANGE "); printf(" key= "); /* 6 chars */ if(pglove.key==NO_KEY) printf("NO_KEY"); if(pglove.key==ONE) printf("ONE "); if(pglove.key==TWO) printf("TWO "); if(pglove.key==THREE) printf("THREE "); if(pglove.key==FOUR) printf("FOUR "); if(pglove.key==FIVE) printf("FIVE "); if(pglove.key==SIX) printf("SIX "); if(pglove.key==SEVEN) printf("SEVEN "); if(pglove.key==EIGHT) printf("EIGHT "); if(pglove.key==NINE) printf("NINE "); if(pglove.key==ENTER) printf("ENTER "); if(pglove.key==UP) printf("UP "); if(pglove.key==DOWN) printf("DOWN "); if(pglove.key==RIGHT) printf("RIGHT "); if(pglove.key==LEFT) printf("LEFT "); if(pglove.key==A) printf("A "); if(pglove.key==B) printf("B "); if(pglove.key==SELECT) printf("SELECT"); if(pglove.key==START) printf("START "); if(pglove.key==CENTER) printf("CENTER"); if(pglove.key==BAD) printf("BAD "); } /*** End of stream.c ***/