home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / PCGLOVE / GLOVE / OBJGLV.ZIP / SRC / DEMO4B / USERINT / JOYSTICK.CPP next >
C/C++ Source or Header  |  1993-05-02  |  4KB  |  172 lines

  1. /* Read the joystick */
  2.  
  3. /* Written by Bernie Roehl, January 1992 (broehl@sunee.waterloo.edu)
  4.    Adapted from code written by ajmyrvold@violet.waterloo.edu (Alan J. Myrvold)
  5.    who got technical assistance from : uunet!netxcom!jallen (John Allen)
  6.  */
  7.  
  8. /* DSmods: - rotate calibration - switch debounce */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <dos.h>
  13. #include <bios.h>
  14. #include "userint.hpp"   /* for joystick struct */
  15. #include "rend386.hpp"   /* for interrupts_occurred */
  16.  
  17. /* This routine returns two bits; bit 0 on => joystick 1 found, bit 1 => joystick 2 */
  18.  
  19. int joystick_check()
  20. {
  21.     int c, result;
  22.     disable();
  23.     outportb(0x201,0xff); /* Trigger joystick */
  24.     c = inportb(0x201);
  25.     c = inportb(0x201);
  26.     c = inportb(0x201);
  27.     delay(2); /* wait a few milliseconds */
  28.     c ^= inportb(0x201); /* any bits that changed state are now set */
  29.     enable();
  30.     result = 0;
  31.     if (c & 0x03) result |= 1;
  32.     if (c & 0x0C) result |= 2;
  33.     return result;
  34. }
  35.  
  36. /* This routine reads the joystick, setting x y and buttons */
  37.  
  38. #define PIC_MASK    0x21
  39. #define IRQ0_MASK   0xFE    /* mask for timer int's */
  40. #define PIC_CMD     0x20    /* constants for PIC EOI command */
  41. #define NONSPEC_EOI 0x20
  42.  
  43. #include "isr.hpp"
  44.  
  45. int joystick_read(joystick_data *joy)
  46. {
  47.     int c, k, jx, jy;
  48.     int savemask;
  49.  
  50.     if (joy->port == -1) return 0;
  51.     /* mask all but timer IRQ */
  52.     disable();
  53.     outportb(PIC_MASK,((savemask=inportb(PIC_MASK))|IRQ0_MASK));
  54.     outportb(PIC_CMD, NONSPEC_EOI);
  55.     enable();
  56.  
  57.     tempISR::resetInterruptsOccurred();
  58.     /* interrupts_occurred = 0; /* repeat if timer interrupt! */
  59.     do {
  60.         if (segaISR::interruptsOccurred()) for (c = 0; c < 1000; c++);  /* let it reset */
  61.         segaISR::resetInterruptsOccurred();
  62.         /* interrupts_occurred = 0; /* repeat if timer interrupt! */
  63.         outportb(0x201, 0xff); /* Trigger joystick */
  64.         c = inportb(0x201);
  65.         if (joy->port) c >>= 2;
  66.         joy->buttons = ((~c) >> 4) & 0x0F;
  67.  
  68.         for (k = 0; c & 3; k++) /* Get X and Y positions */
  69.         {
  70.             if (c & 1) jx = k;
  71.             if (c & 2) jy = k;
  72.             c = inportb(0x201);
  73.             if (joy->port) c >>= 2;
  74.         }
  75.     }
  76.     while (segaISR::interruptsOccurred());
  77.  
  78.     disable();
  79.     outportb(PIC_MASK,savemask); // re-enable
  80.     enable();
  81.  
  82.     joy->x = jx - joy->cenx;
  83.     joy->y = jy - joy->ceny;
  84.     if (joy->scale) {
  85.         joy->x = (joy->x * joy->scale) / joy->xrange;
  86.         joy->y = (joy->y * joy->scale) / joy->yrange;
  87.     }
  88.     return 1;
  89. }
  90.  
  91. /* This routine assumes the joystick is centered; sets the port and the
  92.    maximum range for the joystick (i.e. minx to maxx) */
  93.  
  94. void joystick_init(joystick_data *joy, int port)
  95. {
  96.     joy->cenx = joy->ceny = 0;
  97.     joy->port = port; 
  98.     joy->scale = 0;
  99.     joystick_read(joy);
  100.     joy->cenx = joy->x; 
  101.     joy->ceny = joy->y;
  102.     joy->xrange = 2*joy->x;
  103.     joy->yrange = 2*joy->y;
  104. }
  105.  
  106. void joystick_setscale(joystick_data *joy, int value)
  107. {
  108.     joy->scale = value;
  109. }
  110.  
  111. void joystick_quit()
  112. {
  113. }
  114.  
  115. /* If dir == 0, we're at top left; else, we're at bottom right */
  116. #pragma argsused
  117. void joystick_scale(joystick_data *joy, int dir)
  118. {
  119.     long t;
  120.     long maxx, maxy, minx, miny;
  121.  
  122.     maxx = maxy = 0;
  123.     minx = miny = 10000;
  124.  
  125.     t = joy->scale;
  126.     joy->scale = 0;
  127.     do {
  128.         joystick_read(joy);
  129.         if (joy->x > maxx) maxx = joy->x;
  130.         if (joy->y > maxy) maxy = joy->y;
  131.         if (joy->x < minx) minx = joy->x;
  132.         if (joy->y < miny) miny = joy->y;
  133.     }
  134.     while (joy->buttons == 0);
  135.  
  136.     joy->xrange = maxx - minx;
  137.     joy->yrange = maxy - miny;
  138.     delay(10);
  139.     do {
  140.         joystick_read(joy);
  141.     }
  142.     while (joy->buttons);
  143.     delay(10);
  144.  
  145.     joy->scale = t;
  146. }
  147.  
  148.  
  149. #ifdef TEST
  150. void main()
  151. {
  152.     joystick_data joy;
  153.     if (joystick_check())
  154.         printf("We found a joystick!\n");
  155.     else {
  156.         printf("No joy.\n");
  157.         exit(0);
  158.     }
  159.     joystick_init(&joy, 0);
  160.     joystick_setscale(&joy, 100);
  161.     printf("Move joystick to upper left:\n");
  162.     joystick_scale(&joy, 0);
  163.     printf("Move joystick to lower right:\n");
  164.     joystick_scale(&joy, 1);
  165.     do {
  166.         joystick_read(&joy);
  167.         printf("%d,%d        \r", joy.x, joy.y);
  168.     }
  169.     while (joy.buttons == 0);
  170. }
  171. #endif
  172.