#include <stdio.h>

#include "DeviceToolKits/GamePort.h"
#ifndef  TESTPROTO
#define  NO_PRAGMAS  1
#endif
#include "DeviceToolKits/proto/GamePort.h"
#include "DeviceToolKits/GamePortBase.h"

DTGamePort_t               Unit1;
DTGamePort_t               Unit1Copy;
BYTE                       type;
struct   GamePortTrigger   trigger;
struct   InputEvent        buffer;
ULONG                      length;

main(argc,argv)
int   argc;
char  *argv[];
{
   long  status;

#ifdef   TESTSHARED
/*  Open the GamePort library  */

   DTGamePortOpen(DTGAMEPORTREV);
#endif

/*  Try to initialize unit 1 of the GamePort  */

   if ((Unit1 = DTGamePortCreate(1L,&status)) == NULL) {
      fprintf(stderr,"Error initializing unit 1 = %ld.\n",status);
      fflush(stderr);
      goto cleanup;
   }

   fprintf(stderr,"Unit1 = %lX\n",(long) Unit1);
   fflush(stderr);

/*  Make a copy of the control structure  */

   if ((Unit1Copy = DTGamePortCreateLike(Unit1,&status)) == NULL) {
      fprintf(stderr,"Error copying unit 1 = %ld.\n",status);
      fflush(stderr);
      goto cleanup;
   }

   fprintf(stderr,"Unit1Copy = %lX\n",(long) Unit1Copy);
   fflush(stderr);

/*  Find out what kind of controller is on unit 1  */

   if ((status = DTGamePortGetType(Unit1,&type)) != 0) {
      fprintf(stderr,"Error getting unit 1 type = %ld,%ld.\n",
               status,Unit1->gp_error);
      fflush(stderr);
      goto cleanup;
   }

   printf("Unit 1 controller type = %d.\n",type);

/*  Set the controller for an absolute joystick  */

   type = GPCT_ABSJOYSTICK;
   if ((status = DTGamePortSetType(Unit1,&type)) != 0) {
      fprintf(stderr,"Error setting unit 1 type = %ld,%ld.\n",
               status,Unit1->gp_error);
      fflush(stderr);
      goto cleanup;
   }

/*  Find out what kind of controller is on unit 1  */

   if ((status = DTGamePortGetType(Unit1Copy,&type)) != 0) {
      fprintf(stderr,"Error getting unit 1 type = %ld,%ld.\n",
               status,Unit1Copy->gp_error);
      fflush(stderr);
      goto cleanup;
   }

   printf("Unit 1 controller type = %d.\n",type);

/*  Find out what kind of trigger is on unit 1  */

   if ((status = DTGamePortGetTrigger(Unit1,&trigger)) != 0) {
      fprintf(stderr,"Error getting unit 1 trigger = %ld,%ld.\n",
               status,Unit1->gp_error);
      fflush(stderr);
      goto cleanup;
   }

   printf("Keys    = %x\n",trigger.gpt_Keys);
   printf("Timeout = %d\n",trigger.gpt_Timeout);
   printf("XDelta  = %d\n",trigger.gpt_XDelta);
   printf("YDelta  = %d\n",trigger.gpt_YDelta);

/*  Set the trigger for an absolute joystick  */

   trigger.gpt_Keys = GPTF_UPKEYS | GPTF_DOWNKEYS;
   trigger.gpt_Timeout = 0;
   trigger.gpt_XDelta = 1;
   trigger.gpt_YDelta = 1;

   if ((status = DTGamePortSetTrigger(Unit1,&trigger)) != 0) {
      fprintf(stderr,"Error setting unit 1 trigger = %ld,%ld.\n",
               status,Unit1->gp_error);
      fflush(stderr);
      goto cleanup;
   }

/*  Find out what kind of trigger is on unit 1  */

   if ((status = DTGamePortGetTrigger(Unit1Copy,&trigger)) != 0) {
      fprintf(stderr,"Error getting unit 1 trigger = %ld,%ld.\n",
               status,Unit1Copy->gp_error);
      fflush(stderr);
      goto cleanup;
   }

   printf("Keys    = %x\n",trigger.gpt_Keys);
   printf("Timeout = %d\n",trigger.gpt_Timeout);
   printf("XDelta  = %d\n",trigger.gpt_XDelta);
   printf("YDelta  = %d\n",trigger.gpt_YDelta);

/*  Sit around waiting for events  */

   if ((status = DTGamePortClear(Unit1)) != 0) {
      fprintf(stderr,"Error clearing unit 1 = %ld,%ld.\n",
               status,Unit1->gp_error);
      fflush(stderr);
      goto cleanup;
   }

   if ((status = DTGamePortQueueRead(Unit1,(BYTE *) &buffer,
         (ULONG) sizeof(buffer))) != 0) {
      fprintf(stderr,"Error queueing unit 1 = %ld,%ld.\n",
               status,Unit1->gp_error);
      fflush(stderr);
      goto cleanup;
   }

   while (1) {
      WaitPort(Unit1->gp_rport);
      status = DTGamePortCheckRead(Unit1,&length);
      if (status != 0) {
         fprintf(stderr,"Error reading unit 1 = %ld,%ld.\n",
                  status,Unit1->gp_error);
         fflush(stderr);
         goto cleanup;
      }
      if (length != 0) {
         if (eventprint(&buffer) < 0) {
            break;
         }
         if ((status = DTGamePortQueueRead(Unit1,(BYTE *) &buffer,
               (ULONG) sizeof(buffer))) != 0) {
            fprintf(stderr,"Error queueing unit 1 = %ld,%ld.\n",
                     status,Unit1->gp_error);
            fflush(stderr);
            goto cleanup;
         }
      }
   }

/*  Free the stuff  */

cleanup:
   DTGamePortFree(Unit1);
   DTGamePortFree(Unit1Copy);
#ifdef   TESTSHARED
   DTGamePortClose();
#endif
}

int   button_count = 0;

#ifdef   ANSI_PROTO
eventprint(struct InputEvent *event)
#else
eventprint(event)
struct   InputEvent  *event;
#endif

{
   if (event->ie_Code == IECODE_LBUTTON) {
      printf("BUTTON PRESSED ");
   }
   if (event->ie_Code == (IECODE_LBUTTON | IECODE_UP_PREFIX)) {
      printf("BUTTON RELEASED ");
   }
   switch (event->ie_Y) {
      case -1:
         printf("FORWARD ");
         break;

      case 1:
         printf("BACKWARD ");
         break;
   }
   switch (event->ie_X) {
      case -1:
         printf("LEFT");
         break;

      case 1:
         printf("RIGHT");
         break;
   }
   if (event->ie_X == 0 && event->ie_Y == 0) {
      printf("CENTERED");
   }
   else {
      button_count = 0;
   }
   printf("\n");

   if (event->ie_Code == IECODE_LBUTTON && event->ie_X == 0 &&
         event->ie_Y == 0) {
      button_count++;
      if (button_count > 3) {
         return (-1);
      }
   }

   return (0);
}

