Joysticks and Related Input Devices: David Nahon's Source

The hard thing with it is to wire the good cable :

 /*
 DB Male WG	DIN8 Male(Indigo/Indy)	    Name
 -----1---------------------7-----------------DCD
 -----2---------------------5-----------------RD
 -----3---------------------3-----------------TD
 -----4---------------------1-----------------DTR
 -----5---------------------8-----------------SG
 -----7---------------------6-----------------RTS
 -----8---------------------2-----------------CTS
 
 DB Male WG	DB9 Male (Onyx)  	    Name
 -----1----------------------8---------------DCD
 -----2----------------------3---------------RD
 -----3----------------------2---------------TD
 -----4----------------------9---------------DTR
 -----5----------------------7---------------SG
 -----7----------------------4---------------RTS
 -----8----------------------5---------------CTS
 */
 
 then you need to power the device, and that can be done directly from the DTR 
 and RTS signals that have to remain high.
 
 Here is a kind of minimal demo that can easilly be used in a C program:
 
 /*
  * Minimal Demo for using Colorado Spectrum Workstation Gameport
  *
  * David NAHON / Tristan LORACH - 3/9/95
  * Z.A.Production, 64 rue de la Folie Mericourt, 75011 PARIS - FRANCE
  * voice:33 (1) 48 06 65 66, fax:33 (1) 48 06 48 75, e-mail:nahond@ccr.jussieu.fr
  *
  * Feel free to use or distribute this code the way you want.
  *
  * This code is provided as is, without any waranty. The authors are not
  * responsible for any damage due to the use of this code.
  *
  */
 
 #include <unistd.h>
 #include <termios.h>
 #include <fcntl.h>
 #include <stdio.h>
 extern  int sginap (long ticks);
 
 typedef struct _WG_State {
     int buttons;
     int joy1_pot1;
     int joy1_pot2;
     int joy2_pot1;
     int joy2_pot2;
 } WG_State ;
 
 #define	READBLOCK	0
 #define	READNONBLOCK    1
 
 
 #define JOY_BUT_1   1
 #define JOY_BUT_2   2
 #define JOY_BUT_3   4
 #define JOY_BUT_4   8
 
 #define JOY1_POT1   1
 #define JOY1_POT2   2
 #define JOY2_POT1   3
 #define JOY2_POT2   4
 
 char		values[6]={0, 0, 0, 0, 0, 0};
 int		joyfd;
 
 /******************************************************************
  *
  */
 void get_joystick(WG_State* wgs)
 {
     int	    n;
     char    byte0;
 
     /* wait for sync byte that is always 0*/
     do
     {
 	n=read(joyfd, &byte0, 1);
 /* 	printf("%d %c\n", n, byte0); */
 	if (n==-1)
 	{
 	    fprintf(stderr, "Error reading joy fd\n");
 	    return;
 	}
     }
     while((byte0!=0));
 	
     n=read(joyfd, values, 5);
     if (n==-1)
 	{
 	    fprintf(stderr, "Error reading joy fd\n");
 	    return;
 	}
     wgs->buttons = (values[0] - 0xf) >> 4;
     wgs->joy1_pot1 = (int)values[JOY1_POT1];
     wgs->joy1_pot2 = (int)values[JOY1_POT2];
     wgs->joy2_pot1 = (int)values[JOY2_POT1];
     wgs->joy2_pot2 = (int)values[JOY2_POT2];
 }
 
 void get_joystick_NON_BLOCK(WG_State* wgs)
 {
     int	    n;
     char    byte0;
 
     /* wait for sync byte that is always 0*/
     do
     {
 	n=read(joyfd, &byte0, 1);
 /* 	printf("%d %c\n", n, byte0); */
 	if (n==-1)
 	    return;
     }
     while( (n!=1) || (byte0!=0) );
 	
     n=read(joyfd, values, 5);
     if (n==-1)
 	    return;
     wgs->buttons = (values[0] - 0xf) >> 4;
     wgs->joy1_pot1 = (int)values[JOY1_POT1];
     wgs->joy1_pot2 = (int)values[JOY1_POT2];
     wgs->joy2_pot1 = (int)values[JOY2_POT1];
     wgs->joy2_pot2 = (int)values[JOY2_POT2];
 }
 
 void init_joystick( int portnum, int nonblock )
 {
     int result;
     int flags=TIOCM_DTR|TIOCM_RTS|TIOCM_LE|TIOCM_CTS;
     char str232[128];
     struct termio termio;
 
     printf("----------------------------------------------------------------\n");
     printf("Initialisation du Joystick...\n");
 
     sprintf( str232, "/dev/ttyd%d", portnum );
     printf("Use RS232-Device %s for Workstation GamePort JOYSTICK\n", str232 );
 
     joyfd = open( str232, O_RDONLY);
     if ( joyfd == -1 )
     {
 	printf( "Can't open seriel port /dev/ttyd%d\n", portnum );
 	exit(1);
     }
 
     result = ioctl( joyfd, TCGETA, &termio );
     if (nonblock)
         fcntl(joyfd, F_SETFL, FNONBLK);
 
     termio.c_iflag = 0;/*IXON|IXOFF|IGNBRK | IGNPAR;*/
     termio.c_oflag = 0;
     termio.c_cflag =  B9600 | CS8 | CREAD | CLOCAL| CSTOPB;
     termio.c_lflag = 0;				/* -ECHO */
 
     ioctl( joyfd, TCSETA, &termio );
 
     /*
      * check if gameport is likelly to be properly powered,
      * i.e TIOCM_RTS and TIOCM_DTR must be high
      */
     ioctl( joyfd, TIOCMGET,&flags );
     if ( (flags&(TIOCM_RTS|TIOCM_DTR)) != (TIOCM_RTS|TIOCM_DTR) )
     {
     	fprintf(stderr, "------> TIOCM_RTS and TIOCM_DTR not 1\n");
 	printf("TIOCM_RTS(%d) et TIOCM_DTR(%d) /
 (TIOCMGET=%x)\n",TIOCM_RTS,TIOCM_DTR, flags);
 	exit(1);
     }	
 
     printf("Init done.\n");
     printf("----------------------------------------------------------------\n");
 
 }
 
 void print_wgstate(const WG_State* wgs)
 {
     printf("J1_POT1:%3d ", wgs->joy1_pot1 );
     printf("J1_POT2:%3d ", wgs->joy1_pot2 );
     printf("J2_POT1:%3d ", wgs->joy2_pot1 );
     printf("J2_POT2:%3d ", wgs->joy2_pot2 );
 
     if ( wgs->buttons & JOY_BUT_1)
 	printf("BUT_1 ");
     else
 	printf("      ");
     if ( wgs->buttons & JOY_BUT_2)
 	printf("BUT_2 ");
     else
 	printf("      ");
     if ( wgs->buttons & JOY_BUT_3)
 	printf("BUT_3 ");
     else			
 	printf("      ");
     if ( wgs->buttons & JOY_BUT_4)
 	printf("BUT_4 ");
     else		
 	printf("      ");
 
 /*     printf("\r"); */
     printf("\n");
     fflush(stdout);
 }
 
 void close_joystick()
 {
 	close( joyfd );
 }
 
 main(int argc, char **argv)
 {
     WG_State wg_state;
     int nonblock=0;
     int portnumber=-1;
 
     if( (argc!=2) && (argc!=3) )
     {
 	printf("Usage: %s <serial_number> [nb]\n If nb is used, the serial-line read 
 won't block\n", argv[0]);
 	exit(1);
     }
 
     portnumber=atoi(argv[1]);
     if (!portnumber)
     {
 	fprintf(stderr, "Bad port number\n");
 	exit(1);
     }
 
     if ( (argc==3) && (strcmp(argv[2], "nb")) == 0 ) /* non blocking mode */
     {
 	 init_joystick( portnumber, READNONBLOCK );
 	 while(1)
 	 {
 	    get_joystick_NON_BLOCK(&wg_state);
 	    print_wgstate(&wg_state);
 	    sginap(1);
 	 }
     }
 
     else
     {
 	init_joystick( portnumber, READBLOCK );
 
 	while(1)
 	{
 	    get_joystick(&wg_state);
 	    print_wgstate(&wg_state);
 	}
     }
 }

One can connect any PC joystick without doing any special wiring, I've used a Gravis, which has 4 independant buttons.

If one wants to use 2 different joysticks, I guess you just have to make a cable that directs the good potentiometers values and switches to the good connections onto the WG, knowing that the joystick DB-15 connector on the WG has the following pinout:

 Pin Number                         Function
 1,8,9,15                             +5V       (Pot common)
 2                                  Switch 1
 3                                    Pot 1
 4,5,12                              Ground   (Switch common)
 6                                    Pot 2
 7                                    Sw 2
 10                                   Sw 3
 11                                   Pot 3
 13                                   Pot 4
 14                                   Sw 4

(If anybody tries this, please mail me the exact connections you made).

 David Nahon, Z.A. Production R & D
 nahond@ccr.jussieu.fr
 64, rue de la Folie Mericourt
 75011 Paris - France
 Phone : 33 (1) 48 06 65 66
   FAX : 33 (1) 48 06 48 75

Brent Bates' other notes on installing third party hardware on SGI's:

CD-ROM's, DAT's, Hard Disks,
Floppies/Flopticals, Joysticks, Magneto Opticals,

Memory, CDR's (Writeable CD-ROM's), DLT's (Digital Linear Tape), Mice


If you have any additions, corrects, or updates to the above information, please email me at: blbates@vigyan.com, thanks.

Total number of accesses to this page since its creation :

Last update: May 14, 2002