Skip to content

Instantly share code, notes, and snippets.

@skeeto
Created February 22, 2023 23:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skeeto/bbfaaba4fe525e0015233b5f5114e028 to your computer and use it in GitHub Desktop.
Save skeeto/bbfaaba4fe525e0015233b5f5114e028 to your computer and use it in GitHub Desktop.
Infinite gamepad rumble on Windows
// $ cc -nostartfiles example.c
// $ cl example.c /link /subsystem:console kernel32.lib
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <xinput.h>
struct gamepad {
void (*XInputEnable)(BOOL);
DWORD (*XInputSetState)(DWORD, XINPUT_VIBRATION *);
DWORD (*XInputGetState)(DWORD, XINPUT_STATE *);
DWORD (*XInputGetKeystroke)(DWORD, DWORD, PXINPUT_KEYSTROKE);
int enabled; // per-controller bit flags
};
static struct gamepad loadgamepad(void)
{
struct gamepad g = {0};
HINSTANCE h = 0;
h = h ? h : LoadLibraryA("xinput1_4.dll");
h = h ? h : LoadLibraryA("xinput1_3.dll");
h = h ? h : LoadLibraryA("xinput9_1_0.dll");
if (h) {
g.XInputEnable = (void *)GetProcAddress(h, "XInputEnable");
g.XInputSetState = (void *)GetProcAddress(h, "XInputSetState");
g.XInputGetState = (void *)GetProcAddress(h, "XInputGetState");
g.XInputGetKeystroke = (void *)GetProcAddress(h, "XInputGetKeystroke");
if (g.XInputEnable) {
g.XInputEnable(TRUE);
for (int i = 0; i < 4; i++) {
XINPUT_STATE state;
if (!g.XInputGetState(i, &state)) {
g.enabled |= 1 << i;
}
}
}
}
return g;
}
int mainCRTStartup(void)
{
struct gamepad gp = loadgamepad();
XINPUT_VIBRATION vibration;
vibration.wLeftMotorSpeed = -1;
vibration.wRightMotorSpeed = -1;
for (int i = 0; i < 4; i++) {
if (gp.enabled & (1<<i)) {
gp.XInputSetState(i, &vibration);
}
}
Sleep(INFINITE);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment