Skip to content

feat: add DInput/WinMM controller support for Windows#71

Draft
deadman96385 wants to merge 1 commit intosmartcmd:mainfrom
deadman96385:controllers
Draft

feat: add DInput/WinMM controller support for Windows#71
deadman96385 wants to merge 1 commit intosmartcmd:mainfrom
deadman96385:controllers

Conversation

@deadman96385
Copy link
Contributor

@deadman96385 deadman96385 commented Mar 1, 2026

Pull Request

Description

Adds support for non-XInput controllers (PS4/DS4, generic HID gamepads) on Windows by bridging the WinMM joystick API into the game's XInput-based input pipeline.

Changes

Previous Behavior

Only XInput-compatible controllers (Xbox controllers and XInput-mode adapters) worked on the Windows build. Connecting a PS4 DualShock 4 or any other DirectInput/HID gamepad produced no input in the game.

Root Cause

The game's input library (4J_Input.lib) is a precompiled static library that exclusively uses the XInput API (XInputGetState, XInputGetCapabilities). XInput is Xbox-specific and is completely blind to non-XInput devices — the DS4 and other
HID gamepads register with Windows as DirectInput/WinMM joysticks and are never enumerated by XInput, so the game had no path to receive their input.

New Behavior

Non-XInput controllers are automatically detected and assigned to empty controller slots. The DS4 and other HID gamepads work with correct button and axis mapping: face buttons, D-pad, shoulder buttons, analog sticks, and analog triggers all
behave as they would on an Xbox controller. The device list is refreshed every ~3 seconds to handle hot-plugging.

Fix Implementation

Since 4J_Input.lib is statically linked, it shares the host executable's Import Address Table (IAT). At startup, DInputManager_Init() walks the PE header of the process (IMAGE_DOS_HEADER → IMAGE_NT_HEADERS → IMAGE_IMPORT_DESCRIPTOR) to find the XInput DLL import entries and overwrites the XInputGetState and XInputGetCapabilities function pointers with hooks using VirtualProtect. The hooked XInputGetState first tries the real XInput call; if a slot reports ERROR_DEVICE_NOT_CONNECTED, it checks whether a WinMM joystick has been assigned to that slot and reads it via joyGetPosEx. The WinMM state is then translated into XINPUT_STATE format — DS4 buttons are mapped via the dwButtons bitmask, the POV hat is converted to XInput DPAD flags, stick axes are scaled from WinMM's 0–65535 range to XInput's −32768–32767 (with Y axes inverted), and trigger axes (DS4 HID axis order: Z=RSX, Rz=RSY, Ry=R2, Rx=L2) are scaled to 0–255. DInputManager_Tick() is called once per frame and periodically re-runs slot assignment to pick up newly connected devices.

…amepads)

Hooks XInputGetState and XInputGetCapabilities via IAT patching so non-XInput controllers (DS4, generic HID gamepads) are visible to 4J_Input.lib and the rest of the game. Uses the WinMM joystick API to read device state and translates it to XINPUT_STATE format, mapping DS4 axes (Z=RSX, Rz=RSY, Ry=R2, Rx=L2) and buttons to their Xbox equivalents. Unoccupied XInput slots are assigned toDInput devices and rescanned every ~3 seconds.
@void2012
Copy link
Collaborator

void2012 commented Mar 1, 2026

WIP?

@deadman96385
Copy link
Contributor Author

Works fully on DS4 and my BT Xbox controller but haven't tested on generic ones.

@void2012
Copy link
Collaborator

void2012 commented Mar 1, 2026

Please do and report back

@deadman96385
Copy link
Contributor Author

I do not have any sadly

@Legeend28
Copy link

pls :D great addition

Copy link

@Legeend28 Legeend28 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea pretty good bro 10/10 legeend28 approved

Copy link

@omnifla omnifla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@void2012
Copy link
Collaborator

void2012 commented Mar 2, 2026

I will not merge until someone with a controller tests this one. We've had too much of untested/hallucinated by LLM PRs on day 1.

@void2012 void2012 marked this pull request as draft March 2, 2026 12:06
@WhyCron
Copy link

WhyCron commented Mar 2, 2026

I have just finished testing this with seven different controller configurations:

  • DualSense (Bluetooth) worked as expected
  • DualSense (Wired) worked as expected
  • GameCube Controller using Mayflash's Adapter worked as expected
  • Stadia Controller (Bluetooth) was not recognised
  • Stadia Controller (Wired) was not recognised
  • GameSir G8+ (Bluetooth, DS4 mode) was not recognised
  • NSO N64 Controller (Bluetooth) was recognised, but had strange mapping issues such as right on the analog stick not being recognised but up, left, and down all working as expected.

Besides the N64 controller having mapping issues (which is to be expected, it's a controller that wouldn't realistically be usable for Minecraft), I think that a 50% success rate isn't high enough to say that it brings proper compatibility for DInput controllers.

Are there any other ways to bridge the API that would offer better compatibility?
(While I have programming experience, I have no experience with C++, so I cannot offer any contribution beyond testing at the moment)

@void2012
Copy link
Collaborator

void2012 commented Mar 2, 2026

@deadman96385

@hostk0211
Copy link

How do I download it, what do I need to do it, it seems a bit silly to ask

@void2012
Copy link
Collaborator

void2012 commented Mar 2, 2026

How do I download it, what do I need to do it, it seems a bit silly to ask

Click on the deadman96385:controllers at the top of the screen, download the repository or git clone and build with Visual Studio 2022/2026

@hostk0211
Copy link

How do I download it, what do I need to do it, it seems a bit silly to ask

Click on the deadman96385:controllers at the top of the screen, download the repository or git clone and build with Visual Studio 2022/2026

I don't know anything about this, I've never done it, can you send it to me so I can just run it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants