{"id":22144889,"url":"https://github.com/xan105/inputfusion","last_synced_at":"2025-10-12T13:30:45.952Z","repository":{"id":265356897,"uuid":"895838674","full_name":"xan105/InputFusion","owner":"xan105","description":"Re-implementation of Gamepad APIs such as XInput over SDL3 akin to Steam Input","archived":false,"fork":false,"pushed_at":"2025-01-22T02:46:46.000Z","size":11447,"stargazers_count":17,"open_issues_count":5,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-22T03:27:43.729Z","etag":null,"topics":["dinput","gamepad","sdl3","steam-input","winmm","xinput"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xan105.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"xan105","custom":"https://www.paypal.me/xan105"}},"created_at":"2024-11-29T02:38:03.000Z","updated_at":"2025-01-22T02:46:50.000Z","dependencies_parsed_at":"2025-01-22T03:34:41.540Z","dependency_job_id":null,"html_url":"https://github.com/xan105/InputFusion","commit_stats":null,"previous_names":["xan105/inputfusion"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xan105%2FInputFusion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xan105%2FInputFusion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xan105%2FInputFusion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xan105%2FInputFusion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xan105","download_url":"https://codeload.github.com/xan105/InputFusion/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236220542,"owners_count":19114341,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dinput","gamepad","sdl3","steam-input","winmm","xinput"],"created_at":"2024-12-01T22:34:43.661Z","updated_at":"2025-10-12T13:30:45.945Z","avatar_url":"https://github.com/xan105.png","language":"C++","readme":"About\n=====\n\nThis is an attempt at creating an _\"open source Steam Input\"_. Specifically the Gamepad APIs translating part.\n\nThis project aims to hook and re-implement various gamepad APIs such as XInput over [SDL3](https://www.libsdl.org/).\n\nThe goal is to allow old and new games to support any gamepad controller supported by SDL3 (over 200+) out of the box with zero configuration.\n\nIf you are a game developper and you'd like your game to support a variety of gamepad controllers without rewriting your game, this project might be of interest to you.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/xan105/InputFusion/raw/main/screenshot/debug.png\"\u003e\n  \u003cem\u003eXInput API calls (\"Debug mode\")\u003c/em\u003e\n\u003c/p\u003e\n\nGamepad APIs support\n====================\n\n- ~~GameInput~~\n- XInput\n- DInput8\n- DInput(1-7)\n- WinMM\n\nNB: DInput and DInput8 are still a work in progress. Depending on the game, \"your mileage may vary\", as they say.\n  \n## Out of scope (for now)\n\n\u003cdetails\u003e\u003csummary\u003eSteam Input API\u003c/summary\u003e\n  \u003cbr/\u003e\n  Steam Input API only games. You need an action set to translate input. Hooking these API is going down the Steam Enulator rabbit hole.\n  \n  Not sure yet how best to handle this. Meanwhile when using a Steam Emulator that translates Steam Input to XInput you can leverage InputFusion to then translate XInput to SDL.\n  \n  \u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/xan105/InputFusion/raw/main/screenshot/SteamInput_to_XInput.png\"\u003e\n  \u003cem\u003eSteam Input -\u003e XInput -\u003e SDL (\"Debug mode\")\u003c/em\u003e\n  \u003c/p\u003e\n  \n\u003c/details\u003e\n  \n\u003cdetails\u003e\u003csummary\u003eHID / Raw\u003c/summary\u003e\n  \u003cbr/\u003e\n  These APIs aren't really like the standardised Gamepad APIs like XInput. They are much akin to low level access.\n  \n  SDL mostly uses these low level APIs.\n  \n  If a game uses these APIs to add support for a specific Gamepad;\n  The game devs probably have a certain experience in mind and we shouldn't interfere with it.\n  \n  Many mods and other 3rd party \"fix\" rely on these low level access to do their job.\n  And they often complain about the new Steam Input capabilities of hooking system wide all relevant APIs for gamepad while Steam is running.\n  \n  As such, I do no think these API are relevant for my project (for now).\n  \n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003eWGI: Windows.Gaming.Input Namespace\u003c/summary\u003e\n  \u003cbr/\u003e\n  Originaly designed for UWP/WinRT apps, now legacy, it can be used in win32 apps with some effort.\n\u003c/details\u003e\n\nUsage\n=====\n\nInputFusion can be used either as \n- **A)** a drop-in replacement _(DLL side-loading)_ or\n- **B)** by being injected into a target process.\n\nUnless you know what you are doing stick with the first approach.\n\n## A) DLL side-loading\n\nUse `xinput*.dll` or `dinput8.dll` or `winmm.dll` depending on which API the game is using.\n\nReplace the corresponding DLL in the game directory if present, otherwise place it next to the game's executable.\n\nIn the case of XInput, this might require a little guess work to find which version of XInput the game is using: xinput1_4.dll, xinput1_3.dll, xinput9_1_0.dll.\n\n_NB: If necessary, you can opt-in to also hook/detour API calls to force the game to use the ones from the DLL. See `Env Var` section below._\n\n## B) DLL Injection\n\n\u003e [!IMPORTANT]\n\u003e Before executing and injecting into your target process, you must specify which API you intend to hook/detour.\n\u003e This is achieved by setting the corresponding environment variable for the desired API.\n\u003e\n\u003e If you do not configure the environment variable before injection, the process will only initialize SDL without performing any meaningful actions.\n\u003e For details please refer to the `Env Var` section below.\n\nYou need a DLL injector to inject `InputFusion` into the target process.\n\nA quick google search will find you plenty on GitHub.\u003cbr/\u003e\n🐧 Linux: the classic combo `createRemoteThread()` + `LoadLibrary()` from `Kernel32` works under Wine/Proton.\n\nAlternatively, here are some of my own:\n\n- [xan105/Mini-Launcher](https://github.com/xan105/Mini-Launcher):\n\n  \u003e CLI launcher with DLL Injection, Lua Scripting, Splash screen, and other goodies.\n\n- [xan105/node-remote-thread](https://github.com/xan105/node-remote-thread):\n\n  \u003e Node.js NAPI Native addon for Windows DLL injection with support for Wow64 and Unicode path.\n\n\u003e [!TIP]\n\u003e Consider changing the file extension from `.dll` to `.asi` to help prevent false positive with Windows Defender.\n\n\u003cdetails\u003e\u003csummary\u003eExample (xan105/Mini-Launcher)\u003c/summary\u003e\n\n```json\n{\n  \"bin\": \"Binaries/NMS.exe\",\n  \"env\": {\n    \"GAMEPAD_API_XINPUT\": \"HOOK\"\n  },\n  \"addons\": [\n    { \"path\": \"Binaries/InputFusion.asi\", \"required\": true }\n  ]\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003eExample (xan105/node-remote-thread)\u003c/summary\u003e\n\n```js\nimport { env } from \"node:process\";\nimport { spawn } from \"node:child_process\";\nimport { dirname } from \"node:path\";\nimport { createRemoteThread } from \"@xan105/remote-thread\";\n\nconst EXECUTABLE = \"G:\\\\METAPHOR\\\\METAPHOR.exe\";\nconst ADDON = \"G:\\\\METAPHOR\\\\InputFusion.dll\";\nconst ARGS = [];\n\nconst binary = spawn(EXECUTABLE, ARGS, {\n  cwd: dirname(EXECUTABLE),\n  stdio:[ \"ignore\", \"ignore\", \"ignore\" ], \n  detached: true,\n  env: {\n    ...env,\n    \"GAMEPAD_API_XINPUT\": \"HOOK\"\n  }\n});\n\nbinary.once(\"spawn\", () =\u003e {\n  binary.unref();\n  createRemoteThread(binary.pid, ADDON);\n});\n```\n\u003c/details\u003e\n\nGamepad Layout\n==============\n\nGames have different layout expectation depending on their era and/or gamepads they support.\nFor practical reasons, this project tries to mimic a Xbox controller unless otherwise specified.\nVery old and legacy APIs tend to have a more custom/retro layout to match their era.\n\n💡 Please be advised that SDL has also the ability to change the mapping of a gamepad: see [Input Re-mapping](#input-re-mapping) below.\n\n- XInput:\n\nAs an Xbox controller\n\n- DInput8:\n\nAs an Xbox controller therefore it has the same limitations as a real Xbox controller with DInput such as no individual trigger axis.\n\n- DInput (1-7):\n\nAs DInput8.\n\n- WinMM:\n\n\u003e [!NOTE] \n\u003e After considering the games from that era that could be played with a gamepad. I somewhat deviated from the \"usual\" modern mapping for this implementation.\n\nThe D-Pad and the left joystick both map the X/Y axis, usually used for movement.\nThe right joystick maps to Z/R axes and to the POV when pressed + _direction_, usually used to move the camera point of view.\nThe right and left trigger are mapped to buttons.\nButtons order is tweaked to allow triggers in games supporting a limited amount of buttons and start/options to usually end up as the PAUSE button.\n\n\u003e [!TIP]\n\u003e If for some reasons you'd like the modern Xbox controller layout with WinMM, you can use the env. var. `GAMEPAD_API_WINMM_LAYOUT=XBOX` (See below).\n\nInput Re-mapping\n================\n\nSDL has the ability to change the mapping of an existing gamepad or add support for gamepads that SDL is unaware of.\nTo manually do so the end user can, for example, use the env var `SDL_GAMECONTROLLERCONFIG` or `SDL_GAMECONTROLLERCONFIG_FILE`.\n\nThe mapping string has the format: `GUID,name,mapping`. \n\nExample of a valid mapping for a Dualshock4 v2:\n```\n\"03008fe54c050000a00b000000016800,*,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,touchpad:b11,crc:e58f,platform:Windows,\"\n```\n\n🎮 Buttons can be used as axes and vice versa.\n\nExample to swap the D-PAD with the Left Joystick for retro gaming:\n```\n[...] dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,-leftx:h0.8,+leftx:h0.2,-lefty:h0.1,+lefty:h0.4, [...]\n```\n\n📄 For more details, please kindly see the [SDL documentation](https://wiki.libsdl.org/SDL3/SDL_AddGamepadMapping).\n\n\u003e [!TIP]\n\u003e [SDL testcontroller](https://github.com/libsdl-org/SDL/tree/main/test) is a GUI tool that can be used to create a string mapping (Setup Mapping \u003e Copy).\n\u003e A precompiled build can be found in this repo `/test/SDL_testcontroller` folder.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/xan105/InputFusion/raw/main/screenshot/SDL_testcontroller.png\"\u003e\n  \u003cem\u003eSDL testcontroller\u003c/em\u003e\n\u003c/p\u003e\n\nEnv Var\n=======\n\n🧪 Mostly experimental features are behind env var flags.\n\n#### `GAMEPAD_LED=BATTERYLVL`\n\n**BATTERYLVL**\n\nWhen enabled the LED light of the controller is used to show the battery level of the controller:\n\n  - 100% / Green\n  - 75% / Yellow\n  - 50% / Orange\n  - 25% / Red\n  \nCurrently only available for PS4/PS5 controller in wireless.\n\n`DLL: Any`\n\n#### `GAMEPAD_API_XINPUT=HOOK`\n\nEnable XInput functions hooking / detouring.\u003cbr /\u003e\nThis forces the use of the XInput functions from the DLL when calling XInput functions.\n\n`DLL: InputFusion, XInput`\n\n#### `GAMEPAD_API_DINPUT8=HOOK`\n\nEnable DInput8 functions hooking / detouring.\nThis forces the use of the DInput8 functions from the DLL when calling DInput8 functions.\n\n`DLL: InputFusion, Dinput8, XInput`\n\n#### `GAMEPAD_API_DINPUT=HOOK`\n\nEnable DInput 1-7 functions hooking / detouring.\nThis forces the use of the DInput functions from the DLL when calling DInput functions.\n\n`DLL: InputFusion, Dinput`\n\n#### `GAMEPAD_API_WINMM=HOOK`\n\nEnable WinMM functions hooking / detouring.\nThis forces the use of the WinMM functions from the DLL when calling WinMM Joystick related functions.\n\n`DLL: InputFusion, WinMM`\n\n#### `GAMEPAD_API_WINMM_LAYOUT=XBOX`\n\nUse the modern Xbox controller layout with WinMM. Useful for modern games that decided to use a legacy API for a Xbox controller such as [Deadly Premonition](https://store.steampowered.com/app/247660/Deadly_Premonition_The_Directors_Cut/).\n\n`DLL: InputFusion, WinMM`\n\nLinux (Wine/Proton)\n===================\n\nWine/Proton already translates Windows gamepad API calls. So it's a bit redundant, but yes this project does work under Wine/Proton.\nYou just need to tell Wine/Proton to load the dll instead of its built-in:\n\nExample:\n\n```\nWINEDLLOVERRIDES=\"xinput1_3=n,b\n```\n\nNB: In case of DLL injection you need a DLL injector that can run under Wine/Proton.\nThe classic combo `createRemoteThread()` + `LoadLibrary()` from Kernel32 works under Wine/Proton.\nA quick google search will find you plenty on GitHub. Otherwise may I suggest one of my own: [xan105/Mini-Launcher](https://github.com/xan105/Mini-Launcher)\n\nCaveats\n=======\n\n- SDL might still be initializing when the game does it's first Gamepad API call (on startup).\n\n- Games that support more than one input API usually, but not always, do a lot of Win32 APIs sniffing behind the scenes to determine which input API to use.\n  Therefore even tho an input API is translated to SDL, your gamepad may still not work due to how a game engine is programmed and how it decides to handle input.\n  The focus of this project is **for now** on API translation and not on compatibility for _poorly engineered_ games. \n\nBuild\n=====\n\n🆚 **Visual Studio 2022**\n\n📦 Vendor dependencies:\n  - [Microsoft Detours library](https://github.com/microsoft/Detours)\n  - [SDL3 Library](https://github.com/libsdl-org/SDL) recompiled as a static lib.\n\nSolution: `./vc/InputFusion.sln`\n\nThe 5 projects inside the solution control the build output:\n  - InputFusion -\u003e `InputFusion.dll` (DLL injection)\n  - XInput      -\u003e `xinput.dll` (DLL sideloading / injection)\n  - DInput8     -\u003e `dinput8.dll` (DLL sideloading / injection)\n  - DInput      -\u003e `dinput.dll` (DLL sideloading / injection)\n  - WinMM       -\u003e `winmm.dll` (DLL sideloading / injection)\n  \nOutput: `./build/${project}/output/${platform}/${config}`\n\n## Github Actions\n\n`./.github/workflows/vs-build-on-windows.yaml`\n\nBuild all targets (debug and release) and create a release.\n","funding_links":["https://github.com/sponsors/xan105","https://www.paypal.me/xan105"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxan105%2Finputfusion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxan105%2Finputfusion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxan105%2Finputfusion/lists"}