home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / datafiles / text / c_manual / devices / gameportdevice / example1.c < prev    next >
C/C++ Source or Header  |  1995-02-27  |  16KB  |  470 lines

  1. /***********************************************************/
  2. /*                                                         */
  3. /* Amiga C Encyclopedia (ACE) V3.0      Amiga C Club (ACC) */
  4. /* -------------------------------      ------------------ */
  5. /*                                                         */
  6. /* Book:    ACM Devices                 Amiga C Club       */
  7. /* Chapter: Gameport Device             Tulevagen 22       */
  8. /* File:    Example1.c                  181 41  LIDINGO    */
  9. /* Author:  Anders Bjerin               SWEDEN             */
  10. /* Date:    92-04-27                                       */
  11. /* Version: 1.00                                           */
  12. /*                                                         */
  13. /*   Copyright 1992, Anders Bjerin - Amiga C Club (ACC)    */
  14. /*                                                         */
  15. /* Registered members may use this program freely in their */
  16. /*     own commercial/noncommercial programs/articles.     */
  17. /*                                                         */
  18. /***********************************************************/
  19.  
  20.  
  21.  
  22. /* This program will read 20 joystick events,   */
  23. /* using port 2 (the "Joystick Port"), before   */
  24. /* it will terminate. This example is "nice"    */
  25. /* to the system and does everything according  */
  26. /* to the "rules".                              */
  27. /*                                              */
  28. /* While we are waiting for something to happen */
  29. /* our task is put to sleep, so we do not waste */
  30. /* any computer time. However, if you want to   */
  31. /* do something while you are waiting, see next */
  32. /* example.                                     */
  33.  
  34.  
  35.  
  36. #include <exec/types.h>         /* UWORD, STRPTR */
  37. #include <devices/gameport.h>   /* GPCT_ABSJOYSTICK  */
  38. #include <devices/inputevent.h> /* struct InputEvent */
  39.  
  40.  
  41.  
  42. #define RIGHTGAMEPORT 1 /* The "Joystick" port. */
  43. #define LEFTGAMEPORT  0 /* The "Mouse" port.    */
  44.  
  45.  
  46.  
  47. /* Pointer to the Graphics library: */
  48. struct GfxBase *GfxBase;
  49.  
  50.  
  51.  
  52. struct IOStdReq *game_io_msg;    /* Pointer to our IOStdReq str.    */
  53. struct MsgPort   *game_msg_port; /* Pointer to our message port.    */
  54. BOOL deviceerror;                /* Have we opened the device, OK?  */
  55.  
  56.  
  57.  
  58. /* Declare some external functions:        */
  59. /* (We must otherwise do so much casting.) */
  60. extern struct MsgPort *CreatePort();
  61. extern struct IOStdReq *CreateStdIO();    
  62.  
  63.  
  64.  
  65. /* Declare all functions in this module: */
  66. void main();
  67. void PrintJoystickData();    /* Print some information about the joystick. */
  68. BYTE SetControllerType();    /* Set type of controller.                    */
  69. BYTE SetControllerTrigger(); /* Set trigger.                               */
  70. void SetControllerRead();    /* Prepare it so we can read.                 */
  71. BYTE GetControllerType();    /* Get type of controller already connected.  */
  72. void clean_up();             /* Cleanup, and quit.                         */
  73.  
  74.  
  75.  
  76. void main()
  77. {
  78.   /* Put all data in this structure: */
  79.   struct InputEvent gamedata;
  80.  
  81.   BYTE type;
  82.   int counter;
  83.  
  84.  
  85.  
  86.   /* Open the Graphics library: */
  87.   GfxBase = (struct GfxBase *)
  88.     OpenLibrary( "graphics.library", 0 );
  89.   if( !GfxBase )
  90.     clean_up( "ERROR! Could not open the Graphics library!" );
  91.  
  92.  
  93.   /* 1. Create a message port so the system can communicate with us: */
  94.   game_msg_port = CreatePort( 0, 0 );
  95.   if( !game_msg_port )
  96.     clean_up( "ERROR! Could not create message port!" );
  97.  
  98.  
  99.   /* 2. Allocate and initialize a new I/O request block.  */
  100.   /* It should use our new message port as reply port:    */
  101.   game_io_msg = CreateStdIO( game_msg_port );     
  102.   if( !game_io_msg )
  103.     clean_up( "ERROR! Could not allocate new I/O request block!" );
  104.  
  105.  
  106.   /* 3. Open the Game Port Device, use the right port: */
  107.   deviceerror = OpenDevice( "gameport.device", RIGHTGAMEPORT, game_io_msg, 0xFFFF );
  108.   if( deviceerror )
  109.     clean_up( "ERROR! Could not open the Game Port Device!" );
  110.  
  111.  
  112.   /* 4. Check if some other task is already using the gameport: */
  113.   if( type = GetControllerType() )
  114.   {
  115.     switch( type )
  116.     {
  117.       case GPCT_MOUSE:
  118.         printf( "A mouse is connected to the port!\n" );
  119.         break;
  120.  
  121.       case GPCT_RELJOYSTICK:
  122.         printf( "A proportional joystick is connected to the port!\n" );
  123.         break;
  124.  
  125.       case GPCT_ABSJOYSTICK:
  126.         printf( "A normal joystick is connected to the port!\n" );
  127.         break;
  128.     }
  129.     
  130.     /* Do not close the device! If we do it, the other task will */
  131.     /* then not be able to use the gameport device either!       */
  132.     deviceerror = TRUE;
  133.     clean_up( "ERROR! Some other task is already using the Gameport!" );
  134.   }
  135.  
  136.  
  137.   /* 5. Set device type (absolute joystick): */
  138.   if( SetControllerType( GPCT_ABSJOYSTICK ) )
  139.     clean_up( "ERROR! Could not set device type!" );
  140.  
  141.  
  142.   /* 6. Set device trigger: */
  143.   if( SetControllerTrigger
  144.       (                            /* Report following events:        */
  145.         GPTF_DOWNKEYS|GPTF_UPKEYS, /* firebutton pressed and release, */ 
  146.         0,                         /* no timeout messages,            */
  147.         1,                         /* every X movements, and          */
  148.         1                          /* every Y movements.              */
  149.       )
  150.     )
  151.     clean_up( "ERROR! Could not set device trigger!" );
  152.  
  153.  
  154.   /* 7. Prepare the device to read: */
  155.   SetControllerRead( &gamedata );
  156.  
  157.  
  158.  
  159.   printf( "Gameport Device - Joystick Example - Waiting\n" );
  160.   /* Collect 20 messages, and the leave: */
  161.   counter = 0;
  162.   while( counter < 20 )
  163.   {
  164.     printf("\nWaiting... ");
  165.  
  166.     /* Do our request, and return without delay: */
  167.     SendIO( game_io_msg );
  168.  
  169.  
  170.     /* Wait for a message to arrive at our message port. */
  171.     /* While we are waiting our task is put to sleep,    */
  172.     /* which means that we will not waste any computer   */ 
  173.     /* time. Zzz Zzz Zzz...                              */
  174.     WaitPort( game_msg_port );
  175.  
  176.  
  177.     /* Try to collect a message: */
  178.     if( GetMsg( game_msg_port ) )
  179.     {
  180.       /* Print some information abut the joystick: */
  181.       PrintJoystickData( &gamedata );
  182.       counter++;
  183.     }
  184.   }
  185.  
  186.  
  187.   /* 8. Clean up nicely, and quit: */
  188.   clean_up( "The End!" );
  189. }    
  190.  
  191.  
  192.  
  193. /****************************************************************/
  194. /*                                                              */
  195. /* PrintJoystickData() prints current stick and button position */
  196. /* of a Joystick.                                               */
  197. /*                                                              */
  198. /* Synopsis: PrintJoystickData( data );                         */
  199. /*                                                              */
  200. /* data:     (struct InputEvent *) Pointer to an InputEvent     */
  201. /*           structure which has previously been initialized.   */
  202. /*                                                              */
  203. /****************************************************************/
  204.  
  205. void PrintJoystickData( data )
  206. struct InputEvent *data;
  207. {
  208.   WORD xdirection;
  209.   WORD ydirection;
  210.   UWORD code;
  211.  
  212.   /* Collect data: */
  213.   xdirection = data->ie_X;
  214.   ydirection = data->ie_Y;
  215.   code = data->ie_Code;
  216.  
  217.  
  218.   /* Was the button pressed or released? */
  219.   if( code == IECODE_LBUTTON ) 
  220.     printf("Button pressed. ");
  221.  
  222.   if( code == IECODE_LBUTTON + IECODE_UP_PREFIX )
  223.     printf("Button released. ");
  224.  
  225.  
  226.   /* What is the position of the stick: */
  227.   printf( "Stick position:" );
  228.   switch(ydirection) 
  229.   {
  230.     case -1:
  231.       printf( " Forward" );
  232.       break;
  233.  
  234.     case 1:
  235.       printf( " Back" );
  236.       break;
  237.   }
  238.  
  239.   switch(xdirection) 
  240.   {
  241.     case -1:
  242.       printf( " Left" );
  243.       break;
  244.  
  245.     case 1:
  246.       printf( " Right" );
  247.       break;
  248.   }
  249. }
  250.  
  251.  
  252.  
  253. /*************************************************************/
  254. /*                                                           */
  255. /* SetControllerType() tells the System what type of device  */
  256. /* (absolute joystick, proportional joystick or a mouse) you */
  257. /* want to handle.                                           */
  258. /*                                                           */
  259. /* Synopsis: error = SetControllerType( type, data );        */
  260. /*                                                           */
  261. /* error:    (BYTE) If the function could set controller     */
  262. /*           type it will return 0, else if something failed */
  263. /*           it will return an error number. For the moment  */
  264. /*           there exist only one type of error message and  */
  265. /*           that is GPDERR_SETCTYPE - the controller you    */
  266. /*           asked for is not valid at this time.            */
  267. /*                                                           */
  268. /* type:     (UBYTE) Type of controller you want to handle:  */
  269. /*           GPCT_MOUSE       - mouse                        */
  270. /*           GPCT_ABSJOYSTICK - absolute (normal) joystick   */
  271. /*           GPCT_RELJOYSTICK - proportional joystick        */
  272. /*                                                           */
  273. /*************************************************************/
  274.  
  275. BYTE SetControllerType( type )
  276. BYTE type;
  277. {
  278.   /* We want to set controller type: */
  279.   game_io_msg->io_Command = GPD_SETCTYPE;
  280.  
  281.   /* The message is only one byte long: */
  282.   game_io_msg->io_Length = 1;
  283.  
  284.   /* The data we want to send: */
  285.   game_io_msg->io_Data = (APTR) &type;  
  286.  
  287.   /* Do our request, and return when it is done: */
  288.   DoIO( game_io_msg );  
  289.  
  290.   /* Return any error message, or 0 if everything is OK: */
  291.   return( game_io_msg->io_Error );
  292. }
  293.  
  294.  
  295.  
  296. /****************************************************************/
  297. /*                                                              */
  298. /* SetControllerTrigger() tells the system what conditions      */
  299. /* should be fulfilled before a gameport event will occur.      */
  300. /* You can for example tell the device to only respond if       */
  301. /* the mouse has been moved more that 20 counts, and/or         */
  302. /* if nothing has happened within, let us say, 30 seconds,      */
  303. /* and/or a button has been pressed or released.                */
  304. /*                                                              */
  305. /* Synopsis: error = SetControllerTrigger( keys, time, x, y );  */
  306. /*                                                              */
  307. /* error:    (BYTE) If the function could set controller        */
  308. /*           trigger it will return 0, else if something failed */
  309. /*           it will return an error number. For the moment     */
  310. /*           there does not exist any special error code for    */
  311. /*           this function.                                     */
  312. /*                                                              */
  313. /* keys:     (UWORD) If you want that a gameport event is       */
  314. /*           triggered each time a button is pressed set the    */
  315. /*           flag "GPTF_DOWNKEYS", if you want that a gameport  */
  316. /*           event is triggered each time a button is           */
  317. /*           released set the flag "GPTF_UPKEYS". (If you want  */
  318. /*           both up and down key messages, set the binary      */
  319. /*           or ("|") operator between the flags. Example:      */
  320. /*           "GPTF_DOWNKEYS | GPTF_UPKEYS")                     */
  321. /*                                                              */
  322. /* time:     (UWORD) Set here how much time should pass before  */
  323. /*           a gameport event is triggered. The value is        */
  324. /*           in vertical blank units, which means 60 = 1 sec.   */
  325. /*           If you want to trigger an event each third minute  */
  326. /*           set the time value to 10800 (60 * 60 * 3). If      */
  327. /*           you do not want any time event, set time to 0.     */
  328. /*                                                              */
  329. /* x:        (UWORD) Set here how many x movements should be    */
  330. /*           reported, before a gameport event is triggered.    */
  331. /*           If you want to read a normal joystick, set x to 1. */
  332. /*                                                              */
  333. /* y:        (UWORD) Set here how many y movements should be    */
  334. /*           reported, before a gameport event is triggered.    */
  335. /*           If you want to read a normal joystick, set y to 1. */
  336. /*                                                              */
  337. /****************************************************************/
  338.  
  339. BYTE SetControllerTrigger( keys, timeout, xdelta, ydelta )
  340. UWORD keys;
  341. UWORD timeout;
  342. UWORD xdelta;
  343. UWORD ydelta;
  344. {
  345.   struct GamePortTrigger gpt;
  346.  
  347.   /* Set our requirements: */
  348.   gpt.gpt_Keys = keys;
  349.   gpt.gpt_Timeout = timeout;
  350.   gpt.gpt_XDelta = xdelta;
  351.   gpt.gpt_YDelta = ydelta;
  352.  
  353.   /* We want to set controller trigger: */
  354.   game_io_msg->io_Command = GPD_SETTRIGGER;
  355.  
  356.   /* The message is sizeof(struct GamePortTrigger) bytes long: */ 
  357.   game_io_msg->io_Length = sizeof( gpt );
  358.  
  359.   /* The data we want to send: */
  360.   game_io_msg->io_Data = (APTR) &gpt;
  361.  
  362.   /* Do our request and return when it is done: */
  363.   DoIO( game_io_msg );
  364.  
  365.   /* Return any error message, or 0 if everything is OK: */
  366.   return( game_io_msg->io_Error );
  367. }
  368.  
  369.  
  370.  
  371.  
  372. /*************************************************************/
  373. /*                                                           */
  374. /* SetControllerRead() prepares the system for reading data  */
  375. /* from the selected device, and place the information in    */
  376. /* the data structure.                                       */
  377. /*                                                           */
  378. /* Synopsis: SetControllerRead( data );                      */
  379. /*                                                           */
  380. /* data:     (struct InputEvent *) Pointer to an InputEvent  */
  381. /*           structure which will be filled with information */
  382. /*           when a gameport event occurs.                   */
  383. /*                                                           */
  384. /*************************************************************/
  385.  
  386. void SetControllerRead( data )
  387. struct InputEvent *data;
  388. {
  389.   /* We want to read gameport events: */
  390.   game_io_msg->io_Command = GPD_READEVENT;  
  391.  
  392.   /* The gameport event is sizeof(struct InputEvent) bytes long: */
  393.   game_io_msg->io_Length = sizeof(struct InputEvent);  
  394.  
  395.   /* Where we want the data to be placed: */
  396.   game_io_msg->io_Data = (APTR) data;
  397.  
  398.   /* Read one event each time we go back to the gameport: */
  399.   game_io_msg->io_Flags = 0;
  400. }
  401.  
  402.  
  403.  
  404. /**************************************************************/
  405. /*                                                            */
  406. /* GetControllerType() tells us what type of device (nothing, */
  407. /* absolute joystick, proportional joystick or a mouse) is    */
  408. /* already connected to the Gameport.                         */
  409. /*                                                            */
  410. /* Synopsis: type = GetControllerType();                      */
  411. /*                                                            */
  412. /* type:     (UBYTE) Type of controller connected:            */
  413. /*             GPCT_NOCONTROLLER - nothing                    */
  414. /*             GPCT_MOUSE        - mouse                      */
  415. /*             GPCT_ABSJOYSTICK  - absolute (normal) joystick */
  416. /*             GPCT_RELJOYSTICK  - proportional joystick      */
  417. /*                                                            */
  418. /**************************************************************/
  419.  
  420. BYTE GetControllerType()
  421. {
  422.   BYTE type = 0;
  423.  
  424.   /* We want to know if any controller is already set: */
  425.   game_io_msg->io_Command = GPD_ASKCTYPE;
  426.  
  427.   /* The message is only one byte long: */
  428.   game_io_msg->io_Length = 1;
  429.  
  430.   /* Where we want the data stored: */
  431.   game_io_msg->io_Data = (APTR) &type;  
  432.  
  433.   /* Do our request, and return when it is done: */
  434.   DoIO( game_io_msg );  
  435.  
  436.   /* Return the answer: */
  437.   return( type );
  438. }
  439.  
  440.  
  441.  
  442.  
  443. void clean_up( message )
  444. STRPTR message;
  445. {
  446.   /* Close the gameport device: */
  447.   if( !deviceerror )
  448.   {
  449.     SetControllerType( GPCT_NOCONTROLLER );
  450.     CloseDevice( game_io_msg );
  451.   }
  452.  
  453.   /* Deallocate I/O request block: */
  454.   if( game_io_msg )
  455.     DeleteStdIO( game_io_msg );
  456.  
  457.   /* Close message port: */
  458.   if( game_msg_port )
  459.     DeletePort( game_msg_port );
  460.  
  461.   /* Print message before we quit: */
  462.   printf( "%s\n", message );
  463.  
  464.   /* Quit: */
  465.   exit( 0 );
  466. }
  467.  
  468.  
  469.  
  470.