gremlin/libs/glfw/lib/amigaos/amigaos_joystick.c
2011-01-04 18:11:59 +01:00

360 lines
10 KiB
C

//========================================================================
// GLFW - An OpenGL framework
// File: amigaos_joystick.c
// Platforms: AmigaOS, MorphOS
// API version: 2.6
// WWW: http://glfw.sourceforge.net
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//************************************************************************
//**** GLFW internal functions ****
//************************************************************************
//========================================================================
// _glfwSendJoyReadRequest() - Send joystick read request
//========================================================================
static void _glfwSendJoyReadRequest( void )
{
// Send read request
_glfwJoy.GameIO->io_Command = GPD_READEVENT;
_glfwJoy.GameIO->io_Flags = 0;
_glfwJoy.GameIO->io_Data = (APTR) &_glfwJoy.GameEvent;
_glfwJoy.GameIO->io_Length = sizeof(struct InputEvent);
SendIO( (struct IORequest *) _glfwJoy.GameIO );
}
//========================================================================
// _glfwInitJoysticks() - Initialize joystick interface
//========================================================================
void _glfwInitJoysticks( void )
{
unsigned char controller_type = 0;
struct GamePortTrigger game_trigger;
// Start by clearing all handles
_glfwJoy.GameMP = NULL;
_glfwJoy.GameIO = NULL;
_glfwJoy.Present = 0;
_glfwJoy.GameDeviceOpen = 0;
// Create gameport.device message port
if( !(_glfwJoy.GameMP = CreatePort( NULL, 0 )) )
{
return;
}
// Create gameport.device I/O request
if( !( _glfwJoy.GameIO = (struct IOStdReq *)
CreateExtIO(_glfwJoy.GameMP, sizeof(struct IOStdReq)) ) )
{
_glfwTerminateJoysticks();
return;
}
// Open gameport.device (unit 1 = port 2)
_glfwJoy.GameIO->io_Message.mn_Node.ln_Type = NT_UNKNOWN;
if( OpenDevice( "gameport.device", 1,
(struct IORequest *)_glfwJoy.GameIO, 0 ) )
{
_glfwTerminateJoysticks();
return;
}
_glfwJoy.GameDeviceOpen = 1;
// Start critical section
Forbid();
// Find out if anyone else is using the stick
_glfwJoy.GameIO->io_Command = GPD_ASKCTYPE;
_glfwJoy.GameIO->io_Flags = IOF_QUICK;
_glfwJoy.GameIO->io_Data = (APTR) &controller_type;
_glfwJoy.GameIO->io_Length = 1;
DoIO( (struct IORequest *) _glfwJoy.GameIO );
// Was it already allocated?
if( controller_type != GPCT_NOCONTROLLER )
{
Permit();
_glfwTerminateJoysticks();
return;
}
// Allocate joystick
controller_type = GPCT_ABSJOYSTICK;
_glfwJoy.GameIO->io_Command = GPD_SETCTYPE;
_glfwJoy.GameIO->io_Flags = IOF_QUICK;
_glfwJoy.GameIO->io_Data = (APTR) &controller_type;
_glfwJoy.GameIO->io_Length = 1;
DoIO( (struct IORequest *) _glfwJoy.GameIO );
_glfwJoy.Present = 1;
// End critical section
Permit();
// Set trigger conditions
game_trigger.gpt_Keys = GPTF_UPKEYS | GPTF_DOWNKEYS;
game_trigger.gpt_XDelta = 1;
game_trigger.gpt_YDelta = 1;
game_trigger.gpt_Timeout = (UWORD) 0xFFFF; // ~20 minutes
_glfwJoy.GameIO->io_Command = GPD_SETTRIGGER;
_glfwJoy.GameIO->io_Flags = IOF_QUICK;
_glfwJoy.GameIO->io_Data = (APTR) &game_trigger;
_glfwJoy.GameIO->io_Length = (LONG) sizeof(struct GamePortTrigger);
DoIO( (struct IORequest *) _glfwJoy.GameIO );
// Flush buffer
_glfwJoy.GameIO->io_Command = CMD_CLEAR;
_glfwJoy.GameIO->io_Flags = IOF_QUICK;
_glfwJoy.GameIO->io_Data = NULL;
_glfwJoy.GameIO->io_Length = 0;
DoIO( (struct IORequest *) _glfwJoy.GameIO );
// Send joystick read request (asynchronous)
_glfwSendJoyReadRequest();
}
//========================================================================
// _glfwTerminateJoysticks() - Close all opened joystick handles
//========================================================================
void _glfwTerminateJoysticks( void )
{
unsigned char controller_type;
// Remove any remaining asynchronous messages
if( _glfwJoy.GameIO )
{
if( !CheckIO( (struct IORequest *)_glfwJoy.GameIO ) )
{
AbortIO( (struct IORequest *)_glfwJoy.GameIO );
WaitIO( (struct IORequest *)_glfwJoy.GameIO );
}
}
// Deallocate joystick
if( _glfwJoy.Present )
{
controller_type = GPCT_NOCONTROLLER;
_glfwJoy.GameIO->io_Command = GPD_SETCTYPE;
_glfwJoy.GameIO->io_Flags = IOF_QUICK;
_glfwJoy.GameIO->io_Data = (APTR) &controller_type;
_glfwJoy.GameIO->io_Length = 1;
DoIO( (struct IORequest *) _glfwJoy.GameIO );
_glfwJoy.Present = 0;
}
// Close gameport.device
if( _glfwJoy.GameDeviceOpen )
{
CloseDevice( (struct IORequest *) _glfwJoy.GameIO );
_glfwJoy.GameDeviceOpen = 0;
}
// Delete I/O request
if( _glfwJoy.GameIO )
{
DeleteExtIO( (struct IORequest *) _glfwJoy.GameIO );
_glfwJoy.GameIO = NULL;
}
// Delete message port
if( _glfwJoy.GameMP )
{
DeletePort( _glfwJoy.GameMP );
_glfwJoy.GameMP = NULL;
}
}
//========================================================================
// _glfwPollJoystickEvents() - Empty joystick event queue
//========================================================================
static void _glfwPollJoystickEvents( void )
{
int got_event = 0;
// Do we have a stick?
if( !_glfwJoy.Present )
{
return;
}
// Empty the message queue
while( GetMsg( _glfwJoy.GameMP ) != NULL )
{
// Flag: we got an event
got_event = 1;
switch( _glfwJoy.GameEvent.ie_Code )
{
// Left button pressed
case IECODE_LBUTTON:
_glfwJoy.Button[ 0 ] = 1;
break;
// Left button released
case (IECODE_LBUTTON | IECODE_UP_PREFIX):
_glfwJoy.Button[ 0 ] = 0;
break;
// Right button pressed
case IECODE_RBUTTON:
_glfwJoy.Button[ 1 ] = 1;
break;
// Right button released
case (IECODE_RBUTTON | IECODE_UP_PREFIX):
_glfwJoy.Button[ 1 ] = 0;
break;
// Axis event
case IECODE_NOBUTTON:
_glfwJoy.Axis[ 0 ] = (float) _glfwJoy.GameEvent.ie_X;
_glfwJoy.Axis[ 1 ] = (float) -_glfwJoy.GameEvent.ie_Y;
break;
default:
break;
}
}
// Did we get any events?
if( got_event )
{
// Send joystick read request (asynchronous)
_glfwSendJoyReadRequest();
}
}
//************************************************************************
//**** Platform implementation functions ****
//************************************************************************
//========================================================================
// _glfwPlatformGetJoystickParam() - Determine joystick capabilities
//========================================================================
int _glfwPlatformGetJoystickParam( int joy, int param )
{
// Is joystick present?
if( joy != GLFW_JOYSTICK_1 || !_glfwJoy.Present )
{
return 0;
}
// We assume that the joystick is connected, and has two axes and two
// buttons (since there is no way of retrieving this information from
// AmigaOS)
switch( param )
{
case GLFW_PRESENT:
return GL_TRUE;
case GLFW_AXES:
return 2;
case GLFW_BUTTONS:
return 2;
default:
break;
}
return 0;
}
//========================================================================
// _glfwPlatformGetJoystickPos() - Get joystick axis positions
//========================================================================
int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes )
{
int k;
// Is joystick present?
if( joy != GLFW_JOYSTICK_1 || !_glfwJoy.Present )
{
return 0;
}
// Update joystick state
_glfwPollJoystickEvents();
// Copy axis position information to output vector
if( numaxes > 2 )
{
numaxes = 2;
}
for( k = 0; k < numaxes; ++ k )
{
pos[ k ] = _glfwJoy.Axis[ k ];
}
return numaxes;
}
//========================================================================
// _glfwPlatformGetJoystickButtons() - Get joystick button states
//========================================================================
int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons,
int numbuttons )
{
int k;
// Is joystick present?
if( joy != GLFW_JOYSTICK_1 || !_glfwJoy.Present )
{
return 0;
}
// Update joystick state
_glfwPollJoystickEvents();
// Copy button information to output vector
if( numbuttons > 2 )
{
numbuttons = 2;
}
for( k = 0; k < numbuttons; ++ k )
{
buttons[ k ] = _glfwJoy.Button[ k ];
}
return numbuttons;
}