mirror of
https://github.com/glfw/glfw.git
synced 2024-11-10 00:51:47 +00:00
New joystick API.
This commit is contained in:
parent
c4d856bcb2
commit
7f2eb7b15b
@ -530,10 +530,6 @@ extern "C" {
|
||||
#define GLFW_CURSOR_HIDDEN 0x00040002
|
||||
#define GLFW_CURSOR_CAPTURED 0x00040003
|
||||
|
||||
#define GLFW_PRESENT 0x00050001
|
||||
#define GLFW_AXES 0x00050002
|
||||
#define GLFW_BUTTONS 0x00050003
|
||||
|
||||
#define GLFW_GAMMA_RAMP_SIZE 256
|
||||
|
||||
#define GLFW_CONNECTED 0x00061000
|
||||
@ -1930,37 +1926,31 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cb
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI int glfwGetJoystickParam(int joy, int param);
|
||||
GLFWAPI int glfwJoystickPresent(int joy);
|
||||
|
||||
/*! @brief Returns the values of axes of the specified joystick.
|
||||
*
|
||||
* This function returns the current positions of axes of the specified
|
||||
* joystick.
|
||||
*
|
||||
/*! @brief Returns the values of all axes of the specified joystick.
|
||||
* @param[in] joy The joystick to query.
|
||||
* @param[out] axes The array to hold the values.
|
||||
* @param[in] numaxes The size of the provided array.
|
||||
* @return The number of values written to `axes`, or zero if an error
|
||||
* occurred.
|
||||
* @param[out] count The size of the returned array.
|
||||
* @return An array of axis values, or @c NULL if the joystick is not present.
|
||||
*
|
||||
* @note The returned array is valid only until the next call to @ref
|
||||
* glfwGetJoystickAxes for that joystick.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI int glfwGetJoystickAxes(int joy, float* axes, int numaxes);
|
||||
GLFWAPI float* glfwGetJoystickAxes(int joy, int* count);
|
||||
|
||||
/*! @brief Returns the values of buttons of the specified joystick.
|
||||
*
|
||||
* This function returns the current state of buttons of the specified
|
||||
* joystick.
|
||||
*
|
||||
/*! @brief Returns the values of all buttons of the specified joystick.
|
||||
* @param[in] joy The joystick to query.
|
||||
* @param[out] buttons The array to hold the values.
|
||||
* @param[in] numbuttons The size of the provided array.
|
||||
* @return The number of values written to `buttons`, or zero if an error
|
||||
* occurred.
|
||||
* @param[out] count The size of the returned array.
|
||||
* @return An array of axis values, or @c NULL if the joystick is not present.
|
||||
*
|
||||
* @note The returned array is valid only until the next call to @ref
|
||||
* glfwGetJoystickButtons for that joystick.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI int glfwGetJoystickButtons(int joy, unsigned char* buttons, int numbuttons);
|
||||
GLFWAPI unsigned char* glfwGetJoystickButtons(int joy, int* count);
|
||||
|
||||
/*! @brief Returns the name of the specified joystick.
|
||||
*
|
||||
|
@ -47,8 +47,6 @@ typedef struct
|
||||
{
|
||||
IOHIDElementCookie cookie;
|
||||
|
||||
long value;
|
||||
|
||||
long min;
|
||||
long max;
|
||||
|
||||
@ -63,20 +61,17 @@ static void getElementsCFArrayHandler(const void* value, void* parameter);
|
||||
|
||||
// Adds an element to the specified joystick
|
||||
//
|
||||
static void addJoystickElement(_GLFWjoy* joystick, CFTypeRef refElement)
|
||||
static void addJoystickElement(_GLFWjoy* joystick, CFTypeRef elementRef)
|
||||
{
|
||||
long elementType, usagePage, usage;
|
||||
CFTypeRef refElementType, refUsagePage, refUsage;
|
||||
|
||||
refElementType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementTypeKey));
|
||||
refUsagePage = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementUsagePageKey));
|
||||
refUsage = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementUsageKey));
|
||||
|
||||
CFMutableArrayRef elementsArray = NULL;
|
||||
|
||||
CFNumberGetValue(refElementType, kCFNumberLongType, &elementType);
|
||||
CFNumberGetValue(refUsagePage, kCFNumberLongType, &usagePage);
|
||||
CFNumberGetValue(refUsage, kCFNumberLongType, &usage);
|
||||
CFNumberGetValue(CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementTypeKey)),
|
||||
kCFNumberLongType, &elementType);
|
||||
CFNumberGetValue(CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementUsagePageKey)),
|
||||
kCFNumberLongType, &usagePage);
|
||||
CFNumberGetValue(CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementUsageKey)),
|
||||
kCFNumberLongType, &usage);
|
||||
|
||||
if ((elementType == kIOHIDElementTypeInput_Axis) ||
|
||||
(elementType == kIOHIDElementTypeInput_Button) ||
|
||||
@ -97,12 +92,10 @@ static void addJoystickElement(_GLFWjoy* joystick, CFTypeRef refElement)
|
||||
case kHIDUsage_GD_Slider:
|
||||
case kHIDUsage_GD_Dial:
|
||||
case kHIDUsage_GD_Wheel:
|
||||
joystick->numAxes++;
|
||||
elementsArray = joystick->axes;
|
||||
elementsArray = joystick->axisElements;
|
||||
break;
|
||||
case kHIDUsage_GD_Hatswitch:
|
||||
joystick->numHats++;
|
||||
elementsArray = joystick->hats;
|
||||
elementsArray = joystick->hatElements;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -110,8 +103,7 @@ static void addJoystickElement(_GLFWjoy* joystick, CFTypeRef refElement)
|
||||
}
|
||||
|
||||
case kHIDPage_Button:
|
||||
joystick->numButtons++;
|
||||
elementsArray = joystick->buttons;
|
||||
elementsArray = joystick->buttonElements;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -120,35 +112,33 @@ static void addJoystickElement(_GLFWjoy* joystick, CFTypeRef refElement)
|
||||
if (elementsArray)
|
||||
{
|
||||
long number;
|
||||
CFTypeRef refType;
|
||||
|
||||
CFTypeRef numberRef;
|
||||
_GLFWjoyelement* element = (_GLFWjoyelement*) malloc(sizeof(_GLFWjoyelement));
|
||||
|
||||
CFArrayAppendValue(elementsArray, element);
|
||||
|
||||
refType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementCookieKey));
|
||||
if (refType && CFNumberGetValue(refType, kCFNumberLongType, &number))
|
||||
numberRef = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementCookieKey));
|
||||
if (numberRef && CFNumberGetValue(numberRef, kCFNumberLongType, &number))
|
||||
element->cookie = (IOHIDElementCookie) number;
|
||||
|
||||
refType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementMinKey));
|
||||
if (refType && CFNumberGetValue(refType, kCFNumberLongType, &number))
|
||||
numberRef = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementMinKey));
|
||||
if (numberRef && CFNumberGetValue(numberRef, kCFNumberLongType, &number))
|
||||
element->minReport = element->min = number;
|
||||
|
||||
refType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementMaxKey));
|
||||
if (refType && CFNumberGetValue(refType, kCFNumberLongType, &number))
|
||||
numberRef = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementMaxKey));
|
||||
if (numberRef && CFNumberGetValue(numberRef, kCFNumberLongType, &number))
|
||||
element->maxReport = element->max = number;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CFTypeRef refElementTop = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementKey));
|
||||
if (refElementTop)
|
||||
CFTypeRef array = CFDictionaryGetValue(elementRef, CFSTR(kIOHIDElementKey));
|
||||
if (array)
|
||||
{
|
||||
CFTypeID type = CFGetTypeID (refElementTop);
|
||||
if (type == CFArrayGetTypeID())
|
||||
if (CFGetTypeID(array) == CFArrayGetTypeID())
|
||||
{
|
||||
CFRange range = {0, CFArrayGetCount (refElementTop)};
|
||||
CFArrayApplyFunction(refElementTop, range, getElementsCFArrayHandler, joystick);
|
||||
CFRange range = { 0, CFArrayGetCount(array) };
|
||||
CFArrayApplyFunction(array, range, getElementsCFArrayHandler, joystick);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -195,42 +185,28 @@ static void removeJoystick(_GLFWjoy* joystick)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (joystick->present)
|
||||
{
|
||||
joystick->present = GL_FALSE;
|
||||
if (!joystick->present)
|
||||
return;
|
||||
|
||||
for (i = 0; i < joystick->numAxes; i++)
|
||||
{
|
||||
_GLFWjoyelement* axes =
|
||||
(_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->axes, i);
|
||||
free(axes);
|
||||
}
|
||||
CFArrayRemoveAllValues(joystick->axes);
|
||||
joystick->numAxes = 0;
|
||||
for (i = 0; i < CFArrayGetCount(joystick->axisElements); i++)
|
||||
free((void*) CFArrayGetValueAtIndex(joystick->axisElements, i));
|
||||
CFArrayRemoveAllValues(joystick->axisElements);
|
||||
|
||||
for (i = 0; i < joystick->numButtons; i++)
|
||||
{
|
||||
_GLFWjoyelement* button =
|
||||
(_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->buttons, i);
|
||||
free(button);
|
||||
}
|
||||
CFArrayRemoveAllValues(joystick->buttons);
|
||||
joystick->numButtons = 0;
|
||||
for (i = 0; i < CFArrayGetCount(joystick->buttonElements); i++)
|
||||
free((void*) CFArrayGetValueAtIndex(joystick->buttonElements, i));
|
||||
CFArrayRemoveAllValues(joystick->buttonElements);
|
||||
|
||||
for (i = 0; i < joystick->numHats; i++)
|
||||
{
|
||||
_GLFWjoyelement* hat =
|
||||
(_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->hats, i);
|
||||
free(hat);
|
||||
}
|
||||
CFArrayRemoveAllValues(joystick->hats);
|
||||
joystick->hats = 0;
|
||||
for (i = 0; i < CFArrayGetCount(joystick->hatElements); i++)
|
||||
free((void*) CFArrayGetValueAtIndex(joystick->hatElements, i));
|
||||
CFArrayRemoveAllValues(joystick->hatElements);
|
||||
|
||||
(*(joystick->interface))->close(joystick->interface);
|
||||
(*(joystick->interface))->Release(joystick->interface);
|
||||
free(joystick->axes);
|
||||
free(joystick->buttons);
|
||||
|
||||
joystick->interface = NULL;
|
||||
}
|
||||
(*(joystick->interface))->close(joystick->interface);
|
||||
(*(joystick->interface))->Release(joystick->interface);
|
||||
|
||||
memset(joystick, 0, sizeof(_GLFWjoy));
|
||||
}
|
||||
|
||||
// Callback for user-initiated joystick removal
|
||||
@ -244,34 +220,63 @@ static void removalCallback(void* target, IOReturn result, void* refcon, void* s
|
||||
//
|
||||
static void pollJoystickEvents(void)
|
||||
{
|
||||
int i;
|
||||
CFIndex j;
|
||||
int joy;
|
||||
|
||||
for (i = 0; i < GLFW_JOYSTICK_LAST + 1; i++)
|
||||
for (joy = 0; joy <= GLFW_JOYSTICK_LAST; joy++)
|
||||
{
|
||||
_GLFWjoy* joystick = &_glfw.ns.joysticks[i];
|
||||
CFIndex i;
|
||||
int buttonIndex = 0;
|
||||
_GLFWjoy* joystick = _glfw.ns.joysticks + joy;
|
||||
|
||||
if (joystick->present)
|
||||
if (!joystick->present)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(joystick->buttonElements); i++)
|
||||
{
|
||||
for (j = 0; j < joystick->numButtons; j++)
|
||||
{
|
||||
_GLFWjoyelement* button =
|
||||
(_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->buttons, j);
|
||||
button->value = getElementValue(joystick, button);
|
||||
}
|
||||
_GLFWjoyelement* button =
|
||||
(_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->buttonElements, i);
|
||||
|
||||
for (j = 0; j < joystick->numAxes; j++)
|
||||
{
|
||||
_GLFWjoyelement* axes =
|
||||
(_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->axes, j);
|
||||
axes->value = getElementValue(joystick, axes);
|
||||
}
|
||||
if (getElementValue(joystick, button))
|
||||
joystick->buttons[buttonIndex++] = GLFW_PRESS;
|
||||
else
|
||||
joystick->buttons[buttonIndex++] = GLFW_RELEASE;
|
||||
}
|
||||
|
||||
for (j = 0; j < joystick->numHats; j++)
|
||||
for (i = 0; i < CFArrayGetCount(joystick->axisElements); i++)
|
||||
{
|
||||
_GLFWjoyelement* axis =
|
||||
(_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->axisElements, i);
|
||||
|
||||
long value = getElementValue(joystick, axis);
|
||||
long readScale = axis->maxReport - axis->minReport;
|
||||
|
||||
if (readScale == 0)
|
||||
joystick->axes[i] = value;
|
||||
else
|
||||
joystick->axes[i] = (2.f * (value - axis->minReport) / readScale) - 1.f;
|
||||
|
||||
if (i & 1)
|
||||
joystick->axes[i] = -joystick->axes[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(joystick->hatElements); i++)
|
||||
{
|
||||
_GLFWjoyelement* hat =
|
||||
(_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->hatElements, i);
|
||||
|
||||
// Bit fields of button presses for each direction, including nil
|
||||
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };
|
||||
|
||||
long j, value = getElementValue(joystick, hat);
|
||||
if (value < 0 || value > 8)
|
||||
value = 8;
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
_GLFWjoyelement* hat =
|
||||
(_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick->hats, j);
|
||||
hat->value = getElementValue(joystick, hat);
|
||||
if (directions[value] & (1 << j))
|
||||
joystick->buttons[buttonIndex++] = GLFW_PRESS;
|
||||
else
|
||||
joystick->buttons[buttonIndex++] = GLFW_RELEASE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -286,7 +291,7 @@ static void pollJoystickEvents(void)
|
||||
//
|
||||
void _glfwInitJoysticks(void)
|
||||
{
|
||||
int deviceCounter = 0;
|
||||
int joy = 0;
|
||||
IOReturn result = kIOReturnSuccess;
|
||||
mach_port_t masterPort = 0;
|
||||
io_iterator_t objectIterator = 0;
|
||||
@ -318,7 +323,7 @@ void _glfwInitJoysticks(void)
|
||||
while ((ioHIDDeviceObject = IOIteratorNext(objectIterator)))
|
||||
{
|
||||
kern_return_t result;
|
||||
CFTypeRef refCF = 0;
|
||||
CFTypeRef valueRef = 0;
|
||||
|
||||
IOCFPlugInInterface** ppPlugInInterface = NULL;
|
||||
HRESULT plugInResult = S_OK;
|
||||
@ -327,27 +332,29 @@ void _glfwInitJoysticks(void)
|
||||
long usagePage, usage;
|
||||
|
||||
// Check device type
|
||||
refCF = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,
|
||||
CFSTR(kIOHIDPrimaryUsagePageKey),
|
||||
kCFAllocatorDefault,
|
||||
kNilOptions);
|
||||
if (refCF)
|
||||
valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,
|
||||
CFSTR(kIOHIDPrimaryUsagePageKey),
|
||||
kCFAllocatorDefault,
|
||||
kNilOptions);
|
||||
if (valueRef)
|
||||
{
|
||||
CFNumberGetValue(refCF, kCFNumberLongType, &usagePage);
|
||||
CFNumberGetValue(valueRef, kCFNumberLongType, &usagePage);
|
||||
if (usagePage != kHIDPage_GenericDesktop)
|
||||
{
|
||||
// This device is not relevant to GLFW
|
||||
continue;
|
||||
}
|
||||
|
||||
CFRelease(valueRef);
|
||||
}
|
||||
|
||||
refCF = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,
|
||||
CFSTR(kIOHIDPrimaryUsageKey),
|
||||
kCFAllocatorDefault,
|
||||
kNilOptions);
|
||||
if (refCF)
|
||||
valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,
|
||||
CFSTR(kIOHIDPrimaryUsageKey),
|
||||
kCFAllocatorDefault,
|
||||
kNilOptions);
|
||||
if (valueRef)
|
||||
{
|
||||
CFNumberGetValue(refCF, kCFNumberLongType, &usage);
|
||||
CFNumberGetValue(valueRef, kCFNumberLongType, &usage);
|
||||
|
||||
if ((usage != kHIDUsage_GD_Joystick &&
|
||||
usage != kHIDUsage_GD_GamePad &&
|
||||
@ -356,10 +363,11 @@ void _glfwInitJoysticks(void)
|
||||
// This device is not relevant to GLFW
|
||||
continue;
|
||||
}
|
||||
|
||||
CFRelease(valueRef);
|
||||
}
|
||||
|
||||
_GLFWjoy* joystick = &_glfw.ns.joysticks[deviceCounter];
|
||||
|
||||
_GLFWjoy* joystick = _glfw.ns.joysticks + joy;
|
||||
joystick->present = GL_TRUE;
|
||||
|
||||
result = IOCreatePlugInInterfaceForService(ioHIDDeviceObject,
|
||||
@ -388,42 +396,45 @@ void _glfwInitJoysticks(void)
|
||||
joystick);
|
||||
|
||||
// Get product string
|
||||
refCF = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,
|
||||
CFSTR(kIOHIDProductKey),
|
||||
kCFAllocatorDefault,
|
||||
kNilOptions);
|
||||
if (refCF)
|
||||
valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,
|
||||
CFSTR(kIOHIDProductKey),
|
||||
kCFAllocatorDefault,
|
||||
kNilOptions);
|
||||
if (valueRef)
|
||||
{
|
||||
CFStringGetCString(refCF,
|
||||
CFStringGetCString(valueRef,
|
||||
joystick->name,
|
||||
sizeof(joystick->name),
|
||||
kCFStringEncodingUTF8);
|
||||
CFRelease(valueRef);
|
||||
}
|
||||
|
||||
joystick->numAxes = 0;
|
||||
joystick->numButtons = 0;
|
||||
joystick->numHats = 0;
|
||||
joystick->axes = CFArrayCreateMutable(NULL, 0, NULL);
|
||||
joystick->buttons = CFArrayCreateMutable(NULL, 0, NULL);
|
||||
joystick->hats = CFArrayCreateMutable(NULL, 0, NULL);
|
||||
joystick->axisElements = CFArrayCreateMutable(NULL, 0, NULL);
|
||||
joystick->buttonElements = CFArrayCreateMutable(NULL, 0, NULL);
|
||||
joystick->hatElements = CFArrayCreateMutable(NULL, 0, NULL);
|
||||
|
||||
CFTypeRef refTopElement;
|
||||
|
||||
refTopElement = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,
|
||||
CFSTR(kIOHIDElementKey),
|
||||
kCFAllocatorDefault,
|
||||
kNilOptions);
|
||||
CFTypeID type = CFGetTypeID(refTopElement);
|
||||
if (type == CFArrayGetTypeID())
|
||||
valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,
|
||||
CFSTR(kIOHIDElementKey),
|
||||
kCFAllocatorDefault,
|
||||
kNilOptions);
|
||||
if (CFGetTypeID(valueRef) == CFArrayGetTypeID())
|
||||
{
|
||||
CFRange range = { 0, CFArrayGetCount(refTopElement) };
|
||||
CFArrayApplyFunction(refTopElement,
|
||||
CFRange range = { 0, CFArrayGetCount(valueRef) };
|
||||
CFArrayApplyFunction(valueRef,
|
||||
range,
|
||||
getElementsCFArrayHandler,
|
||||
(void*) joystick);
|
||||
CFRelease(valueRef);
|
||||
}
|
||||
|
||||
deviceCounter++;
|
||||
joystick->axes = (float*) calloc(CFArrayGetCount(joystick->axisElements),
|
||||
sizeof(float));
|
||||
joystick->buttons = (unsigned char*) calloc(CFArrayGetCount(joystick->buttonElements) +
|
||||
CFArrayGetCount(joystick->hatElements) * 4, 1);
|
||||
|
||||
joy++;
|
||||
if (joy > GLFW_JOYSTICK_LAST)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -445,118 +456,44 @@ void _glfwTerminateJoysticks(void)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformGetJoystickParam(int joy, int param)
|
||||
int _glfwPlatformJoystickPresent(int joy)
|
||||
{
|
||||
if (!_glfw.ns.joysticks[joy].present)
|
||||
return GL_FALSE;
|
||||
|
||||
switch (param)
|
||||
{
|
||||
case GLFW_PRESENT:
|
||||
return GL_TRUE;
|
||||
|
||||
case GLFW_AXES:
|
||||
return (int) CFArrayGetCount(_glfw.ns.joysticks[joy].axes);
|
||||
|
||||
case GLFW_BUTTONS:
|
||||
return (int) CFArrayGetCount(_glfw.ns.joysticks[joy].buttons) +
|
||||
(int) CFArrayGetCount(_glfw.ns.joysticks[joy].hats) * 4;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
int _glfwPlatformGetJoystickAxes(int joy, float* axes, int numaxes)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST)
|
||||
return 0;
|
||||
|
||||
_GLFWjoy joystick = _glfw.ns.joysticks[joy];
|
||||
|
||||
if (!joystick.present)
|
||||
return 0;
|
||||
|
||||
numaxes = numaxes < joystick.numAxes ? numaxes : joystick.numAxes;
|
||||
|
||||
// Update joystick state
|
||||
pollJoystickEvents();
|
||||
|
||||
for (i = 0; i < numaxes; i++)
|
||||
{
|
||||
_GLFWjoyelement* elements =
|
||||
(_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick.axes, i);
|
||||
|
||||
long readScale = elements->maxReport - elements->minReport;
|
||||
|
||||
if (readScale == 0)
|
||||
axes[i] = elements->value;
|
||||
else
|
||||
axes[i] = (2.0f * (elements->value - elements->minReport) / readScale) - 1.0f;
|
||||
|
||||
if (i & 1)
|
||||
axes[i] = -axes[i];
|
||||
}
|
||||
|
||||
return numaxes;
|
||||
return _glfw.ns.joysticks[joy].present;
|
||||
}
|
||||
|
||||
int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
|
||||
int numbuttons)
|
||||
float* _glfwPlatformGetJoystickAxes(int joy, int* count)
|
||||
{
|
||||
int i, j, button;
|
||||
_GLFWjoy* joystick = _glfw.ns.joysticks + joy;
|
||||
|
||||
if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST)
|
||||
return 0;
|
||||
|
||||
_GLFWjoy joystick = _glfw.ns.joysticks[joy];
|
||||
|
||||
if (!joystick.present)
|
||||
return 0;
|
||||
|
||||
// Update joystick state
|
||||
pollJoystickEvents();
|
||||
|
||||
for (button = 0; button < numbuttons && button < joystick.numButtons; button++)
|
||||
{
|
||||
_GLFWjoyelement* element = (_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick.buttons, button);
|
||||
buttons[button] = element->value ? GLFW_PRESS : GLFW_RELEASE;
|
||||
}
|
||||
if (!joystick->present)
|
||||
return NULL;
|
||||
|
||||
// Virtual buttons - Inject data from hats
|
||||
// Each hat is exposed as 4 buttons which exposes 8 directions with concurrent button presses
|
||||
*count = (int) CFArrayGetCount(joystick->axisElements);
|
||||
return joystick->axes;
|
||||
}
|
||||
|
||||
// Bit fields of button presses for each direction, including nil
|
||||
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };
|
||||
unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)
|
||||
{
|
||||
_GLFWjoy* joystick = _glfw.ns.joysticks + joy;
|
||||
|
||||
for (i = 0; i < joystick.numHats; i++)
|
||||
{
|
||||
_GLFWjoyelement* hat = (_GLFWjoyelement*) CFArrayGetValueAtIndex(joystick.hats, i);
|
||||
pollJoystickEvents();
|
||||
|
||||
int value = hat->value;
|
||||
if (value < 0 || value > 8)
|
||||
value = 8;
|
||||
if (!joystick->present)
|
||||
return NULL;
|
||||
|
||||
for (j = 0; j < 4 && button < numbuttons; j++)
|
||||
{
|
||||
if (directions[value] & (1 << j))
|
||||
buttons[button] = GLFW_PRESS;
|
||||
else
|
||||
buttons[button] = GLFW_RELEASE;
|
||||
|
||||
button++;
|
||||
}
|
||||
}
|
||||
|
||||
return button;
|
||||
*count = (int) CFArrayGetCount(joystick->buttonElements) +
|
||||
(int) CFArrayGetCount(joystick->hatElements) * 4;
|
||||
return joystick->buttons;
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetJoystickName(int joy)
|
||||
{
|
||||
pollJoystickEvents();
|
||||
|
||||
return _glfw.ns.joysticks[joy].name;
|
||||
}
|
||||
|
||||
|
@ -78,18 +78,17 @@ typedef struct _GLFWwindowNS
|
||||
//------------------------------------------------------------------------
|
||||
typedef struct
|
||||
{
|
||||
int present;
|
||||
char name[256];
|
||||
int present;
|
||||
char name[256];
|
||||
|
||||
IOHIDDeviceInterface** interface;
|
||||
|
||||
int numAxes;
|
||||
int numButtons;
|
||||
int numHats;
|
||||
CFMutableArrayRef axisElements;
|
||||
CFMutableArrayRef buttonElements;
|
||||
CFMutableArrayRef hatElements;
|
||||
|
||||
CFMutableArrayRef axes;
|
||||
CFMutableArrayRef buttons;
|
||||
CFMutableArrayRef hats;
|
||||
float* axes;
|
||||
unsigned char* buttons;
|
||||
|
||||
} _GLFWjoy;
|
||||
|
||||
|
@ -407,20 +407,20 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string);
|
||||
*/
|
||||
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window);
|
||||
|
||||
/*! @copydoc glfwGetJoystickParam
|
||||
/*! @copydoc glfwJoystickPresent
|
||||
* @ingroup platform
|
||||
*/
|
||||
int _glfwPlatformGetJoystickParam(int joy, int param);
|
||||
int _glfwPlatformJoystickPresent(int joy);
|
||||
|
||||
/*! @copydoc glfwGetJoystickAxes
|
||||
* @ingroup platform
|
||||
*/
|
||||
int _glfwPlatformGetJoystickAxes(int joy, float* axes, int numaxes);
|
||||
float* _glfwPlatformGetJoystickAxes(int joy, int* count);
|
||||
|
||||
/*! @copydoc glfwGetJoystickButtons
|
||||
* @ingroup platform
|
||||
*/
|
||||
int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons, int numbuttons);
|
||||
unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count);
|
||||
|
||||
/*! @copydoc glfwGetJoystickName
|
||||
* @ingroup platform
|
||||
|
@ -35,7 +35,7 @@
|
||||
////// GLFW public API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWAPI int glfwGetJoystickParam(int joy, int param)
|
||||
GLFWAPI int glfwJoystickPresent(int joy)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||
|
||||
@ -45,59 +45,37 @@ GLFWAPI int glfwGetJoystickParam(int joy, int param)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _glfwPlatformGetJoystickParam(joy, param);
|
||||
return _glfwPlatformJoystickPresent(joy);
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetJoystickAxes(int joy, float* axes, int numaxes)
|
||||
GLFWAPI float* glfwGetJoystickAxes(int joy, int* count)
|
||||
{
|
||||
int i;
|
||||
*count = 0;
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, NULL);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (axes == NULL || numaxes < 0)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Clear positions
|
||||
for (i = 0; i < numaxes; i++)
|
||||
axes[i] = 0.0f;
|
||||
|
||||
return _glfwPlatformGetJoystickAxes(joy, axes, numaxes);
|
||||
return _glfwPlatformGetJoystickAxes(joy, count);
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetJoystickButtons(int joy,
|
||||
unsigned char* buttons,
|
||||
int numbuttons)
|
||||
GLFWAPI unsigned char* glfwGetJoystickButtons(int joy, int* count)
|
||||
{
|
||||
int i;
|
||||
*count = 0;
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, NULL);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (buttons == NULL || numbuttons < 0)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Clear button states
|
||||
for (i = 0; i < numbuttons; i++)
|
||||
buttons[i] = GLFW_RELEASE;
|
||||
|
||||
return _glfwPlatformGetJoystickButtons(joy, buttons, numbuttons);
|
||||
return _glfwPlatformGetJoystickButtons(joy, count);
|
||||
}
|
||||
|
||||
GLFWAPI const char* glfwGetJoystickName(int joy)
|
||||
|
@ -37,23 +37,6 @@
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Return GL_TRUE if joystick is present, otherwise GL_FALSE
|
||||
//
|
||||
static GLboolean isJoystickPresent(int joy)
|
||||
{
|
||||
JOYINFO ji;
|
||||
|
||||
// Is it a valid stick ID (Windows don't support more than 16 sticks)?
|
||||
if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_16)
|
||||
return GL_FALSE;
|
||||
|
||||
// Is the joystick present?
|
||||
if (_glfw_joyGetPos(joy - GLFW_JOYSTICK_1, &ji) != JOYERR_NOERROR)
|
||||
return GL_FALSE;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
// Calculate normalized joystick position
|
||||
//
|
||||
static float calcJoystickPos(DWORD pos, DWORD min, DWORD max)
|
||||
@ -91,107 +74,68 @@ void _glfwTerminateJoysticks(void)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformGetJoystickParam(int joy, int param)
|
||||
int _glfwPlatformJoystickPresent(int joy)
|
||||
{
|
||||
JOYCAPS jc;
|
||||
int hats;
|
||||
JOYINFO ji;
|
||||
|
||||
if (!isJoystickPresent(joy))
|
||||
return 0;
|
||||
if (_glfw_joyGetPos(joy, &ji) != JOYERR_NOERROR)
|
||||
return GL_FALSE;
|
||||
|
||||
// We got this far, the joystick is present
|
||||
if (param == GLFW_PRESENT)
|
||||
return GL_TRUE;
|
||||
|
||||
// Get joystick capabilities
|
||||
_glfw_joyGetDevCaps(joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS));
|
||||
|
||||
hats = (jc.wCaps & JOYCAPS_HASPOV) && (jc.wCaps & JOYCAPS_POV4DIR) ? 1 : 0;
|
||||
|
||||
switch (param)
|
||||
{
|
||||
case GLFW_AXES:
|
||||
// Return number of joystick axes
|
||||
return jc.wNumAxes;
|
||||
|
||||
case GLFW_BUTTONS:
|
||||
// Return number of joystick buttons
|
||||
return jc.wNumButtons + hats * 4;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
int _glfwPlatformGetJoystickAxes(int joy, float* axes, int numaxes)
|
||||
float* _glfwPlatformGetJoystickAxes(int joy, int* count)
|
||||
{
|
||||
JOYCAPS jc;
|
||||
JOYINFOEX ji;
|
||||
int axis;
|
||||
float* axes = _glfw.win32.joystick[joy].axes;
|
||||
|
||||
if (!isJoystickPresent(joy))
|
||||
return 0;
|
||||
if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR)
|
||||
return NULL;
|
||||
|
||||
// Get joystick capabilities
|
||||
_glfw_joyGetDevCaps(joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS));
|
||||
|
||||
// Get joystick state
|
||||
ji.dwSize = sizeof(JOYINFOEX);
|
||||
ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ |
|
||||
JOY_RETURNR | JOY_RETURNU | JOY_RETURNV;
|
||||
_glfw_joyGetPosEx(joy - GLFW_JOYSTICK_1, &ji);
|
||||
if (_glfw_joyGetPosEx(joy, &ji) != JOYERR_NOERROR)
|
||||
return NULL;
|
||||
|
||||
// Get position values for all axes
|
||||
axis = 0;
|
||||
if (axis < numaxes)
|
||||
axes[axis++] = calcJoystickPos(ji.dwXpos, jc.wXmin, jc.wXmax);
|
||||
axes[(*count)++] = calcJoystickPos(ji.dwXpos, jc.wXmin, jc.wXmax);
|
||||
axes[(*count)++] = -calcJoystickPos(ji.dwYpos, jc.wYmin, jc.wYmax);
|
||||
|
||||
if (axis < numaxes)
|
||||
axes[axis++] = -calcJoystickPos(ji.dwYpos, jc.wYmin, jc.wYmax);
|
||||
if (jc.wCaps & JOYCAPS_HASZ)
|
||||
axes[(*count)++] = calcJoystickPos(ji.dwZpos, jc.wZmin, jc.wZmax);
|
||||
|
||||
if (axis < numaxes && jc.wCaps & JOYCAPS_HASZ)
|
||||
axes[axis++] = calcJoystickPos(ji.dwZpos, jc.wZmin, jc.wZmax);
|
||||
if (jc.wCaps & JOYCAPS_HASR)
|
||||
axes[(*count)++] = calcJoystickPos(ji.dwRpos, jc.wRmin, jc.wRmax);
|
||||
|
||||
if (axis < numaxes && jc.wCaps & JOYCAPS_HASR)
|
||||
axes[axis++] = calcJoystickPos(ji.dwRpos, jc.wRmin, jc.wRmax);
|
||||
if (jc.wCaps & JOYCAPS_HASU)
|
||||
axes[(*count)++] = calcJoystickPos(ji.dwUpos, jc.wUmin, jc.wUmax);
|
||||
|
||||
if (axis < numaxes && jc.wCaps & JOYCAPS_HASU)
|
||||
axes[axis++] = calcJoystickPos(ji.dwUpos, jc.wUmin, jc.wUmax);
|
||||
if (jc.wCaps & JOYCAPS_HASV)
|
||||
axes[(*count)++] = -calcJoystickPos(ji.dwVpos, jc.wVmin, jc.wVmax);
|
||||
|
||||
if (axis < numaxes && jc.wCaps & JOYCAPS_HASV)
|
||||
axes[axis++] = -calcJoystickPos(ji.dwVpos, jc.wVmin, jc.wVmax);
|
||||
|
||||
return axis;
|
||||
return axes;
|
||||
}
|
||||
|
||||
int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
|
||||
int numbuttons)
|
||||
unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)
|
||||
{
|
||||
JOYCAPS jc;
|
||||
JOYINFOEX ji;
|
||||
int button, hats;
|
||||
unsigned char* buttons = _glfw.win32.joystick[joy].buttons;
|
||||
|
||||
// Bit fields of button presses for each direction, including nil
|
||||
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };
|
||||
if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR)
|
||||
return NULL;
|
||||
|
||||
if (!isJoystickPresent(joy))
|
||||
return 0;
|
||||
|
||||
// Get joystick capabilities
|
||||
_glfw_joyGetDevCaps(joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS));
|
||||
|
||||
// Get joystick state
|
||||
ji.dwSize = sizeof(JOYINFOEX);
|
||||
ji.dwFlags = JOY_RETURNBUTTONS | JOY_RETURNPOV;
|
||||
_glfw_joyGetPosEx(joy - GLFW_JOYSTICK_1, &ji);
|
||||
if (_glfw_joyGetPosEx(joy, &ji) != JOYERR_NOERROR)
|
||||
return NULL;
|
||||
|
||||
// Get states of all requested buttons
|
||||
for (button = 0; button < numbuttons && button < (int) jc.wNumButtons; button++)
|
||||
while (*count < jc.wNumButtons)
|
||||
{
|
||||
buttons[button] = (unsigned char)
|
||||
(ji.dwButtons & (1UL << button) ? GLFW_PRESS : GLFW_RELEASE);
|
||||
buttons[*count] = (unsigned char)
|
||||
(ji.dwButtons & (1UL << *count) ? GLFW_PRESS : GLFW_RELEASE);
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
// Virtual buttons - Inject data from hats
|
||||
@ -199,42 +143,38 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
|
||||
// concurrent button presses
|
||||
// NOTE: this API exposes only one hat
|
||||
|
||||
hats = (jc.wCaps & JOYCAPS_HASPOV) && (jc.wCaps & JOYCAPS_POV4DIR) ? 1 : 0;
|
||||
|
||||
if (hats > 0)
|
||||
if ((jc.wCaps & JOYCAPS_HASPOV) && (jc.wCaps & JOYCAPS_POV4DIR))
|
||||
{
|
||||
int j, value = ji.dwPOV / 100 / 45;
|
||||
int i, value = ji.dwPOV / 100 / 45;
|
||||
|
||||
// Bit fields of button presses for each direction, including nil
|
||||
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };
|
||||
|
||||
if (value < 0 || value > 8)
|
||||
value = 8;
|
||||
|
||||
for (j = 0; j < 4 && button < numbuttons; j++)
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (directions[value] & (1 << j))
|
||||
buttons[button] = GLFW_PRESS;
|
||||
if (directions[value] & (1 << i))
|
||||
buttons[(*count)++] = GLFW_PRESS;
|
||||
else
|
||||
buttons[button] = GLFW_RELEASE;
|
||||
|
||||
button++;
|
||||
buttons[(*count)++] = GLFW_RELEASE;
|
||||
}
|
||||
}
|
||||
|
||||
return button;
|
||||
return buttons;
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetJoystickName(int joy)
|
||||
{
|
||||
JOYCAPS jc;
|
||||
const int i = joy - GLFW_JOYSTICK_1;
|
||||
|
||||
if (!isJoystickPresent(joy))
|
||||
if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR)
|
||||
return NULL;
|
||||
|
||||
_glfw_joyGetDevCaps(i, &jc, sizeof(JOYCAPS));
|
||||
free(_glfw.win32.joystick[joy].name);
|
||||
_glfw.win32.joystick[joy].name = _glfwCreateUTF8FromWideString(jc.szPname);
|
||||
|
||||
free(_glfw.win32.joystick[i].name);
|
||||
_glfw.win32.joystick[i].name = _glfwCreateUTF8FromWideString(jc.szPname);
|
||||
|
||||
return _glfw.win32.joystick[i].name;
|
||||
return _glfw.win32.joystick[joy].name;
|
||||
}
|
||||
|
||||
|
@ -200,6 +200,8 @@ typedef struct _GLFWlibraryWin32
|
||||
} dwmapi;
|
||||
|
||||
struct {
|
||||
float axes[6];
|
||||
unsigned char buttons[36]; // 32 buttons plus one hat
|
||||
char* name;
|
||||
} joystick[GLFW_JOYSTICK_LAST + 1];
|
||||
|
||||
|
@ -50,7 +50,7 @@
|
||||
static int openJoystickDevice(int joy, const char* path)
|
||||
{
|
||||
#ifdef __linux__
|
||||
char numAxes, numButtons;
|
||||
char axisCount, buttonCount;
|
||||
char name[256];
|
||||
int fd, version;
|
||||
|
||||
@ -74,14 +74,14 @@ static int openJoystickDevice(int joy, const char* path)
|
||||
|
||||
_glfw.x11.joystick[joy].name = strdup(name);
|
||||
|
||||
ioctl(fd, JSIOCGAXES, &numAxes);
|
||||
_glfw.x11.joystick[joy].numAxes = (int) numAxes;
|
||||
ioctl(fd, JSIOCGAXES, &axisCount);
|
||||
_glfw.x11.joystick[joy].axisCount = (int) axisCount;
|
||||
|
||||
ioctl(fd, JSIOCGBUTTONS, &numButtons);
|
||||
_glfw.x11.joystick[joy].numButtons = (int) numButtons;
|
||||
ioctl(fd, JSIOCGBUTTONS, &buttonCount);
|
||||
_glfw.x11.joystick[joy].buttonCount = (int) buttonCount;
|
||||
|
||||
_glfw.x11.joystick[joy].axis = (float*) calloc(numAxes, sizeof(float));
|
||||
_glfw.x11.joystick[joy].button = (unsigned char*) calloc(numButtons, 1);
|
||||
_glfw.x11.joystick[joy].axes = (float*) calloc(axisCount, sizeof(float));
|
||||
_glfw.x11.joystick[joy].buttons = (unsigned char*) calloc(buttonCount, 1);
|
||||
|
||||
_glfw.x11.joystick[joy].present = GL_TRUE;
|
||||
#endif // __linux__
|
||||
@ -110,7 +110,12 @@ static void pollJoystickEvents(void)
|
||||
result = read(_glfw.x11.joystick[i].fd, &e, sizeof(e));
|
||||
|
||||
if (errno == ENODEV)
|
||||
{
|
||||
free(_glfw.x11.joystick[i].axes);
|
||||
free(_glfw.x11.joystick[i].buttons);
|
||||
free(_glfw.x11.joystick[i].name);
|
||||
_glfw.x11.joystick[i].present = GL_FALSE;
|
||||
}
|
||||
|
||||
if (result == -1)
|
||||
break;
|
||||
@ -121,21 +126,21 @@ static void pollJoystickEvents(void)
|
||||
switch (e.type)
|
||||
{
|
||||
case JS_EVENT_AXIS:
|
||||
_glfw.x11.joystick[i].axis[e.number] =
|
||||
_glfw.x11.joystick[i].axes[e.number] =
|
||||
(float) e.value / 32767.0f;
|
||||
|
||||
// We need to change the sign for the Y axes, so that
|
||||
// positive = up/forward, according to the GLFW spec.
|
||||
if (e.number & 1)
|
||||
{
|
||||
_glfw.x11.joystick[i].axis[e.number] =
|
||||
-_glfw.x11.joystick[i].axis[e.number];
|
||||
_glfw.x11.joystick[i].axes[e.number] =
|
||||
-_glfw.x11.joystick[i].axes[e.number];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case JS_EVENT_BUTTON:
|
||||
_glfw.x11.joystick[i].button[e.number] =
|
||||
_glfw.x11.joystick[i].buttons[e.number] =
|
||||
e.value ? GLFW_PRESS : GLFW_RELEASE;
|
||||
break;
|
||||
|
||||
@ -214,8 +219,8 @@ void _glfwTerminateJoysticks(void)
|
||||
if (_glfw.x11.joystick[i].present)
|
||||
{
|
||||
close(_glfw.x11.joystick[i].fd);
|
||||
free(_glfw.x11.joystick[i].axis);
|
||||
free(_glfw.x11.joystick[i].button);
|
||||
free(_glfw.x11.joystick[i].axes);
|
||||
free(_glfw.x11.joystick[i].buttons);
|
||||
free(_glfw.x11.joystick[i].name);
|
||||
|
||||
_glfw.x11.joystick[i].present = GL_FALSE;
|
||||
@ -229,72 +234,38 @@ void _glfwTerminateJoysticks(void)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformGetJoystickParam(int joy, int param)
|
||||
int _glfwPlatformJoystickPresent(int joy)
|
||||
{
|
||||
pollJoystickEvents();
|
||||
|
||||
if (!_glfw.x11.joystick[joy].present)
|
||||
return 0;
|
||||
|
||||
switch (param)
|
||||
{
|
||||
case GLFW_PRESENT:
|
||||
return GL_TRUE;
|
||||
|
||||
case GLFW_AXES:
|
||||
return _glfw.x11.joystick[joy].numAxes;
|
||||
|
||||
case GLFW_BUTTONS:
|
||||
return _glfw.x11.joystick[joy].numButtons;
|
||||
|
||||
default:
|
||||
_glfwInputError(GLFW_INVALID_ENUM, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return _glfw.x11.joystick[joy].present;
|
||||
}
|
||||
|
||||
int _glfwPlatformGetJoystickAxes(int joy, float* axes, int numAxes)
|
||||
float* _glfwPlatformGetJoystickAxes(int joy, int* count)
|
||||
{
|
||||
int i;
|
||||
|
||||
pollJoystickEvents();
|
||||
|
||||
if (!_glfw.x11.joystick[joy].present)
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
if (_glfw.x11.joystick[joy].numAxes < numAxes)
|
||||
numAxes = _glfw.x11.joystick[joy].numAxes;
|
||||
|
||||
for (i = 0; i < numAxes; i++)
|
||||
axes[i] = _glfw.x11.joystick[joy].axis[i];
|
||||
|
||||
return numAxes;
|
||||
*count = _glfw.x11.joystick[joy].axisCount;
|
||||
return _glfw.x11.joystick[joy].axes;
|
||||
}
|
||||
|
||||
int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
|
||||
int numButtons)
|
||||
unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)
|
||||
{
|
||||
int i;
|
||||
|
||||
pollJoystickEvents();
|
||||
|
||||
if (!_glfw.x11.joystick[joy].present)
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
if (_glfw.x11.joystick[joy].numButtons < numButtons)
|
||||
numButtons = _glfw.x11.joystick[joy].numButtons;
|
||||
|
||||
for (i = 0; i < numButtons; i++)
|
||||
buttons[i] = _glfw.x11.joystick[joy].button[i];
|
||||
|
||||
return numButtons;
|
||||
*count = _glfw.x11.joystick[joy].buttonCount;
|
||||
return _glfw.x11.joystick[joy].buttons;
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetJoystickName(int joy)
|
||||
{
|
||||
if (!_glfw.x11.joystick[joy].present)
|
||||
return NULL;
|
||||
pollJoystickEvents();
|
||||
|
||||
return _glfw.x11.joystick[joy].name;
|
||||
}
|
||||
|
@ -189,10 +189,10 @@ typedef struct _GLFWlibraryX11
|
||||
struct {
|
||||
int present;
|
||||
int fd;
|
||||
int numAxes;
|
||||
int numButtons;
|
||||
float* axis;
|
||||
unsigned char* button;
|
||||
float* axes;
|
||||
int axisCount;
|
||||
unsigned char* buttons;
|
||||
int buttonCount;
|
||||
char* name;
|
||||
} joystick[GLFW_JOYSTICK_LAST + 1];
|
||||
|
||||
|
@ -136,30 +136,32 @@ static void refresh_joysticks(void)
|
||||
{
|
||||
Joystick* j = joysticks + i;
|
||||
|
||||
if (glfwGetJoystickParam(GLFW_JOYSTICK_1 + i, GLFW_PRESENT))
|
||||
if (glfwJoystickPresent(GLFW_JOYSTICK_1 + i))
|
||||
{
|
||||
float* axes;
|
||||
unsigned char* buttons;
|
||||
int axis_count, button_count;
|
||||
|
||||
free(j->name);
|
||||
j->name = strdup(glfwGetJoystickName(GLFW_JOYSTICK_1 + i));
|
||||
|
||||
axis_count = glfwGetJoystickParam(GLFW_JOYSTICK_1 + i, GLFW_AXES);
|
||||
axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1 + i, &axis_count);
|
||||
if (axis_count != j->axis_count)
|
||||
{
|
||||
j->axis_count = axis_count;
|
||||
j->axes = realloc(j->axes, j->axis_count * sizeof(float));
|
||||
}
|
||||
|
||||
glfwGetJoystickAxes(GLFW_JOYSTICK_1 + i, j->axes, j->axis_count);
|
||||
memcpy(j->axes, axes, axis_count * sizeof(float));
|
||||
|
||||
button_count = glfwGetJoystickParam(GLFW_JOYSTICK_1 + i, GLFW_BUTTONS);
|
||||
buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_1 + i, &button_count);
|
||||
if (button_count != j->button_count)
|
||||
{
|
||||
j->button_count = button_count;
|
||||
j->buttons = realloc(j->buttons, j->button_count);
|
||||
}
|
||||
|
||||
glfwGetJoystickButtons(GLFW_JOYSTICK_1 + i, j->buttons, j->button_count);
|
||||
memcpy(j->buttons, buttons, button_count * sizeof(unsigned char));
|
||||
|
||||
if (!j->present)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user