From d380e431660f8a18d311641b962743b5839f8136 Mon Sep 17 00:00:00 2001 From: Ali Salehi Date: Sun, 18 Feb 2024 21:28:30 +0100 Subject: [PATCH 1/2] Add xinput bindings to core:sys/windows --- core/sys/windows/xinput.odin | 227 +++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 core/sys/windows/xinput.odin diff --git a/core/sys/windows/xinput.odin b/core/sys/windows/xinput.odin new file mode 100644 index 000000000..2b1303e0d --- /dev/null +++ b/core/sys/windows/xinput.odin @@ -0,0 +1,227 @@ +// +build windows +package sys_windows + +foreign import "system:xinput.lib" + +// Device types available in XINPUT_CAPABILITIES +// Correspond to XINPUT_DEVTYPE_... +XINPUT_DEVTYPE :: enum BYTE { + GAMEPAD = 0x01, +} + +// Device subtypes available in XINPUT_CAPABILITIES +// Correspond to XINPUT_DEVSUBTYPE_... +XINPUT_DEVSUBTYPE :: enum BYTE { + UNKNOWN = 0x00, + GAMEPAD = 0x01, + WHEEL = 0x02, + ARCADE_STICK = 0x03, + FLIGHT_STICK = 0x04, + DANCE_PAD = 0x05, + GUITAR = 0x06, + GUITAR_ALTERNATE = 0x07, + DRUM_KIT = 0x08, + GUITAR_BASS = 0x0B, + ARCADE_PAD = 0x13, +} + +// Flags for XINPUT_CAPABILITIES +// Correspond to log2(XINPUT_CAPS_...) +XINPUT_CAP :: enum { + FFB_SUPPORTED = 0, + WIRELESS = 1, + VOICE_SUPPORTED = 2, + PMD_SUPPORTED = 3, + NO_NAVIGATION = 4, +} +XINPUT_CAPS :: bit_set[XINPUT_CAP;WORD] + +// Constants for gamepad buttons +// Correspond to log2(XINPUT_GAMEPAD_...) +XINPUT_GAMEPAD_BUTTON_BIT :: enum { + DPAD_UP = 0, + DPAD_DOWN = 1, + DPAD_LEFT = 2, + DPAD_RIGHT = 3, + START = 4, + BACK = 5, + LEFT_THUMB = 6, + RIGHT_THUMB = 7, + LEFT_SHOULDER = 8, + RIGHT_SHOULDER = 9, + A = 12, + B = 13, + X = 14, + Y = 15, +} +XINPUT_GAMEPAD_BUTTON :: bit_set[XINPUT_GAMEPAD_BUTTON_BIT;WORD] + +// Gamepad thresholds +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE: SHORT : 7849 +XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE: SHORT : 8689 +XINPUT_GAMEPAD_TRIGGER_THRESHOLD: SHORT : 30 + +// Flags to pass to XInputGetCapabilities +// Corresponds to log2(XINPUT_FLAG_...) +XINPUT_FLAG_BIT :: enum { + GAMEPAD = 0, +} +XINPUT_FLAG :: bit_set[XINPUT_FLAG_BIT;DWORD] + +// Devices that support batteries +// Corresponds to BATTERY_DEVTYPE_... +BATTERY_DEVTYPE :: enum BYTE { + GAMEPAD = 0x00, + HEADSET = 0x01, +} + +// Flags for battery status level +// Correspond to BATTERY_TYPE_... +BATTERY_TYPE :: enum BYTE { + DISCONNECTED = 0x00, // This device is not connected + WIRED = 0x01, // Wired device, no battery + ALKALINE = 0x02, // Alkaline battery source + NIMH = 0x03, // Nickel Metal Hydride battery source + UNKNOWN = 0xFF, // Cannot determine the battery type +} + +// These are only valid for wireless, connected devices, with known battery types +// The amount of use time remaining depends on the type of device. +// Correspond to BATTERY_LEVEL_... +BATTERY_LEVEL :: enum BYTE { + EMPTY = 0x00, + LOW = 0x01, + MEDIUM = 0x02, + FULL = 0x03, +} + +// User index definitions + +// Index of the gamer associated with the device +XUSER :: enum DWORD { + One = 0, + Two = 1, + Three = 2, + Four = 3, + Any = 0x000000FF, // Can be only used with XInputGetKeystroke +} + +XUSER_MAX_COUNT :: 4 + +// Codes returned for the gamepad keystroke +// Corresponds to VK_PAD_... +VK_PAD :: enum WORD { + A = 0x5800, + B = 0x5801, + X = 0x5802, + Y = 0x5803, + RSHOULDER = 0x5804, + LSHOULDER = 0x5805, + LTRIGGER = 0x5806, + RTRIGGER = 0x5807, + DPAD_UP = 0x5810, + DPAD_DOWN = 0x5811, + DPAD_LEFT = 0x5812, + DPAD_RIGHT = 0x5813, + START = 0x5814, + BACK = 0x5815, + LTHUMB_PRESS = 0x5816, + RTHUMB_PRESS = 0x5817, + LTHUMB_UP = 0x5820, + LTHUMB_DOWN = 0x5821, + LTHUMB_RIGHT = 0x5822, + LTHUMB_LEFT = 0x5823, + LTHUMB_UPLEFT = 0x5824, + LTHUMB_UPRIGHT = 0x5825, + LTHUMB_DOWNRIGHT = 0x5826, + LTHUMB_DOWNLEFT = 0x5827, + RTHUMB_UP = 0x5830, + RTHUMB_DOWN = 0x5831, + RTHUMB_RIGHT = 0x5832, + RTHUMB_LEFT = 0x5833, + RTHUMB_UPLEFT = 0x5834, + RTHUMB_UPRIGHT = 0x5835, + RTHUMB_DOWNRIGHT = 0x5836, + RTHUMB_DOWNLEFT = 0x5837, +} + +// Flags used in XINPUT_KEYSTROKE +// Correspond to log2(XINPUT_KEYSTROKE_...) +XINPUT_KEYSTROKE_BIT :: enum { + KEYDOWN = 0, + KEYUP = 1, + REPEAT = 2, +} +XINPUT_KEYSTROKES :: bit_set[XINPUT_KEYSTROKE_BIT;WORD] + +// Structures used by XInput APIs +XINPUT_GAMEPAD :: struct { + wButtons: XINPUT_GAMEPAD_BUTTON, + bLeftTrigger: BYTE, + bRightTrigger: BYTE, + sThumbLX: SHORT, + sThumbLY: SHORT, + sThumbRX: SHORT, + sThumbRY: SHORT, +} + +XINPUT_STATE :: struct { + dwPacketNumber: DWORD, + Gamepad: XINPUT_GAMEPAD, +} + +XINPUT_VIBRATION :: struct { + wLeftMotorSpeed: WORD, + wRightMotorSpeed: WORD, +} + +XINPUT_CAPABILITIES :: struct { + Type: XINPUT_DEVTYPE, + SubType: XINPUT_DEVSUBTYPE, + Flags: XINPUT_CAPS, + Gamepad: XINPUT_GAMEPAD, + Vibration: XINPUT_VIBRATION, +} + +XINPUT_BATTERY_INFORMATION :: struct { + BatteryType: BATTERY_TYPE, + BatteryLevel: BATTERY_LEVEL, +} + +XINPUT_KEYSTROKE :: struct { + VirtualKey: VK_PAD, + Unicode: WCHAR, + Flags: XINPUT_KEYSTROKES, + UserIndex: XUSER, + HidCode: BYTE, +} + +// XInput APIs +@(default_calling_convention = "system") +foreign xinput { + + @(link_name = "XInputGetState") + XInputGetState :: proc(user: XUSER, pState: ^XINPUT_STATE) -> System_Error --- + + @(link_name = "XInputSetState") + XInputSetState :: proc(user: XUSER, pVibration: ^XINPUT_VIBRATION) -> System_Error --- + + @(link_name = "XInputGetCapabilities") + XInputGetCapabilities :: proc(user: XUSER, dwFlags: XINPUT_FLAG, pCapabilities: ^XINPUT_CAPABILITIES) -> System_Error --- + + @(link_name = "XInputEnable") + XInputEnable :: proc(enable: BOOL) --- + + @(link_name = "XInputGetAudioDeviceIds") + XInputGetAudioDeviceIds :: proc(user: XUSER, pRenderDeviceId: LPWSTR, pRenderCount: ^UINT, pCaptureDeviceId: LPWSTR, pCaptureCount: ^UINT) -> System_Error --- + + @(link_name = "XInputGetBatteryInformation") + XInputGetBatteryInformation :: proc(user: XUSER, devType: BATTERY_DEVTYPE, pBatteryInformation: ^XINPUT_BATTERY_INFORMATION) -> System_Error --- + + @(link_name = "XInputGetKeystroke") + XInputGetKeystroke :: proc(user: XUSER, dwReserved: DWORD, pKeystroke: ^XINPUT_KEYSTROKE) -> System_Error --- + + @(link_name = "XInputGetDSoundAudioDeviceGuids") + XInputGetDSoundAudioDeviceGuids :: proc(user: XUSER, pDSoundRenderGuid: ^GUID, pDSoundCaptureGuid: ^GUID) -> System_Error --- + +} From 8aab0f9e34ab8818b7599c285799819b22319cad Mon Sep 17 00:00:00 2001 From: Ali Salehi Date: Mon, 19 Feb 2024 15:55:57 +0100 Subject: [PATCH 2/2] Add distinct and remove unnecessary link_names --- core/sys/windows/xinput.odin | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/core/sys/windows/xinput.odin b/core/sys/windows/xinput.odin index 2b1303e0d..014d2573a 100644 --- a/core/sys/windows/xinput.odin +++ b/core/sys/windows/xinput.odin @@ -27,18 +27,18 @@ XINPUT_DEVSUBTYPE :: enum BYTE { // Flags for XINPUT_CAPABILITIES // Correspond to log2(XINPUT_CAPS_...) -XINPUT_CAP :: enum { +XINPUT_CAP :: enum WORD { FFB_SUPPORTED = 0, WIRELESS = 1, VOICE_SUPPORTED = 2, PMD_SUPPORTED = 3, NO_NAVIGATION = 4, } -XINPUT_CAPS :: bit_set[XINPUT_CAP;WORD] +XINPUT_CAPS :: distinct bit_set[XINPUT_CAP;WORD] // Constants for gamepad buttons // Correspond to log2(XINPUT_GAMEPAD_...) -XINPUT_GAMEPAD_BUTTON_BIT :: enum { +XINPUT_GAMEPAD_BUTTON_BIT :: enum WORD { DPAD_UP = 0, DPAD_DOWN = 1, DPAD_LEFT = 2, @@ -54,7 +54,7 @@ XINPUT_GAMEPAD_BUTTON_BIT :: enum { X = 14, Y = 15, } -XINPUT_GAMEPAD_BUTTON :: bit_set[XINPUT_GAMEPAD_BUTTON_BIT;WORD] +XINPUT_GAMEPAD_BUTTON :: distinct bit_set[XINPUT_GAMEPAD_BUTTON_BIT;WORD] // Gamepad thresholds XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE: SHORT : 7849 @@ -63,10 +63,10 @@ XINPUT_GAMEPAD_TRIGGER_THRESHOLD: SHORT : 30 // Flags to pass to XInputGetCapabilities // Corresponds to log2(XINPUT_FLAG_...) -XINPUT_FLAG_BIT :: enum { +XINPUT_FLAG_BIT :: enum WORD { GAMEPAD = 0, } -XINPUT_FLAG :: bit_set[XINPUT_FLAG_BIT;DWORD] +XINPUT_FLAG :: distinct bit_set[XINPUT_FLAG_BIT;DWORD] // Devices that support batteries // Corresponds to BATTERY_DEVTYPE_... @@ -147,12 +147,12 @@ VK_PAD :: enum WORD { // Flags used in XINPUT_KEYSTROKE // Correspond to log2(XINPUT_KEYSTROKE_...) -XINPUT_KEYSTROKE_BIT :: enum { +XINPUT_KEYSTROKE_BIT :: enum WORD { KEYDOWN = 0, KEYUP = 1, REPEAT = 2, } -XINPUT_KEYSTROKES :: bit_set[XINPUT_KEYSTROKE_BIT;WORD] +XINPUT_KEYSTROKES :: distinct bit_set[XINPUT_KEYSTROKE_BIT;WORD] // Structures used by XInput APIs XINPUT_GAMEPAD :: struct { @@ -199,29 +199,12 @@ XINPUT_KEYSTROKE :: struct { // XInput APIs @(default_calling_convention = "system") foreign xinput { - - @(link_name = "XInputGetState") XInputGetState :: proc(user: XUSER, pState: ^XINPUT_STATE) -> System_Error --- - - @(link_name = "XInputSetState") XInputSetState :: proc(user: XUSER, pVibration: ^XINPUT_VIBRATION) -> System_Error --- - - @(link_name = "XInputGetCapabilities") XInputGetCapabilities :: proc(user: XUSER, dwFlags: XINPUT_FLAG, pCapabilities: ^XINPUT_CAPABILITIES) -> System_Error --- - - @(link_name = "XInputEnable") XInputEnable :: proc(enable: BOOL) --- - - @(link_name = "XInputGetAudioDeviceIds") XInputGetAudioDeviceIds :: proc(user: XUSER, pRenderDeviceId: LPWSTR, pRenderCount: ^UINT, pCaptureDeviceId: LPWSTR, pCaptureCount: ^UINT) -> System_Error --- - - @(link_name = "XInputGetBatteryInformation") XInputGetBatteryInformation :: proc(user: XUSER, devType: BATTERY_DEVTYPE, pBatteryInformation: ^XINPUT_BATTERY_INFORMATION) -> System_Error --- - - @(link_name = "XInputGetKeystroke") XInputGetKeystroke :: proc(user: XUSER, dwReserved: DWORD, pKeystroke: ^XINPUT_KEYSTROKE) -> System_Error --- - - @(link_name = "XInputGetDSoundAudioDeviceGuids") XInputGetDSoundAudioDeviceGuids :: proc(user: XUSER, pDSoundRenderGuid: ^GUID, pDSoundCaptureGuid: ^GUID) -> System_Error --- - }