SDL - added new SDL_JoystickCurrentPowerLevel() API that returns the battery level of the selected joystick. Currently only implemented for XInput devices, other platforms are a TODO. CR: Sam
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
diff --git a/include/SDL_joystick.h b/include/SDL_joystick.h
index cad06a8..a707e6c 100644
--- a/include/SDL_joystick.h
+++ b/include/SDL_joystick.h
@@ -71,6 +71,16 @@ typedef struct {
typedef Sint32 SDL_JoystickID;
+typedef enum
+{
+ SDL_JOYSTICK_POWER_UNKNOWN = -1,
+ SDL_JOYSTICK_POWER_EMPTY,
+ SDL_JOYSTICK_POWER_LOW,
+ SDL_JOYSTICK_POWER_MEDIUM,
+ SDL_JOYSTICK_POWER_FULL,
+ SDL_JOYSTICK_POWER_WIRED,
+ SDL_JOYSTICK_POWER_MAX
+} SDL_JoystickPowerLevel;
/* Function prototypes */
/**
@@ -242,6 +252,11 @@ extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick * joystick,
*/
extern DECLSPEC void SDLCALL SDL_JoystickClose(SDL_Joystick * joystick);
+/**
+* Return the battery level of this joystick
+*/
+extern DECLSPEC SDL_JoystickPowerLevel SDLCALL SDL_JoystickCurrentPowerLevel(SDL_Joystick * joystick);
+
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
diff --git a/src/core/windows/SDL_xinput.c b/src/core/windows/SDL_xinput.c
index f892a8d..1e13fae 100644
--- a/src/core/windows/SDL_xinput.c
+++ b/src/core/windows/SDL_xinput.c
@@ -29,6 +29,7 @@
XInputGetState_t SDL_XInputGetState = NULL;
XInputSetState_t SDL_XInputSetState = NULL;
XInputGetCapabilities_t SDL_XInputGetCapabilities = NULL;
+XInputGetBatteryInformation_t SDL_XInputGetBatteryInformation = NULL;
DWORD SDL_XInputVersion = 0;
static HANDLE s_pXInputDLL = 0;
@@ -55,6 +56,7 @@ WIN_LoadXInputDLL(void)
SDL_XInputGetState = (XInputGetState_t)XInputGetState;
SDL_XInputSetState = (XInputSetState_t)XInputSetState;
SDL_XInputGetCapabilities = (XInputGetCapabilities_t)XInputGetCapabilities;
+ SDL_XInputGetBatteryInformation = (XInputGetBatteryInformation_t)XInputGetBatteryInformation;
/* XInput 1.4 ships with Windows 8 and 8.1: */
SDL_XInputVersion = (1 << 16) | 4;
@@ -108,6 +110,7 @@ WIN_LoadXInputDLL(void)
}
SDL_XInputSetState = (XInputSetState_t)GetProcAddress((HMODULE)s_pXInputDLL, "XInputSetState");
SDL_XInputGetCapabilities = (XInputGetCapabilities_t)GetProcAddress((HMODULE)s_pXInputDLL, "XInputGetCapabilities");
+ SDL_XInputGetBatteryInformation = (XInputGetBatteryInformation_t)GetProcAddress( (HMODULE)s_pXInputDLL, "XInputGetBatteryInformation" );
if (!SDL_XInputGetState || !SDL_XInputSetState || !SDL_XInputGetCapabilities) {
WIN_UnloadXInputDLL();
return -1;
diff --git a/src/core/windows/SDL_xinput.h b/src/core/windows/SDL_xinput.h
index 5c57737..664edd0 100644
--- a/src/core/windows/SDL_xinput.h
+++ b/src/core/windows/SDL_xinput.h
@@ -76,6 +76,29 @@
#define XINPUT_GAMEPAD_GUIDE 0x0400
#endif
+#ifndef BATTERY_DEVTYPE_GAMEPAD
+#define BATTERY_DEVTYPE_GAMEPAD 0x00
+#endif
+#ifndef BATTERY_TYPE_WIRED
+#define BATTERY_TYPE_WIRED 0x01
+#endif
+
+#ifndef BATTERY_TYPE_UNKNOWN
+#define BATTERY_TYPE_UNKNOWN 0xFF
+#endif
+#ifndef BATTERY_LEVEL_EMPTY
+#define BATTERY_LEVEL_EMPTY 0x00
+#endif
+#ifndef BATTERY_LEVEL_LOW
+#define BATTERY_LEVEL_LOW 0x01
+#endif
+#ifndef BATTERY_LEVEL_MEDIUM
+#define BATTERY_LEVEL_MEDIUM 0x02
+#endif
+#ifndef BATTERY_LEVEL_FULL
+#define BATTERY_LEVEL_FULL 0x03
+#endif
+
/* typedef's for XInput structs we use */
typedef struct
{
@@ -95,6 +118,12 @@ typedef struct
XINPUT_GAMEPAD_EX Gamepad;
} XINPUT_STATE_EX;
+typedef struct _XINPUT_BATTERY_INFORMATION
+{
+ BYTE BatteryType;
+ BYTE BatteryLevel;
+} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION;
+
/* Forward decl's for XInput API's we load dynamically and use if available */
typedef DWORD (WINAPI *XInputGetState_t)
(
@@ -115,17 +144,26 @@ typedef DWORD (WINAPI *XInputGetCapabilities_t)
XINPUT_CAPABILITIES* pCapabilities /* [out] Receives the capabilities */
);
+typedef DWORD (WINAPI *XInputGetBatteryInformation_t)
+ (
+ _In_ DWORD dwUserIndex,
+ _In_ BYTE devType,
+ _Out_ XINPUT_BATTERY_INFORMATION *pBatteryInformation
+ );
+
extern int WIN_LoadXInputDLL(void);
extern void WIN_UnloadXInputDLL(void);
extern XInputGetState_t SDL_XInputGetState;
extern XInputSetState_t SDL_XInputSetState;
extern XInputGetCapabilities_t SDL_XInputGetCapabilities;
+extern XInputGetBatteryInformation_t SDL_XInputGetBatteryInformation;
extern DWORD SDL_XInputVersion; /* ((major << 16) & 0xFF00) | (minor & 0xFF) */
#define XINPUTGETSTATE SDL_XInputGetState
#define XINPUTSETSTATE SDL_XInputSetState
#define XINPUTGETCAPABILITIES SDL_XInputGetCapabilities
+#define XINPUTGETBATTERYINFORMATION SDL_XInputGetBatteryInformation
#endif /* HAVE_XINPUT_H */
diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c
index 4725a57..532748c 100644
--- a/src/joystick/SDL_joystick.c
+++ b/src/joystick/SDL_joystick.c
@@ -178,6 +178,7 @@ SDL_JoystickOpen(int device_index)
if (joystick->buttons) {
SDL_memset(joystick->buttons, 0, joystick->nbuttons * sizeof(Uint8));
}
+ joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN;
/* Add joystick to list */
++joystick->ref_count;
@@ -619,10 +620,10 @@ SDL_PrivateJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state)
/* Make sure we're not getting garbage or duplicate events */
if (button >= joystick->nbuttons) {
return 0;
- }
- if (state == joystick->buttons[button]) {
- return 0;
- }
+ }
+ if (state == joystick->buttons[button]) {
+ return 0;
+ }
/* We ignore events if we don't have keyboard focus, except for button
* release. */
@@ -825,4 +826,21 @@ SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID)
}
+/* update the power level for this joystick */
+void SDL_PrivateJoystickBatteryLevel(SDL_Joystick * joystick, SDL_JoystickPowerLevel ePowerLevel)
+{
+ joystick->epowerlevel = ePowerLevel;
+}
+
+
+/* return its power level */
+SDL_JoystickPowerLevel SDL_JoystickCurrentPowerLevel(SDL_Joystick * joystick)
+{
+ if (!SDL_PrivateJoystickValid(joystick)) {
+ return (SDL_JOYSTICK_POWER_UNKNOWN);
+ }
+ return joystick->epowerlevel;
+}
+
+
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h
index ee4a14a..2da74bd 100644
--- a/src/joystick/SDL_joystick_c.h
+++ b/src/joystick/SDL_joystick_c.h
@@ -41,6 +41,8 @@ extern int SDL_PrivateJoystickHat(SDL_Joystick * joystick,
Uint8 hat, Uint8 value);
extern int SDL_PrivateJoystickButton(SDL_Joystick * joystick,
Uint8 button, Uint8 state);
+extern void SDL_PrivateJoystickBatteryLevel( SDL_Joystick * joystick,
+ SDL_JoystickPowerLevel ePowerLevel );
/* Internal sanity checking functions */
extern int SDL_PrivateJoystickValid(SDL_Joystick * joystick);
diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h
index 7c104b5..f03e404 100644
--- a/src/joystick/SDL_sysjoystick.h
+++ b/src/joystick/SDL_sysjoystick.h
@@ -54,6 +54,7 @@ struct _SDL_Joystick
int ref_count; /* Reference count for multiple opens */
SDL_bool force_recentering; /* SDL_TRUE if this device needs to have its state reset to 0 */
+ SDL_JoystickPowerLevel epowerlevel; /* power level of this joystick, SDL_JOYSTICK_POWER_UNKNOWN if not supported */
struct _SDL_Joystick *next; /* pointer to next joystick we have allocated */
};
diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c
index b1c22ab..b3a4c9e 100644
--- a/src/joystick/windows/SDL_xinputjoystick.c
+++ b/src/joystick/windows/SDL_xinputjoystick.c
@@ -221,8 +221,39 @@ SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde
return 0;
}
+static void
+UpdateXInputJoystickBatteryInformation(SDL_Joystick * joystick, XINPUT_BATTERY_INFORMATION *pBatteryInformation)
+{
+ if ( pBatteryInformation->BatteryType != BATTERY_TYPE_UNKNOWN )
+ {
+ SDL_JoystickPowerLevel ePowerLevel = SDL_JOYSTICK_POWER_UNKNOWN;
+ if (pBatteryInformation->BatteryType == BATTERY_TYPE_WIRED) {
+ ePowerLevel = SDL_JOYSTICK_POWER_WIRED;
+ } else {
+ switch ( pBatteryInformation->BatteryLevel )
+ {
+ case BATTERY_LEVEL_EMPTY:
+ ePowerLevel = SDL_JOYSTICK_POWER_EMPTY;
+ break;
+ case BATTERY_LEVEL_LOW:
+ ePowerLevel = SDL_JOYSTICK_POWER_LOW;
+ break;
+ case BATTERY_LEVEL_MEDIUM:
+ ePowerLevel = SDL_JOYSTICK_POWER_MEDIUM;
+ break;
+ default:
+ case BATTERY_LEVEL_FULL:
+ ePowerLevel = SDL_JOYSTICK_POWER_FULL;
+ break;
+ }
+ }
+
+ SDL_PrivateJoystickBatteryLevel( joystick, ePowerLevel );
+ }
+}
+
static void
-UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState)
+UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION *pBatteryInformation)
{
static WORD s_XInputButtons[] = {
XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT,
@@ -244,10 +275,12 @@ UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputS
for (button = 0; button < SDL_arraysize(s_XInputButtons); ++button) {
SDL_PrivateJoystickButton(joystick, button, (wButtons & s_XInputButtons[button]) ? SDL_PRESSED : SDL_RELEASED);
}
+
+ UpdateXInputJoystickBatteryInformation( joystick, pBatteryInformation );
}
static void
-UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState)
+UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION *pBatteryInformation)
{
static WORD s_XInputButtons[] = {
XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y,
@@ -283,6 +316,8 @@ UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState
hat |= SDL_HAT_RIGHT;
}
SDL_PrivateJoystickHat(joystick, 0, hat);
+
+ UpdateXInputJoystickBatteryInformation( joystick, pBatteryInformation );
}
void
@@ -290,6 +325,7 @@ SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick)
{
HRESULT result;
XINPUT_STATE_EX XInputState;
+ XINPUT_BATTERY_INFORMATION XBatteryInformation;
if (!XINPUTGETSTATE)
return;
@@ -301,12 +337,18 @@ SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick)
return;
}
+ SDL_zero( XBatteryInformation );
+ if ( XINPUTGETBATTERYINFORMATION )
+ {
+ result = XINPUTGETBATTERYINFORMATION( joystick->hwdata->userid, BATTERY_DEVTYPE_GAMEPAD, &XBatteryInformation );
+ }
+
/* only fire events if the data changed from last time */
if (XInputState.dwPacketNumber && XInputState.dwPacketNumber != joystick->hwdata->dwPacketNumber) {
if (SDL_XInputUseOldJoystickMapping()) {
- UpdateXInputJoystickState_OLD(joystick, &XInputState);
+ UpdateXInputJoystickState_OLD(joystick, &XInputState, &XBatteryInformation);
} else {
- UpdateXInputJoystickState(joystick, &XInputState);
+ UpdateXInputJoystickState(joystick, &XInputState, &XBatteryInformation);
}
joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber;
}