home *** CD-ROM | disk | FTP | other *** search
/ Teach Yourself Game Programming in 21 Days / TYGAMES_R.ISO / source / day_07 / joytst.c < prev    next >
Encoding:
Text File  |  1994-05-16  |  9.0 KB  |  353 lines

  1.  
  2. // I N C L U D E S ///////////////////////////////////////////////////////////
  3.  
  4. #include <dos.h>
  5. #include <bios.h>
  6. #include <stdio.h>
  7. #include <math.h>
  8. #include <conio.h>
  9. #include <graph.h>
  10.  
  11.  
  12. // D E F I N E S  ////////////////////////////////////////////////////////////
  13.  
  14. #define JOYPORT      0x201  // joyport is at 201 hex
  15.  
  16. #define BUTTON_1_1   0x10   // joystick 1, button 1
  17. #define BUTTON_1_2   0x20   // joystick 1, button 2
  18. #define BUTTON_2_1   0x40   // joystick 2, button 1
  19. #define BUTTON_2_2   0x80   // joystick 2, button 2
  20.  
  21. #define JOYSTICK_1   0x01   // joystick 1, in general
  22. #define JOYSTICK_2   0x02   // joystick 2, in general
  23.  
  24. #define JOYSTICK_1_X 0x01   // joystick 1, x axis
  25. #define JOYSTICK_1_Y 0x02   // joystick 1, y axis
  26. #define JOYSTICK_2_X 0x04   // joystick 2, x axis
  27. #define JOYSTICK_2_Y 0x08   // joystick 2, y axis
  28.  
  29. #define JOY_1_CAL       1   // command to calibrate joystick #1
  30. #define JOY_2_CAL       2   // command to calibrate joystick #2
  31.  
  32.  
  33. // G L O B A L S  ////////////////////////////////////////////////////////////
  34.  
  35. unsigned int joy_1_max_x,   // global joystick calibration variables
  36.              joy_1_max_y,
  37.              joy_1_min_x,
  38.              joy_1_min_y,
  39.              joy_1_cx,
  40.              joy_1_cy,
  41.              joy_2_max_x,
  42.              joy_2_max_y,
  43.              joy_2_min_x,
  44.              joy_2_min_y,
  45.              joy_2_cx,
  46.              joy_2_cy;
  47.  
  48.  
  49.  
  50. // F U N C T I O N S /////////////////////////////////////////////////////////
  51.  
  52. unsigned char Buttons(unsigned char button)
  53. {
  54. // read the joystick buttons by peeking the port that the switches are attached
  55. // to.
  56.  
  57. outp(JOYPORT,0); // clear the latch and request a sample
  58.  
  59. // invert buttons then mask with request
  60.  
  61. return( ~inp(JOYPORT) & button);
  62.  
  63. } // end Buttons
  64.  
  65. //////////////////////////////////////////////////////////////////////////////
  66.  
  67. unsigned int Joystick(unsigned char stick)
  68. {
  69. // reads the joystick values manually by conting how long the capacitors take
  70. // to charge/discharge
  71. // let's use the inline assembler.  It's Cool!
  72.  
  73. __asm
  74.     {
  75.     cli                    ; disable interupts
  76.  
  77.     mov ah, byte ptr stick ; get mask into ah to selct joystick to read
  78.     xor al,al              ; zero out al, xor is a trick
  79.     xor cx,cx              ; same with cx which we will use as a counter
  80.     mov dx,JOYPORT         ; dx is used by inp and outp
  81.     out dx,al              ; write 0's to the port
  82. discharge:
  83.     in al,dx               ; read the data back from port
  84.     test al,ah             ; has the bit in question changed?
  85.     loopne discharge       ; if the stick isn't ready then --cx and loop
  86.  
  87.     sti                    ; re-enable interrupts
  88.     xor ax,ax              ; zero out ax
  89.     sub ax,cx              ; ax now holds the position of the axis switch
  90.  
  91.     } // end asm
  92.  
  93. // since ax has the result the function will return it properly
  94.  
  95. } // end Joystick
  96.  
  97. //////////////////////////////////////////////////////////////////////////////
  98.  
  99. unsigned int Joystick_Bios(unsigned char stick)
  100. {
  101. // bios version of joystick read
  102.  
  103. union _REGS inregs, outregs;
  104.  
  105. inregs.h.ah = 0x84; // joystick function 84h
  106. inregs.x.dx = 0x01; // read joysticks subfunction 1h
  107.  
  108. // call dos
  109.  
  110. _int86(0x15,&inregs, &outregs);
  111.  
  112. // return proper value depending on sent command
  113.  
  114. switch(stick)
  115.       {
  116.       case JOYSTICK_1_X:
  117.            {
  118.            return(outregs.x.ax);
  119.            } break;
  120.  
  121.       case JOYSTICK_1_Y:
  122.            {
  123.            return(outregs.x.bx);
  124.            } break;
  125.  
  126.       case JOYSTICK_2_X:
  127.            {
  128.            return(outregs.x.cx);
  129.            } break;
  130.  
  131.       case JOYSTICK_2_Y:
  132.            {
  133.            return(outregs.x.dx);
  134.            } break;
  135.  
  136.       default:break;
  137.  
  138.       } // end switch stick
  139.  
  140. } // end Joystick_Bios
  141.  
  142.  
  143. //////////////////////////////////////////////////////////////////////////////
  144.  
  145. unsigned char Buttons_Bios(unsigned char button)
  146. {
  147. // bios version of buttons read
  148.  
  149. union _REGS inregs, outregs;
  150.  
  151. inregs.h.ah = 0x84; // joystick function 84h
  152. inregs.x.dx = 0x00; // read buttons subfunction 0h
  153.  
  154. // call dos
  155.  
  156. _int86(0x15,&inregs, &outregs);
  157.  
  158. // invert buttons then mask with request
  159.  
  160. return( (~outregs.h.al) & button);
  161.  
  162. } // end Buttons_Bios
  163.  
  164. //////////////////////////////////////////////////////////////////////////////
  165.  
  166. void Joystick_Calibrate(int stick)
  167. {
  168. // calibrates the joystick by finding the min and max deflections in both the
  169. // X and Y axis.  Then stores it in a global data structure for future use.
  170.  
  171. unsigned int x_new,y_new; // temp joystick positions
  172.  
  173. // set vars so that we can find there actual values
  174.  
  175. if (stick==JOY_1_CAL)
  176.    {
  177.  
  178.    printf("\nCalibrating Joystick #1: Swirl stick then release and press fire");
  179.  
  180.    // set calibrations to impossible values
  181.  
  182.    joy_1_max_x=0;
  183.    joy_1_max_y=0;
  184.    joy_1_min_x=10000;
  185.    joy_1_min_y=10000;
  186.  
  187.    // now the user should shwirl joystick let the stick fall neutral then press
  188.    // any button
  189.  
  190.    while(!Buttons(BUTTON_1_1 | BUTTON_1_2))
  191.         {
  192.         // get the new values and try to update calibration
  193.         x_new = Joystick_Bios(JOYSTICK_1_X);
  194.         y_new = Joystick_Bios(JOYSTICK_1_Y);
  195.  
  196.         // process X - axis
  197.  
  198.         if (x_new >= joy_1_max_x)
  199.             joy_1_max_x = x_new;
  200.  
  201.         if (x_new <= joy_1_min_x)
  202.             joy_1_min_x = x_new;
  203.  
  204.         // process Y - axis
  205.  
  206.         if (y_new >= joy_1_max_y)
  207.             joy_1_max_y = y_new;
  208.  
  209.         if (y_new <= joy_1_min_y)
  210.             joy_1_min_y = y_new;
  211.  
  212.         } // end while
  213.  
  214.         // user has let stick go to center so that must be the center
  215.  
  216.         joy_1_cx = x_new;
  217.         joy_1_cy = y_new;
  218.  
  219.    } // end calibrate joystick #1
  220. else
  221. if (stick==JOY_2_CAL)
  222.    {
  223.    printf("\nCalibrating Joystick #2: Swirl stick then release and press fire");
  224.  
  225.    // set calibrations to impossible values
  226.  
  227.    joy_2_max_x=0;
  228.    joy_2_max_y=0;
  229.    joy_2_min_x=10000;
  230.    joy_2_min_y=10000;
  231.  
  232.    // now the user should shwirl joystick let the stick fall neutral then press
  233.    // any button
  234.  
  235.    while(!Buttons(BUTTON_2_1 | BUTTON_2_2))
  236.         {
  237.         // get the new values and try to update calibration
  238.         x_new = Joystick(JOYSTICK_2_X);
  239.         y_new = Joystick(JOYSTICK_2_Y);
  240.  
  241.         // process X - axis
  242.  
  243.         if (x_new >= joy_2_max_x)
  244.             joy_2_max_x = x_new;
  245.         else
  246.         if (x_new <= joy_2_min_x)
  247.             joy_2_min_x = x_new;
  248.  
  249.         // process Y - axis
  250.  
  251.         if (y_new >= joy_2_max_y)
  252.             joy_2_max_y = y_new;
  253.         else
  254.         if (y_new <= joy_2_min_y)
  255.             joy_2_min_y = y_new;
  256.  
  257.         } // end while
  258.  
  259.         // user has let stick go to center so that must be the center
  260.  
  261.         joy_2_cx = x_new;
  262.         joy_2_cy = y_new;
  263.  
  264.  
  265.    } // end calibrate joystick #2
  266.  
  267. printf("\nCalibration Complete...hit any key to continue.");
  268.  
  269. getch();
  270.  
  271. } // end Joystick_Calibrate
  272.  
  273. //////////////////////////////////////////////////////////////////////////////
  274.  
  275. int Joystick_Available(int stick_num)
  276. {
  277. // test if the joystick is plugged in that the user is requesting tested
  278.  
  279. if (stick_num == JOYSTICK_1)
  280.    {
  281.    // test if joystick 1 is plugged in by testing the port values
  282.    // they will be 0,0 if there is no stick
  283.  
  284.    return(Joystick_Bios(JOYSTICK_1_X)+Joystick_Bios(JOYSTICK_1_Y));
  285.  
  286.    } // end if joystick 1
  287. else
  288.    {
  289.    // test if joystick 2 is plugged in by testing the port values
  290.    // they will be 0,0 if there is no stick
  291.  
  292.    return(Joystick_Bios(JOYSTICK_2_X)+Joystick_Bios(JOYSTICK_2_Y));
  293.  
  294.    } // end else joystick 2
  295.  
  296. } // end Joystick_Available
  297.  
  298.  
  299. ///////////////////////////////////////////////////////////////////////////////
  300.  
  301. void main(void) // to test the joystick interface
  302. {
  303.  
  304. // test if joy stick is plugged in
  305.  
  306. if (!Joystick_Available(JOYSTICK_1))
  307.    {
  308.    printf("\nThere is not a joystick plugged into port #1.");
  309.    return;
  310.  
  311.    } // end if joystick not installed
  312.  
  313. // calibrate the joystick
  314.  
  315. Joystick_Calibrate(JOY_1_CAL);
  316.  
  317. _clearscreen(_GCLEARSCREEN);
  318.  
  319. // let user fiddle with the joystick
  320.  
  321. while(!kbhit())
  322.      {
  323.  
  324.      _settextposition(2,0);
  325.  
  326.      printf("Joystick 1 = [%u,%u]    ",Joystick_Bios(JOYSTICK_1_X),Joystick_Bios(JOYSTICK_1_Y));
  327.  
  328.      if (Buttons_Bios(BUTTON_1_1))
  329.         printf("\nButton 1 pressed   ");
  330.      else
  331.      if (Buttons_Bios(BUTTON_1_2))
  332.         printf("\nButton 2 pressed   ");
  333.      else
  334.         printf("\nNo Button Pressed  ");
  335.      } // end while
  336.  
  337. // let user know what the calibrations turned out to be
  338.  
  339. printf("\nThe calibration data was:");
  340.  
  341. printf("\nmax x=%u, max y=%u,min x=%u,min y=%u,cx=%u,cy=%u",joy_1_max_x,
  342.                                                             joy_1_max_y,
  343.                                                             joy_1_min_x,
  344.                                                             joy_1_min_y,
  345.                                                             joy_1_cx,
  346.                                                             joy_1_cy);
  347.  
  348. // later!
  349.  
  350. } // end main
  351.  
  352.  
  353.