/*
Sample C code for reading joystick axis

Joysticks & gamecards vary in their physical characteristics from one to
another.  For this reason the high state duration of joysticks in their
extreme positions must be predetermined for each joystick & gamecard
combinations.  The following program will prompt the user to move the
joystick to all its extreme positions at startup time.  Axis high state
duration will be recorded at these positions for computing joystick
position at a later time in the program.

*/

#include <conio.h>
#include <stdio.h>

/* Declare external functions */

extern unsigned char joyread(unsigned int *values, unsigned char *buttons, unsigned char ax_mask);

/* Declare local functions */

short compute_axis (short, short, short);  /* Compute axis coordinate */
void display_coordinate (void);            /* Display joystick coordinate */

/*
Declare variable
*/
short stick_a_min_x;          /* Minimum high state duration for X axis of joystick A */
short stick_a_max_x;          /* Maximun high state duration for X axis of joystick A */
short stick_a_range_x;	      /* Joystick A - X axis travel range */
short stick_a_min_y;          /* Minimum high state duration for Y axis of joystick A */
short stick_a_max_y;          /* Maximum high state duration for Y axis of joystick A */
short stick_a_range_y;	      /* Joystick A - Y axis travel range */
short stick_b_min_x;          /* Minimum high state duration for X axis of joystick B */
short stick_b_max_x;          /* Maximum high state duration for X axis of joystick B */
short stick_b_range_x;	      /* Joystick B - X axis travel range */
short stick_b_min_y;          /* Minimum high state duration for Y axis of joystick B */
short stick_b_max_y;          /* Maximum high state duration for Y axis of joystick B */
short stick_b_range_y;	      /* Joystick B - Y axis travel range */

unsigned char axis_mask;      /* Axis mask value */
unsigned int  axis_values[4]; /* Array of axis values */
unsigned char button_values;  /* Button values */

/* Definitions for axis mask bits */

#define JOYSTICK_A_X_AXIS  0x01
#define JOYSTICK_A_Y_AXIS  0x02
#define JOYSTICK_B_X_AXIS  0x04
#define JOYSTICK_B_Y_AXIS  0x08

/* Definitions for button mask bits */

#define JOYSTICK_A_BUTTON1 0x01
#define JOYSTICK_A_BUTTON2 0x02
#define JOYSTICK_B_BUTTON1 0x04
#define JOYSTICK_B_BUTTON2 0x08

main ()
{

   /* Call joyread with axis mask of 0x0f to see how many axes we have */
   axis_mask = joyread(axis_values,&button_values,0x0f);

   if(axis_mask & JOYSTICK_A_X_AXIS) {
      printf("Joystick A - X Axis Detected. \n");
   }

   if(axis_mask & JOYSTICK_A_Y_AXIS) {
      printf("Joystick A - Y Axis Detected. \n");
   }

   if(axis_mask & JOYSTICK_B_X_AXIS) {
      printf("Joystick B - X Axis Detected. \n");
   }

   if(axis_mask & JOYSTICK_B_Y_AXIS) {
      printf("Joystick B - Y Axis Detected. \n");
   }

   printf("\n");

	/* Joystick A - X-Axis*/
   if(axis_mask & JOYSTICK_A_X_AXIS) {
      
      printf ("Move stick A farthest left, and press a button\n");
	   
      /* Wait for button press */
   	while (button_values == 0) joyread(axis_values,&button_values,axis_mask);
   	while (button_values != 0) joyread(axis_values,&button_values,axis_mask);

      /* Button pressed, read joystick A - X axis */
   	stick_a_min_x = axis_values[0];

      printf ("Move stick A farthest right, and press a button\n");

      /* Wait for button press */
   	while (button_values == 0) joyread(axis_values,&button_values,axis_mask);
   	while (button_values != 0) joyread(axis_values,&button_values,axis_mask);

      /* Button pressed, read joystick A - X axis */
      stick_a_max_x = axis_values[0];

   	/* Compute joystick A - X axis travel range */
   	stick_a_range_x = stick_a_max_x - stick_a_min_x;
   
   }
 
	/* Joystick A - Y-Axis*/
   if(axis_mask & JOYSTICK_A_X_AXIS) {

      printf ("Move stick A farthest forward, and press a button\n");
	   
      /* Wait for button press */
   	while (button_values == 0) joyread(axis_values,&button_values,axis_mask);
   	while (button_values != 0) joyread(axis_values,&button_values,axis_mask);

      /* Button pressed, read joystick A - Y axis */
   	stick_a_min_y = axis_values[1];

      printf ("Move stick A farthest back, and press a button\n");

      /* Wait for button press */
   	while (button_values == 0) joyread(axis_values,&button_values,axis_mask);
   	while (button_values != 0) joyread(axis_values,&button_values,axis_mask);

      /* Button pressed, read joystick A - Y axis */
      stick_a_max_y = axis_values[1];

   	/* Compute joystick A - Y axis travel range */
   	stick_a_range_y = stick_a_max_y - stick_a_min_y;

   }


	/* Joystick B - X-Axis*/
   if(axis_mask & JOYSTICK_B_X_AXIS) {
      
      printf ("Move stick B farthest left, and press a button\n");
	   
      /* Wait for button press */
   	while (button_values == 0) joyread(axis_values,&button_values,axis_mask);
   	while (button_values != 0) joyread(axis_values,&button_values,axis_mask);

      /* Button pressed, read joystick B - X axis */
   	stick_b_min_x = axis_values[2];

      printf ("Move stick B farthest right, and press a button\n");

      /* Wait for button press */
   	while (button_values == 0) joyread(axis_values,&button_values,axis_mask);
   	while (button_values != 0) joyread(axis_values,&button_values,axis_mask);

      /* Button pressed, read joystick B - X axis */
      stick_b_max_x = axis_values[2];

   	/* Compute joystick B - X axis travel range */
   	stick_b_range_x = stick_b_max_x - stick_b_min_x;
   
   }
 
	/* Joystick B - Y-Axis*/
   if(axis_mask & JOYSTICK_B_Y_AXIS) {

      printf ("Move stick B farthest forward, and press a button\n");
	   
      /* Wait for button press */
   	while (button_values == 0) joyread(axis_values,&button_values,axis_mask);
   	while (button_values != 0) joyread(axis_values,&button_values,axis_mask);

      /* Button pressed, read joystick B - Y axis */
   	stick_b_min_y = axis_values[3];

      printf ("Move stick B farthest back, and press a button\n");

      /* Wait for button press */
   	while (button_values == 0) joyread(axis_values,&button_values,axis_mask);
   	while (button_values != 0) joyread(axis_values,&button_values,axis_mask);

      /* Button pressed, read joystick B - Y axis */
      stick_b_max_y = axis_values[3];

   	/* Compute joystick B - Y axis travel range */
   	stick_b_range_y = stick_b_max_y - stick_b_min_y;

   }

   printf("\nStick A - X-Axis: MIN=%5d  MAX=%5d  RANGE=%5d\n",stick_a_min_x,stick_a_max_x,stick_a_range_x);
   printf("Stick B - Y-Axis: MIN=%5d  MAX=%5d  RANGE=%5d\n",stick_a_min_y,stick_a_max_y,stick_a_range_y);
   printf("Stick C - X-Axis: MIN=%5d  MAX=%5d  RANGE=%5d\n",stick_b_min_x,stick_b_max_x,stick_b_range_x);
   printf("Stick D - Y-Axis: MIN=%5d  MAX=%5d  RANGE=%5d\n",stick_b_min_y,stick_b_max_y,stick_b_range_y);

   printf("\n\n             Stick A                               Stick B\n");
   printf("             -------                               -------\n");
   printf("    X-Axis    Y-Axis  Btn 1  Btn 2        X-Axis    Y-Axis  Btn 1  Btn 2\n");
   printf("----------------------------------    ----------------------------------\n");

	/* Display joystick coordinate */
	while (!kbhit ()) display_coordinate ();

   /* Flush keyboard buffer before quitting */
	if (getch () == 0) getch ();

   printf("\n");

}


/*
Display all 4 joystick coordinates from a range of 0 to 100
*/

void display_coordinate ()
{
	short stick_a_x, stick_a_y, stick_b_x, stick_b_y;

   joyread(axis_values,&button_values,axis_mask);

   stick_a_x = axis_values[0];
	stick_a_y = axis_values[1];
	stick_b_x = axis_values[2];
	stick_b_y = axis_values[3];

	if (stick_a_x < stick_a_min_x)
		stick_a_x = stick_a_min_x;
	else
		if (stick_a_x > stick_a_max_x)
			stick_a_x = stick_a_max_x;
	if (stick_a_range_x == 0)
		printf ("         0");
	else
		printf ("%10d", compute_axis (stick_a_x, stick_a_min_x, stick_a_range_x));

	if (stick_a_y < stick_a_min_y)
		stick_a_y = stick_a_min_y;
	else
		if (stick_a_y > stick_a_max_y)
			stick_a_y = stick_a_max_y;
	if (stick_a_range_y == 0)
		printf ("         0");
	else
		printf ("%10d", compute_axis (stick_a_y, stick_a_min_y, stick_a_range_y));

   if (button_values & JOYSTICK_A_BUTTON1) printf("   DOWN");
   else printf("     UP");
      
   if (button_values & JOYSTICK_A_BUTTON2) printf("   DOWN");
   else printf("     UP");
 
   if (stick_b_x < stick_b_min_x)
		stick_b_x = stick_b_min_x;
	else
		if (stick_b_x > stick_b_max_x)
			stick_b_x = stick_b_max_x;
	if (stick_b_range_x == 0)
		printf ("             0");
	else
		printf ("%14d", compute_axis (stick_b_x, stick_b_min_x, stick_b_range_x));

	if (stick_b_y < stick_b_min_y)
		stick_b_y = stick_b_min_y;
	else
		if (stick_b_y > stick_b_max_y)
			stick_b_y = stick_b_max_y;
	if (stick_b_range_y == 0)
		printf ("         0");
	else
		printf ("%10d", compute_axis (stick_b_y, stick_b_min_y, stick_b_range_y));

   if (button_values & JOYSTICK_B_BUTTON1) printf("   DOWN");
   else printf("     UP");
      
   if (button_values & JOYSTICK_B_BUTTON2) printf("   DOWN");
   else printf("     UP");

   printf("\r"); 
   
}


/*
Compute axis coordinate from a range of 0 to 100
*/
short compute_axis (axis, min, range)
short axis, min, range;
{
	return (((long) 100 * (long) (axis - min)) / (long) range);
}
