home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 1.2 / amidev_cd_12.iso / reference_library / devices / dev_examples / absolute_joystick.c next >
Encoding:
C/C++ Source or Header  |  1992-08-20  |  9.5 KB  |  329 lines

  1. /*
  2.  * Absolute_Joystick.c
  3.  *
  4.  * Gameport device absolute joystick example
  5.  *
  6.  * Compile with SAS 5.10  lc -b1 -cfistq -v -y -L
  7.  *
  8.  * Run from CLI only
  9.  */
  10.  
  11. #include <exec/types.h>
  12. #include <exec/io.h>
  13. #include <exec/memory.h>
  14. #include <intuition/intuition.h>
  15. #include <exec/exec.h>
  16. #include <dos/dos.h>
  17. #include <devices/gameport.h>
  18. #include <devices/inputevent.h>
  19.  
  20. #include <clib/exec_protos.h>
  21. #include <clib/alib_protos.h>
  22. #include <clib/dos_protos.h>
  23. #include <clib/intuition_protos.h>
  24.  
  25. #include <stdio.h>
  26.  
  27. #ifdef LATTICE
  28. int CXBRK(void) { return(0); }     /* Disable SAS CTRL/C handling */
  29. int chkabort(void) { return(0); }  /* really */
  30. #endif
  31.  
  32. #define JOY_X_DELTA (1)
  33. #define JOY_Y_DELTA (1)
  34. #define TIMEOUT_SECONDS (10)
  35.  
  36. extern struct ExecBase *SysBase;
  37.  
  38. /*-----------------------------------------------------------------------
  39. ** Routine to print out some information for the user.
  40. */
  41. VOID printInstructions(VOID)
  42. {
  43. printf("\n >>> gameport.device Absolute Joystick Demo <<<\n\n");
  44.  
  45. if (SysBase->VBlankFrequency==60)
  46.     printf(" Running on NTSC system (60 Hz).\n");
  47. else if (SysBase->VBlankFrequency==50)
  48.     printf(" Running on PAL system (50 Hz).\n");
  49.  
  50. printf(" Attach joystick to rear connector (A3000) and (A1000).\n"
  51.        " Attach joystick to right connector (A2000).\n"
  52.        " Attach joystick to left connector (A500).\n"
  53.        " Then move joystick and click its button(s).\n\n"
  54.        " To exit program press and release fire button 3 times in a row.\n"
  55.        " The program also exits if no activity occurs for 1 minute.\n\n");
  56. }
  57.  
  58. /*-----------------------------------------------------------------------
  59. ** print out information on the event received.
  60. */
  61. BOOL check_move(struct InputEvent *game_event)
  62. {
  63. WORD xmove, ymove;
  64. BOOL timeout=FALSE;
  65.  
  66. xmove = game_event->ie_X;
  67. ymove = game_event->ie_Y;
  68.  
  69. if (xmove == 1)
  70.     {
  71.     if (ymove == 1) printf("RIGHT DOWN\n");
  72.     else if (ymove == 0) printf("RIGHT\n");
  73.     else if (ymove ==-1) printf("RIGHT UP\n");
  74.     else printf("UNKNOWN Y\n");
  75.     }
  76. else if (xmove ==-1)
  77.     {
  78.     if (ymove == 1) printf("LEFT DOWN\n");
  79.     else if (ymove == 0) printf("LEFT\n");
  80.     else if (ymove ==-1) printf("LEFT UP\n");
  81.     else printf("UNKNOWN Y\n");
  82.     }
  83. else if (xmove == 0)
  84.     {
  85.     if (ymove == 1) printf("DOWN\n");
  86.     /* note that 0,0 can be a timeout, or a direction release. */
  87.     else if (ymove == 0)
  88.         {
  89.         if (game_event->ie_TimeStamp.tv_secs >=
  90.                         (UWORD)(SysBase->VBlankFrequency)*TIMEOUT_SECONDS)
  91.             {
  92.             printf("TIMEOUT\n");
  93.             timeout=TRUE;
  94.             }
  95.         else printf("RELEASE\n");
  96.         }
  97.     else if (ymove ==-1) printf("UP\n");
  98.     else printf("UNKNOWN Y\n");
  99.     }
  100. else
  101.     {
  102.     printf("UNKNOWN X ");
  103.     if (ymove == 1) printf("unknown action\n");
  104.     else if (ymove == 0) printf("unknown action\n");
  105.     else if (ymove ==-1) printf("unknown action\n");
  106.     else printf("UNKNOWN Y\n");
  107.     }
  108.  
  109. return(timeout);
  110.  
  111. }
  112.  
  113. /*-----------------------------------------------------------------------
  114. ** send a request to the gameport to read an event.
  115. */
  116. VOID send_read_request( struct InputEvent *game_event,
  117.                         struct IOStdReq *game_io_msg)
  118. {
  119. game_io_msg->io_Command = GPD_READEVENT;
  120. game_io_msg->io_Flags   = 0;
  121. game_io_msg->io_Data    = (APTR)game_event;
  122. game_io_msg->io_Length  = sizeof(struct InputEvent);
  123. SendIO(game_io_msg);  /* Asynchronous - message will return later */
  124. }
  125.  
  126. /*-----------------------------------------------------------------------
  127. ** simple loop to process gameport events.
  128. */
  129. VOID processEvents( struct IOStdReq *game_io_msg,
  130.                     struct MsgPort  *game_msg_port)
  131. {
  132. BOOL timeout;
  133. SHORT timeouts;
  134. SHORT button_count;
  135. BOOL  not_finished;
  136. struct InputEvent game_event;   /* where input event will be stored */
  137.  
  138. /* From now on, just read input events into the event buffer,
  139. ** one at a time.  READEVENT waits for the preset conditions.
  140. */
  141. timeouts = 0;
  142. button_count = 0;
  143. not_finished = TRUE;
  144.  
  145. while ((timeouts < 6) && (not_finished))
  146.     {
  147.     /* Send the read request */
  148.     send_read_request(&game_event,game_io_msg);
  149.  
  150.     /* Wait for joystick action */
  151.     Wait(1L << game_msg_port->mp_SigBit);
  152.     while (NULL != GetMsg(game_msg_port))
  153.         {
  154.         timeout=FALSE;
  155.         switch(game_event.ie_Code)
  156.             {
  157.             case IECODE_LBUTTON:
  158.                 printf(" FIRE BUTTON PRESSED \n");
  159.                 break;
  160.  
  161.             case (IECODE_LBUTTON | IECODE_UP_PREFIX):
  162.                 printf(" FIRE BUTTON RELEASED \n");
  163.                 if (3 == ++button_count)
  164.                     not_finished = FALSE;
  165.                 break;
  166.  
  167.             case IECODE_RBUTTON:
  168.                 printf(" ALT BUTTON PRESSED \n");
  169.                 button_count = 0;
  170.                 break;
  171.  
  172.             case (IECODE_RBUTTON | IECODE_UP_PREFIX):
  173.                 printf(" ALT BUTTON RELEASED \n");
  174.                 button_count = 0;
  175.                 break;
  176.  
  177.             case IECODE_NOBUTTON:
  178.                 /* Check for change in position */
  179.                 timeout = check_move(&game_event);
  180.                 button_count = 0;
  181.                 break;
  182.  
  183.             default:
  184.                 break;
  185.             }
  186.  
  187.         if (timeout)
  188.             timeouts++;
  189.         else
  190.             timeouts=0;
  191.         }
  192.     }
  193. }
  194.  
  195. /*-----------------------------------------------------------------------
  196. ** allocate the controller if it is available.
  197. ** you allocate the controller by setting its type to something
  198. ** other than GPCT_NOCONTROLLER.  Before you allocate the thing
  199. ** you need to check if anyone else is using it (it is free if
  200. ** it is set to GPCT_NOCONTROLLER).
  201. */
  202. BOOL set_controller_type(BYTE type, struct IOStdReq *game_io_msg)
  203. {
  204. BOOL success = FALSE;
  205. BYTE controller_type = 0;
  206.  
  207. /* begin critical section
  208. ** we need to be sure that between the time we check that the controller
  209. ** is available and the time we allocate it, no one else steals it.
  210. */
  211. Forbid();
  212.  
  213. game_io_msg->io_Command = GPD_ASKCTYPE;    /* inquire current status */
  214. game_io_msg->io_Flags   = IOF_QUICK;
  215. game_io_msg->io_Data    = (APTR)&controller_type; /* put answer in here */
  216. game_io_msg->io_Length  = 1;
  217. DoIO(game_io_msg);
  218.  
  219. /* No one is using this device unit, let's claim it */
  220. if (controller_type == GPCT_NOCONTROLLER)
  221.     {
  222.     game_io_msg->io_Command = GPD_SETCTYPE;
  223.     game_io_msg->io_Flags   = IOF_QUICK;
  224.     game_io_msg->io_Data    = (APTR)&type;
  225.     game_io_msg->io_Length  = 1;
  226.     DoIO( game_io_msg);
  227.     success = TRUE;
  228.     }
  229.  
  230. Permit(); /* critical section end */
  231. return(success);
  232. }
  233.  
  234. /*-----------------------------------------------------------------------
  235. ** tell the gameport when to trigger.
  236. */
  237. VOID set_trigger_conditions(struct GamePortTrigger *gpt,
  238.                             struct IOStdReq *game_io_msg)
  239. {
  240. /* trigger on all joystick key transitions */
  241. gpt->gpt_Keys   = GPTF_UPKEYS | GPTF_DOWNKEYS;
  242. gpt->gpt_XDelta = JOY_X_DELTA;
  243. gpt->gpt_YDelta = JOY_Y_DELTA;
  244. /* timeout trigger every TIMEOUT_SECONDS second(s) */
  245. gpt->gpt_Timeout = (UWORD)(SysBase->VBlankFrequency) * TIMEOUT_SECONDS;
  246.  
  247. game_io_msg->io_Command = GPD_SETTRIGGER;
  248. game_io_msg->io_Flags   = IOF_QUICK;
  249. game_io_msg->io_Data    = (APTR)gpt;
  250. game_io_msg->io_Length  = (LONG)sizeof(struct GamePortTrigger);
  251. DoIO(game_io_msg);
  252. }
  253.  
  254. /*-----------------------------------------------------------------------
  255. ** clear the buffer.  do this before you begin to be sure you
  256. ** start in a known state.
  257. */
  258. VOID flush_buffer(struct IOStdReq *game_io_msg)
  259. {
  260. game_io_msg->io_Command = CMD_CLEAR;
  261. game_io_msg->io_Flags   = IOF_QUICK;
  262. game_io_msg->io_Data    = NULL;
  263. game_io_msg->io_Length  = 0;
  264. DoIO(game_io_msg);
  265. }
  266.  
  267. /*-----------------------------------------------------------------------
  268. ** free the unit by setting its type back to GPCT_NOCONTROLLER.
  269. */
  270. VOID free_gp_unit(struct IOStdReq *game_io_msg)
  271. {
  272. BYTE type = GPCT_NOCONTROLLER;
  273.  
  274. game_io_msg->io_Command = GPD_SETCTYPE;
  275. game_io_msg->io_Flags   = IOF_QUICK;
  276. game_io_msg->io_Data    = (APTR)&type;
  277. game_io_msg->io_Length  = 1;
  278. DoIO(game_io_msg);
  279. }
  280.  
  281. /*-----------------------------------------------------------------------
  282. ** allocate everything and go.  On failure, free any resources that
  283. ** have been allocated.  this program fails quietly-no error messages.
  284. */
  285. VOID main(int argc,char **argv)
  286. {
  287. struct GamePortTrigger   joytrigger;
  288. struct IOStdReq         *game_io_msg;
  289. struct MsgPort          *game_msg_port;
  290.  
  291. /* Create port for gameport device communications */
  292. if (game_msg_port = CreatePort("RKM_game_port",0))
  293.     {
  294.     /* Create message block for device IO */
  295.     if (game_io_msg = (struct IOStdReq *)
  296.                       CreateExtIO(game_msg_port,sizeof(*game_io_msg)))
  297.         {
  298.         game_io_msg->io_Message.mn_Node.ln_Type = NT_UNKNOWN;
  299.  
  300.         /* Open the right/back (unit 1, number 2) gameport.device unit */
  301.         if (!OpenDevice("gameport.device",1,game_io_msg,0))
  302.             {
  303.             /* Set controller type to joystick */
  304.             if (set_controller_type(GPCT_ABSJOYSTICK,game_io_msg))
  305.                 {
  306.                 /* Specify the trigger conditions */
  307.                 set_trigger_conditions(&joytrigger,game_io_msg);
  308.  
  309.                 printInstructions();
  310.  
  311.                 /* Clear device buffer to start from a known state.
  312.                 ** There might still be events left
  313.                 */
  314.                 flush_buffer(game_io_msg);
  315.  
  316.                 processEvents(game_io_msg,game_msg_port);
  317.  
  318.                 /* Free gameport unit so other applications can use it ! */
  319.                 free_gp_unit(game_io_msg);
  320.                 }
  321.             CloseDevice(game_io_msg);
  322.             }
  323.         DeleteExtIO(game_io_msg);
  324.         }
  325.     DeletePort(game_msg_port);
  326.     }
  327. }
  328.  
  329.