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