This document describes how GameInputSharp.Core aligns with Microsoft's official GameInput API. Historical changes (e.g. initialization and enumeration fixes) are recorded in CHANGELOG.md.
Reference: GameInput API members | GameInputCreate | GameInputDeviceInfo | IGameInput | IGameInputDevice
- The wrapper uses GameInputCreate(IGameInput**) as the only entry point. The DLL is loaded, GameInputCreate is resolved and called, and the returned pointer is marshalled to IGameInput via GetObjectForIUnknown. GameInputInitialize is not used.
- RegisterDeviceCallback is called with a device kind filter: GameInputKindGamepad | GameInputKindController | GameInputKindKeyboard | GameInputKindMouse so gamepads, keyboards, and mice are enumerated. GameInputKindUnknown is not used for enumeration.
- GameInputDeviceInfo documents that all string members use UTF-8 encoding;
displayNameandpnpPathareconst char*. Offsets in code follow the documented field order (vendorId through containerId, then displayName/pnpPath pointers). Any string read from native uses UTF-8 viaPtrToUtf8. On PC, the wrapper does not read the displayName or pnpPath pointers (doing so can cause AccessViolation); those fields are returned as empty strings. DeviceId and other fields are read and work as documented.
| Area | Our usage | Doc / notes |
|---|---|---|
| Entry point | GameInputCreate(out IntPtr) | GameInputCreate(IGameInput**); we marshal ppv to IGameInput via GetObjectForIUnknown. |
| IGameInput | GetCurrentTimestamp, GetCurrentReading, GetNextReading, GetPreviousReading, RegisterDeviceCallback, RegisterReadingCallback, RegisterSystemButtonCallback, RegisterKeyboardLayoutCallback, StopCallback, UnregisterCallback, CreateDispatcher, FindDeviceFromId, FindDeviceFromPlatformString, SetFocusPolicy, CreateAggregateDevice, DisableAggregateDevice | Method names and intent match; vtable order in GameInputComInterfaces.cs must match native (IUnknown + interface methods). |
| IGameInputDevice | GetDeviceInfo, GetHapticInfo, GetDeviceStatus, CreateForceFeedbackEffect, IsForceFeedbackMotorPoweredOn, SetForceFeedbackMotorGain, SetRumbleState, DirectInputEscape, CreateInputMapper, GetExtraAxisCount/GetExtraButtonCount/GetExtraAxisIndexes/GetExtraButtonIndexes, CreateRawDeviceReport, SendRawDeviceOutput | Method set matches doc; parameter types and order must match native. |
| IGameInputDispatcher | Dispatch(quotaMicroseconds), OpenWaitHandle | Matches doc. |
| GameInputDeviceInfo | Offsets for vendorId, productId, usage, versions, deviceId, deviceRootId, deviceFamily, supportedInput, supportedRumbleMotors, supportedSystemButtons, containerId, displayName, pnpPath, then subtype info pointers | Layout comment and constants reference the official struct; displayName/pnpPath are not read on PC to avoid crashes. |
| Callbacks | GameInputDeviceCallback, GameInputReadingCallback, GameInputSystemButtonCallback, GameInputKeyboardLayoutCallback | Names and usage match Register* and UnregisterCallback. |
| Constants | GameInputKind*, GameInputDeviceConnected, GameInputBlockingEnumeration, etc. | Sourced from GameInputNative.cs / Native/*; values match GameInput.h. |
-
Display name and pnpPath on PC
ReadingdisplayName/pnpPathfrom GameInputDeviceInfo on the PC runtime can cause AccessViolation. The wrapper returns empty strings until a safe read path exists (e.g. confirmed layout for the NuGet runtime or a small native probe). Official doc: UTF-8, layout as in GameInputDeviceInfo. -
COM vtable order
IGameInput and IGameInputDevice method order in GameInputComInterfaces.cs must match the native vtable (QueryInterface, AddRef, Release plus interface methods in the same order as the C++ header). When adding or reordering methods, verify against the SDK header or a known-good def. -
Struct layouts
GameInputVersion, GameInputUsage, AppLocalDeviceId, GameInputHapticInfo, force feedback params, reading state structs, etc. — layout and size must match the native headers. Any mismatch can cause wrong data or crashes when passing structs to native (e.g. GetHapticInfo, CreateForceFeedbackEffect). -
New APIs
When updating to a newer GameInput version, cross-check GameInput API members and add/update interfaces, constants, and wrappers accordingly.
- Any new GameInput entry point or COM method: confirm name and signature against Microsoft docs (learn.microsoft.com/gaming/gdk/docs/reference/input/gameinput/...).
- Structs passed to or from native: verify layout (field order, sizes, padding) against GameInput.h / docs.
- String encoding: GameInputDeviceInfo and other doc-specified strings are UTF-8 unless stated otherwise.
- Enums and constants: use values from official docs or GameInput.h to avoid mismatches with the runtime.