home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / REND386 / DEVEL5 / JOYSTICK.C < prev    next >
C/C++ Source or Header  |  1992-09-06  |  4KB  |  169 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 "../include/userint.h"   /* for joystick struct */
  15. #include "../include/rend386.h"   /* 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.  
  44. int joystick_read(joystick_data *joy)
  45. {
  46.     int c, k, jx, jy;
  47.     int savemask;
  48.  
  49.     if (joy->port == -1) return 0;
  50.     /* mask all but timer IRQ */
  51.     disable();
  52.     outportb(PIC_MASK,((savemask=inportb(PIC_MASK))|IRQ0_MASK));
  53.     outportb(PIC_CMD, NONSPEC_EOI);
  54.     enable();
  55.  
  56.     interrupts_occurred = 0; /* repeat if timer interrupt! */
  57.     do {
  58.         if (interrupts_occurred) for (c = 0; c < 1000; c++);  /* let it reset */
  59.         interrupts_occurred = 0; /* repeat if timer interrupt! */
  60.         outportb(0x201, 0xff); /* Trigger joystick */
  61.         c = inportb(0x201);
  62.         if (joy->port) c >>= 2;
  63.         joy->buttons = ((~c) >> 4) & 0x0F;
  64.  
  65.         for (k = 0; c & 3; k++) /* Get X and Y positions */
  66.         {
  67.             if (c & 1) jx = k;
  68.             if (c & 2) jy = k;
  69.             c = inportb(0x201);
  70.             if (joy->port) c >>= 2;
  71.         }
  72.     }
  73.     while (interrupts_occurred != 0);
  74.  
  75.     disable();
  76.     outportb(PIC_MASK,savemask); /* re-enable */
  77.     enable();
  78.  
  79.     joy->x = jx - joy->cenx;
  80.     joy->y = jy - joy->ceny;
  81.     if (joy->scale) {
  82.         joy->x = (joy->x * joy->scale) / joy->xrange;
  83.         joy->y = (joy->y * joy->scale) / joy->yrange;
  84.     }
  85.     return 1;
  86. }
  87.  
  88. /* This routine assumes the joystick is centered; sets the port and the
  89.    maximum range for the joystick (i.e. minx to maxx) */
  90.  
  91. void joystick_init(joystick_data *joy, int port)
  92. {
  93.     joy->cenx = joy->ceny = 0;
  94.     joy->port = port; 
  95.     joy->scale = 0;
  96.     joystick_read(joy);
  97.     joy->cenx = joy->x; 
  98.     joy->ceny = joy->y;
  99.     joy->xrange = 2*joy->x; 
  100.     joy->yrange = 2*joy->y;
  101. }
  102.  
  103. void joystick_setscale(joystick_data *joy, int value)
  104. {
  105.     joy->scale = value;
  106. }
  107.  
  108. void joystick_quit()
  109. {
  110. }
  111.  
  112. /* If dir == 0, we're at top left; else, we're at bottom right */
  113.  
  114. void joystick_scale(joystick_data *joy, int dir)
  115. {
  116.     long t;
  117.     long maxx, maxy, minx, miny;
  118.  
  119.     maxx = maxy = 0;
  120.     minx = miny = 10000;
  121.  
  122.     t = joy->scale;
  123.     joy->scale = 0;
  124.     do {
  125.         joystick_read(joy);
  126.         if (joy->x > maxx) maxx = joy->x;
  127.         if (joy->y > maxy) maxy = joy->y;
  128.         if (joy->x < minx) minx = joy->x;
  129.         if (joy->y < miny) miny = joy->y;
  130.     }
  131.     while (joy->buttons == 0);
  132.  
  133.     joy->xrange = maxx - minx;
  134.     joy->yrange = maxy - miny;
  135.     delay(10);
  136.     do {
  137.         joystick_read(joy);
  138.     }
  139.     while (joy->buttons);
  140.     delay(10);
  141.  
  142.     joy->scale = t;
  143. }
  144.  
  145.  
  146. #ifdef TEST
  147. void main()
  148. {
  149.     joystick_data joy;
  150.     if (joystick_check())
  151.         printf("We found a joystick!\n");
  152.     else {
  153.         printf("No joy.\n");
  154.         exit(0);
  155.     }
  156.     joystick_init(&joy, 0);
  157.     joystick_setscale(&joy, 100);
  158.     printf("Move joystick to upper left:\n");
  159.     joystick_scale(&joy, 0);
  160.     printf("Move joystick to lower right:\n");
  161.     joystick_scale(&joy, 1);
  162.     do {
  163.         joystick_read(&joy);
  164.         printf("%d,%d        \r", joy.x, joy.y);
  165.     }
  166.     while (joy.buttons == 0);
  167. }
  168. #endif
  169.