mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 10:42:42 +01:00
internal/gamepad: implement gamepad detection callbacks for Xbox
Updates #2084
This commit is contained in:
parent
8cb023e3c8
commit
97039ff714
@ -19,6 +19,8 @@ package gamepad
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
@ -30,6 +32,53 @@ var (
|
||||
procGameInputCreate = gameInput.NewProc("GameInputCreate")
|
||||
)
|
||||
|
||||
type _GameInputEnumerationKind int32
|
||||
|
||||
const (
|
||||
_GameInputNoEnumeration _GameInputEnumerationKind = 0
|
||||
_GameInputAsyncEnumeration _GameInputEnumerationKind = 1
|
||||
_GameInputBlockingEnumeration _GameInputEnumerationKind = 2
|
||||
)
|
||||
|
||||
type _GameInputCallbackToken uint64
|
||||
|
||||
type _GameInputDeviceStatus int32
|
||||
|
||||
const (
|
||||
_GameInputDeviceNoStatus _GameInputDeviceStatus = 0x00000000
|
||||
_GameInputDeviceConnected _GameInputDeviceStatus = 0x00000001
|
||||
_GameInputDeviceInputEnabled _GameInputDeviceStatus = 0x00000002
|
||||
_GameInputDeviceOutputEnabled _GameInputDeviceStatus = 0x00000004
|
||||
_GameInputDeviceRawIoEnabled _GameInputDeviceStatus = 0x00000008
|
||||
_GameInputDeviceAudioCapture _GameInputDeviceStatus = 0x00000010
|
||||
_GameInputDeviceAudioRender _GameInputDeviceStatus = 0x00000020
|
||||
_GameInputDeviceSynchronized _GameInputDeviceStatus = 0x00000040
|
||||
_GameInputDeviceWireless _GameInputDeviceStatus = 0x00000080
|
||||
_GameInputDeviceUserIdle _GameInputDeviceStatus = 0x00100000
|
||||
_GameInputDeviceAnyStatus _GameInputDeviceStatus = 0x00FFFFFF
|
||||
)
|
||||
|
||||
type _GameInputKind int32
|
||||
|
||||
const (
|
||||
_GameInputKindUnknown _GameInputKind = 0x00000000
|
||||
_GameInputKindRawDeviceReport _GameInputKind = 0x00000001
|
||||
_GameInputKindControllerAxis _GameInputKind = 0x00000002
|
||||
_GameInputKindControllerButton _GameInputKind = 0x00000004
|
||||
_GameInputKindControllerSwitch _GameInputKind = 0x00000008
|
||||
_GameInputKindController _GameInputKind = 0x0000000E
|
||||
_GameInputKindKeyboard _GameInputKind = 0x00000010
|
||||
_GameInputKindMouse _GameInputKind = 0x00000020
|
||||
_GameInputKindTouch _GameInputKind = 0x00000100
|
||||
_GameInputKindMotion _GameInputKind = 0x00001000
|
||||
_GameInputKindArcadeStick _GameInputKind = 0x00010000
|
||||
_GameInputKindFlightStick _GameInputKind = 0x00020000
|
||||
_GameInputKindGamepad _GameInputKind = 0x00040000
|
||||
_GameInputKindRacingWheel _GameInputKind = 0x00080000
|
||||
_GameInputKindUiNavigation _GameInputKind = 0x01000000
|
||||
_GameInputKindAny _GameInputKind = 0x0FFFFFFF
|
||||
)
|
||||
|
||||
func _GameInputCreate() (*_IGameInput, error) {
|
||||
var gameInput *_IGameInput
|
||||
r, _, _ := procGameInputCreate.Call(uintptr(unsafe.Pointer(&gameInput)))
|
||||
@ -47,4 +96,72 @@ type _IGameInput_Vtbl struct {
|
||||
QueryInterface uintptr
|
||||
AddRef uintptr
|
||||
Release uintptr
|
||||
|
||||
GetCurrentTimestamp uintptr
|
||||
GetCurrentReading uintptr
|
||||
GetNextReading uintptr
|
||||
GetPreviousReading uintptr
|
||||
GetTemporalReading uintptr
|
||||
RegisterReadingCallback uintptr
|
||||
RegisterDeviceCallback uintptr
|
||||
RegisterGuideButtonCallback uintptr
|
||||
RegisterKeyboardLayoutCallback uintptr
|
||||
StopCallback uintptr
|
||||
UnregisterCallback uintptr
|
||||
CreateDispatcher uintptr
|
||||
CreateAggregateDevice uintptr
|
||||
FindDeviceFromId uintptr
|
||||
FindDeviceFromObject uintptr
|
||||
FindDeviceFromPlatformHandle uintptr
|
||||
FindDeviceFromPlatformString uintptr
|
||||
EnableOemDeviceSupport uintptr
|
||||
SetFocusPolicy uintptr
|
||||
}
|
||||
|
||||
func (i *_IGameInput) RegisterDeviceCallback(device *_IGameInputDevice,
|
||||
inputKind _GameInputKind,
|
||||
statusFilter _GameInputDeviceStatus,
|
||||
enumerationKind _GameInputEnumerationKind,
|
||||
context unsafe.Pointer,
|
||||
callbackFunc uintptr,
|
||||
callbackToken *_GameInputCallbackToken) error {
|
||||
r, _, _ := syscall.Syscall9(i.vtbl.RegisterDeviceCallback, 8, uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(device)), uintptr(inputKind), uintptr(statusFilter),
|
||||
uintptr(enumerationKind), uintptr(context), callbackFunc,
|
||||
uintptr(unsafe.Pointer(callbackToken)), 0)
|
||||
runtime.KeepAlive(device)
|
||||
runtime.KeepAlive(callbackToken)
|
||||
if uint32(r) != uint32(windows.S_OK) {
|
||||
return fmt.Errorf("gamepad: IGameInput::RegisterDeviceCallback failed: HRESULT(%d)", uint32(r))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type _IGameInputDevice struct {
|
||||
vtbl *_IGameInputDevice_Vtbl
|
||||
}
|
||||
|
||||
type _IGameInputDevice_Vtbl struct {
|
||||
QueryInterface uintptr
|
||||
AddRef uintptr
|
||||
Release uintptr
|
||||
|
||||
GetDeviceInfo uintptr
|
||||
GetDeviceStatus uintptr
|
||||
GetBatteryState uintptr
|
||||
CreateForceFeedbackEffect uintptr
|
||||
IsForceFeedbackMotorPoweredOn uintptr
|
||||
SetForceFeedbackMotorGain uintptr
|
||||
SetHapticMotorState uintptr
|
||||
SetRumbleState uintptr
|
||||
SetInputSynchronizationState uintptr
|
||||
SendInputSynchronizationHint uintptr
|
||||
PowerOff uintptr
|
||||
CreateRawDeviceReport uintptr
|
||||
GetRawDeviceFeature uintptr
|
||||
SetRawDeviceFeature uintptr
|
||||
SendRawDeviceOutput uintptr
|
||||
ExecuteRawDeviceIoControl uintptr
|
||||
AcquireExclusiveRawDeviceAccess uintptr
|
||||
ReleaseExclusiveRawDeviceAccess uintptr
|
||||
}
|
||||
|
@ -17,8 +17,27 @@
|
||||
|
||||
package gamepad
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type nativeGamepadsXbox struct {
|
||||
gameInput *_IGameInput
|
||||
gameInput *_IGameInput
|
||||
deviceCallbackPtr uintptr
|
||||
token _GameInputCallbackToken
|
||||
}
|
||||
|
||||
func xboxDeviceCallback(
|
||||
callbackToken _GameInputCallbackToken,
|
||||
context unsafe.Pointer,
|
||||
device *_IGameInputDevice,
|
||||
timestamp uint64,
|
||||
currentStatus _GameInputDeviceStatus,
|
||||
previousStatus _GameInputDeviceStatus) uintptr {
|
||||
// TODO: Implement this.
|
||||
return 0
|
||||
}
|
||||
|
||||
func (n *nativeGamepadsXbox) init(gamepads *gamepads) error {
|
||||
@ -26,7 +45,21 @@ func (n *nativeGamepadsXbox) init(gamepads *gamepads) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n.gameInput = g
|
||||
n.deviceCallbackPtr = windows.NewCallbackCDecl(xboxDeviceCallback)
|
||||
|
||||
if err := n.gameInput.RegisterDeviceCallback(
|
||||
nil,
|
||||
_GameInputKindGamepad,
|
||||
_GameInputDeviceConnected,
|
||||
_GameInputBlockingEnumeration,
|
||||
nil,
|
||||
n.deviceCallbackPtr,
|
||||
&n.token,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user