home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / REND386 / JIREND / JOYSTICK.C < prev    next >
C/C++ Source or Header  |  1993-04-11  |  4KB  |  176 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 <stdlib.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <dos.h>
  14. #include <bios.h>
  15.  
  16. #include "rend386.h"   /* for interrupts_occurred */
  17. #include "userint.h"   /* for joystick struct */
  18.   
  19. /* This routine returns two bits; bit 0 on => joystick 1 found, bit 1 => joystick 2 */
  20.   
  21. int joystick_check(void)
  22. {
  23.    int c, result;
  24.    disable();
  25.    outportb(0x201,0xff); /* Trigger joystick */
  26.    c = inportb(0x201);
  27.    c = inportb(0x201);
  28.    c = inportb(0x201);
  29.    delay(2); /* wait a few milliseconds */
  30.    c ^= inportb(0x201); /* any bits that changed state are now set */
  31.    enable();
  32.    result = 0;
  33.    if (c & 0x03) result |= 1;
  34.    if (c & 0x0C) result |= 2;
  35.    return result;
  36. }
  37.   
  38. /* This routine reads the joystick, setting x y and buttons */
  39.   
  40. #define PIC_MASK    0x21
  41. #define IRQ0_MASK   0xFE    /* mask for timer int's */
  42. #define PIC_CMD     0x20    /* constants for PIC EOI command */
  43. #define NONSPEC_EOI 0x20
  44.   
  45.   
  46. int joystick_read(joystick_data *joy)
  47. {
  48.    int c, k, jx, jy;
  49.    int savemask;
  50.   
  51.    if (joy->port == -1) return 0;
  52.    #ifdef COMMENT
  53.       // may cause joystick to glicth if int processing takes too long
  54.       // mask all but timer IRQ
  55.    disable();
  56.    outportb(PIC_MASK,((savemask=inportb(PIC_MASK))|IRQ0_MASK));
  57.    outportb(PIC_CMD, NONSPEC_EOI);
  58.    enable();
  59.    #endif
  60.   
  61.    interrupts_occurred = 0; /* repeat if timer interrupt! */
  62.    do {
  63.       if (interrupts_occurred) for (c = 0; c < 1000; c++);  /* let it reset */
  64.       interrupts_occurred = 0; /* repeat if timer interrupt! */
  65.       outportb(0x201, 0xff); /* Trigger joystick */
  66.       c = inportb(0x201);
  67.       if (joy->port) c >>= 2;
  68.       joy->buttons = ((~c) >> 4) & 0x0F;
  69.   
  70.       for (k = 0; c & 3; k++) /* Get X and Y positions */
  71.       {
  72.          if (c & 1) jx = k;
  73.          if (c & 2) jy = k;
  74.          c = inportb(0x201);
  75.          if (joy->port) c >>= 2;
  76.       }
  77.    }
  78.    while (interrupts_occurred != 0);
  79.   
  80.    #ifdef COMMENT
  81.    disable();
  82.    outportb(PIC_MASK,savemask); /* re-enable */
  83.    enable();
  84.    #endif
  85.   
  86.    joy->x = jx - joy->cenx;
  87.    joy->y = jy - joy->ceny;
  88.    if (joy->scale) {
  89.       joy->x = (joy->x * joy->scale) / joy->xrange;
  90.       joy->y = (joy->y * joy->scale) / joy->yrange;
  91.    }
  92.    return 1;
  93. }
  94.   
  95. /* This routine assumes the joystick is centered; sets the port and the
  96.    maximum range for the joystick (i.e. minx to maxx) */
  97.   
  98. void joystick_init(joystick_data *joy, int port)
  99. {
  100.    joy->cenx = joy->ceny = 0;
  101.    joy->port = port;
  102.    joy->scale = 0;
  103.    joystick_read(joy);
  104.    joy->cenx = joy->x;
  105.    joy->ceny = joy->y;
  106.    joy->xrange = 2*joy->x;
  107.    joy->yrange = 2*joy->y;
  108. }
  109.   
  110. void joystick_setscale(joystick_data *joy, int value)
  111. {
  112.    joy->scale = value;
  113. }
  114.   
  115. void joystick_quit(void)
  116. {
  117. }
  118.   
  119. /* If dir == 0, we're at top left; else, we're at bottom right */
  120.   
  121. void joystick_scale(joystick_data *joy, int dir)
  122. {
  123.    long t;
  124.    long maxx, maxy, minx, miny;
  125.   
  126.    maxx = maxy = 0;
  127.    minx = miny = 10000;
  128.   
  129.    t = joy->scale;
  130.    joy->scale = 0;
  131.    do {
  132.       joystick_read(joy);
  133.       if (joy->x > maxx) maxx = joy->x;
  134.       if (joy->y > maxy) maxy = joy->y;
  135.       if (joy->x < minx) minx = joy->x;
  136.       if (joy->y < miny) miny = joy->y;
  137.    }
  138.    while (joy->buttons == 0);
  139.   
  140.    joy->xrange = maxx - minx;
  141.    joy->yrange = maxy - miny;
  142.    delay(10);
  143.    do {
  144.       joystick_read(joy);
  145.    }
  146.    while (joy->buttons);
  147.    delay(10);
  148.   
  149.    joy->scale = t;
  150. }
  151.   
  152.   
  153. #ifdef TEST
  154. void main()
  155. {
  156.    joystick_data joy;
  157.    if (joystick_check())
  158.       printf("We found a joystick!\n");
  159.    else {
  160.       printf("No joy.\n");
  161.       exit(0);
  162.    }
  163.    joystick_init(&joy, 0);
  164.    joystick_setscale(&joy, 100);
  165.    printf("Move joystick to upper left:\n");
  166.    joystick_scale(&joy, 0);
  167.    printf("Move joystick to lower right:\n");
  168.    joystick_scale(&joy, 1);
  169.    do {
  170.       joystick_read(&joy);
  171.       printf("%d,%d        \r", joy.x, joy.y);
  172.    }
  173.    while (joy.buttons == 0);
  174. }
  175. #endif
  176.