mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-27 03:02:49 +01:00
parent
a6f6fdbfb7
commit
ac5c48f575
@ -32,14 +32,6 @@ 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 _GameInputCallbackToken uint64
|
||||||
|
|
||||||
type _GameInputDeviceStatus int32
|
type _GameInputDeviceStatus int32
|
||||||
@ -58,6 +50,34 @@ const (
|
|||||||
_GameInputDeviceAnyStatus _GameInputDeviceStatus = 0x00FFFFFF
|
_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
|
type _GameInputKind int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -79,6 +99,16 @@ const (
|
|||||||
_GameInputKindAny _GameInputKind = 0x0FFFFFFF
|
_GameInputKindAny _GameInputKind = 0x0FFFFFFF
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type _GameInputGamepadState struct {
|
||||||
|
buttons _GameInputGamepadButtons
|
||||||
|
leftTrigger float32
|
||||||
|
rightTrigger float32
|
||||||
|
leftThumbstickX float32
|
||||||
|
leftThumbstickY float32
|
||||||
|
rightThumbstickX float32
|
||||||
|
rightThumbstickY float32
|
||||||
|
}
|
||||||
|
|
||||||
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)))
|
||||||
@ -118,6 +148,18 @@ type _IGameInput_Vtbl struct {
|
|||||||
SetFocusPolicy uintptr
|
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,
|
func (i *_IGameInput) RegisterDeviceCallback(device *_IGameInputDevice,
|
||||||
inputKind _GameInputKind,
|
inputKind _GameInputKind,
|
||||||
statusFilter _GameInputDeviceStatus,
|
statusFilter _GameInputDeviceStatus,
|
||||||
@ -165,3 +207,42 @@ type _IGameInputDevice_Vtbl struct {
|
|||||||
AcquireExclusiveRawDeviceAccess uintptr
|
AcquireExclusiveRawDeviceAccess uintptr
|
||||||
ReleaseExclusiveRawDeviceAccess 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"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/windows"
|
"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 {
|
type nativeGamepadsXbox struct {
|
||||||
gameInput *_IGameInput
|
gameInput *_IGameInput
|
||||||
deviceCallbackPtr uintptr
|
deviceCallbackPtr uintptr
|
||||||
@ -41,7 +83,7 @@ func (n *nativeGamepadsXbox) init(gamepads *gamepads) error {
|
|||||||
|
|
||||||
if err := n.gameInput.RegisterDeviceCallback(
|
if err := n.gameInput.RegisterDeviceCallback(
|
||||||
nil,
|
nil,
|
||||||
_GameInputKindAny,
|
_GameInputKindGamepad,
|
||||||
_GameInputDeviceConnected,
|
_GameInputDeviceConnected,
|
||||||
_GameInputBlockingEnumeration,
|
_GameInputBlockingEnumeration,
|
||||||
unsafe.Pointer(gamepads),
|
unsafe.Pointer(gamepads),
|
||||||
@ -80,9 +122,22 @@ func (n *nativeGamepadsXbox) deviceCallback(callbackToken _GameInputCallbackToke
|
|||||||
|
|
||||||
type nativeGamepadXbox struct {
|
type nativeGamepadXbox struct {
|
||||||
gameInputDevice *_IGameInputDevice
|
gameInputDevice *_IGameInputDevice
|
||||||
|
state _GameInputGamepadState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nativeGamepadXbox) update(gamepads *gamepads) error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,11 +146,11 @@ func (n *nativeGamepadXbox) hasOwnStandardLayoutMapping() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *nativeGamepadXbox) axisCount() int {
|
func (n *nativeGamepadXbox) axisCount() int {
|
||||||
return 0
|
return int(gamepaddb.StandardAxisMax) + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nativeGamepadXbox) buttonCount() int {
|
func (n *nativeGamepadXbox) buttonCount() int {
|
||||||
return 0
|
return int(gamepaddb.StandardButtonMax) + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nativeGamepadXbox) hatCount() int {
|
func (n *nativeGamepadXbox) hatCount() int {
|
||||||
@ -103,14 +158,55 @@ func (n *nativeGamepadXbox) hatCount() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *nativeGamepadXbox) axisValue(axis int) float64 {
|
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
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nativeGamepadXbox) buttonValue(button int) float64 {
|
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
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nativeGamepadXbox) isButtonPressed(button int) bool {
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user