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