Import PLIB JS code into FlightGear
- will permit bug-fixing which cannot occur for official PLIB.
This commit is contained in:
parent
50518862fe
commit
102fe04e91
18 changed files with 1802 additions and 68 deletions
4
3rdparty/CMakeLists.txt
vendored
4
3rdparty/CMakeLists.txt
vendored
|
@ -30,6 +30,10 @@ if (ENABLE_HID_INPUT)
|
|||
add_subdirectory(hidapi)
|
||||
endif()
|
||||
|
||||
if (ENABLE_PLIB_JOYSTICK)
|
||||
add_subdirectory(joystick)
|
||||
endif()
|
||||
|
||||
if (NOT SYSTEM_CPPUNIT)
|
||||
add_subdirectory(cppunit)
|
||||
endif()
|
||||
|
|
44
3rdparty/joystick/CMakeLists.txt
vendored
Normal file
44
3rdparty/joystick/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
message(STATUS "Enabling legacy joystick code (from PLIB)")
|
||||
|
||||
if(APPLE)
|
||||
# resolve frameworks to full paths
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
find_library(CF_LIBRARY CoreFoundation)
|
||||
set(JS_LIBS ${IOKIT_LIBRARY} ${CF_LIBRARY})
|
||||
set(JS_SOURCES js.cxx jsMacOSX.cxx)
|
||||
elseif(WIN32)
|
||||
set(WINMM_LIBRARY winmm)
|
||||
set(JS_LIBS ${WINMM_LIBRARY})
|
||||
set(JS_SOURCES js.cxx jsWindows.cxx)
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
set(JS_SOURCES js.cxx jsLinux.cxx)
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
find_library(USBHID_LIBRARY usbhid)
|
||||
# check_function_exists(hidinit)
|
||||
set(JS_LIBS ${USBHID_LIBRARY})
|
||||
set(JS_SOURCES js.cxx jsBSD.cxx)
|
||||
else()
|
||||
message(WARNING "Unsupported platform for Joystick")
|
||||
set(JS_SOURCES js.cxx jsNone.cxx)
|
||||
endif()
|
||||
|
||||
add_library(PLIBJoystick STATIC ${JS_SOURCES})
|
||||
|
||||
# for logging code at least, more in the future
|
||||
target_link_libraries(PLIBJoystick SimGearCore)
|
||||
|
||||
if(APPLE)
|
||||
target_link_libraries(PLIBJoystick ${IOKIT_LIBRARY} ${CF_LIBRARY} )
|
||||
elseif(WIN32)
|
||||
target_link_libraries(PLIBJoystick ${WINMM_LIBRARY})
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
# no libs here?
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
target_link_libraries(PLIBJoystick ${USBHID_LIBRARY})
|
||||
else()
|
||||
# other / none platform
|
||||
endif()
|
||||
|
||||
target_include_directories(PLIBJoystick PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
# eof
|
92
3rdparty/joystick/js.cxx
vendored
Normal file
92
3rdparty/joystick/js.cxx
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
PLIB - A Suite of Portable Game Libraries
|
||||
Copyright (C) 1998,2002 Steve Baker
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "js.h"
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
float jsJoystick::fudge_axis ( float value, int axis ) const
|
||||
{
|
||||
if ( value < center[axis] )
|
||||
{
|
||||
float xx = ( value - center[ axis ] ) /
|
||||
( center [ axis ] - min [ axis ] ) ;
|
||||
|
||||
if ( xx < -saturate [ axis ] )
|
||||
return -1.0f ;
|
||||
|
||||
if ( xx > -dead_band [ axis ] )
|
||||
return 0.0f ;
|
||||
|
||||
xx = ( xx + dead_band [ axis ] ) /
|
||||
( saturate [ axis ] - dead_band [ axis ] ) ;
|
||||
|
||||
return ( xx < -1.0f ) ? -1.0f : xx ;
|
||||
}
|
||||
else
|
||||
{
|
||||
float xx = ( value - center [ axis ] ) /
|
||||
( max [ axis ] - center [ axis ] ) ;
|
||||
|
||||
if ( xx > saturate [ axis ] )
|
||||
return 1.0f ;
|
||||
|
||||
if ( xx < dead_band [ axis ] )
|
||||
return 0.0f ;
|
||||
|
||||
xx = ( xx - dead_band [ axis ] ) /
|
||||
( saturate [ axis ] - dead_band [ axis ] ) ;
|
||||
|
||||
return ( xx > 1.0f ) ? 1.0f : xx ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void jsJoystick::read ( int *buttons, float *axes )
|
||||
{
|
||||
if ( error )
|
||||
{
|
||||
if ( buttons )
|
||||
*buttons = 0 ;
|
||||
|
||||
if ( axes )
|
||||
for ( int i = 0 ; i < num_axes ; i++ )
|
||||
axes[i] = 0.0f ;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
float raw_axes [ _JS_MAX_AXES ] ;
|
||||
|
||||
rawRead ( buttons, raw_axes ) ;
|
||||
|
||||
if ( axes )
|
||||
for ( int i = 0 ; i < num_axes ; i++ )
|
||||
axes[i] = fudge_axis ( raw_axes[i], i ) ;
|
||||
}
|
||||
|
||||
void jsSetError(int level, const std::string& msg)
|
||||
{
|
||||
SG_LOG(SG_INPUT, static_cast<sgDebugPriority>(level), msg);
|
||||
}
|
96
3rdparty/joystick/js.h
vendored
Normal file
96
3rdparty/joystick/js.h
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
PLIB - A Suite of Portable Game Libraries
|
||||
Copyright (C) 1998,2002 Steve Baker
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: js.h 2067 2006-01-30 07:36:01Z bram $
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDED_JS_H__
|
||||
#define __INCLUDED_JS_H__ 1
|
||||
#define JS_NEW
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
#define _JS_MAX_AXES 16
|
||||
#define _JS_MAX_BUTTONS 32
|
||||
#define _JS_MAX_HATS 4
|
||||
|
||||
#define JS_TRUE 1
|
||||
#define JS_FALSE 0
|
||||
|
||||
|
||||
class jsJoystick
|
||||
{
|
||||
int id ;
|
||||
protected:
|
||||
struct os_specific_s *os ;
|
||||
friend struct os_specific_s ;
|
||||
int error ;
|
||||
char name [ 128 ] ;
|
||||
int num_axes ;
|
||||
int num_buttons ;
|
||||
|
||||
float dead_band [ _JS_MAX_AXES ] ;
|
||||
float saturate [ _JS_MAX_AXES ] ;
|
||||
float center [ _JS_MAX_AXES ] ;
|
||||
float max [ _JS_MAX_AXES ] ;
|
||||
float min [ _JS_MAX_AXES ] ;
|
||||
|
||||
void open () ;
|
||||
void close () ;
|
||||
|
||||
float fudge_axis ( float value, int axis ) const ;
|
||||
|
||||
public:
|
||||
|
||||
jsJoystick ( int ident = 0 ) ;
|
||||
~jsJoystick () { close () ; }
|
||||
|
||||
const char* getName () const { return name ; }
|
||||
int getNumAxes () const { return num_axes ; }
|
||||
int getNumButtons () const { return num_buttons; }
|
||||
int notWorking () const { return error ; }
|
||||
void setError () { error = JS_TRUE ; }
|
||||
|
||||
float getDeadBand ( int axis ) const { return dead_band [ axis ] ; }
|
||||
void setDeadBand ( int axis, float db ) { dead_band [ axis ] = db ; }
|
||||
|
||||
float getSaturation ( int axis ) const { return saturate [ axis ] ; }
|
||||
void setSaturation ( int axis, float st ) { saturate [ axis ] = st ; }
|
||||
|
||||
void setMinRange ( float *axes ) { memcpy ( min , axes, num_axes * sizeof(float) ) ; }
|
||||
void setMaxRange ( float *axes ) { memcpy ( max , axes, num_axes * sizeof(float) ) ; }
|
||||
void setCenter ( float *axes ) { memcpy ( center, axes, num_axes * sizeof(float) ) ; }
|
||||
|
||||
void getMinRange ( float *axes ) const { memcpy ( axes, min , num_axes * sizeof(float) ) ; }
|
||||
void getMaxRange ( float *axes ) const { memcpy ( axes, max , num_axes * sizeof(float) ) ; }
|
||||
void getCenter ( float *axes ) const { memcpy ( axes, center, num_axes * sizeof(float) ) ; }
|
||||
|
||||
void read ( int *buttons, float *axes ) ;
|
||||
void rawRead ( int *buttons, float *axes ) ;
|
||||
// bool SetForceFeedBack ( int axe, float force );
|
||||
} ;
|
||||
|
||||
extern void jsInit () ;
|
||||
|
||||
void jsSetError(int, const std::string& msg);
|
||||
|
||||
#endif
|
518
3rdparty/joystick/jsBSD.cxx
vendored
Normal file
518
3rdparty/joystick/jsBSD.cxx
vendored
Normal file
|
@ -0,0 +1,518 @@
|
|||
/*
|
||||
PLIB - A Suite of Portable Game Libraries
|
||||
Copyright (C) 1998,2002 Steve Baker
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: jsBSD.cxx 2133 2008-07-18 14:32:22Z fayjf $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Inspired by the X-Mame USB HID joystick driver for NetBSD and
|
||||
* FreeBSD by Krister Walfridsson <cato@df.lth.se>.
|
||||
* Incorporates the original analog joystick driver for BSD by
|
||||
* Stephen Montgomery-Smith <stephen@math.missouri.edu>, with
|
||||
* NetBSD mods courtesy of Rene Hexel.
|
||||
*
|
||||
* Bert Driehuis <driehuis@playbeing.org>
|
||||
*
|
||||
* Notes:
|
||||
* Hats are mapped to two axes for now. A cleaner implementation requires
|
||||
* an API extension, and to be useful for my devious purposes, FlightGear
|
||||
* would need to understand that.
|
||||
*/
|
||||
|
||||
#include "js.h"
|
||||
|
||||
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
||||
#define HAVE_USB_JS 1
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#if defined(__FreeBSD__)
|
||||
# include <sys/joystick.h>
|
||||
#else
|
||||
# include <machine/joystick.h> // For analog joysticks
|
||||
#endif
|
||||
#ifdef HAVE_USB_JS
|
||||
#if defined(__NetBSD__)
|
||||
#ifdef HAVE_USBHID_H
|
||||
#include <usbhid.h>
|
||||
#else
|
||||
#include <usb.h>
|
||||
#endif
|
||||
#elif defined(__FreeBSD__)
|
||||
extern "C" {
|
||||
# if __FreeBSD_version < 500000
|
||||
# include <libusbhid.h>
|
||||
# else
|
||||
# define HAVE_USBHID_H 1
|
||||
# include <usbhid.h>
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbhid.h>
|
||||
|
||||
/* Compatibility with older usb.h revisions */
|
||||
#if !defined(USB_MAX_DEVNAMES) && defined(MAXDEVNAMES)
|
||||
#define USB_MAX_DEVNAMES MAXDEVNAMES
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int hatmap_x[9] = { 0, 0, 1, 1, 1, 0, -1, -1, -1 };
|
||||
static int hatmap_y[9] = { 0, 1, 1, 0, -1, -1, -1, 0, 1 };
|
||||
struct os_specific_s {
|
||||
char fname [128 ];
|
||||
int fd;
|
||||
int is_analog;
|
||||
// The following structure members are specific to analog joysticks
|
||||
struct joystick ajs;
|
||||
#ifdef HAVE_USB_JS
|
||||
// The following structure members are specific to USB joysticks
|
||||
struct hid_item *hids;
|
||||
int hid_dlen;
|
||||
int hid_offset;
|
||||
char *hid_data_buf;
|
||||
int axes_usage [ _JS_MAX_AXES ] ;
|
||||
#endif
|
||||
// We keep button and axes state ourselves, as they might not be updated
|
||||
// on every read of a USB device
|
||||
int cache_buttons ;
|
||||
float cache_axes [ _JS_MAX_AXES ] ;
|
||||
float axes_minimum [ _JS_MAX_AXES ] ;
|
||||
float axes_maximum [ _JS_MAX_AXES ] ;
|
||||
};
|
||||
|
||||
// Idents lower than USB_IDENT_OFFSET are for analog joysticks.
|
||||
#define USB_IDENT_OFFSET 2
|
||||
|
||||
#define USBDEV "/dev/usb"
|
||||
#define UHIDDEV "/dev/uhid"
|
||||
#define AJSDEV "/dev/joy"
|
||||
|
||||
#ifdef HAVE_USB_JS
|
||||
/*
|
||||
* findusbdev (and its helper, walkusbdev) try to locate the full name
|
||||
* of a USB device. If /dev/usbN isn't readable, we punt and return the
|
||||
* uhidN device name. We warn the user of this situation once.
|
||||
*/
|
||||
static char *
|
||||
walkusbdev(int f, char *dev, char *out, int outlen)
|
||||
{
|
||||
struct usb_device_info di;
|
||||
int i, a;
|
||||
char *cp;
|
||||
|
||||
for (a = 1; a < USB_MAX_DEVICES; a++) {
|
||||
di.udi_addr = a;
|
||||
if (ioctl(f, USB_DEVICEINFO, &di) != 0)
|
||||
return NULL;
|
||||
for (i = 0; i < USB_MAX_DEVNAMES; i++)
|
||||
if (di.udi_devnames[i][0] &&
|
||||
strcmp(di.udi_devnames[i], dev) == 0) {
|
||||
cp = new char[strlen(di.udi_vendor) + strlen(di.udi_product) + 2];
|
||||
strcpy(cp, di.udi_vendor);
|
||||
strcat(cp, " ");
|
||||
strcat(cp, di.udi_product);
|
||||
strncpy(out, cp, outlen - 1);
|
||||
out[outlen - 1] = 0;
|
||||
delete cp;
|
||||
return out;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
findusbdev(char *name, char *out, int outlen)
|
||||
{
|
||||
int i, f;
|
||||
char buf[50];
|
||||
char *cp;
|
||||
static int protection_warned = 0;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
sprintf(buf, "%s%d", USBDEV, i);
|
||||
f = open(buf, O_RDONLY);
|
||||
if (f >= 0) {
|
||||
cp = walkusbdev(f, name, out, outlen);
|
||||
close(f);
|
||||
if (cp)
|
||||
return 1;
|
||||
} else if (errno == EACCES) {
|
||||
if (!protection_warned) {
|
||||
fprintf(stderr, "Can't open %s for read!\n",
|
||||
buf);
|
||||
protection_warned = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int joy_initialize_hid(struct os_specific_s *os,
|
||||
int *num_axes, int *num_buttons)
|
||||
{
|
||||
int size, is_joystick;
|
||||
#ifdef HAVE_USBHID_H
|
||||
int report_id = 0;
|
||||
#endif
|
||||
struct hid_data *d;
|
||||
struct hid_item h;
|
||||
report_desc_t rd;
|
||||
|
||||
if ((rd = hid_get_report_desc(os->fd)) == 0)
|
||||
{
|
||||
fprintf(stderr, "error: %s: %s", os->fname, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
os->hids = NULL;
|
||||
|
||||
#ifdef HAVE_USBHID_H
|
||||
if (ioctl(os->fd, USB_GET_REPORT_ID, &report_id) < 0)
|
||||
{
|
||||
fprintf(stderr, "error: %s: %s", os->fname, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size = hid_report_size(rd, hid_input, report_id);
|
||||
#else
|
||||
size = hid_report_size(rd, 0, hid_input);
|
||||
#endif
|
||||
os->hid_data_buf = new char[size];
|
||||
os->hid_dlen = size;
|
||||
|
||||
is_joystick = 0;
|
||||
#ifdef HAVE_USBHID_H
|
||||
d = hid_start_parse(rd, 1 << hid_input, report_id);
|
||||
#else
|
||||
d = hid_start_parse(rd, 1 << hid_input);
|
||||
#endif
|
||||
while (hid_get_item(d, &h))
|
||||
{
|
||||
int usage, page, interesting_hid;
|
||||
|
||||
page = HID_PAGE(h.usage);
|
||||
usage = HID_USAGE(h.usage);
|
||||
|
||||
/* This test is somewhat too simplistic, but this is how MicroSoft
|
||||
* does, so I guess it works for all joysticks/game pads. */
|
||||
is_joystick = is_joystick ||
|
||||
(h.kind == hid_collection &&
|
||||
page == HUP_GENERIC_DESKTOP &&
|
||||
(usage == HUG_JOYSTICK || usage == HUG_GAME_PAD));
|
||||
|
||||
if (h.kind != hid_input)
|
||||
continue;
|
||||
|
||||
if (!is_joystick)
|
||||
continue;
|
||||
|
||||
interesting_hid = TRUE;
|
||||
if (page == HUP_GENERIC_DESKTOP)
|
||||
{
|
||||
switch(usage) {
|
||||
case HUG_X:
|
||||
case HUG_RX:
|
||||
case HUG_Y:
|
||||
case HUG_RY:
|
||||
case HUG_Z:
|
||||
case HUG_RZ:
|
||||
case HUG_SLIDER:
|
||||
if (*num_axes < _JS_MAX_AXES)
|
||||
{
|
||||
os->axes_usage[*num_axes] = usage;
|
||||
os->axes_minimum[*num_axes] = h.logical_minimum;
|
||||
os->axes_maximum[*num_axes] = h.logical_maximum;
|
||||
(*num_axes)++;
|
||||
}
|
||||
break;
|
||||
case HUG_HAT_SWITCH:
|
||||
if (*num_axes + 1 < _JS_MAX_AXES) // Allocate two axes for a hat
|
||||
{
|
||||
os->axes_usage[*num_axes] = usage;
|
||||
(*num_axes)++;
|
||||
os->axes_usage[*num_axes] = usage;
|
||||
(*num_axes)++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
interesting_hid = FALSE;
|
||||
}
|
||||
}
|
||||
else if (page == HUP_BUTTON)
|
||||
{
|
||||
interesting_hid = (usage > 0) && (usage <= _JS_MAX_BUTTONS);
|
||||
|
||||
if (interesting_hid && usage - 1 > *num_buttons)
|
||||
{
|
||||
*num_buttons = usage - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (interesting_hid)
|
||||
{
|
||||
h.next = os->hids;
|
||||
os->hids = new struct hid_item;
|
||||
*os->hids = h;
|
||||
}
|
||||
}
|
||||
hid_end_parse(d);
|
||||
|
||||
return (os->hids != NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
void jsJoystick::open ()
|
||||
{
|
||||
char *cp;
|
||||
|
||||
name [0] = '\0' ;
|
||||
|
||||
for ( int i = 0 ; i < _JS_MAX_AXES ; i++ )
|
||||
os->cache_axes [ i ] = 0.0f ;
|
||||
|
||||
os->cache_buttons = 0 ;
|
||||
|
||||
os->fd = ::open ( os->fname, O_RDONLY | O_NONBLOCK) ;
|
||||
|
||||
if (os->fd < 0 && errno == EACCES)
|
||||
fprintf(stderr, "%s exists but is not readable by you\n", os->fname);
|
||||
|
||||
error = ( os->fd < 0 ) ;
|
||||
|
||||
if ( error )
|
||||
return ;
|
||||
|
||||
num_axes = 0;
|
||||
num_buttons = 0;
|
||||
if ( os->is_analog )
|
||||
{
|
||||
num_axes = 2 ;
|
||||
num_buttons = 32 ;
|
||||
FILE *joyfile ;
|
||||
char joyfname [ 1024 ] ;
|
||||
int noargs, in_no_axes ;
|
||||
|
||||
float axes [ _JS_MAX_AXES ] ;
|
||||
int buttons [ _JS_MAX_AXES ] ;
|
||||
|
||||
rawRead ( buttons, axes ) ;
|
||||
error = axes[0] < -1000000000.0f && axes[1] < -1000000000.0f ;
|
||||
if ( error )
|
||||
return ;
|
||||
|
||||
sprintf( joyfname, "%s/.joy%drc", ::getenv ( "HOME" ), id ) ;
|
||||
|
||||
joyfile = fopen ( joyfname, "r" ) ;
|
||||
error = ( joyfile == NULL ) ;
|
||||
if ( error )
|
||||
{
|
||||
jsSetError ( SG_WARN, "unable to open calibration file %s (%s), joystick %i disabled (you can generate the calibration file with the plib-jscal utility)",
|
||||
joyfname, strerror ( errno ), id + 1 );
|
||||
return ;
|
||||
}
|
||||
|
||||
noargs = fscanf ( joyfile, "%d%f%f%f%f%f%f", &in_no_axes,
|
||||
&min [ 0 ], ¢er [ 0 ], &max [ 0 ],
|
||||
&min [ 1 ], ¢er [ 1 ], &max [ 1 ] ) ;
|
||||
error = noargs != 7 || in_no_axes != _JS_MAX_AXES ;
|
||||
fclose ( joyfile ) ;
|
||||
if ( error )
|
||||
return ;
|
||||
|
||||
for ( int i = 0 ; i < _JS_MAX_AXES ; i++ )
|
||||
{
|
||||
dead_band [ i ] = 0.0f ;
|
||||
saturate [ i ] = 1.0f ;
|
||||
}
|
||||
|
||||
return; // End of analog code
|
||||
}
|
||||
|
||||
#ifdef HAVE_USB_JS
|
||||
if ( !joy_initialize_hid(os, &num_axes, &num_buttons ) )
|
||||
{
|
||||
::close(os->fd);
|
||||
error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
cp = strrchr(os->fname, '/');
|
||||
if (cp) {
|
||||
if (findusbdev(&cp[1], name, sizeof(name)) == 0)
|
||||
strcpy(name, &cp[1]);
|
||||
}
|
||||
|
||||
if ( num_axes > _JS_MAX_AXES )
|
||||
num_axes = _JS_MAX_AXES ;
|
||||
|
||||
for ( int i = 0 ; i < _JS_MAX_AXES ; i++ )
|
||||
{
|
||||
if ( os->axes_usage [ i ] == HUG_HAT_SWITCH )
|
||||
{
|
||||
max [ i ] = 1.0f ;
|
||||
center [ i ] = 0.0f ;
|
||||
min [ i ] = -1.0f ;
|
||||
}
|
||||
else
|
||||
{
|
||||
max [ i ] = os->axes_maximum [ i ];
|
||||
min [ i ] = os->axes_minimum [ i ];
|
||||
center [ i ] = (max [ i ] + min [ i ]) / 2;
|
||||
}
|
||||
dead_band [ i ] = 0.0f ;
|
||||
saturate [ i ] = 1.0f ;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void jsJoystick::close ()
|
||||
{
|
||||
if (os) {
|
||||
if ( ! error )
|
||||
::close ( os->fd ) ;
|
||||
#ifdef HAVE_USB_JS
|
||||
if (os->hids)
|
||||
delete os->hids;
|
||||
if (os->hid_data_buf)
|
||||
delete os->hid_data_buf;
|
||||
#endif
|
||||
delete os;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
jsJoystick::jsJoystick ( int ident )
|
||||
{
|
||||
id = ident ;
|
||||
error = 0;
|
||||
|
||||
os = new struct os_specific_s;
|
||||
memset(os, 0, sizeof(struct os_specific_s));
|
||||
if (ident < USB_IDENT_OFFSET)
|
||||
os->is_analog = 1;
|
||||
if (os->is_analog)
|
||||
sprintf(os->fname, "%s%d", AJSDEV, ident);
|
||||
else
|
||||
sprintf(os->fname, "%s%d", UHIDDEV, ident - USB_IDENT_OFFSET);
|
||||
open () ;
|
||||
}
|
||||
|
||||
|
||||
void jsJoystick::rawRead ( int *buttons, float *axes )
|
||||
{
|
||||
int len, usage, page, d;
|
||||
struct hid_item *h;
|
||||
|
||||
if ( error )
|
||||
{
|
||||
if ( buttons )
|
||||
*buttons = 0 ;
|
||||
|
||||
if ( axes )
|
||||
for ( int i = 0 ; i < num_axes ; i++ )
|
||||
axes[i] = 1500.0f ;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
if ( os->is_analog )
|
||||
{
|
||||
int status = ::read ( os->fd, &os->ajs, sizeof(os->ajs) );
|
||||
if ( status != sizeof(os->ajs) ) {
|
||||
perror ( os->fname ) ;
|
||||
setError () ;
|
||||
return ;
|
||||
}
|
||||
if ( buttons != NULL )
|
||||
*buttons = ( os->ajs.b1 ? 1 : 0 ) | ( os->ajs.b2 ? 2 : 0 ) ;
|
||||
|
||||
if ( axes != NULL )
|
||||
{
|
||||
if ( os->ajs.x >= -1000000000 )
|
||||
os->cache_axes[0] = os->ajs.x;
|
||||
if ( os->ajs.y >= -1000000000 )
|
||||
os->cache_axes[1] = os->ajs.y;
|
||||
|
||||
axes[0] = os->cache_axes[0];
|
||||
axes[1] = os->cache_axes[1];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_USB_JS
|
||||
while ((len = ::read(os->fd, os->hid_data_buf, os->hid_dlen)) == os->hid_dlen)
|
||||
{
|
||||
for (h = os->hids; h; h = h->next)
|
||||
{
|
||||
d = hid_get_data(os->hid_data_buf, h);
|
||||
|
||||
page = HID_PAGE(h->usage);
|
||||
usage = HID_USAGE(h->usage);
|
||||
|
||||
if (page == HUP_GENERIC_DESKTOP)
|
||||
{
|
||||
for (int i = 0; i < num_axes; i++)
|
||||
if (os->axes_usage[i] == usage)
|
||||
{
|
||||
if (usage == HUG_HAT_SWITCH)
|
||||
{
|
||||
if (d < 0 || d > 8)
|
||||
d = 0; // safety
|
||||
os->cache_axes[i] = (float)hatmap_x[d];
|
||||
os->cache_axes[i + 1] = (float)hatmap_y[d];
|
||||
}
|
||||
else
|
||||
{
|
||||
os->cache_axes[i] = (float)d;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (page == HUP_BUTTON)
|
||||
{
|
||||
if (usage > 0 && usage < _JS_MAX_BUTTONS + 1)
|
||||
{
|
||||
if (d)
|
||||
os->cache_buttons |= (1 << usage - 1) ;
|
||||
else
|
||||
os->cache_buttons &= ~(1 << usage - 1) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (len < 0 && errno != EAGAIN)
|
||||
{
|
||||
perror( os->fname ) ;
|
||||
setError () ;
|
||||
error = 1;
|
||||
}
|
||||
if ( buttons != NULL ) *buttons = os->cache_buttons ;
|
||||
if ( axes != NULL )
|
||||
memcpy ( axes, os->cache_axes, sizeof(float) * num_axes ) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
void jsInit () {}
|
202
3rdparty/joystick/jsLinux.cxx
vendored
Normal file
202
3rdparty/joystick/jsLinux.cxx
vendored
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
PLIB - A Suite of Portable Game Libraries
|
||||
Copyright (C) 1998,2002 Steve Baker
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: jsLinux.cxx 2017 2005-02-21 07:37:25Z bram $
|
||||
*/
|
||||
|
||||
#include "js.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <linux/joystick.h>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
|
||||
#if defined(JS_VERSION) && JS_VERSION >= 0x010000
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
struct os_specific_s {
|
||||
js_event js ;
|
||||
int tmp_buttons ;
|
||||
float tmp_axes [ _JS_MAX_AXES ] ;
|
||||
char fname [ 128 ] ;
|
||||
int fd ;
|
||||
};
|
||||
|
||||
void jsInit () {}
|
||||
|
||||
void jsJoystick::open ()
|
||||
{
|
||||
name [0] = '\0' ;
|
||||
|
||||
for ( int i = 0 ; i < _JS_MAX_AXES ; i++ )
|
||||
os->tmp_axes [ i ] = 0.0f ;
|
||||
|
||||
os->tmp_buttons = 0 ;
|
||||
|
||||
os->fd = ::open ( os->fname, O_RDONLY ) ;
|
||||
|
||||
error = ( os->fd < 0 ) ;
|
||||
|
||||
if ( error )
|
||||
return ;
|
||||
|
||||
/*
|
||||
Set the correct number of axes for the linux driver
|
||||
*/
|
||||
|
||||
/* Melchior Franz's fixes for big-endian Linuxes since writing
|
||||
* to the upper byte of an uninitialized word doesn't work.
|
||||
* 9 April 2003
|
||||
*/
|
||||
unsigned char u ;
|
||||
ioctl ( os->fd, JSIOCGAXES , &u ) ;
|
||||
num_axes = u ;
|
||||
ioctl ( os->fd, JSIOCGBUTTONS, &u ) ;
|
||||
num_buttons = u ;
|
||||
ioctl ( os->fd, JSIOCGNAME ( sizeof(name) ), name ) ;
|
||||
fcntl ( os->fd, F_SETFL , O_NONBLOCK ) ;
|
||||
|
||||
int all_axes = num_axes;
|
||||
if ( num_axes > _JS_MAX_AXES )
|
||||
num_axes = _JS_MAX_AXES ;
|
||||
|
||||
// Remove any deadband value already done in the kernel.
|
||||
// Since we have our own deadband management this is save to do so.
|
||||
struct js_corr* corr = new js_corr[ all_axes ] ;
|
||||
ioctl ( os->fd, JSIOCGCORR, corr );
|
||||
for ( int i = 0; i < num_axes ; ++i ) {
|
||||
if ( corr[ i ] . type == JS_CORR_BROKEN ) {
|
||||
int nodeadband = ( corr[ i ] . coef[ 0 ] + corr[ i ] . coef[ 1 ] ) / 2 ;
|
||||
corr[ i ] . coef[ 0 ] = nodeadband ;
|
||||
corr[ i ] . coef[ 1 ] = nodeadband ;
|
||||
}
|
||||
}
|
||||
ioctl ( os->fd, JSIOCSCORR, corr );
|
||||
delete [] corr;
|
||||
|
||||
for ( int i = 0 ; i < _JS_MAX_AXES ; i++ )
|
||||
{
|
||||
max [ i ] = 32767.0f ;
|
||||
center [ i ] = 0.0f ;
|
||||
min [ i ] = -32767.0f ;
|
||||
dead_band [ i ] = 0.0f ;
|
||||
saturate [ i ] = 1.0f ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void jsJoystick::close ()
|
||||
{
|
||||
if ( ! error )
|
||||
::close ( os->fd ) ;
|
||||
delete os;
|
||||
}
|
||||
|
||||
|
||||
jsJoystick::jsJoystick ( int ident )
|
||||
{
|
||||
id = ident ;
|
||||
os = new struct os_specific_s;
|
||||
|
||||
sprintf ( os->fname, "/dev/input/js%d", ident ) ;
|
||||
|
||||
if ( access ( os->fname, F_OK ) != 0 )
|
||||
sprintf ( os->fname, "/dev/js%d", ident ) ;
|
||||
|
||||
open () ;
|
||||
}
|
||||
|
||||
|
||||
void jsJoystick::rawRead ( int *buttons, float *axes )
|
||||
{
|
||||
if ( error )
|
||||
{
|
||||
if ( buttons )
|
||||
*buttons = 0 ;
|
||||
|
||||
if ( axes )
|
||||
for ( int i = 0 ; i < num_axes ; i++ )
|
||||
axes[i] = 1500.0f ;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
int status = ::read ( os->fd, &(os->js), sizeof(js_event) ) ;
|
||||
|
||||
if ( status != sizeof(js_event) )
|
||||
{
|
||||
/* use the old values */
|
||||
|
||||
if ( buttons != NULL ) *buttons = os->tmp_buttons ;
|
||||
if ( axes != NULL )
|
||||
memcpy ( axes, os->tmp_axes, sizeof(float) * num_axes ) ;
|
||||
|
||||
if ( errno == EAGAIN )
|
||||
return ;
|
||||
|
||||
perror( os->fname ) ;
|
||||
setError () ;
|
||||
return ;
|
||||
}
|
||||
|
||||
switch ( os->js.type & ~JS_EVENT_INIT )
|
||||
{
|
||||
case JS_EVENT_BUTTON :
|
||||
if ( os->js.value == 0 ) /* clear the flag */
|
||||
os->tmp_buttons &= ~(1 << os->js.number) ;
|
||||
else
|
||||
os->tmp_buttons |= (1 << os->js.number) ;
|
||||
break ;
|
||||
|
||||
case JS_EVENT_AXIS:
|
||||
if ( os->js.number < num_axes )
|
||||
{
|
||||
os->tmp_axes [ os->js.number ] = (float) os->js.value ;
|
||||
|
||||
if ( axes )
|
||||
memcpy ( axes, os->tmp_axes, sizeof(float) * num_axes ) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
default:
|
||||
jsSetError ( SG_WARN, "PLIB_JS: Unrecognised /dev/js return!?!" ) ;
|
||||
|
||||
/* use the old values */
|
||||
|
||||
if ( buttons != NULL ) *buttons = os->tmp_buttons ;
|
||||
if ( axes != NULL )
|
||||
memcpy ( axes, os->tmp_axes, sizeof(float) * num_axes ) ;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
if ( buttons != NULL )
|
||||
*buttons = os->tmp_buttons ;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
464
3rdparty/joystick/jsMacOSX.cxx
vendored
Normal file
464
3rdparty/joystick/jsMacOSX.cxx
vendored
Normal file
|
@ -0,0 +1,464 @@
|
|||
/*
|
||||
PLIB - A Suite of Portable Game Libraries
|
||||
Copyright (C) 1998,2002 Steve Baker
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: jsMacOSX.cxx 2165 2011-01-22 22:56:03Z fayjf $
|
||||
*/
|
||||
|
||||
#include "js.h"
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/hid/IOHIDLib.h>
|
||||
#include <mach/mach_error.h>
|
||||
#include <IOKit/hid/IOHIDKeys.h>
|
||||
#include <IOKit/IOCFPlugIn.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#ifdef MACOS_10_0_4
|
||||
# include <IOKit/hidsystem/IOHIDUsageTables.h>
|
||||
#else
|
||||
/* The header was moved here in MacOS X 10.1 */
|
||||
# include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
static const int kNumDevices = 32;
|
||||
static int numDevices = -1;
|
||||
static io_object_t ioDevices[kNumDevices];
|
||||
|
||||
static int NS_hat[8] = {1, 1, 0, -1, -1, -1, 0, 1};
|
||||
static int WE_hat[8] = {0, 1, 1, 1, 0, -1, -1, -1};
|
||||
|
||||
struct os_specific_s {
|
||||
IOHIDDeviceInterface ** hidDev;
|
||||
IOHIDElementCookie buttonCookies[41];
|
||||
IOHIDElementCookie axisCookies[_JS_MAX_AXES];
|
||||
IOHIDElementCookie hatCookies[_JS_MAX_HATS];
|
||||
int num_hats;
|
||||
long hat_min[_JS_MAX_HATS];
|
||||
long hat_max[_JS_MAX_HATS];
|
||||
|
||||
void enumerateElements(jsJoystick* joy, CFTypeRef element);
|
||||
static void elementEnumerator( const void *element, void* vjs);
|
||||
/// callback for CFArrayApply
|
||||
void parseElement(jsJoystick* joy, CFDictionaryRef element);
|
||||
void addAxisElement(jsJoystick* joy, CFDictionaryRef axis);
|
||||
void addButtonElement(jsJoystick* joy, CFDictionaryRef button);
|
||||
void addHatElement(jsJoystick* joy, CFDictionaryRef hat);
|
||||
};
|
||||
|
||||
static void findDevices(mach_port_t);
|
||||
static CFDictionaryRef getCFProperties(io_object_t);
|
||||
|
||||
|
||||
void jsInit()
|
||||
{
|
||||
if (numDevices < 0) {
|
||||
numDevices = 0;
|
||||
|
||||
mach_port_t masterPort;
|
||||
IOReturn rv = IOMasterPort(bootstrap_port, &masterPort);
|
||||
if (rv != kIOReturnSuccess) {
|
||||
jsSetError(SG_WARN, "error getting master Mach port");
|
||||
return;
|
||||
}
|
||||
|
||||
findDevices(masterPort);
|
||||
}
|
||||
}
|
||||
|
||||
/** open the IOKit connection, enumerate all the HID devices, add their
|
||||
interface references to the static array. We then use the array index
|
||||
as the device number when we come to open() the joystick. */
|
||||
static void findDevices(mach_port_t masterPort)
|
||||
{
|
||||
CFMutableDictionaryRef hidMatch = NULL;
|
||||
IOReturn rv = kIOReturnSuccess;
|
||||
io_iterator_t hidIterator;
|
||||
|
||||
// build a dictionary matching HID devices
|
||||
hidMatch = IOServiceMatching(kIOHIDDeviceKey);
|
||||
|
||||
rv = IOServiceGetMatchingServices(masterPort, hidMatch, &hidIterator);
|
||||
if (rv != kIOReturnSuccess || !hidIterator) {
|
||||
jsSetError(SG_WARN, "no joystick (HID) devices found");
|
||||
return;
|
||||
}
|
||||
|
||||
// iterate
|
||||
io_object_t ioDev;
|
||||
|
||||
while ((ioDev = IOIteratorNext(hidIterator))) {
|
||||
// filter out keyboard and mouse devices
|
||||
CFDictionaryRef properties = getCFProperties(ioDev);
|
||||
long usage, page;
|
||||
|
||||
CFTypeRef refPage = CFDictionaryGetValue (properties, CFSTR(kIOHIDPrimaryUsagePageKey));
|
||||
CFTypeRef refUsage = CFDictionaryGetValue (properties, CFSTR(kIOHIDPrimaryUsageKey));
|
||||
CFNumberGetValue((CFNumberRef) refUsage, kCFNumberLongType, &usage);
|
||||
CFNumberGetValue((CFNumberRef) refPage, kCFNumberLongType, &page);
|
||||
|
||||
// keep only joystick devices
|
||||
if ( (page == kHIDPage_GenericDesktop) &&
|
||||
((usage == kHIDUsage_GD_Joystick) ||
|
||||
(usage == kHIDUsage_GD_GamePad)
|
||||
// || (usage == kHIDUsage_GD_MultiAxisController)
|
||||
// || (usage == kHIDUsage_GD_Hatswitch)
|
||||
)
|
||||
)
|
||||
{
|
||||
// add it to the array
|
||||
ioDevices[numDevices++] = ioDev;
|
||||
}
|
||||
}
|
||||
|
||||
IOObjectRelease(hidIterator);
|
||||
}
|
||||
|
||||
|
||||
jsJoystick::jsJoystick(int ident) :
|
||||
id(ident),
|
||||
os(NULL),
|
||||
error(JS_FALSE),
|
||||
num_axes(0),
|
||||
num_buttons(0)
|
||||
{
|
||||
if (ident >= numDevices) {
|
||||
setError();
|
||||
return;
|
||||
}
|
||||
|
||||
os = new struct os_specific_s;
|
||||
os->num_hats = 0;
|
||||
|
||||
// get the name now too
|
||||
CFDictionaryRef properties = getCFProperties(ioDevices[id]);
|
||||
CFTypeRef ref = CFDictionaryGetValue (properties, CFSTR(kIOHIDProductKey));
|
||||
if (!ref)
|
||||
ref = CFDictionaryGetValue (properties, CFSTR("USB Product Name"));
|
||||
|
||||
if (!ref || !CFStringGetCString ((CFStringRef) ref, name, 128, CFStringGetSystemEncoding ())) {
|
||||
jsSetError(SG_WARN, "error getting device name");
|
||||
name[0] = '\0';
|
||||
}
|
||||
//printf("Joystick name: %s \n", name);
|
||||
open();
|
||||
}
|
||||
|
||||
void jsJoystick::open()
|
||||
{
|
||||
#if 0 // test already done in the constructor
|
||||
if (id >= numDevices) {
|
||||
jsSetError(SG_WARN, "device index out of range in jsJoystick::open");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// create device interface
|
||||
IOReturn rv;
|
||||
SInt32 score;
|
||||
IOCFPlugInInterface **plugin;
|
||||
|
||||
rv = IOCreatePlugInInterfaceForService(ioDevices[id],
|
||||
kIOHIDDeviceUserClientTypeID,
|
||||
kIOCFPlugInInterfaceID,
|
||||
&plugin, &score);
|
||||
|
||||
if (rv != kIOReturnSuccess) {
|
||||
jsSetError(SG_WARN, "error creting plugin for io device");
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT pluginResult = (*plugin)->QueryInterface(plugin,
|
||||
CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID*)&(os->hidDev) );
|
||||
|
||||
if (pluginResult != S_OK)
|
||||
jsSetError(SG_WARN, "QI-ing IO plugin to HID Device interface failed");
|
||||
|
||||
(*plugin)->Release(plugin); // don't leak a ref
|
||||
if (os->hidDev == NULL) return;
|
||||
|
||||
// store the interface in this instance
|
||||
rv = (*(os->hidDev))->open(os->hidDev, 0);
|
||||
if (rv != kIOReturnSuccess) {
|
||||
jsSetError(SG_WARN, "error opening device interface");
|
||||
return;
|
||||
}
|
||||
|
||||
CFDictionaryRef props = getCFProperties(ioDevices[id]);
|
||||
|
||||
// recursively enumerate all the bits (buttons, axes, hats, ...)
|
||||
CFTypeRef topLevelElement =
|
||||
CFDictionaryGetValue (props, CFSTR(kIOHIDElementKey));
|
||||
os->enumerateElements(this, topLevelElement);
|
||||
CFRelease(props);
|
||||
|
||||
// for hats to be implemented as axes: must be the last axes:
|
||||
for (int h = 0; h<2*os->num_hats; h++)
|
||||
{
|
||||
int index = num_axes++;
|
||||
dead_band [ index ] = 0.0f ;
|
||||
saturate [ index ] = 1.0f ;
|
||||
center [ index ] = 0.0f;
|
||||
max [ index ] = 1.0f;
|
||||
min [ index ] = -1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
CFDictionaryRef getCFProperties(io_object_t ioDev)
|
||||
{
|
||||
IOReturn rv;
|
||||
CFMutableDictionaryRef cfProperties;
|
||||
|
||||
#if 0
|
||||
// comment copied from darwin/SDL_sysjoystick.c
|
||||
/* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also
|
||||
* get dictionary for usb properties: step up two levels and get CF dictionary for USB properties
|
||||
*/
|
||||
|
||||
io_registry_entry_t parent1, parent2;
|
||||
|
||||
rv = IORegistryEntryGetParentEntry (ioDev, kIOServicePlane, &parent1);
|
||||
if (rv != kIOReturnSuccess) {
|
||||
jsSetError(SG_WARN, "error getting device entry parent");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rv = IORegistryEntryGetParentEntry (parent1, kIOServicePlane, &parent2);
|
||||
if (rv != kIOReturnSuccess) {
|
||||
jsSetError(SG_WARN, "error getting device entry parent 2");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
rv = IORegistryEntryCreateCFProperties( ioDev /*parent2*/,
|
||||
&cfProperties, kCFAllocatorDefault, kNilOptions);
|
||||
if (rv != kIOReturnSuccess || !cfProperties) {
|
||||
jsSetError(SG_WARN, "error getting device properties");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cfProperties;
|
||||
}
|
||||
|
||||
void jsJoystick::close()
|
||||
{
|
||||
if (!os)
|
||||
return;
|
||||
if (os->hidDev != NULL) (*(os->hidDev))->close(os->hidDev);
|
||||
if (os) delete os;
|
||||
}
|
||||
|
||||
/** element enumerator function : pass NULL for top-level*/
|
||||
void os_specific_s::enumerateElements(jsJoystick* joy, CFTypeRef element)
|
||||
{
|
||||
assert(CFGetTypeID(element) == CFArrayGetTypeID());
|
||||
|
||||
CFRange range = {0, CFArrayGetCount ((CFArrayRef)element)};
|
||||
CFArrayApplyFunction((CFArrayRef) element, range,
|
||||
&elementEnumerator, joy);
|
||||
}
|
||||
|
||||
void os_specific_s::elementEnumerator( const void *element, void* vjs)
|
||||
{
|
||||
if (CFGetTypeID((CFTypeRef) element) != CFDictionaryGetTypeID()) {
|
||||
jsSetError(SG_WARN, "element enumerator passed non-dictionary value");
|
||||
return;
|
||||
}
|
||||
|
||||
static_cast<jsJoystick*>(vjs)->
|
||||
os->parseElement( static_cast<jsJoystick*>(vjs), (CFDictionaryRef) element);
|
||||
}
|
||||
|
||||
void os_specific_s::parseElement(jsJoystick* joy, CFDictionaryRef element)
|
||||
{
|
||||
CFTypeRef refPage = CFDictionaryGetValue ((CFDictionaryRef) element, CFSTR(kIOHIDElementUsagePageKey));
|
||||
CFTypeRef refUsage = CFDictionaryGetValue ((CFDictionaryRef) element, CFSTR(kIOHIDElementUsageKey));
|
||||
|
||||
long type, page, usage;
|
||||
|
||||
CFNumberGetValue((CFNumberRef)
|
||||
CFDictionaryGetValue ((CFDictionaryRef) element, CFSTR(kIOHIDElementTypeKey)),
|
||||
kCFNumberLongType, &type);
|
||||
|
||||
switch (type) {
|
||||
case kIOHIDElementTypeInput_Misc:
|
||||
case kIOHIDElementTypeInput_Axis:
|
||||
case kIOHIDElementTypeInput_Button:
|
||||
//printf("got input element...");
|
||||
CFNumberGetValue((CFNumberRef) refUsage, kCFNumberLongType, &usage);
|
||||
CFNumberGetValue((CFNumberRef) refPage, kCFNumberLongType, &page);
|
||||
|
||||
if (page == kHIDPage_GenericDesktop) {
|
||||
switch (usage) /* look at usage to determine function */
|
||||
{
|
||||
case kHIDUsage_GD_X:
|
||||
case kHIDUsage_GD_Y:
|
||||
case kHIDUsage_GD_Z:
|
||||
case kHIDUsage_GD_Rx:
|
||||
case kHIDUsage_GD_Ry:
|
||||
case kHIDUsage_GD_Rz:
|
||||
case kHIDUsage_GD_Slider: // for throttle / trim controls
|
||||
case kHIDUsage_GD_Dial:
|
||||
//printf(" axis\n");
|
||||
/*joy->os->*/addAxisElement(joy, (CFDictionaryRef) element);
|
||||
break;
|
||||
|
||||
case kHIDUsage_GD_Hatswitch:
|
||||
//printf(" hat\n");
|
||||
/*joy->os->*/addHatElement(joy, (CFDictionaryRef) element);
|
||||
break;
|
||||
|
||||
default:
|
||||
SG_LOG(SG_INPUT, SG_WARN, "input type element has weird usage:" << usage);
|
||||
break;
|
||||
}
|
||||
} else if (page == kHIDPage_Simulation) {
|
||||
switch (usage) /* look at usage to determine function */
|
||||
{
|
||||
case kHIDUsage_Sim_Rudder:
|
||||
case kHIDUsage_Sim_Throttle:
|
||||
//printf(" axis\n");
|
||||
/*joy->os->*/addAxisElement(joy, (CFDictionaryRef) element);
|
||||
break;
|
||||
default:
|
||||
SG_LOG(SG_INPUT, SG_WARN, "Simulation page input type element has weird usage:" << usage);
|
||||
}
|
||||
} else if (page == kHIDPage_Button) {
|
||||
//printf(" button\n");
|
||||
/*joy->os->*/addButtonElement(joy, (CFDictionaryRef) element);
|
||||
} else if (page == kHIDPage_PID) {
|
||||
SG_LOG(SG_INPUT, SG_WARN, "Force feedback and related data ignored");
|
||||
} else
|
||||
SG_LOG(SG_INPUT, SG_WARN, "input type element has weird usage:" << usage);
|
||||
break;
|
||||
|
||||
case kIOHIDElementTypeCollection:
|
||||
/*joy->os->*/enumerateElements(joy,
|
||||
CFDictionaryGetValue(element, CFSTR(kIOHIDElementKey))
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void os_specific_s::addAxisElement(jsJoystick* joy, CFDictionaryRef axis)
|
||||
{
|
||||
long cookie, lmin, lmax;
|
||||
CFNumberGetValue ((CFNumberRef)
|
||||
CFDictionaryGetValue (axis, CFSTR(kIOHIDElementCookieKey)),
|
||||
kCFNumberLongType, &cookie);
|
||||
|
||||
int index = joy->num_axes++;
|
||||
|
||||
/*joy->os->*/axisCookies[index] = (IOHIDElementCookie) cookie;
|
||||
|
||||
CFNumberGetValue ((CFNumberRef)
|
||||
CFDictionaryGetValue (axis, CFSTR(kIOHIDElementMinKey)),
|
||||
kCFNumberLongType, &lmin);
|
||||
|
||||
CFNumberGetValue ((CFNumberRef)
|
||||
CFDictionaryGetValue (axis, CFSTR(kIOHIDElementMaxKey)),
|
||||
kCFNumberLongType, &lmax);
|
||||
|
||||
joy->min[index] = lmin;
|
||||
joy->max[index] = lmax;
|
||||
joy->dead_band[index] = 0.0;
|
||||
joy->saturate[index] = 1.0;
|
||||
joy->center[index] = (lmax - lmin) * 0.5 + lmin;
|
||||
}
|
||||
|
||||
void os_specific_s::addButtonElement(jsJoystick* joy, CFDictionaryRef button)
|
||||
{
|
||||
long cookie;
|
||||
CFNumberGetValue ((CFNumberRef)
|
||||
CFDictionaryGetValue (button, CFSTR(kIOHIDElementCookieKey)),
|
||||
kCFNumberLongType, &cookie);
|
||||
|
||||
/*joy->os->*/buttonCookies[joy->num_buttons++] = (IOHIDElementCookie) cookie;
|
||||
// anything else for buttons?
|
||||
}
|
||||
|
||||
void os_specific_s::addHatElement(jsJoystick* joy, CFDictionaryRef hat)
|
||||
{
|
||||
long cookie, lmin, lmax;
|
||||
CFNumberGetValue ((CFNumberRef)
|
||||
CFDictionaryGetValue (hat, CFSTR(kIOHIDElementCookieKey)),
|
||||
kCFNumberLongType, &cookie);
|
||||
|
||||
int index = /*joy->*/num_hats++;
|
||||
|
||||
/*joy->os->*/hatCookies[index] = (IOHIDElementCookie) cookie;
|
||||
|
||||
CFNumberGetValue ((CFNumberRef)
|
||||
CFDictionaryGetValue (hat, CFSTR(kIOHIDElementMinKey)),
|
||||
kCFNumberLongType, &lmin);
|
||||
|
||||
CFNumberGetValue ((CFNumberRef)
|
||||
CFDictionaryGetValue (hat, CFSTR(kIOHIDElementMaxKey)),
|
||||
kCFNumberLongType, &lmax);
|
||||
|
||||
hat_min[index] = lmin;
|
||||
hat_max[index] = lmax;
|
||||
// do we map hats to axes or buttons?
|
||||
// axes; there is room for that: Buttons are limited to 32.
|
||||
// (a joystick with 2 hats will use 16 buttons!)
|
||||
}
|
||||
|
||||
void jsJoystick::rawRead(int *buttons, float *axes)
|
||||
{
|
||||
if (buttons)
|
||||
*buttons = 0;
|
||||
|
||||
IOHIDEventStruct hidEvent;
|
||||
|
||||
for (int b=0; b<num_buttons; ++b) {
|
||||
(*(os->hidDev))->getElementValue(os->hidDev, os->buttonCookies[b], &hidEvent);
|
||||
if (hidEvent.value && buttons)
|
||||
*buttons |= 1 << b;
|
||||
}
|
||||
|
||||
// real axes:
|
||||
int real_num_axes = num_axes - 2*os->num_hats;
|
||||
for (int a=0; a<real_num_axes; ++a) {
|
||||
(*(os->hidDev))->getElementValue(os->hidDev, os->axisCookies[a], &hidEvent);
|
||||
axes[a] = hidEvent.value;
|
||||
}
|
||||
|
||||
// hats:
|
||||
for (int h=0; h < os->num_hats; ++h) {
|
||||
(*(os->hidDev))->getElementValue(os->hidDev, os->hatCookies[h], &hidEvent);
|
||||
long result = ( hidEvent.value - os->hat_min[h] ) * 8;
|
||||
result /= ( os->hat_max[h] - os->hat_min[h] + 1 );
|
||||
if ( (result>=0) && (result<8) )
|
||||
{
|
||||
axes[h+real_num_axes+1] = NS_hat[result];
|
||||
axes[h+real_num_axes] = WE_hat[result];
|
||||
}
|
||||
else
|
||||
{
|
||||
axes[h+real_num_axes] = 0;
|
||||
axes[h+real_num_axes+1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
54
3rdparty/joystick/jsNone.cxx
vendored
Normal file
54
3rdparty/joystick/jsNone.cxx
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Copyright (C) 1998,2002 Steve Baker
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: jsNone.cxx 1960 2004-09-21 11:45:55Z smokydiamond $
|
||||
*/
|
||||
|
||||
#include "js.h"
|
||||
|
||||
struct os_specific_s ;
|
||||
|
||||
|
||||
void jsJoystick::open ()
|
||||
{
|
||||
error = TRUE ;
|
||||
num_axes = num_buttons = 0 ;
|
||||
}
|
||||
|
||||
|
||||
void jsJoystick::close ()
|
||||
{
|
||||
error = TRUE ;
|
||||
}
|
||||
|
||||
|
||||
jsJoystick::jsJoystick ( int ident )
|
||||
{
|
||||
error = TRUE ;
|
||||
num_axes = num_buttons = 0 ;
|
||||
os = NULL;
|
||||
}
|
||||
|
||||
|
||||
void jsJoystick::rawRead ( int *buttons, float *axes )
|
||||
{
|
||||
if ( buttons != NULL ) *buttons = 0 ;
|
||||
}
|
||||
|
||||
void jsInit () {}
|
274
3rdparty/joystick/jsWindows.cxx
vendored
Normal file
274
3rdparty/joystick/jsWindows.cxx
vendored
Normal file
|
@ -0,0 +1,274 @@
|
|||
/*
|
||||
PLIB - A Suite of Portable Game Libraries
|
||||
Copyright (C) 1998,2002 Steve Baker
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: jsWindows.cxx 2164 2011-01-22 22:47:30Z fayjf $
|
||||
*/
|
||||
|
||||
#include "js.h"
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <RegStr.h> // for REGSTR_PATH_JOYCONFIG, etc
|
||||
|
||||
#define _JS_MAX_AXES_WIN 8 /* X,Y,Z,R,U,V,POV_X,POV_Y */
|
||||
|
||||
struct os_specific_s {
|
||||
JOYCAPS jsCaps ;
|
||||
JOYINFOEX js ;
|
||||
UINT js_id ;
|
||||
static bool getOEMProductName ( jsJoystick* joy, char *buf, int buf_sz ) ;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Inspired by
|
||||
// http://msdn.microsoft.com/archive/en-us/dnargame/html/msdn_sidewind3d.asp
|
||||
|
||||
bool os_specific_s::getOEMProductName ( jsJoystick* joy, char *buf, int buf_sz )
|
||||
{
|
||||
if ( joy->error ) return false ;
|
||||
|
||||
union
|
||||
{
|
||||
char key [ 256 ] ;
|
||||
char value [ 256 ] ;
|
||||
} ;
|
||||
char OEMKey [ 256 ] ;
|
||||
|
||||
HKEY hKey ;
|
||||
DWORD dwcb ;
|
||||
LONG lr ;
|
||||
int hkcu = 0;
|
||||
|
||||
// Open .. MediaResources\CurrentJoystickSettings
|
||||
sprintf ( key, "%s\\%s\\%s",
|
||||
REGSTR_PATH_JOYCONFIG, joy->os->jsCaps.szRegKey,
|
||||
REGSTR_KEY_JOYCURR ) ;
|
||||
|
||||
lr = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, key, 0, KEY_QUERY_VALUE, &hKey) ;
|
||||
|
||||
if ( lr != ERROR_SUCCESS )
|
||||
{
|
||||
hkcu = 1;
|
||||
// XP/Vista/7 seem to have moved it to "current user"
|
||||
lr = RegOpenKeyEx ( HKEY_CURRENT_USER, key, 0, KEY_QUERY_VALUE, &hKey) ;
|
||||
if ( lr != ERROR_SUCCESS ) return false ;
|
||||
}
|
||||
|
||||
// Get OEM Key name
|
||||
dwcb = sizeof(OEMKey) ;
|
||||
|
||||
// JOYSTICKID1-16 is zero-based; registry entries for VJOYD are 1-based.
|
||||
sprintf ( value, "Joystick%d%s", joy->os->js_id + 1, REGSTR_VAL_JOYOEMNAME ) ;
|
||||
|
||||
lr = RegQueryValueEx ( hKey, value, 0, 0, (LPBYTE) OEMKey, &dwcb);
|
||||
RegCloseKey ( hKey ) ;
|
||||
|
||||
if ( lr != ERROR_SUCCESS ) return false ;
|
||||
|
||||
// Open OEM Key from ...MediaProperties
|
||||
sprintf ( key, "%s\\%s", REGSTR_PATH_JOYOEM, OEMKey ) ;
|
||||
|
||||
if (!hkcu)
|
||||
lr = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, key, 0, KEY_QUERY_VALUE, &hKey) ;
|
||||
else
|
||||
lr = RegOpenKeyEx ( HKEY_CURRENT_USER, key, 0, KEY_QUERY_VALUE, &hKey) ;
|
||||
if ( lr != ERROR_SUCCESS )
|
||||
{
|
||||
return false ;
|
||||
}
|
||||
|
||||
// Get OEM Name
|
||||
dwcb = buf_sz ;
|
||||
|
||||
lr = RegQueryValueEx ( hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, (LPBYTE) buf,
|
||||
&dwcb ) ;
|
||||
RegCloseKey ( hKey ) ;
|
||||
|
||||
if ( lr != ERROR_SUCCESS ) return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
void jsJoystick::open ()
|
||||
{
|
||||
name [0] = '\0' ;
|
||||
|
||||
os->js . dwFlags = JOY_RETURNALL ;
|
||||
os->js . dwSize = sizeof ( os->js ) ;
|
||||
|
||||
memset ( &(os->jsCaps), 0, sizeof(os->jsCaps) ) ;
|
||||
|
||||
error = ( joyGetDevCaps( os->js_id, &(os->jsCaps), sizeof(os->jsCaps) )
|
||||
!= JOYERR_NOERROR ) ;
|
||||
num_buttons = os->jsCaps.wNumButtons ;
|
||||
if ( os->jsCaps.wNumAxes == 0 )
|
||||
{
|
||||
num_axes = 0 ;
|
||||
setError () ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Device name from jsCaps is often "Microsoft PC-joystick driver",
|
||||
// at least for USB. Try to get the real name from the registry.
|
||||
if ( ! os->getOEMProductName ( this, name, sizeof(name) ) )
|
||||
{
|
||||
jsSetError ( SG_WARN,
|
||||
"JS: Failed to read joystick name from registry" ) ;
|
||||
|
||||
strncpy ( name, os->jsCaps.szPname, sizeof(name) ) ;
|
||||
}
|
||||
|
||||
// Windows joystick drivers may provide any combination of
|
||||
// X,Y,Z,R,U,V,POV - not necessarily the first n of these.
|
||||
if ( os->jsCaps.wCaps & JOYCAPS_HASPOV )
|
||||
{
|
||||
num_axes = _JS_MAX_AXES_WIN ;
|
||||
min [ 7 ] = -1.0 ; max [ 7 ] = 1.0 ; // POV Y
|
||||
min [ 6 ] = -1.0 ; max [ 6 ] = 1.0 ; // POV X
|
||||
}
|
||||
else
|
||||
num_axes = 6 ;
|
||||
|
||||
min [ 5 ] = (float) os->jsCaps.wVmin ; max [ 5 ] = (float) os->jsCaps.wVmax ;
|
||||
min [ 4 ] = (float) os->jsCaps.wUmin ; max [ 4 ] = (float) os->jsCaps.wUmax ;
|
||||
min [ 3 ] = (float) os->jsCaps.wRmin ; max [ 3 ] = (float) os->jsCaps.wRmax ;
|
||||
min [ 2 ] = (float) os->jsCaps.wZmin ; max [ 2 ] = (float) os->jsCaps.wZmax ;
|
||||
min [ 1 ] = (float) os->jsCaps.wYmin ; max [ 1 ] = (float) os->jsCaps.wYmax ;
|
||||
min [ 0 ] = (float) os->jsCaps.wXmin ; max [ 0 ] = (float) os->jsCaps.wXmax ;
|
||||
}
|
||||
|
||||
for ( int i = 0 ; i < num_axes ; i++ )
|
||||
{
|
||||
center [ i ] = ( max[i] + min[i] ) / 2.0f ;
|
||||
dead_band [ i ] = 0.0f ;
|
||||
saturate [ i ] = 1.0f ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void jsJoystick::close ()
|
||||
{
|
||||
delete os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
jsJoystick::jsJoystick ( int ident )
|
||||
{
|
||||
id = ident ;
|
||||
os = new struct os_specific_s;
|
||||
|
||||
if (ident >= 0 && ident < (int)joyGetNumDevs()) {
|
||||
os->js_id = JOYSTICKID1 + ident;
|
||||
open();
|
||||
}
|
||||
else {
|
||||
num_axes = 0;
|
||||
setError();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void jsJoystick::rawRead ( int *buttons, float *axes )
|
||||
{
|
||||
if ( error )
|
||||
{
|
||||
if ( buttons )
|
||||
*buttons = 0 ;
|
||||
|
||||
if ( axes )
|
||||
for ( int i = 0 ; i < num_axes ; i++ )
|
||||
axes[i] = 1500.0f ;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
MMRESULT status = joyGetPosEx ( os->js_id, &(os->js) ) ;
|
||||
|
||||
if ( status != JOYERR_NOERROR )
|
||||
{
|
||||
setError() ;
|
||||
return ;
|
||||
}
|
||||
|
||||
if ( buttons != NULL )
|
||||
*buttons = (int) os->js.dwButtons ;
|
||||
|
||||
if ( axes != NULL )
|
||||
{
|
||||
/* WARNING - Fall through case clauses!! */
|
||||
|
||||
switch ( num_axes )
|
||||
{
|
||||
case 8:
|
||||
// Generate two POV axes from the POV hat angle.
|
||||
// Low 16 bits of js.dwPOV gives heading (clockwise from ahead) in
|
||||
// hundredths of a degree, or 0xFFFF when idle.
|
||||
|
||||
if ( ( os->js.dwPOV & 0xFFFF ) == 0xFFFF )
|
||||
{
|
||||
axes [ 6 ] = 0.0 ;
|
||||
axes [ 7 ] = 0.0 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is the contentious bit: how to convert angle to X/Y.
|
||||
// wk: I know of no define for PI that we could use here:
|
||||
// SG_PI would pull in sg, M_PI is undefined for MSVC
|
||||
// But the accuracy of the value of PI is very unimportant at
|
||||
// this point.
|
||||
|
||||
float s = (float) sin ( ( os->js.dwPOV & 0xFFFF ) * ( 0.01 * 3.1415926535f / 180 ) ) ;
|
||||
float c = (float) cos ( ( os->js.dwPOV & 0xFFFF ) * ( 0.01 * 3.1415926535f / 180 ) ) ;
|
||||
|
||||
// Convert to coordinates on a square so that North-East
|
||||
// is (1,1) not (.7,.7), etc.
|
||||
// s and c cannot both be zero so we won't divide by zero.
|
||||
if ( fabs ( s ) < fabs ( c ) )
|
||||
{
|
||||
axes [ 6 ] = ( c < 0.0 ) ? -s/c : s/c ;
|
||||
axes [ 7 ] = ( c < 0.0 ) ? -1.0f : 1.0f ;
|
||||
}
|
||||
else
|
||||
{
|
||||
axes [ 6 ] = ( s < 0.0 ) ? -1.0f : 1.0f ;
|
||||
axes [ 7 ] = ( s < 0.0 ) ? -c/s : c/s ;
|
||||
}
|
||||
}
|
||||
|
||||
case 6: axes[5] = (float) os->js . dwVpos ;
|
||||
case 5: axes[4] = (float) os->js . dwUpos ;
|
||||
case 4: axes[3] = (float) os->js . dwRpos ;
|
||||
case 3: axes[2] = (float) os->js . dwZpos ;
|
||||
case 2: axes[1] = (float) os->js . dwYpos ;
|
||||
case 1: axes[0] = (float) os->js . dwXpos ;
|
||||
break;
|
||||
|
||||
default:
|
||||
jsSetError ( SG_WARN, "PLIB_JS: Wrong num_axes. Joystick input is now invalid" ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void jsInit() {}
|
|
@ -222,7 +222,10 @@ option(ENABLE_QT "Set to ON to build the internal Qt launcher" ON)
|
|||
option(ENABLE_TRAFFIC "Set to ON to build the external traffic generator modules" ON)
|
||||
option(ENABLE_FGQCANVAS "Set to ON to build the Qt-based remote canvas application" OFF)
|
||||
option(ENABLE_DEMCONVERT "Set to ON to build the dem conversion tool (default)" ON)
|
||||
option(ENABLE_HID_INPUT "Set to ON to build HID-based input code (default)" OFF)
|
||||
option(ENABLE_HID_INPUT "Set to ON to build HID-based input code" OFF)
|
||||
option(ENABLE_PLIB_JOYSTICK "Set to ON to enable legacy joystick code (default)" ON)
|
||||
|
||||
|
||||
|
||||
# Test-suite options.
|
||||
option(ENABLE_AUTOTESTING "Set to ON to execute the test suite after building the test_suite target (default)" ON)
|
||||
|
@ -281,12 +284,6 @@ if(EVENT_INPUT)
|
|||
message(STATUS "Enabling HID-API input")
|
||||
list(APPEND EVENT_INPUT_LIBRARIES hidapi)
|
||||
endif()
|
||||
|
||||
# Keep PLIB INPUT enabled as long as EventInput does not replace current joystick configurations.
|
||||
set(ENABLE_PLIB_JOYSTICK 1)
|
||||
else(EVENT_INPUT)
|
||||
message(STATUS "Event-based input disabled by config")
|
||||
set(ENABLE_PLIB_JOYSTICK 1)
|
||||
endif(EVENT_INPUT)
|
||||
|
||||
# check required dependencies
|
||||
|
@ -404,7 +401,7 @@ else()
|
|||
endif (ENABLE_QT)
|
||||
##############################################################################
|
||||
|
||||
find_package(PLIB REQUIRED puaux pu js fnt)
|
||||
find_package(PLIB REQUIRED puaux pu fnt)
|
||||
|
||||
# FlightGear and SimGear versions need to match major + minor
|
||||
# split version string into components, note CMAKE_MATCH_0 is the entire regexp match
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Locate PLIB
|
||||
# This module defines
|
||||
# PLIB_LIBRARIES
|
||||
# PLIB_FOUND, if false, do not try to link to PLIB
|
||||
# PLIB_FOUND, if false, do not try to link to PLIB
|
||||
# PLIB_INCLUDE_DIR, where to find the headers
|
||||
#
|
||||
# $PLIBDIR is an environment variable that would
|
||||
|
@ -28,14 +28,14 @@ include(SelectLibraryConfigurations)
|
|||
set(save_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK})
|
||||
set(CMAKE_FIND_FRAMEWORK ONLY)
|
||||
FIND_PATH(PLIB_INCLUDE_DIR ul.h
|
||||
PATH_SUFFIXES include/plib include
|
||||
PATH_SUFFIXES include/plib include
|
||||
PATHS ${ADDITIONAL_LIBRARY_PATHS}
|
||||
)
|
||||
set(CMAKE_FIND_FRAMEWORK ${save_FIND_FRAMEWORK})
|
||||
|
||||
if(NOT PLIB_INCLUDE_DIR)
|
||||
FIND_PATH(PLIB_INCLUDE_DIR plib/ul.h
|
||||
PATH_SUFFIXES include
|
||||
PATH_SUFFIXES include
|
||||
HINTS $ENV{PLIBDIR}
|
||||
PATHS ${ADDITIONAL_LIBRARY_PATHS}
|
||||
)
|
||||
|
@ -51,7 +51,7 @@ FIND_LIBRARY(PLIB_LIBRARIES
|
|||
PATHS ${ADDITIONAL_LIBRARY_PATHS}
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
if (MSVC)
|
||||
set (PUNAME "pui")
|
||||
else (MSVC)
|
||||
set (PUNAME "pu")
|
||||
|
@ -65,7 +65,7 @@ macro(find_static_component comp libs)
|
|||
else(MSVC)
|
||||
set(compLib "plib${comp}")
|
||||
endif(MSVC)
|
||||
|
||||
|
||||
string(TOUPPER "PLIB_${comp}" compLibBase)
|
||||
set( compLibName ${compLibBase}_LIBRARY )
|
||||
|
||||
|
@ -97,13 +97,13 @@ macro(find_static_component comp libs)
|
|||
endif()
|
||||
endmacro()
|
||||
|
||||
if(${PLIB_LIBRARIES} STREQUAL "PLIB_LIBRARIES-NOTFOUND")
|
||||
if(${PLIB_LIBRARIES} STREQUAL "PLIB_LIBRARIES-NOTFOUND")
|
||||
set(PLIB_LIBRARIES "") # clear value
|
||||
|
||||
|
||||
# based on the contents of deps, add other required PLIB
|
||||
# static library dependencies. Eg PUI requires FNT
|
||||
set(outDeps ${PLIB_FIND_COMPONENTS})
|
||||
|
||||
|
||||
foreach(c ${PLIB_FIND_COMPONENTS})
|
||||
if (${c} STREQUAL "pu")
|
||||
# handle MSVC confusion over pu/pui naming, by removing
|
||||
|
@ -116,7 +116,7 @@ if(${PLIB_LIBRARIES} STREQUAL "PLIB_LIBRARIES-NOTFOUND")
|
|||
list(APPEND outDeps "sg")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
||||
list(APPEND outDeps "ul") # everything needs ul
|
||||
list(REMOVE_DUPLICATES outDeps) # clean up
|
||||
|
||||
|
@ -127,30 +127,5 @@ if(${PLIB_LIBRARIES} STREQUAL "PLIB_LIBRARIES-NOTFOUND")
|
|||
endforeach()
|
||||
endif()
|
||||
|
||||
list(FIND outDeps "js" haveJs)
|
||||
if(${haveJs} GREATER -1)
|
||||
message(STATUS "adding runtime JS dependencies")
|
||||
if(APPLE)
|
||||
# resolve frameworks to full paths
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
find_library(CF_LIBRARY CoreFoundation)
|
||||
set(JS_LIBS ${IOKIT_LIBRARY} ${CF_LIBRARY})
|
||||
elseif(WIN32)
|
||||
set(WINMM_LIBRARY winmm)
|
||||
set(JS_LIBS ${WINMM_LIBRARY})
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
# anything needed here?
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
find_library(USBHID_LIBRARY usbhid)
|
||||
# check_function_exists(hidinit)
|
||||
set(JS_LIBS ${USBHID_LIBRARY})
|
||||
else()
|
||||
message(WARNING "Unsupported platform for PLIB JS libs")
|
||||
endif()
|
||||
|
||||
list(APPEND PLIB_LIBRARIES ${JS_LIBS})
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PLIB DEFAULT_MSG PLIB_LIBRARIES PLIB_INCLUDE_DIR)
|
||||
|
||||
|
|
|
@ -56,6 +56,9 @@ function(setup_fgfs_libraries target)
|
|||
${SIMGEAR_LIBRARIES}
|
||||
)
|
||||
|
||||
if (ENABLE_PLIB_JOYSTICK)
|
||||
target_link_libraries(${target} PLIBJoystick)
|
||||
endif()
|
||||
|
||||
if(ENABLE_FLITE)
|
||||
if(SYSTEM_HTS_ENGINE)
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
|
||||
#cmakedefine ENABLE_FLITE
|
||||
#cmakedefine ENABLE_HID_INPUT
|
||||
#cmakedefine ENABLE_PLIB_JOYSTICK
|
||||
|
||||
#cmakedefine HAVE_QT
|
||||
|
||||
|
|
|
@ -15,13 +15,11 @@ if (ENABLE_HID_INPUT)
|
|||
list(APPEND EVENT_INPUT_HEADERS FGHIDEventInput.hxx)
|
||||
endif()
|
||||
|
||||
|
||||
set(SOURCES
|
||||
FGButton.cxx
|
||||
FGCommonInput.cxx
|
||||
FGDeviceConfigurationMap.cxx
|
||||
FGEventInput.cxx
|
||||
FGJoystickInput.cxx
|
||||
FGKeyboardInput.cxx
|
||||
FGMouseInput.cxx
|
||||
input.cxx
|
||||
|
@ -32,19 +30,23 @@ set(HEADERS
|
|||
FGCommonInput.hxx
|
||||
FGDeviceConfigurationMap.hxx
|
||||
FGEventInput.hxx
|
||||
FGJoystickInput.hxx
|
||||
FGKeyboardInput.hxx
|
||||
FGMouseInput.hxx
|
||||
input.hxx
|
||||
)
|
||||
|
||||
if (ENABLE_PLIB_JOYSTICK)
|
||||
list(APPEND SOURCES FGJoystickInput.cxx)
|
||||
list(APPEND HEADERS FGJoystickInput.hxx)
|
||||
endif()
|
||||
|
||||
if(EVENT_INPUT)
|
||||
list(APPEND SOURCES ${EVENT_INPUT_SOURCES})
|
||||
list(APPEND SOURCES ${EVENT_INPUT_HEADERS})
|
||||
list(APPEND HEADERS ${EVENT_INPUT_HEADERS})
|
||||
include_directories(${UDEV_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if(ENABLE_FGJS)
|
||||
if(ENABLE_FGJS AND ENABLE_PLIB_JOYSTICK)
|
||||
set(FGJS_SOURCES
|
||||
fgjs.cxx
|
||||
jsinput.cxx
|
||||
|
@ -53,18 +55,18 @@ if(ENABLE_FGJS)
|
|||
|
||||
add_executable(fgjs ${FGJS_SOURCES})
|
||||
target_link_libraries(fgjs
|
||||
SimGearCore
|
||||
${PLIB_LIBRARIES}
|
||||
SimGearCore
|
||||
PLIBJoystick
|
||||
)
|
||||
|
||||
install(TARGETS fgjs RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
endif()
|
||||
|
||||
if(ENABLE_JS_DEMO)
|
||||
if(ENABLE_JS_DEMO AND ENABLE_PLIB_JOYSTICK)
|
||||
add_executable(js_demo js_demo.cxx)
|
||||
target_link_libraries(js_demo
|
||||
SimGearCore
|
||||
${PLIB_LIBRARIES}
|
||||
PLIBJoystick
|
||||
)
|
||||
|
||||
install(TARGETS js_demo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
|
|
@ -31,7 +31,10 @@
|
|||
#include <Main/fg_props.hxx>
|
||||
#include "FGMouseInput.hxx"
|
||||
#include "FGKeyboardInput.hxx"
|
||||
|
||||
#if defined(ENABLE_PLIB_JOYSTICK)
|
||||
#include "FGJoystickInput.hxx"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_EVENTINPUT
|
||||
#if defined( SG_WINDOWS )
|
||||
|
@ -71,11 +74,14 @@ FGInput::FGInput ()
|
|||
set_subsystem( "input-keyboard", new FGKeyboardInput() );
|
||||
}
|
||||
|
||||
#if defined(ENABLE_PLIB_JOYSTICK)
|
||||
if( fgGetBool("/sim/input/no-joystick-input",false) ) {
|
||||
SG_LOG(SG_INPUT,SG_ALERT,"Joystick input disabled!");
|
||||
} else {
|
||||
set_subsystem( "input-joystick", new FGJoystickInput() );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INPUTEVENT_CLASS
|
||||
if( fgGetBool("/sim/input/no-event-input",false) ) {
|
||||
SG_LOG(SG_INPUT,SG_ALERT,"Event input disabled!");
|
||||
|
|
|
@ -28,6 +28,8 @@ using std::endl;
|
|||
|
||||
#include "jsinput.h"
|
||||
|
||||
#include <simgear/timing/timestamp.hxx>
|
||||
|
||||
jsInput::jsInput(jsSuper *j) {
|
||||
jss=j;
|
||||
pretty_display=true;
|
||||
|
@ -109,7 +111,7 @@ int jsInput::getInput() {
|
|||
fflush ( stdout ) ;
|
||||
}
|
||||
|
||||
ulMilliSecondSleep(1);
|
||||
SGTimeStamp::sleepForMSec(1);
|
||||
}
|
||||
if(button_bits != 0) {
|
||||
for(int i=0;i<=31;i++) {
|
||||
|
@ -138,12 +140,12 @@ void jsInput::findDeadBand() {
|
|||
}
|
||||
} while( jss->nextJoystick() );
|
||||
|
||||
ulClock clock;
|
||||
SGTimeStamp clock = SGTimeStamp::now();
|
||||
cout << 10;
|
||||
cout.flush();
|
||||
|
||||
for (int j = 9; j >= 0; j--) {
|
||||
double start_time = clock.getAbsTime();
|
||||
clock.stamp();
|
||||
do {
|
||||
jss->firstJoystick();
|
||||
do {
|
||||
|
@ -159,9 +161,8 @@ void jsInput::findDeadBand() {
|
|||
|
||||
} while( jss->nextJoystick());
|
||||
|
||||
ulMilliSecondSleep(1);
|
||||
clock.update();
|
||||
} while (clock.getAbsTime() - start_time < 1.0);
|
||||
SGTimeStamp::sleepForMSec(1);
|
||||
} while (clock.elapsedMSec() < 1000);
|
||||
|
||||
cout << " - " << j;
|
||||
cout.flush();
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#ifndef _JSINPUT_H
|
||||
#define _JSINPUT_H
|
||||
|
||||
#include <cmath> // for fabs
|
||||
|
||||
#include "jssuper.h"
|
||||
|
||||
class jsInput {
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h> // plib/js.h should really include this !!!!!!
|
||||
#include <plib/js.h>
|
||||
#include "js.h"
|
||||
|
||||
#define MAX_JOYSTICKS 8
|
||||
|
||||
|
@ -37,28 +36,28 @@ class jsSuper {
|
|||
int currentJoystick;
|
||||
int first, last;
|
||||
jsJoystick* js[MAX_JOYSTICKS];
|
||||
|
||||
public:
|
||||
|
||||
public:
|
||||
jsSuper(void);
|
||||
~jsSuper(void);
|
||||
|
||||
|
||||
inline int getNumJoysticks(void) { return activeJoysticks; }
|
||||
|
||||
|
||||
inline int atFirst(void) { return currentJoystick == first; }
|
||||
inline int atLast(void) { return currentJoystick == last; }
|
||||
|
||||
|
||||
inline void firstJoystick(void) { currentJoystick=first; }
|
||||
inline void lastJoystick(void) { currentJoystick=last; }
|
||||
|
||||
int nextJoystick(void);
|
||||
int prevJoystick(void);
|
||||
|
||||
inline jsJoystick* getJoystick(int Joystick)
|
||||
inline jsJoystick* getJoystick(int Joystick)
|
||||
{ currentJoystick=Joystick; return js[Joystick]; }
|
||||
|
||||
inline jsJoystick* getJoystick(void) { return js[currentJoystick]; }
|
||||
|
||||
|
||||
inline int getCurrentJoystickId(void) { return currentJoystick; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue