360 lines
10 KiB
C
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;
|
|
}
|