mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-27 19:22:49 +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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
@ -30,6 +32,53 @@ var (
|
|||||||
procGameInputCreate = gameInput.NewProc("GameInputCreate")
|
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) {
|
func _GameInputCreate() (*_IGameInput, error) {
|
||||||
var gameInput *_IGameInput
|
var gameInput *_IGameInput
|
||||||
r, _, _ := procGameInputCreate.Call(uintptr(unsafe.Pointer(&gameInput)))
|
r, _, _ := procGameInputCreate.Call(uintptr(unsafe.Pointer(&gameInput)))
|
||||||
@ -47,4 +96,72 @@ type _IGameInput_Vtbl struct {
|
|||||||
QueryInterface uintptr
|
QueryInterface uintptr
|
||||||
AddRef uintptr
|
AddRef uintptr
|
||||||
Release 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
|
package gamepad
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
type nativeGamepadsXbox struct {
|
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 {
|
func (n *nativeGamepadsXbox) init(gamepads *gamepads) error {
|
||||||
@ -26,7 +45,21 @@ func (n *nativeGamepadsXbox) init(gamepads *gamepads) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
n.gameInput = g
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user