/* Demonstration of reading joy stick postition
       Written March 24, 1988
       Written by : [email protected] (Alan J. Myrvold)
       Technical assistance from : uunet!netxcom!jallen (John Allen)
       Turbo C Version 1.0
*/

#include <stdio.h>
#include <dos.h>
#include <bios.h>
#include <conio.h>
#include "cursor.c"

typedef struct {
       int sw1,sw2;
       int x,y;
       int cenx,ceny;
       } joy_stick;

joy_stick joy;

#define keypressed (bioskey(1) != 0)
#define kb_clear() while keypressed bioskey(0);

void GotoXY(int x,int y)
{
       union REGS r;
/* Set XY position */
       r.h.ah = 2;
       r.h.bh = 0;            /* Assume Video Page 0 */
       r.h.dh = (char) y;
       r.h.dl = (char) x;
       int86(16,&r,&r);
}

/*
From: uunet!netxcom!jallen (John Allen)

1.  Trigger the joystick oneshots with an 'out' to 0x201.
       This will set all of the joystick bits on.

2.  Read (in) 0x201, finding:

       Bit             Contents
       0               Joystick A X coordinate
       1               Joystick A Y coordinate
       2               Joystick B X coordinate
       3               Joystick B Y coordinate
       4               Button A 1
       5               Button A 2
       6               Button B 1
       7               Button B 2

3.  Continue reading 0x201 until all oneshots return to zero,
   recording the loop during which each bit falls to zero.
   The duration of the pulse from each oneshot may be used to
   determine the resistive load (from 0 to 100K) from each
   Joystick, as: Time = 24.2msec. + .011 (r) msec.

4.  To do this correctly, I recommend calibrating the joystick;
   have the user move the stick to each corner, then center it,
   while recording the resulting values.
*/

void disp_stick(int line,joy_stick *joy)
{
   GotoXY(0,line);
   printf("sw1 %d sw2 %d",joy -> sw1,joy -> sw2);
   GotoXY(0,line+1);
       printf("x %6d y %6d",joy -> x,joy -> y);
}

void read_stick(int stick,joy_stick *joy)
{
   int k,jx,jy;
   int c,m1,m2,m3,m4,m5;

/* Define masks for the chosen joystick */
   if (stick == 1) m4 = 1; else
   if (stick == 2) m4 = 4; else
   printf("Invalid stick %d\n",stick);

       m5 = m4 << 1;
   m1 = m4 << 4;
   m2 = m5 << 4;
   m3 = m4 + m5;

/* Trigger joystick */
   outportb(0x201,0xff);
       c = inportb(0x201);

/* Read switch settings */
   joy -> sw1 = (c & m1) == 0;
   joy -> sw2 = (c & m2) == 0;

/* Get X and Y positions */
   for (k = 0; (c & m3) != 0; k++) {
       if ((c & m4) != 0) jx = k;
       if ((c & m5) != 0) jy = k;
       c = inportb(0x201);
   }
   joy -> x = jx - (joy -> cenx);
       joy -> y = jy - (joy -> ceny);
}

int choose_stick(joy_stick *joy)
{
   int init_swa,init_swb,swa,swb;
   int c,retval;

       printf("Joystick testing program\n");
       printf("------------------------\n\n");
       printf("Center joystick and press fire, or press any key\n");
       kb_clear();
   outportb(0x201,0xff);
   c = inportb(0x201);
   init_swa = c & 0x30;
   init_swb = c & 0xc0;
   do {
      outportb(0x201,0xff);
      c = inportb(0x201);
      swa = c & 0x30;
      swb = c & 0xc0;
   } while ((swa == init_swa) && (swb == init_swb) && !keypressed);
       if (swa != init_swa) {
      printf("Joystick 1 selected\n");
      retval = 1;
   } else if (swb != init_swb) {
      printf("Joystick 2 selected\n");
      retval = 2;
       } else {
          printf("Keyboard selected\n");
          kb_clear();
          retval = 0;
   }

   if (retval != 0) { /* Determine Center */
          joy -> cenx = joy -> ceny = 0;
          read_stick(retval,joy);
          joy -> cenx = joy -> x;
          joy -> ceny = joy -> y;
       }

       return(retval);
}

main()
{
  int k;

  clrscr();
  HideCur();
  k = choose_stick(&joy);
  if (k != 0) while (!keypressed) {
               read_stick(k,&joy);
               disp_stick(6,&joy);
  }
  clrscr();
  ShowCur();
}