mirror of
https://github.com/glfw/glfw.git
synced 2025-10-04 05:36:35 +00:00
Add possiblity to use XInput to handle josyticks
This commit is contained in:
parent
a7b75792ec
commit
149994c626
@ -27,6 +27,7 @@ option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF)
|
||||
|
||||
if (WIN32)
|
||||
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()
|
||||
|
||||
if (APPLE)
|
||||
@ -210,6 +211,10 @@ if (_GLFW_WIN32)
|
||||
if (GLFW_USE_HYBRID_HPG)
|
||||
set(_GLFW_USE_HYBRID_HPG 1)
|
||||
endif()
|
||||
|
||||
if (GLFW_USE_XINPUT)
|
||||
set(_GLFW_USE_XINPUT 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
@ -461,4 +466,3 @@ if (GLFW_INSTALL)
|
||||
"${GLFW_BINARY_DIR}/cmake_uninstall.cmake")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -17,10 +17,16 @@ if (_GLFW_COCOA)
|
||||
set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_monitor.m
|
||||
cocoa_window.m iokit_joystick.m mach_time.c posix_tls.c)
|
||||
elseif (_GLFW_WIN32)
|
||||
set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_tls.h
|
||||
winmm_joystick.h)
|
||||
set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_tls.h)
|
||||
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)
|
||||
set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h
|
||||
linux_joystick.h posix_time.h posix_tls.h)
|
||||
@ -93,4 +99,3 @@ endif()
|
||||
if (GLFW_INSTALL)
|
||||
install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX})
|
||||
endif()
|
||||
|
||||
|
@ -60,6 +60,9 @@
|
||||
// Define this to 1 to force use of high-performance GPU on hybrid systems
|
||||
#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
|
||||
#cmakedefine _GLFW_HAS_XINPUT
|
||||
// Define this to 1 if the Xxf86vm X11 extension is available
|
||||
@ -71,4 +74,3 @@
|
||||
#cmakedefine _GLFW_USE_MENUBAR
|
||||
// Define this to 1 if windows should use full resolution on Retina displays
|
||||
#cmakedefine _GLFW_USE_RETINA
|
||||
|
||||
|
@ -69,15 +69,32 @@ static GLFWbool initLibraries(void)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
#ifndef _GLFW_USE_XINPUT
|
||||
_glfw.win32.winmm.joyGetDevCaps = (JOYGETDEVCAPS_T)
|
||||
GetProcAddress(_glfw.win32.winmm.instance, "joyGetDevCapsW");
|
||||
_glfw.win32.winmm.joyGetPos = (JOYGETPOS_T)
|
||||
GetProcAddress(_glfw.win32.winmm.instance, "joyGetPos");
|
||||
_glfw.win32.winmm.joyGetPosEx = (JOYGETPOSEX_T)
|
||||
GetProcAddress(_glfw.win32.winmm.instance, "joyGetPosEx");
|
||||
#endif
|
||||
_glfw.win32.winmm.timeGetTime = (TIMEGETTIME_T)
|
||||
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");
|
||||
if (!_glfw.win32.user32.instance)
|
||||
{
|
||||
@ -380,4 +397,3 @@ const char* _glfwPlatformGetVersionString(void)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,9 @@
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include <dbt.h>
|
||||
#ifdef _GLFW_USE_XINPUT
|
||||
#include <Xinput.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <malloc.h>
|
||||
@ -100,14 +103,18 @@ typedef struct tagCHANGEFILTERSTRUCT
|
||||
#endif /*Windows 7*/
|
||||
|
||||
// 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);
|
||||
#define _glfw_joyGetDevCaps _glfw.win32.winmm.joyGetDevCaps
|
||||
#define _glfw_joyGetPos _glfw.win32.winmm.joyGetPos
|
||||
#define _glfw_joyGetPosEx _glfw.win32.winmm.joyGetPosEx
|
||||
#ifndef _GLFW_USE_XINPUT
|
||||
typedef MMRESULT(WINAPI * JOYGETDEVCAPS_T)(UINT,LPJOYCAPS,UINT);
|
||||
typedef MMRESULT(WINAPI * JOYGETPOS_T)(UINT,LPJOYINFO);
|
||||
typedef MMRESULT(WINAPI * JOYGETPOSEX_T)(UINT,LPJOYINFOEX);
|
||||
#endif
|
||||
#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
|
||||
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_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_REQUIRED 1
|
||||
#define _GLFW_RECREATION_IMPOSSIBLE 2
|
||||
|
||||
#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)
|
||||
#include "wgl_context.h"
|
||||
@ -171,9 +190,11 @@ typedef struct _GLFWlibraryWin32
|
||||
// winmm.dll
|
||||
struct {
|
||||
HINSTANCE instance;
|
||||
#ifndef _GLFW_USE_XINPUT
|
||||
JOYGETDEVCAPS_T joyGetDevCaps;
|
||||
JOYGETPOS_T joyGetPos;
|
||||
JOYGETPOSEX_T joyGetPosEx;
|
||||
#endif
|
||||
TIMEGETTIME_T timeGetTime;
|
||||
} winmm;
|
||||
|
||||
@ -191,6 +212,14 @@ typedef struct _GLFWlibraryWin32
|
||||
DWMFLUSH_T DwmFlush;
|
||||
} dwmapi;
|
||||
|
||||
#ifdef _GLFW_USE_XINPUT
|
||||
// Xinput.dll
|
||||
struct {
|
||||
HINSTANCE instance;
|
||||
XINPUTGETCAPABILITIES_T XInputGetCapabilities;
|
||||
XINPUTGETSTATE_T XInputGetState;
|
||||
} xinput;
|
||||
#endif
|
||||
} _GLFWlibraryWin32;
|
||||
|
||||
|
||||
|
147
src/xinput_joystick.c
Normal file
147
src/xinput_joystick.c
Normal 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
48
src/xinput_joystick.h
Normal 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_
|
Loading…
Reference in New Issue
Block a user