home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 427_01 / software / minijoy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-17  |  8.3 KB  |  226 lines

  1. /*                                                                        */
  2. /*                                                                        */
  3. /* file MINIJOY.C - compilable with Borland C++ 3.1                       */
  4. /*                                                                        */
  5. /* written in 1994 by Christof Ruch                                       */
  6. /*                                                                        */
  7. /* reads out status of the MULTI JOYSTICK INTERFACE                       */
  8. /*                                                                        */
  9. /* demo file lacking                                                      */
  10. /*   - keyboard support                                                   */
  11. /*   - joystick reassignment                                              */
  12. /*   - disabling if no MULTIJOY is wanted                                 */
  13. /*                                                                        */
  14. /* MINIJOY uses three DOS environment variables:                          */
  15. /*                                                                        */
  16. /* MULTIPATH is the path where the config file is located                 */
  17. /* MULTICFG  is the name of the config file without extension             */
  18. /* MULTIPORT is optional and states the printer port to be used           */
  19. /*           (port 1 is the default if MULTIPORT is empty)                */
  20. /*                                                                        */
  21.  
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <dos.h>
  26. #include <io.h>
  27. #include <ctype.h>
  28.  
  29. #include "minijoy.h"
  30.  
  31. /* contains all joystick status information */
  32. /* and is updated by calling GetAllJoyState */
  33. struct TJoy JoyState[MAXPLAYER];
  34.  
  35. /* stores information about pin assignment  */
  36. /* of the specific interface used           */
  37. struct TDecode
  38. {
  39.         int  stikno1, stikno2;
  40.         char action1, action2;
  41. };
  42.  
  43. char           multipath[128],*multicfg,*multiport,*multidelay;
  44. unsigned char  printer_port;
  45. unsigned int   pout, p_in;
  46. struct TDecode decode[16];
  47. int            invert;
  48. unsigned int   delaycount;
  49. struct TJoy    old[MAXPLAYER];
  50.  
  51. /* C has no sets :-( */
  52. int legalchar (char a)
  53. {
  54.         switch (a)
  55.         {
  56.                 case 'L':
  57.                 case 'R':
  58.                 case 'U':
  59.                 case 'D':
  60.                 case 'F':
  61.                 case '*': return 1;
  62.         }
  63.         return 0;
  64. }
  65.  
  66. /* sets MULTI JOYSTICK INTERFACE to address MJOYADDRESS */
  67. /* reads printer port, i.e. PAPER EMPTY and BUSY bits   */
  68. int read_port (int mjoyaddress)
  69. {
  70.         outport (pout, mjoyaddress);
  71.         asm push cx
  72.         asm mov  cx, delaycount
  73. l:      asm nop
  74.         asm loop l
  75.         asm pop  cx
  76.         return invert ? !inport(p_in) : inport(p_in);
  77. }
  78.  
  79. /* prints a MULTIJOY error message */
  80. void error_msg (int msg_nr, int code)
  81. {
  82.   printf ("MINIJOY.C error message: \n");
  83.   switch (msg_nr)
  84.   {
  85.     case  1 : printf ("Config file read error\n"); break;
  86.     case  2 : printf ("Config file syntax error: undefined action code ('%c')\n", code); break;
  87.     case  3 : printf ("Config file read error: unexpected end of file\n"); break;
  88.     case  4 : printf ("Config file found but not able to read it (%i)\n",code); break;
  89.     case 12 : printf ("Config file error: illegal joystick number (%i)\n", code); break;
  90.     case  5 : printf ("DOS environment does not contain MULTIPATH (path of config file)\n"); break;
  91.     case  6 : printf ("DOS environment does not contain MULTICFG  (name of config file)\n"); break;
  92.     case  7 : printf ("DOS environment variable MULTICFG must not have an extension\n"); break;
  93.     case  8 : printf ("Invalid DOS environment variable MULTIPORT ('%c')\n", code); break;
  94.     case  9 : printf ("MINIJOY does not support keyboard emulation mode\n"); break;
  95.     case 10 : printf ("Config file read error: address out of range ('%i')\n", code); break;
  96.     case 11 : printf ("Printer port %i not found\n",code); break;
  97.     default : printf ("critical error - no appropriate error message found (error #%i)\n",code);
  98.   }
  99.   printf ("\n");
  100.   printf ("MULTIPATH = %s\n", multipath);
  101.   printf ("MULTICFG  = %s\n", multicfg );
  102.   printf ("MULTIPORT = %s\n", multiport);
  103.   exit(1);
  104. }
  105.  
  106. /* find printer port number in a string */
  107. int get_port_no (char port_no)
  108. {
  109.         if (port_no<'1' || port_no>'3') error_msg (8, port_no);
  110.         return port_no-'0';
  111. }
  112.  
  113. /* reads interface pin assignment from disk */
  114. /* resets joystick status variables         */
  115. void InitMultiJoy ()
  116. {
  117.         char cmdline[8];
  118.         FILE *cfg;
  119.         int  i,j;
  120.  
  121.         strncpy(multipath,getenv("MULTIPATH"),100); /* read environment variables */
  122.         multicfg   = getenv("MULTICFG");
  123.         multiport  = getenv("MULTIPORT");
  124.         multidelay = getenv("MULTIDELAY");
  125.  
  126.         if (*multidelay)
  127.                delaycount = atoi(multidelay)+1;
  128.         else
  129.                delaycount = 1;
  130.  
  131.         if (!*multiport) printer_port = 1; else printer_port = get_port_no (*multiport);
  132.  
  133.         pout = peek (0x40, 8 + (printer_port-1)*2);
  134.  
  135.         if (!pout) error_msg(11, printer_port);
  136.         p_in = pout + 1;
  137.  
  138.         if (!multicfg)  error_msg(5, 0);           /* undefined? */
  139.         if (!multipath) error_msg(6, 0);           /* undefined? */
  140.         if (strchr(multicfg,'.')) error_msg(7, 0); /* extension? */
  141.  
  142.         /* read config file */
  143.         if (multipath[strlen(multipath)-1]!='\\') strcat(multipath,"\\");
  144.         strcat(multipath,multicfg);
  145.         strcat(multipath,".cfg");
  146.  
  147.         if (!(cfg = fopen(multipath,"ra"))) error_msg (1, 0);
  148.  
  149.         for (i=0; i<16; i++)
  150.         {
  151.                 if (feof(cfg)) error_msg(3,0);
  152.  
  153.                 if (fscanf(cfg,"%d %d %c %d %c", &j,
  154.                            &decode[i].stikno1, &decode[i].action1,
  155.                            &decode[i].stikno2, &decode[i].action2)!=5)
  156.                         error_msg (4, 0);
  157.  
  158.                 decode[i].stikno1--; /* array begins with index 0 */
  159.                 decode[i].stikno2--;
  160.  
  161.                 if (decode[i].stikno1 < 0 || decode[i].stikno1 >= MAXPLAYER)
  162.                         error_msg(12,decode[i].stikno1);
  163.  
  164.                 decode[i].action1 = toupper(decode[i].action1);
  165.                 if (!legalchar(decode[i].action1))
  166.                         error_msg (2, decode[i].action1);
  167.  
  168.                 if (decode[i].stikno2 < 0 || decode[i].stikno2 >= MAXPLAYER)
  169.                         error_msg(12,decode[i].stikno2);
  170.  
  171.                 decode[i].action2 = toupper(decode[i].action2);
  172.                 if (!legalchar(decode[i].action2))
  173.                         error_msg (2, decode[i].action2);
  174.         }
  175.  
  176.         if (!feof(cfg))
  177.                fgets(cmdline,7,cfg);
  178.         else
  179.                strcpy(cmdline,"");
  180.  
  181.         invert = (strupr(cmdline)=="INVERT");
  182.         fclose (cfg);
  183.  
  184.         /* Initialize joystick status variables */
  185.         memset (JoyState, 0, sizeof(JoyState));
  186. }
  187.  
  188. /* decodes joystick status */
  189. void decode_joystate (int joy, char decode_action)
  190. {
  191.   switch (decode_action)
  192.   {
  193.     case 'L': JoyState[joy].x = -1; JoyState[joy].lhit = old[joy].x!=-1; break;
  194.     case 'R': JoyState[joy].x =  1; JoyState[joy].rhit = old[joy].x!= 1; break;
  195.     case 'U': JoyState[joy].y = -1; JoyState[joy].uhit = old[joy].y!=-1; break;
  196.     case 'D': JoyState[joy].y =  1; JoyState[joy].dhit = old[joy].y!= 1; break;
  197.     case 'F': JoyState[joy].knopf = -1; JoyState[joy].khit = !old[joy].knopf;break;
  198.     case '*': JoyState[joy].xtra  =  1; JoyState[joy].xhit = !old[joy].xtra; break;
  199.   }
  200. }
  201.  
  202. /* gets status of all joysticks */
  203. void GetAllJoyState ()
  204. {
  205.         int   i;
  206.         int  address, joy, pebu;
  207.  
  208.         memcpy(old,JoyState,sizeof(JoyState));
  209.         memset(JoyState,0,sizeof(JoyState));
  210.  
  211.         for (address = 0; address<16; address++)
  212.         {
  213.                 pebu = read_port (address);
  214.                 /* first bit */
  215.                 joy = decode [address].stikno1;
  216.                 if (pebu & 0x20)
  217.                         decode_joystate (joy, (decode [address].action1));
  218.                 /* second bit */
  219.                 joy = decode [address].stikno2;
  220.                 if (!(pebu & 0x80))
  221.                         decode_joystate (joy, decode[address].action2);
  222.         }
  223.  
  224. }
  225.  
  226.