mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
parent
a6f6fdbfb7
commit
ac5c48f575
@ -32,14 +32,6 @@ var (
|
||||
procGameInputCreate = gameInput.NewProc("GameInputCreate")
|
||||
)
|
||||
|
||||
type _GameInputEnumerationKind int32
|
||||
|
||||
const (
|
||||
_GameInputNoEnumeration _GameInputEnumerationKind = 0
|
||||
_GameInputAsyncEnumeration _GameInputEnumerationKind = 1
|
||||
_GameInputBlockingEnumeration _GameInputEnumerationKind = 2
|
||||
)
|
||||
|
||||
type _GameInputCallbackToken uint64
|
||||
|
||||
type _GameInputDeviceStatus int32
|
||||
@ -58,6 +50,34 @@ const (
|
||||
_GameInputDeviceAnyStatus _GameInputDeviceStatus = 0x00FFFFFF
|
||||
)
|
||||
|
||||
type _GameInputEnumerationKind int32
|
||||
|
||||
const (
|
||||
_GameInputNoEnumeration _GameInputEnumerationKind = 0
|
||||
_GameInputAsyncEnumeration _GameInputEnumerationKind = 1
|
||||
_GameInputBlockingEnumeration _GameInputEnumerationKind = 2
|
||||
)
|
||||
|
||||
type _GameInputGamepadButtons int32
|
||||
|
||||
const (
|
||||
_GameInputGamepadNone _GameInputGamepadButtons = 0x00000000
|
||||
_GameInputGamepadMenu _GameInputGamepadButtons = 0x00000001
|
||||
_GameInputGamepadView _GameInputGamepadButtons = 0x00000002
|
||||
_GameInputGamepadA _GameInputGamepadButtons = 0x00000004
|
||||
_GameInputGamepadB _GameInputGamepadButtons = 0x00000008
|
||||
_GameInputGamepadX _GameInputGamepadButtons = 0x00000010
|
||||
_GameInputGamepadY _GameInputGamepadButtons = 0x00000020
|
||||
_GameInputGamepadDPadUp _GameInputGamepadButtons = 0x00000040
|
||||
_GameInputGamepadDPadDown _GameInputGamepadButtons = 0x00000080
|
||||
_GameInputGamepadDPadLeft _GameInputGamepadButtons = 0x00000100
|
||||
_GameInputGamepadDPadRight _GameInputGamepadButtons = 0x00000200
|
||||
_GameInputGamepadLeftShoulder _GameInputGamepadButtons = 0x00000400
|
||||
_GameInputGamepadRightShoulder _GameInputGamepadButtons = 0x00000800
|
||||
_GameInputGamepadLeftThumbstick _GameInputGamepadButtons = 0x00001000
|
||||
_GameInputGamepadRightThumbstick _GameInputGamepadButtons = 0x00002000
|
||||
)
|
||||
|
||||
type _GameInputKind int32
|
||||
|
||||
const (
|
||||
@ -79,6 +99,16 @@ const (
|
||||
_GameInputKindAny _GameInputKind = 0x0FFFFFFF
|
||||
)
|
||||
|
||||
type _GameInputGamepadState struct {
|
||||
buttons _GameInputGamepadButtons
|
||||
leftTrigger float32
|
||||
rightTrigger float32
|
||||
leftThumbstickX float32
|
||||
leftThumbstickY float32
|
||||
rightThumbstickX float32
|
||||
rightThumbstickY float32
|
||||
}
|
||||
|
||||
func _GameInputCreate() (*_IGameInput, error) {
|
||||
var gameInput *_IGameInput
|
||||
r, _, _ := procGameInputCreate.Call(uintptr(unsafe.Pointer(&gameInput)))
|
||||
@ -118,6 +148,18 @@ type _IGameInput_Vtbl struct {
|
||||
SetFocusPolicy uintptr
|
||||
}
|
||||
|
||||
func (i *_IGameInput) GetCurrentReading(inputKind _GameInputKind, device *_IGameInputDevice) (*_IGameInputReading, error) {
|
||||
var reading *_IGameInputReading
|
||||
r, _, _ := syscall.Syscall6(i.vtbl.GetCurrentReading, 4, uintptr(unsafe.Pointer(i)),
|
||||
uintptr(inputKind), uintptr(unsafe.Pointer(device)), uintptr(unsafe.Pointer(&reading)),
|
||||
0, 0)
|
||||
runtime.KeepAlive(device)
|
||||
if uint32(r) != uint32(windows.S_OK) {
|
||||
return nil, fmt.Errorf("gamepad: IGameInput::GetCurrentReading failed: HRESULT(%d)", uint32(r))
|
||||
}
|
||||
return reading, nil
|
||||
}
|
||||
|
||||
func (i *_IGameInput) RegisterDeviceCallback(device *_IGameInputDevice,
|
||||
inputKind _GameInputKind,
|
||||
statusFilter _GameInputDeviceStatus,
|
||||
@ -165,3 +207,42 @@ type _IGameInputDevice_Vtbl struct {
|
||||
AcquireExclusiveRawDeviceAccess uintptr
|
||||
ReleaseExclusiveRawDeviceAccess uintptr
|
||||
}
|
||||
|
||||
type _IGameInputReading struct {
|
||||
vtbl *_IGameInputReading_Vtbl
|
||||
}
|
||||
|
||||
type _IGameInputReading_Vtbl struct {
|
||||
QueryInterface uintptr
|
||||
AddRef uintptr
|
||||
Release uintptr
|
||||
|
||||
GetInputKind uintptr
|
||||
GetSequenceNumber uintptr
|
||||
GetTimestamp uintptr
|
||||
GetDevice uintptr
|
||||
GetRawReport uintptr
|
||||
GetControllerAxisCount uintptr
|
||||
GetControllerAxisState uintptr
|
||||
GetControllerButtonCount uintptr
|
||||
GetControllerButtonState uintptr
|
||||
GetControllerSwitchCount uintptr
|
||||
GetControllerSwitchState uintptr
|
||||
GetKeyCount uintptr
|
||||
GetKeyState uintptr
|
||||
GetMouseState uintptr
|
||||
GetTouchCount uintptr
|
||||
GetTouchState uintptr
|
||||
GetMotionState uintptr
|
||||
GetArcadeStickState uintptr
|
||||
GetFlightStickState uintptr
|
||||
GetGamepadState uintptr
|
||||
GetRacingWheelState uintptr
|
||||
GetUiNavigationState uintptr
|
||||
}
|
||||
|
||||
func (i *_IGameInputReading) GetGamepadState() (_GameInputGamepadState, bool) {
|
||||
var state _GameInputGamepadState
|
||||
r, _, _ := syscall.Syscall(i.vtbl.GetGamepadState, 2, uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(&state)), 0)
|
||||
return state, int32(r) != 0
|
||||
}
|
||||
|
@ -22,8 +22,50 @@ import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/gamepaddb"
|
||||
)
|
||||
|
||||
func standardButtonToGamepadInputGamepadButton(b gamepaddb.StandardButton) (_GameInputGamepadButtons, bool) {
|
||||
switch b {
|
||||
case gamepaddb.StandardButtonRightBottom:
|
||||
return _GameInputGamepadA, true
|
||||
case gamepaddb.StandardButtonRightRight:
|
||||
return _GameInputGamepadB, true
|
||||
case gamepaddb.StandardButtonRightLeft:
|
||||
return _GameInputGamepadX, true
|
||||
case gamepaddb.StandardButtonRightTop:
|
||||
return _GameInputGamepadY, true
|
||||
case gamepaddb.StandardButtonFrontTopLeft:
|
||||
return _GameInputGamepadLeftShoulder, true
|
||||
case gamepaddb.StandardButtonFrontTopRight:
|
||||
return _GameInputGamepadRightShoulder, true
|
||||
case gamepaddb.StandardButtonFrontBottomLeft:
|
||||
return 0, false // Use leftTrigger instead.
|
||||
case gamepaddb.StandardButtonFrontBottomRight:
|
||||
return 0, false // Use rightTrigger instead.
|
||||
case gamepaddb.StandardButtonCenterLeft:
|
||||
return _GameInputGamepadView, true
|
||||
case gamepaddb.StandardButtonCenterRight:
|
||||
return _GameInputGamepadMenu, true
|
||||
case gamepaddb.StandardButtonLeftStick:
|
||||
return _GameInputGamepadLeftThumbstick, true
|
||||
case gamepaddb.StandardButtonRightStick:
|
||||
return _GameInputGamepadRightThumbstick, true
|
||||
case gamepaddb.StandardButtonLeftTop:
|
||||
return _GameInputGamepadDPadUp, true
|
||||
case gamepaddb.StandardButtonLeftBottom:
|
||||
return _GameInputGamepadDPadDown, true
|
||||
case gamepaddb.StandardButtonLeftLeft:
|
||||
return _GameInputGamepadDPadLeft, true
|
||||
case gamepaddb.StandardButtonLeftRight:
|
||||
return _GameInputGamepadDPadRight, true
|
||||
case gamepaddb.StandardButtonCenterCenter:
|
||||
return 0, false
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
type nativeGamepadsXbox struct {
|
||||
gameInput *_IGameInput
|
||||
deviceCallbackPtr uintptr
|
||||
@ -41,7 +83,7 @@ func (n *nativeGamepadsXbox) init(gamepads *gamepads) error {
|
||||
|
||||
if err := n.gameInput.RegisterDeviceCallback(
|
||||
nil,
|
||||
_GameInputKindAny,
|
||||
_GameInputKindGamepad,
|
||||
_GameInputDeviceConnected,
|
||||
_GameInputBlockingEnumeration,
|
||||
unsafe.Pointer(gamepads),
|
||||
@ -80,9 +122,22 @@ func (n *nativeGamepadsXbox) deviceCallback(callbackToken _GameInputCallbackToke
|
||||
|
||||
type nativeGamepadXbox struct {
|
||||
gameInputDevice *_IGameInputDevice
|
||||
state _GameInputGamepadState
|
||||
}
|
||||
|
||||
func (n *nativeGamepadXbox) update(gamepads *gamepads) error {
|
||||
gameInput := gamepads.native.(*nativeGamepadsXbox).gameInput
|
||||
r, err := gameInput.GetCurrentReading(_GameInputKindGamepad, n.gameInputDevice)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
state, ok := r.GetGamepadState()
|
||||
if !ok {
|
||||
n.state = _GameInputGamepadState{}
|
||||
return nil
|
||||
}
|
||||
n.state = state
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -91,11 +146,11 @@ func (n *nativeGamepadXbox) hasOwnStandardLayoutMapping() bool {
|
||||
}
|
||||
|
||||
func (n *nativeGamepadXbox) axisCount() int {
|
||||
return 0
|
||||
return int(gamepaddb.StandardAxisMax) + 1
|
||||
}
|
||||
|
||||
func (n *nativeGamepadXbox) buttonCount() int {
|
||||
return 0
|
||||
return int(gamepaddb.StandardButtonMax) + 1
|
||||
}
|
||||
|
||||
func (n *nativeGamepadXbox) hatCount() int {
|
||||
@ -103,14 +158,55 @@ func (n *nativeGamepadXbox) hatCount() int {
|
||||
}
|
||||
|
||||
func (n *nativeGamepadXbox) axisValue(axis int) float64 {
|
||||
switch gamepaddb.StandardAxis(axis) {
|
||||
case gamepaddb.StandardAxisLeftStickHorizontal:
|
||||
return float64(n.state.leftThumbstickX)
|
||||
case gamepaddb.StandardAxisLeftStickVertical:
|
||||
return float64(n.state.leftThumbstickY)
|
||||
case gamepaddb.StandardAxisRightStickHorizontal:
|
||||
return float64(n.state.rightThumbstickX)
|
||||
case gamepaddb.StandardAxisRightStickVertical:
|
||||
return float64(n.state.rightThumbstickY)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (n *nativeGamepadXbox) buttonValue(button int) float64 {
|
||||
switch gamepaddb.StandardButton(button) {
|
||||
case gamepaddb.StandardButtonFrontBottomLeft:
|
||||
return float64(n.state.leftTrigger)
|
||||
case gamepaddb.StandardButtonFrontBottomRight:
|
||||
return float64(n.state.rightTrigger)
|
||||
}
|
||||
b, ok := standardButtonToGamepadInputGamepadButton(gamepaddb.StandardButton(button))
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
if n.state.buttons&b != 0 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (n *nativeGamepadXbox) isButtonPressed(button int) bool {
|
||||
// Use XInput's trigger dead zone.
|
||||
// See https://source.chromium.org/chromium/chromium/src/+/main:device/gamepad/public/cpp/gamepad.h;l=22-23;drc=6997f8a177359bb99598988ed5e900841984d242
|
||||
// TODO: Integrate this value with the same one in the package gamepaddb.
|
||||
const threshold = 30.0 / 255.0
|
||||
switch gamepaddb.StandardButton(button) {
|
||||
case gamepaddb.StandardButtonFrontBottomLeft:
|
||||
return n.state.leftTrigger >= threshold
|
||||
case gamepaddb.StandardButtonFrontBottomRight:
|
||||
return n.state.rightTrigger >= threshold
|
||||
}
|
||||
|
||||
b, ok := standardButtonToGamepadInputGamepadButton(gamepaddb.StandardButton(button))
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if n.state.buttons&b != 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user