home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
datafiles
/
text
/
c_manual
/
devices
/
gameportdevice
/
example3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-27
|
17KB
|
488 lines
/***********************************************************/
/* */
/* Amiga C Encyclopedia (ACE) V3.0 Amiga C Club (ACC) */
/* ------------------------------- ------------------ */
/* */
/* Book: ACM Devices Amiga C Club */
/* Chapter: Gameport Device Tulevagen 22 */
/* File: Example3.c 181 41 LIDINGO */
/* Author: Anders Bjerin SWEDEN */
/* Date: 92-04-27 */
/* Version: 1.00 */
/* */
/* Copyright 1992, Anders Bjerin - Amiga C Club (ACC) */
/* */
/* Registered members may use this program freely in their */
/* own commercial/noncommercial programs/articles. */
/* */
/***********************************************************/
/* This program demonstrates how you can use the */
/* Gameport Device to read mouse events. The */
/* program will report any mouse movements or if */
/* any buttons was pressed/released. If the user */
/* has not used the mouse for one minnute, the */
/* program will terminate. */
/* */
/* This example is "nice" to the system and does */
/* everything according to the "rules". */
/* */
/* While we are waiting for something to happen */
/* our task is put to sleep, so we do not waste */
/* any computer time. However, if you want to do */
/* something while you are waiting, see next */
/* example. */
/* */
/* NOTE! Since Intuition is already using port 1 */
/* (the "mouse port") we have to use port 2. So */
/* remember to connect the mouse to port 2, */
/* before you run the program. */
#include <exec/types.h> /* UWORD, STRPTR */
#include <devices/gameport.h> /* GPCT_MOUSE */
#include <devices/inputevent.h> /* struct InputEvent */
#define RIGHTGAMEPORT 1 /* The "Joystick" port. */
#define LEFTGAMEPORT 0 /* The "Mouse" port. */
#define MINX 5 /* The mouse must be moved at least 5 stepps */
#define MINY 5 /* before a mouse event should occure. */
/* Pointer to the Graphics library: */
struct GfxBase *GfxBase;
struct IOStdReq *game_io_msg; /* Pointer to our IOStdReq str. */
struct MsgPort *game_msg_port; /* Pointer to our message port. */
BOOL deviceerror; /* Have we opened the device, OK? */
int counter;
/* Declare some external functions: */
/* (We must otherwise do so much casting.) */
extern struct MsgPort *CreatePort();
extern struct IOStdReq *CreateStdIO();
/* Declare all functions in this module: */
void main();
void PrintMouseData(); /* Print some information about the mouse. */
BYTE SetControllerType(); /* Set type of controller. */
BYTE SetControllerTrigger(); /* Set trigger. */
void SetControllerRead(); /* Prepare it so we can read. */
BYTE GetControllerType(); /* Get type of controller already coneccted. */
void clean_up(); /* Cleanup, and quit. */
void main()
{
/* Put all data in this structure: */
struct InputEvent gamedata;
BYTE type;
/* Open the Graphics library: */
GfxBase = (struct GfxBase *)
OpenLibrary( "graphics.library", 0 );
if( !GfxBase )
clean_up( "ERROR! Could not open the Graphics library!" );
/* 1. Create a message port so the system can communicate with us: */
game_msg_port = CreatePort( 0, 0 );
if( !game_msg_port )
clean_up( "ERROR! Could not create message port!" );
/* 2. Allocate and initialize a new I/O request block. */
/* It should use our new message port as reply port: */
game_io_msg = CreateStdIO( game_msg_port );
if( !game_io_msg )
clean_up( "ERROR! Could not allocate new I/O request block!" );
/* 3. Open the Game Port Device, use the right port: */
/* (Intuition is already using the left port!) */
deviceerror = OpenDevice( "gameport.device", RIGHTGAMEPORT, game_io_msg, 0xFFFF );
if( deviceerror )
clean_up( "ERROR! Could not open the Game Port Device!" );
/* 4. Check if some other task is already using the gameport: */
if( type = GetControllerType() )
{
switch( type )
{
case GPCT_MOUSE:
printf( "A mouse is connected to the port!\n" );
break;
case GPCT_RELJOYSTICK:
printf( "A proportional joystick is connected to the port!\n" );
break;
case GPCT_ABSJOYSTICK:
printf( "A normal joystick is connected to the port!\n" );
break;
}
/* Do not close the device! If we do it, the other task will */
/* then not be able to use the gameport device either! */
deviceerror = TRUE;
clean_up( "ERROR! Some other task is already using the Gameport!" );
}
/* 5. Set device type (mouse): */
if( SetControllerType( GPCT_MOUSE ) )
clean_up( "ERROR! Could not set device type!" );
/* 6. Set device trigger: */
if( SetControllerTrigger
( /* Report following events: */
GPTF_DOWNKEYS|GPTF_UPKEYS, /* buttonpressed/released, */
600, /* every 10th second, */
MINX, /* X movements more than MINX, */
MINY /* Y movements more than MINY. */
)
)
clean_up( "ERROR! Could not set device trigger!" );
/* 7. Prepare the device to read: */
SetControllerRead( &gamedata );
printf( "Gameport Device - Mouse Example - Waiting\n" );
/* Stay in the while loop until the user has not moved the */
/* mouse during the last minute: (6 times 10 seconds) */
while( counter < 6 )
{
printf("\nWaiting... ");
/* Do our request, and return without delay: */
SendIO( game_io_msg );
/* Wait for a message to arrive at our message port. */
/* While we are waiting our task is put to sleep, */
/* which means that we will not waste any computer */
/* time. Zzz Zzz Zzz... */
WaitPort( game_msg_port );
/* Try to collect a message: */
if( GetMsg( game_msg_port ) )
{
/* Print some information abut the mouse: */
PrintMouseData( &gamedata );
}
}
/* 8. Clean up nicely, and quit: */
clean_up( "The End!" );
}
/****************************************************************/
/* */
/* PrintMouseData() prints how many x/y counts the mouse has */
/* been moved, and if any buttons has been pressed or released. */
/* */
/* Synopsis: PrintMouseData( data ); */
/* */
/* data: (struct InputEvent *) Pointer to an InputEvent */
/* structure which has previously been initialized. */
/* */
/****************************************************************/
void PrintMouseData( data )
struct InputEvent *data;
{
WORD x;
WORD y;
UWORD code;
/* Collect data: */
x = data->ie_X;
y = data->ie_Y;
code = data->ie_Code;
/* Print: */
switch( code )
{
case IECODE_LBUTTON:
printf( "Left mouse button pressed" );
counter = 0;
break;
case IECODE_RBUTTON:
printf( "Right mouse button pressed" );
counter = 0;
break;
case IECODE_LBUTTON + IECODE_UP_PREFIX:
printf( "Left mouse button released" );
counter = 0;
break;
case IECODE_RBUTTON + IECODE_UP_PREFIX:
printf( "Right mouse button released" );
counter = 0;
break;
case IECODE_NOBUTTON:
/* Mouse moved, or timeout signal: */
if( x || y )
{
printf( "Mouse moved! delta x: %4d, delta y: %4d", x, y );
counter = 0;
}
else
{
printf( "10 seconds passed..." );
counter++;
}
break;
}
}
/*************************************************************/
/* */
/* SetControllerType() tells the System what type of device */
/* (absolute joystick, proportional joystick or a mouse) you */
/* want to handle. */
/* */
/* Synopsis: error = SetControllerType( type, data ); */
/* */
/* error: (BYTE) If the function could set controller */
/* type it will return 0, else if something failed */
/* it will return an error number. For the moment */
/* there exist only one type of error message and */
/* that is GPDERR_SETCTYPE - the controller you */
/* asked for is not valid at this time. */
/* */
/* type: (UBYTE) Type of controller you want to handle: */
/* GPCT_MOUSE - mouse */
/* GPCT_ABSJOYSTICK - absolute (normal) joystick */
/* GPCT_RELJOYSTICK - proportional joystick */
/* */
/*************************************************************/
BYTE SetControllerType( type )
BYTE type;
{
/* We want to set controller type: */
game_io_msg->io_Command = GPD_SETCTYPE;
/* The message is only one byte long: */
game_io_msg->io_Length = 1;
/* The data we want to send: */
game_io_msg->io_Data = (APTR) &type;
/* Do our request, and return when it is done: */
DoIO( game_io_msg );
/* Return any error message, or 0 if everything is OK: */
return( game_io_msg->io_Error );
}
/****************************************************************/
/* */
/* SetControllerTrigger() tells the system what conditions */
/* should be fulfilled before a gameport event will occur. */
/* You can for example tell the device to only respond if */
/* the mouse has been moved more that 20 counts, and/or */
/* if nothing has happened within, let us say, 30 seconds, */
/* and/or a button has been pressed or released. */
/* */
/* Synopsis: error = SetControllerTrigger( keys, time, x, y ); */
/* */
/* error: (BYTE) If the function could set controller */
/* trigger it will return 0, else if something failed */
/* it will return an error number. For the moment */
/* there does not exist any special error code for */
/* this function. */
/* */
/* keys: (UWORD) If you want that a gameport event is */
/* triggered each time a button is pressed set the */
/* flag "GPTF_DOWNKEYS", if you want that a gameport */
/* event is triggered each time a button is */
/* released set the flag "GPTF_UPKEYS". (If you want */
/* both up and down key messages, set the binary */
/* or ("|") operator between the flags. Example: */
/* "GPTF_DOWNKEYS | GPTF_UPKEYS") */
/* */
/* time: (UWORD) Set here how much time should pass before */
/* a gameport event is triggered. The value is */
/* in vertical blank units, which means 60 = 1 sec. */
/* If you want to trigger an event each third minute */
/* set the time value to 10800 (60 * 60 * 3). If */
/* you do not want any time event, set time to 0. */
/* */
/* x: (UWORD) Set here how many x movements should be */
/* reported, before a gameport event is triggered. */
/* If you want to read a normal joystick, set x to 1. */
/* */
/* y: (UWORD) Set here how many y movements should be */
/* reported, before a gameport event is triggered. */
/* If you want to read a normal joystick, set y to 1. */
/* */
/****************************************************************/
BYTE SetControllerTrigger( keys, timeout, xdelta, ydelta )
UWORD keys;
UWORD timeout;
UWORD xdelta;
UWORD ydelta;
{
struct GamePortTrigger gpt;
/* Set our requirements: */
gpt.gpt_Keys = keys;
gpt.gpt_Timeout = timeout;
gpt.gpt_XDelta = xdelta;
gpt.gpt_YDelta = ydelta;
/* We want to set controller trigger: */
game_io_msg->io_Command = GPD_SETTRIGGER;
/* The message is sizeof(struct GamePortTrigger) bytes long: */
game_io_msg->io_Length = sizeof( gpt );
/* The data we want to send: */
game_io_msg->io_Data = (APTR) &gpt;
/* Do our request and return when it is done: */
DoIO( game_io_msg );
/* Return any error message, or 0 if everything is OK: */
return( game_io_msg->io_Error );
}
/*************************************************************/
/* */
/* SetControllerRead() prepares the system for reading data */
/* from the selected device, and place the information in */
/* the data structure. */
/* */
/* Synopsis: SetControllerRead( data ); */
/* */
/* data: (struct InputEvent *) Pointer to an InputEvent */
/* structure which will be filled with information */
/* when a gameport event occurs. */
/* */
/*************************************************************/
void SetControllerRead( data )
struct InputEvent *data;
{
/* We want to read gameport events: */
game_io_msg->io_Command = GPD_READEVENT;
/* The gameport event is sizeof(struct InputEvent) bytes long: */
game_io_msg->io_Length = sizeof(struct InputEvent);
/* Where we want the data to be placed: */
game_io_msg->io_Data = (APTR) data;
/* Read one event each time we go back to the gameport: */
game_io_msg->io_Flags = 0;
}
/**************************************************************/
/* */
/* GetControllerType() tells us what type of device (nothing, */
/* absolute joystick, proportional joystick or a mouse) is */
/* already connected to the Gameport. */
/* */
/* Synopsis: type = GetControllerType(); */
/* */
/* type: (UBYTE) Type of controller connected: */
/* GPCT_NOCONTROLLER - nothing */
/* GPCT_MOUSE - mouse */
/* GPCT_ABSJOYSTICK - absolute (normal) joystick */
/* GPCT_RELJOYSTICK - proportional joystick */
/* */
/**************************************************************/
BYTE GetControllerType()
{
BYTE type = 0;
/* We want to know if any controller is already set: */
game_io_msg->io_Command = GPD_ASKCTYPE;
/* The message is only one byte long: */
game_io_msg->io_Length = 1;
/* Where we want the data stored: */
game_io_msg->io_Data = (APTR) &type;
/* Do our request, and return when it is done: */
DoIO( game_io_msg );
/* Return the answer: */
return( type );
}
void clean_up( message )
STRPTR message;
{
/* Close the gameport device: */
if( !deviceerror )
{
SetControllerType( GPCT_NOCONTROLLER );
CloseDevice( game_io_msg );
}
/* Deallocate I/O request block: */
if( game_io_msg )
DeleteStdIO( game_io_msg );
/* Close message port: */
if( game_msg_port )
DeletePort( game_msg_port );
/* Print message before we quit: */
printf( "%s\n", message );
/* Quit: */
exit( 0 );
}