This commit is contained in:
Sergey Tikhomirov 2015-10-19 14:30:30 +00:00
commit 7fbb65e3d6
7 changed files with 266 additions and 15 deletions

View File

@ -27,6 +27,7 @@ option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF)
if (WIN32) if (WIN32)
option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF) option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF)
option(GLFW_USE_XINPUT "Use XInput to handle josticks" ON)
endif() endif()
if (APPLE) if (APPLE)
@ -209,6 +210,10 @@ if (_GLFW_WIN32)
if (GLFW_USE_HYBRID_HPG) if (GLFW_USE_HYBRID_HPG)
set(_GLFW_USE_HYBRID_HPG 1) set(_GLFW_USE_HYBRID_HPG 1)
endif() endif()
if (GLFW_USE_XINPUT)
set(_GLFW_USE_XINPUT 1)
endif()
endif() endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
@ -453,4 +458,3 @@ if (GLFW_INSTALL)
"${GLFW_BINARY_DIR}/cmake_uninstall.cmake") "${GLFW_BINARY_DIR}/cmake_uninstall.cmake")
endif() endif()
endif() endif()

View File

@ -17,10 +17,16 @@ if (_GLFW_COCOA)
set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_monitor.m set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_monitor.m
cocoa_window.m iokit_joystick.m mach_time.c posix_tls.c) cocoa_window.m iokit_joystick.m mach_time.c posix_tls.c)
elseif (_GLFW_WIN32) elseif (_GLFW_WIN32)
set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_tls.h set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_tls.h)
winmm_joystick.h)
set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_monitor.c win32_time.c set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_monitor.c win32_time.c
win32_tls.c win32_window.c winmm_joystick.c) win32_tls.c win32_window.c)
if (_GLFW_USE_XINPUT)
list(APPEND glfw_HEADERS xinput_joystick.h)
list(APPEND glfw_SOURCES xinput_joystick.c)
else()
list(APPEND glfw_HEADERS winmm_joystick.h)
list(APPEND glfw_SOURCES winmm_joystick.c)
endif()
elseif (_GLFW_X11) elseif (_GLFW_X11)
set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h
linux_joystick.h posix_time.h posix_tls.h) linux_joystick.h posix_time.h posix_tls.h)
@ -93,4 +99,3 @@ endif()
if (GLFW_INSTALL) if (GLFW_INSTALL)
install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX}) install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX})
endif() endif()

View File

@ -60,6 +60,9 @@
// Define this to 1 to force use of high-performance GPU on hybrid systems // Define this to 1 to force use of high-performance GPU on hybrid systems
#cmakedefine _GLFW_USE_HYBRID_HPG #cmakedefine _GLFW_USE_HYBRID_HPG
// Define this to 1 to use XInput to handle joysticks
#cmakedefine _GLFW_USE_XINPUT
// Define this to 1 if the XInput X11 extension is available // Define this to 1 if the XInput X11 extension is available
#cmakedefine _GLFW_HAS_XINPUT #cmakedefine _GLFW_HAS_XINPUT
// Define this to 1 if the Xxf86vm X11 extension is available // Define this to 1 if the Xxf86vm X11 extension is available
@ -71,4 +74,3 @@
#cmakedefine _GLFW_USE_MENUBAR #cmakedefine _GLFW_USE_MENUBAR
// Define this to 1 if windows should use full resolution on Retina displays // Define this to 1 if windows should use full resolution on Retina displays
#cmakedefine _GLFW_USE_RETINA #cmakedefine _GLFW_USE_RETINA

View File

@ -69,15 +69,32 @@ static GLFWbool initLibraries(void)
return GLFW_FALSE; return GLFW_FALSE;
} }
#ifndef _GLFW_USE_XINPUT
_glfw.win32.winmm.joyGetDevCaps = (JOYGETDEVCAPS_T) _glfw.win32.winmm.joyGetDevCaps = (JOYGETDEVCAPS_T)
GetProcAddress(_glfw.win32.winmm.instance, "joyGetDevCapsW"); GetProcAddress(_glfw.win32.winmm.instance, "joyGetDevCapsW");
_glfw.win32.winmm.joyGetPos = (JOYGETPOS_T) _glfw.win32.winmm.joyGetPos = (JOYGETPOS_T)
GetProcAddress(_glfw.win32.winmm.instance, "joyGetPos"); GetProcAddress(_glfw.win32.winmm.instance, "joyGetPos");
_glfw.win32.winmm.joyGetPosEx = (JOYGETPOSEX_T) _glfw.win32.winmm.joyGetPosEx = (JOYGETPOSEX_T)
GetProcAddress(_glfw.win32.winmm.instance, "joyGetPosEx"); GetProcAddress(_glfw.win32.winmm.instance, "joyGetPosEx");
#endif
_glfw.win32.winmm.timeGetTime = (TIMEGETTIME_T) _glfw.win32.winmm.timeGetTime = (TIMEGETTIME_T)
GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime"); GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime");
#ifdef _GLFW_USE_XINPUT
_glfw.win32.xinput.instance = LoadLibraryW(L"XInput9_1_0.dll");
if (!_glfw.win32.xinput.instance)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to load XInput9_1_0.dll");
return GLFW_FALSE;
}
_glfw.win32.xinput.XInputGetCapabilities = (XINPUTGETCAPABILITIES_T)
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities");
_glfw.win32.xinput.XInputGetState = (XINPUTGETSTATE_T)
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState");
#endif
_glfw.win32.user32.instance = LoadLibraryW(L"user32.dll"); _glfw.win32.user32.instance = LoadLibraryW(L"user32.dll");
if (!_glfw.win32.user32.instance) if (!_glfw.win32.user32.instance)
{ {
@ -380,4 +397,3 @@ const char* _glfwPlatformGetVersionString(void)
#endif #endif
; ;
} }

View File

@ -64,6 +64,9 @@
#include <windows.h> #include <windows.h>
#include <mmsystem.h> #include <mmsystem.h>
#include <dbt.h> #include <dbt.h>
#ifdef _GLFW_USE_XINPUT
#include <Xinput.h>
#endif
#if defined(_MSC_VER) #if defined(_MSC_VER)
#include <malloc.h> #include <malloc.h>
@ -100,14 +103,18 @@ typedef struct tagCHANGEFILTERSTRUCT
#endif /*Windows 7*/ #endif /*Windows 7*/
// winmm.dll function pointer typedefs // winmm.dll function pointer typedefs
typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T)(UINT,LPJOYCAPS,UINT);
typedef MMRESULT (WINAPI * JOYGETPOS_T)(UINT,LPJOYINFO);
typedef MMRESULT (WINAPI * JOYGETPOSEX_T)(UINT,LPJOYINFOEX);
typedef DWORD (WINAPI * TIMEGETTIME_T)(void); typedef DWORD (WINAPI * TIMEGETTIME_T)(void);
#define _glfw_joyGetDevCaps _glfw.win32.winmm.joyGetDevCaps #ifndef _GLFW_USE_XINPUT
#define _glfw_joyGetPos _glfw.win32.winmm.joyGetPos typedef MMRESULT(WINAPI * JOYGETDEVCAPS_T)(UINT,LPJOYCAPS,UINT);
#define _glfw_joyGetPosEx _glfw.win32.winmm.joyGetPosEx typedef MMRESULT(WINAPI * JOYGETPOS_T)(UINT,LPJOYINFO);
typedef MMRESULT(WINAPI * JOYGETPOSEX_T)(UINT,LPJOYINFOEX);
#endif
#define _glfw_timeGetTime _glfw.win32.winmm.timeGetTime #define _glfw_timeGetTime _glfw.win32.winmm.timeGetTime
#ifndef _GLFW_USE_XINPUT
#define _glfw_joyGetDevCaps _glfw.win32.winmm.joyGetDevCaps
#define _glfw_joyGetPos _glfw.win32.winmm.joyGetPos
#define _glfw_joyGetPosEx _glfw.win32.winmm.joyGetPosEx
#endif
// user32.dll function pointer typedefs // user32.dll function pointer typedefs
typedef BOOL (WINAPI * SETPROCESSDPIAWARE_T)(void); typedef BOOL (WINAPI * SETPROCESSDPIAWARE_T)(void);
@ -121,12 +128,24 @@ typedef HRESULT (WINAPI * DWMFLUSH_T)(VOID);
#define _glfw_DwmIsCompositionEnabled _glfw.win32.dwmapi.DwmIsCompositionEnabled #define _glfw_DwmIsCompositionEnabled _glfw.win32.dwmapi.DwmIsCompositionEnabled
#define _glfw_DwmFlush _glfw.win32.dwmapi.DwmFlush #define _glfw_DwmFlush _glfw.win32.dwmapi.DwmFlush
#ifdef _GLFW_USE_XINPUT
// Xinput.dll function pointer typedefs
typedef DWORD(WINAPI * XINPUTGETCAPABILITIES_T)(DWORD,DWORD,XINPUT_CAPABILITIES*);
typedef DWORD(WINAPI * XINPUTGETSTATE_T)(DWORD,XINPUT_STATE*);
#define _glfw_XInputGetCapabilities _glfw.win32.xinput.XInputGetCapabilities
#define _glfw_XInputGetState _glfw.win32.xinput.XInputGetState
#endif
#define _GLFW_RECREATION_NOT_NEEDED 0 #define _GLFW_RECREATION_NOT_NEEDED 0
#define _GLFW_RECREATION_REQUIRED 1 #define _GLFW_RECREATION_REQUIRED 1
#define _GLFW_RECREATION_IMPOSSIBLE 2 #define _GLFW_RECREATION_IMPOSSIBLE 2
#include "win32_tls.h" #include "win32_tls.h"
#include "winmm_joystick.h" #ifdef _GLFW_USE_XINPUT
#include "xinput_joystick.h"
#else
#include "winmm_joystick.h"
#endif
#if defined(_GLFW_WGL) #if defined(_GLFW_WGL)
#include "wgl_context.h" #include "wgl_context.h"
@ -175,9 +194,11 @@ typedef struct _GLFWlibraryWin32
// winmm.dll // winmm.dll
struct { struct {
HINSTANCE instance; HINSTANCE instance;
#ifndef _GLFW_USE_XINPUT
JOYGETDEVCAPS_T joyGetDevCaps; JOYGETDEVCAPS_T joyGetDevCaps;
JOYGETPOS_T joyGetPos; JOYGETPOS_T joyGetPos;
JOYGETPOSEX_T joyGetPosEx; JOYGETPOSEX_T joyGetPosEx;
#endif
TIMEGETTIME_T timeGetTime; TIMEGETTIME_T timeGetTime;
} winmm; } winmm;
@ -195,6 +216,14 @@ typedef struct _GLFWlibraryWin32
DWMFLUSH_T DwmFlush; DWMFLUSH_T DwmFlush;
} dwmapi; } dwmapi;
#ifdef _GLFW_USE_XINPUT
// Xinput.dll
struct {
HINSTANCE instance;
XINPUTGETCAPABILITIES_T XInputGetCapabilities;
XINPUTGETSTATE_T XInputGetState;
} xinput;
#endif
} _GLFWlibraryWin32; } _GLFWlibraryWin32;

147
src/xinput_joystick.c Normal file
View File

@ -0,0 +1,147 @@
//========================================================================
// GLFW 3.1 XInput - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2015 Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <stdlib.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
static const DWORD ORDERED_XINPUT_BUTTONS[XINPUT_BUTTONS_COUNT] = {
XINPUT_GAMEPAD_A,
XINPUT_GAMEPAD_B,
XINPUT_GAMEPAD_X,
XINPUT_GAMEPAD_Y,
XINPUT_GAMEPAD_LEFT_SHOULDER,
XINPUT_GAMEPAD_RIGHT_SHOULDER,
XINPUT_GAMEPAD_BACK,
XINPUT_GAMEPAD_START,
XINPUT_GAMEPAD_LEFT_THUMB,
XINPUT_GAMEPAD_RIGHT_THUMB,
};
static float normalizeThumb(SHORT pos, SHORT deadzone)
{
const SHORT THUMB_MIN = -32768;
const SHORT THUMB_MAX = 32767;
if (abs(pos) < deadzone)
return 0.f;
return 2.f * ((float)(pos - THUMB_MIN) / (float)(THUMB_MAX - THUMB_MIN)) - 1.f;
}
static float normalizeTrigger(BYTE pos)
{
return (float)pos / 255.f;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize joystick interface
//
void _glfwInitJoysticks(void)
{
}
// Close all opened joystick handles
//
void _glfwTerminateJoysticks(void)
{
int i;
for (i = 0; i < GLFW_JOYSTICK_LAST; i++)
free(_glfw.xinput_js[i].name);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformJoystickPresent(int joy)
{
XINPUT_CAPABILITIES capabilities;
return _glfw_XInputGetCapabilities(joy, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS;
}
const float* _glfwPlatformGetJoystickAxes(int joy, int* count)
{
XINPUT_STATE state;
XINPUT_GAMEPAD gamepad;
float* axes = _glfw.xinput_js[joy].axes;
ZeroMemory(&state, sizeof(XINPUT_STATE));
if (_glfw_XInputGetState(joy, &state) != ERROR_SUCCESS)
return NULL;
gamepad = state.Gamepad;
axes[(*count)++] = normalizeTrigger(gamepad.bLeftTrigger);
axes[(*count)++] = normalizeTrigger(gamepad.bRightTrigger);
axes[(*count)++] = normalizeThumb(gamepad.sThumbLX, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
axes[(*count)++] = normalizeThumb(gamepad.sThumbLY, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
axes[(*count)++] = normalizeThumb(gamepad.sThumbRX, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
axes[(*count)++] = normalizeThumb(gamepad.sThumbRY, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
return axes;
}
const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)
{
XINPUT_STATE state;
unsigned char* buttons = _glfw.xinput_js[joy].buttons;
ZeroMemory(&state, sizeof(XINPUT_STATE));
if (_glfw_XInputGetState(joy, &state) != ERROR_SUCCESS)
return NULL;
*count = XINPUT_BUTTONS_COUNT;
for (int i = 0; i < XINPUT_BUTTONS_COUNT; i++)
buttons[i] = (unsigned char)((state.Gamepad.wButtons & ORDERED_XINPUT_BUTTONS[i]) ? GLFW_PRESS : GLFW_RELEASE);
return buttons;
}
const char* _glfwPlatformGetJoystickName(int joy)
{
char name[64];
XINPUT_STATE state;
ZeroMemory(&state, sizeof(XINPUT_STATE));
if (!_glfwPlatformJoystickPresent(joy))
return NULL;
sprintf_s(name, sizeof(name), "XInput Joystick %d", joy + 1);
free(_glfw.xinput_js[joy].name);
_glfw.xinput_js[joy].name = strdup(name);
return _glfw.xinput_js[joy].name;
}

48
src/xinput_joystick.h Normal file
View File

@ -0,0 +1,48 @@
//========================================================================
// GLFW 3.2 XInput - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2015 Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifndef _glfw3_xinput_joystick_h_
#define _glfw3_xinput_joystick_h_
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \
_GLFWjoystickXInput xinput_js[GLFW_JOYSTICK_LAST + 1]
// Windows-specific per-joystick data
//
#define XINPUT_BUTTONS_COUNT 14
typedef struct _GLFWjoystickXInput
{
float axes[6];
unsigned char buttons[XINPUT_BUTTONS_COUNT];
char* name;
} _GLFWjoystickXInput;
void _glfwInitJoysticks(void);
void _glfwTerminateJoysticks(void);
#endif // _glfw3_xinput_joystick_h_