mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 13:07:26 +01:00
internal/gamepad: make nativeGamepad(s) interfaces
This is a preparation to switch the gamepad implementation for Xbox. Updates #2084
This commit is contained in:
parent
f1037d8bff
commit
847c4f067a
@ -407,14 +407,16 @@ func (g *gamepads) addIOSGamepad(controller C.uintptr_t, prop *C.struct_Controll
|
|||||||
name := C.GoString(&prop.name[0])
|
name := C.GoString(&prop.name[0])
|
||||||
sdlID := C.GoStringN(&prop.guid[0], 16)
|
sdlID := C.GoStringN(&prop.guid[0], 16)
|
||||||
gp := g.add(name, sdlID)
|
gp := g.add(name, sdlID)
|
||||||
gp.native.controller = uintptr(controller)
|
gp.native = &nativeGamepadImpl{
|
||||||
gp.native.axes = make([]float64, prop.nAxes)
|
controller: uintptr(controller),
|
||||||
gp.native.buttons = make([]bool, prop.nButtons+prop.nHats*4)
|
axes: make([]float64, prop.nAxes),
|
||||||
gp.native.hats = make([]int, prop.nHats)
|
buttons: make([]bool, prop.nButtons+prop.nHats*4),
|
||||||
gp.native.buttonMask = uint16(prop.buttonMask)
|
hats: make([]int, prop.nHats),
|
||||||
gp.native.hasDualshockTouchpad = bool(prop.hasDualshockTouchpad)
|
buttonMask: uint16(prop.buttonMask),
|
||||||
gp.native.hasXboxPaddles = bool(prop.hasXboxPaddles)
|
hasDualshockTouchpad: bool(prop.hasDualshockTouchpad),
|
||||||
gp.native.hasXboxShareButton = bool(prop.hasXboxShareButton)
|
hasXboxPaddles: bool(prop.hasXboxPaddles),
|
||||||
|
hasXboxShareButton: bool(prop.hasXboxShareButton),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *gamepads) removeIOSGamepad(controller C.uintptr_t) {
|
func (g *gamepads) removeIOSGamepad(controller C.uintptr_t) {
|
||||||
@ -422,7 +424,7 @@ func (g *gamepads) removeIOSGamepad(controller C.uintptr_t) {
|
|||||||
defer g.m.Unlock()
|
defer g.m.Unlock()
|
||||||
|
|
||||||
g.remove(func(gamepad *Gamepad) bool {
|
g.remove(func(gamepad *Gamepad) bool {
|
||||||
return gamepad.native.controller == uintptr(controller)
|
return gamepad.native.(*nativeGamepadImpl).controller == uintptr(controller)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,7 +432,7 @@ func initializeIOSGamepads() {
|
|||||||
C.initializeGamepads()
|
C.initializeGamepads()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) updateIOSGamepad() {
|
func (g *nativeGamepadImpl) updateIOSGamepad() {
|
||||||
var state C.struct_ControllerState
|
var state C.struct_ControllerState
|
||||||
C.getControllerState(C.uintptr_t(g.controller), &state, C.uint16_t(g.buttonMask), C.uint8_t(len(g.hats)),
|
C.getControllerState(C.uintptr_t(g.controller), &state, C.uint16_t(g.buttonMask), C.uint8_t(len(g.hats)),
|
||||||
C.bool(g.hasDualshockTouchpad), C.bool(g.hasXboxPaddles), C.bool(g.hasXboxShareButton))
|
C.bool(g.hasDualshockTouchpad), C.bool(g.hasXboxPaddles), C.bool(g.hasXboxShareButton))
|
||||||
|
@ -53,10 +53,12 @@ func (g *gamepads) addAndroidGamepad(androidDeviceID int, name, sdlID string, ax
|
|||||||
defer g.m.Unlock()
|
defer g.m.Unlock()
|
||||||
|
|
||||||
gp := g.add(name, sdlID)
|
gp := g.add(name, sdlID)
|
||||||
gp.native.androidDeviceID = androidDeviceID
|
gp.native = &nativeGamepadImpl{
|
||||||
gp.native.axes = make([]float64, axisCount)
|
androidDeviceID: androidDeviceID,
|
||||||
gp.native.buttons = make([]bool, buttonCount)
|
axes: make([]float64, axisCount),
|
||||||
gp.native.hats = make([]int, hatCount)
|
buttons: make([]bool, buttonCount),
|
||||||
|
hats: make([]int, hatCount),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *gamepads) removeAndroidGamepad(androidDeviceID int) {
|
func (g *gamepads) removeAndroidGamepad(androidDeviceID int) {
|
||||||
@ -64,7 +66,7 @@ func (g *gamepads) removeAndroidGamepad(androidDeviceID int) {
|
|||||||
defer g.m.Unlock()
|
defer g.m.Unlock()
|
||||||
|
|
||||||
g.remove(func(gamepad *Gamepad) bool {
|
g.remove(func(gamepad *Gamepad) bool {
|
||||||
return gamepad.native.androidDeviceID == androidDeviceID
|
return gamepad.native.(*nativeGamepadImpl).androidDeviceID == androidDeviceID
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +75,7 @@ func (g *gamepads) updateAndroidGamepadAxis(androidDeviceID int, axis int, value
|
|||||||
defer g.m.Unlock()
|
defer g.m.Unlock()
|
||||||
|
|
||||||
gp := g.find(func(gamepad *Gamepad) bool {
|
gp := g.find(func(gamepad *Gamepad) bool {
|
||||||
return gamepad.native.androidDeviceID == androidDeviceID
|
return gamepad.native.(*nativeGamepadImpl).androidDeviceID == androidDeviceID
|
||||||
})
|
})
|
||||||
if gp == nil {
|
if gp == nil {
|
||||||
return
|
return
|
||||||
@ -86,7 +88,7 @@ func (g *gamepads) updateAndroidGamepadButton(androidDeviceID int, button Button
|
|||||||
defer g.m.Unlock()
|
defer g.m.Unlock()
|
||||||
|
|
||||||
gp := g.find(func(gamepad *Gamepad) bool {
|
gp := g.find(func(gamepad *Gamepad) bool {
|
||||||
return gamepad.native.androidDeviceID == androidDeviceID
|
return gamepad.native.(*nativeGamepadImpl).androidDeviceID == androidDeviceID
|
||||||
})
|
})
|
||||||
if gp == nil {
|
if gp == nil {
|
||||||
return
|
return
|
||||||
@ -99,7 +101,7 @@ func (g *gamepads) updateAndroidGamepadHat(androidDeviceID int, hat int, dir And
|
|||||||
defer g.m.Unlock()
|
defer g.m.Unlock()
|
||||||
|
|
||||||
gp := g.find(func(gamepad *Gamepad) bool {
|
gp := g.find(func(gamepad *Gamepad) bool {
|
||||||
return gamepad.native.androidDeviceID == androidDeviceID
|
return gamepad.native.(*nativeGamepadImpl).androidDeviceID == androidDeviceID
|
||||||
})
|
})
|
||||||
if gp == nil {
|
if gp == nil {
|
||||||
return
|
return
|
||||||
@ -111,30 +113,33 @@ func (g *Gamepad) updateAndroidGamepadAxis(axis int, value float64) {
|
|||||||
g.m.Lock()
|
g.m.Lock()
|
||||||
defer g.m.Unlock()
|
defer g.m.Unlock()
|
||||||
|
|
||||||
if axis < 0 || axis >= len(g.native.axes) {
|
n := g.native.(*nativeGamepadImpl)
|
||||||
|
if axis < 0 || axis >= len(n.axes) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.native.axes[axis] = value
|
n.axes[axis] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Gamepad) updateAndroidGamepadButton(button Button, pressed bool) {
|
func (g *Gamepad) updateAndroidGamepadButton(button Button, pressed bool) {
|
||||||
g.m.Lock()
|
g.m.Lock()
|
||||||
defer g.m.Unlock()
|
defer g.m.Unlock()
|
||||||
|
|
||||||
if button < 0 || int(button) >= len(g.native.buttons) {
|
n := g.native.(*nativeGamepadImpl)
|
||||||
|
if button < 0 || int(button) >= len(n.buttons) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.native.buttons[button] = pressed
|
n.buttons[button] = pressed
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Gamepad) updateAndroidGamepadHat(hat int, dir AndroidHatDirection, value int) {
|
func (g *Gamepad) updateAndroidGamepadHat(hat int, dir AndroidHatDirection, value int) {
|
||||||
g.m.Lock()
|
g.m.Lock()
|
||||||
defer g.m.Unlock()
|
defer g.m.Unlock()
|
||||||
|
|
||||||
if hat < 0 || hat >= len(g.native.hats) {
|
n := g.native.(*nativeGamepadImpl)
|
||||||
|
if hat < 0 || hat >= len(n.hats) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
v := g.native.hats[hat]
|
v := n.hats[hat]
|
||||||
switch dir {
|
switch dir {
|
||||||
case AndroidHatDirectionX:
|
case AndroidHatDirectionX:
|
||||||
switch {
|
switch {
|
||||||
@ -161,5 +166,5 @@ func (g *Gamepad) updateAndroidGamepadHat(hat int, dir AndroidHatDirection, valu
|
|||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("gamepad: invalid direction: %d", dir))
|
panic(fmt.Sprintf("gamepad: invalid direction: %d", dir))
|
||||||
}
|
}
|
||||||
g.native.hats[hat] = v
|
n.hats[hat] = v
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,14 @@ type gamepads struct {
|
|||||||
native nativeGamepads
|
native nativeGamepads
|
||||||
}
|
}
|
||||||
|
|
||||||
var theGamepads gamepads
|
type nativeGamepads interface {
|
||||||
|
init(gamepads *gamepads) error
|
||||||
|
update(gamepads *gamepads) error
|
||||||
|
}
|
||||||
|
|
||||||
|
var theGamepads = gamepads{
|
||||||
|
native: newNativeGamepadsImpl(),
|
||||||
|
}
|
||||||
|
|
||||||
// AppendGamepadIDs is concurrent-safe.
|
// AppendGamepadIDs is concurrent-safe.
|
||||||
func AppendGamepadIDs(ids []ID) []ID {
|
func AppendGamepadIDs(ids []ID) []ID {
|
||||||
@ -166,7 +173,7 @@ func (g *gamepads) setNativeWindow(nativeWindow uintptr) {
|
|||||||
g.m.Lock()
|
g.m.Lock()
|
||||||
defer g.m.Unlock()
|
defer g.m.Unlock()
|
||||||
|
|
||||||
var n interface{} = &g.native
|
var n interface{} = g.native
|
||||||
if n, ok := n.(interface{ setNativeWindow(uintptr) }); ok {
|
if n, ok := n.(interface{ setNativeWindow(uintptr) }); ok {
|
||||||
n.setNativeWindow(nativeWindow)
|
n.setNativeWindow(nativeWindow)
|
||||||
}
|
}
|
||||||
@ -180,6 +187,19 @@ type Gamepad struct {
|
|||||||
native nativeGamepad
|
native nativeGamepad
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type nativeGamepad interface {
|
||||||
|
update(gamepads *gamepads) error
|
||||||
|
hasOwnStandardLayoutMapping() bool
|
||||||
|
axisCount() int
|
||||||
|
buttonCount() int
|
||||||
|
hatCount() int
|
||||||
|
axisValue(axis int) float64
|
||||||
|
buttonValue(button int) float64
|
||||||
|
isButtonPressed(button int) bool
|
||||||
|
hatState(hat int) int
|
||||||
|
vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64)
|
||||||
|
}
|
||||||
|
|
||||||
func (g *Gamepad) update(gamepads *gamepads) error {
|
func (g *Gamepad) update(gamepads *gamepads) error {
|
||||||
g.m.Lock()
|
g.m.Lock()
|
||||||
defer g.m.Unlock()
|
defer g.m.Unlock()
|
||||||
|
@ -21,17 +21,21 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type nativeGamepads struct{}
|
type nativeGamepadsImpl struct{}
|
||||||
|
|
||||||
func (*nativeGamepads) init(gamepads *gamepads) error {
|
func newNativeGamepadsImpl() nativeGamepads {
|
||||||
|
return &nativeGamepadsImpl{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*nativeGamepadsImpl) init(gamepads *gamepads) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepads) update(gamepads *gamepads) error {
|
func (*nativeGamepadsImpl) update(gamepads *gamepads) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type nativeGamepad struct {
|
type nativeGamepadImpl struct {
|
||||||
androidDeviceID int
|
androidDeviceID int
|
||||||
|
|
||||||
axes []float64
|
axes []float64
|
||||||
@ -39,52 +43,52 @@ type nativeGamepad struct {
|
|||||||
hats []int
|
hats []int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepad) update(gamepad *gamepads) error {
|
func (*nativeGamepadImpl) update(gamepad *gamepads) error {
|
||||||
// Do nothing. The state of gamepads are given via APIs in extern_android.go.
|
// Do nothing. The state of gamepads are given via APIs in extern_android.go.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepad) hasOwnStandardLayoutMapping() bool {
|
func (*nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisCount() int {
|
func (g *nativeGamepadImpl) axisCount() int {
|
||||||
return len(g.axes)
|
return len(g.axes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) buttonCount() int {
|
func (g *nativeGamepadImpl) buttonCount() int {
|
||||||
return len(g.buttons)
|
return len(g.buttons)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hatCount() int {
|
func (g *nativeGamepadImpl) hatCount() int {
|
||||||
return len(g.hats)
|
return len(g.hats)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisValue(axis int) float64 {
|
func (g *nativeGamepadImpl) axisValue(axis int) float64 {
|
||||||
if axis < 0 || axis >= len(g.axes) {
|
if axis < 0 || axis >= len(g.axes) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return g.axes[axis]
|
return g.axes[axis]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) isButtonPressed(button int) bool {
|
func (g *nativeGamepadImpl) isButtonPressed(button int) bool {
|
||||||
if button < 0 || button >= len(g.buttons) {
|
if button < 0 || button >= len(g.buttons) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return g.buttons[button]
|
return g.buttons[button]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepad) buttonValue(button int) float64 {
|
func (*nativeGamepadImpl) buttonValue(button int) float64 {
|
||||||
panic("gamepad: buttonValue is not implemented")
|
panic("gamepad: buttonValue is not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hatState(hat int) int {
|
func (g *nativeGamepadImpl) hatState(hat int) int {
|
||||||
if hat < 0 || hat >= len(g.hats) {
|
if hat < 0 || hat >= len(g.hats) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return g.hats[hat]
|
return g.hats[hat]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
func (g *nativeGamepadImpl) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||||
// TODO: Implement this (#1452)
|
// TODO: Implement this (#1452)
|
||||||
}
|
}
|
||||||
|
@ -23,16 +23,20 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/v2/internal/cbackend"
|
"github.com/hajimehoshi/ebiten/v2/internal/cbackend"
|
||||||
)
|
)
|
||||||
|
|
||||||
type nativeGamepads struct {
|
type nativeGamepadsImpl struct {
|
||||||
gamepads []cbackend.Gamepad
|
gamepads []cbackend.Gamepad
|
||||||
ids map[int]struct{}
|
ids map[int]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepads) init(gamepads *gamepads) error {
|
func newNativeGamepadsImpl() nativeGamepads {
|
||||||
|
return &nativeGamepadsImpl{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*nativeGamepadsImpl) init(gamepads *gamepads) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) update(gamepads *gamepads) error {
|
func (g *nativeGamepadsImpl) update(gamepads *gamepads) error {
|
||||||
g.gamepads = g.gamepads[:0]
|
g.gamepads = g.gamepads[:0]
|
||||||
g.gamepads = cbackend.AppendGamepads(g.gamepads)
|
g.gamepads = cbackend.AppendGamepads(g.gamepads)
|
||||||
|
|
||||||
@ -47,34 +51,37 @@ func (g *nativeGamepads) update(gamepads *gamepads) error {
|
|||||||
g.ids[gp.ID] = struct{}{}
|
g.ids[gp.ID] = struct{}{}
|
||||||
|
|
||||||
gamepad := gamepads.find(func(gamepad *Gamepad) bool {
|
gamepad := gamepads.find(func(gamepad *Gamepad) bool {
|
||||||
return gamepad.native.id == gp.ID
|
return gamepad.native.(*nativeGamepadImpl).id == gp.ID
|
||||||
})
|
})
|
||||||
if gamepad == nil {
|
if gamepad == nil {
|
||||||
gamepad = gamepads.add("", "")
|
gamepad = gamepads.add("", "")
|
||||||
gamepad.native.id = gp.ID
|
gamepad.native = &nativeGamepadImpl{
|
||||||
gamepad.native.standard = gp.Standard
|
id: gp.ID,
|
||||||
gamepad.native.axisValues = make([]float64, gp.AxisCount)
|
standard: gp.Standard,
|
||||||
gamepad.native.buttonPressed = make([]bool, gp.ButtonCount)
|
axisValues: make([]float64, gp.AxisCount),
|
||||||
gamepad.native.buttonValues = make([]float64, gp.ButtonCount)
|
buttonPressed: make([]bool, gp.ButtonCount),
|
||||||
|
buttonValues: make([]float64, gp.ButtonCount),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gamepad.m.Lock()
|
gamepad.m.Lock()
|
||||||
copy(gamepad.native.axisValues, gp.AxisValues[:])
|
n := gamepad.native.(*nativeGamepadImpl)
|
||||||
copy(gamepad.native.buttonValues, gp.ButtonValues[:])
|
copy(n.axisValues, gp.AxisValues[:])
|
||||||
copy(gamepad.native.buttonPressed, gp.ButtonPressed[:])
|
copy(n.buttonValues, gp.ButtonValues[:])
|
||||||
|
copy(n.buttonPressed, gp.ButtonPressed[:])
|
||||||
gamepad.m.Unlock()
|
gamepad.m.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove an unused gamepads.
|
// Remove an unused gamepads.
|
||||||
gamepads.remove(func(gamepad *Gamepad) bool {
|
gamepads.remove(func(gamepad *Gamepad) bool {
|
||||||
_, ok := g.ids[gamepad.native.id]
|
_, ok := g.ids[gamepad.native.(*nativeGamepadImpl).id]
|
||||||
return !ok
|
return !ok
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type nativeGamepad struct {
|
type nativeGamepadImpl struct {
|
||||||
id int
|
id int
|
||||||
standard bool
|
standard bool
|
||||||
|
|
||||||
@ -83,51 +90,51 @@ type nativeGamepad struct {
|
|||||||
buttonValues []float64
|
buttonValues []float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepad) update(gamepad *gamepads) error {
|
func (*nativeGamepadImpl) update(gamepad *gamepads) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hasOwnStandardLayoutMapping() bool {
|
func (g *nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
||||||
return g.standard
|
return g.standard
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisCount() int {
|
func (g *nativeGamepadImpl) axisCount() int {
|
||||||
return len(g.axisValues)
|
return len(g.axisValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) buttonCount() int {
|
func (g *nativeGamepadImpl) buttonCount() int {
|
||||||
return len(g.buttonValues)
|
return len(g.buttonValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hatCount() int {
|
func (g *nativeGamepadImpl) hatCount() int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisValue(axis int) float64 {
|
func (g *nativeGamepadImpl) axisValue(axis int) float64 {
|
||||||
if axis < 0 || axis >= len(g.axisValues) {
|
if axis < 0 || axis >= len(g.axisValues) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return g.axisValues[axis]
|
return g.axisValues[axis]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) isButtonPressed(button int) bool {
|
func (g *nativeGamepadImpl) isButtonPressed(button int) bool {
|
||||||
if button < 0 || button >= len(g.buttonPressed) {
|
if button < 0 || button >= len(g.buttonPressed) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return g.buttonPressed[button]
|
return g.buttonPressed[button]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) buttonValue(button int) float64 {
|
func (g *nativeGamepadImpl) buttonValue(button int) float64 {
|
||||||
if button < 0 || button >= len(g.buttonValues) {
|
if button < 0 || button >= len(g.buttonValues) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return g.buttonValues[button]
|
return g.buttonValues[button]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepad) hatState(hat int) int {
|
func (*nativeGamepadImpl) hatState(hat int) int {
|
||||||
return hatCentered
|
return hatCentered
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
func (g *nativeGamepadImpl) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||||
cbackend.VibrateGamepad(g.id, duration, strongMagnitude, weakMagnitude)
|
cbackend.VibrateGamepad(g.id, duration, strongMagnitude, weakMagnitude)
|
||||||
}
|
}
|
||||||
|
@ -59,14 +59,18 @@ import (
|
|||||||
// void ebitenGamepadRemovalCallback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef device);
|
// void ebitenGamepadRemovalCallback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef device);
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
type nativeGamepads struct {
|
type nativeGamepadsImpl struct {
|
||||||
hidManager C.IOHIDManagerRef
|
hidManager C.IOHIDManagerRef
|
||||||
devicesToAdd []C.IOHIDDeviceRef
|
devicesToAdd []C.IOHIDDeviceRef
|
||||||
devicesToRemove []C.IOHIDDeviceRef
|
devicesToRemove []C.IOHIDDeviceRef
|
||||||
devicesM sync.Mutex
|
devicesM sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) init(gamepads *gamepads) error {
|
func newNativeGamepadsImpl() nativeGamepads {
|
||||||
|
return &nativeGamepadsImpl{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *nativeGamepadsImpl) init(gamepads *gamepads) error {
|
||||||
var dicts []C.CFDictionaryRef
|
var dicts []C.CFDictionaryRef
|
||||||
|
|
||||||
page := C.kHIDPage_GenericDesktop
|
page := C.kHIDPage_GenericDesktop
|
||||||
@ -135,28 +139,31 @@ func (g *nativeGamepads) init(gamepads *gamepads) error {
|
|||||||
|
|
||||||
//export ebitenGamepadMatchingCallback
|
//export ebitenGamepadMatchingCallback
|
||||||
func ebitenGamepadMatchingCallback(ctx unsafe.Pointer, res C.IOReturn, sender unsafe.Pointer, device C.IOHIDDeviceRef) {
|
func ebitenGamepadMatchingCallback(ctx unsafe.Pointer, res C.IOReturn, sender unsafe.Pointer, device C.IOHIDDeviceRef) {
|
||||||
theGamepads.native.devicesM.Lock()
|
n := theGamepads.native.(*nativeGamepadsImpl)
|
||||||
defer theGamepads.native.devicesM.Unlock()
|
n.devicesM.Lock()
|
||||||
theGamepads.native.devicesToAdd = append(theGamepads.native.devicesToAdd, device)
|
defer n.devicesM.Unlock()
|
||||||
|
n.devicesToAdd = append(n.devicesToAdd, device)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export ebitenGamepadRemovalCallback
|
//export ebitenGamepadRemovalCallback
|
||||||
func ebitenGamepadRemovalCallback(ctx unsafe.Pointer, res C.IOReturn, sender unsafe.Pointer, device C.IOHIDDeviceRef) {
|
func ebitenGamepadRemovalCallback(ctx unsafe.Pointer, res C.IOReturn, sender unsafe.Pointer, device C.IOHIDDeviceRef) {
|
||||||
theGamepads.native.devicesM.Lock()
|
n := theGamepads.native.(*nativeGamepadsImpl)
|
||||||
defer theGamepads.native.devicesM.Unlock()
|
n.devicesM.Lock()
|
||||||
theGamepads.native.devicesToRemove = append(theGamepads.native.devicesToRemove, device)
|
defer n.devicesM.Unlock()
|
||||||
|
n.devicesToRemove = append(n.devicesToRemove, device)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) update(gamepads *gamepads) error {
|
func (g *nativeGamepadsImpl) update(gamepads *gamepads) error {
|
||||||
theGamepads.native.devicesM.Lock()
|
n := theGamepads.native.(*nativeGamepadsImpl)
|
||||||
defer theGamepads.native.devicesM.Unlock()
|
n.devicesM.Lock()
|
||||||
|
defer n.devicesM.Unlock()
|
||||||
|
|
||||||
for _, device := range g.devicesToAdd {
|
for _, device := range g.devicesToAdd {
|
||||||
g.addDevice(device, gamepads)
|
g.addDevice(device, gamepads)
|
||||||
}
|
}
|
||||||
for _, device := range g.devicesToRemove {
|
for _, device := range g.devicesToRemove {
|
||||||
gamepads.remove(func(g *Gamepad) bool {
|
gamepads.remove(func(g *Gamepad) bool {
|
||||||
return g.native.device == device
|
return g.native.(*nativeGamepadImpl).device == device
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
g.devicesToAdd = g.devicesToAdd[:0]
|
g.devicesToAdd = g.devicesToAdd[:0]
|
||||||
@ -164,9 +171,9 @@ func (g *nativeGamepads) update(gamepads *gamepads) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) addDevice(device C.IOHIDDeviceRef, gamepads *gamepads) {
|
func (g *nativeGamepadsImpl) addDevice(device C.IOHIDDeviceRef, gamepads *gamepads) {
|
||||||
if gamepads.find(func(g *Gamepad) bool {
|
if gamepads.find(func(g *Gamepad) bool {
|
||||||
return g.native.device == device
|
return g.native.(*nativeGamepadImpl).device == device
|
||||||
}) != nil {
|
}) != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -211,8 +218,11 @@ func (g *nativeGamepads) addDevice(device C.IOHIDDeviceRef, gamepads *gamepads)
|
|||||||
elements := C.IOHIDDeviceCopyMatchingElements(device, 0, C.kIOHIDOptionsTypeNone)
|
elements := C.IOHIDDeviceCopyMatchingElements(device, 0, C.kIOHIDOptionsTypeNone)
|
||||||
defer C.CFRelease(C.CFTypeRef(elements))
|
defer C.CFRelease(C.CFTypeRef(elements))
|
||||||
|
|
||||||
|
n := &nativeGamepadImpl{
|
||||||
|
device: device,
|
||||||
|
}
|
||||||
gp := gamepads.add(name, sdlID)
|
gp := gamepads.add(name, sdlID)
|
||||||
gp.native.device = device
|
gp.native = n
|
||||||
|
|
||||||
for i := C.CFIndex(0); i < C.CFArrayGetCount(elements); i++ {
|
for i := C.CFIndex(0); i < C.CFArrayGetCount(elements); i++ {
|
||||||
native := (C.IOHIDElementRef)(C.CFArrayGetValueAtIndex(elements, i))
|
native := (C.IOHIDElementRef)(C.CFArrayGetValueAtIndex(elements, i))
|
||||||
@ -236,27 +246,27 @@ func (g *nativeGamepads) addDevice(device C.IOHIDDeviceRef, gamepads *gamepads)
|
|||||||
case C.kHIDUsage_GD_X, C.kHIDUsage_GD_Y, C.kHIDUsage_GD_Z,
|
case C.kHIDUsage_GD_X, C.kHIDUsage_GD_Y, C.kHIDUsage_GD_Z,
|
||||||
C.kHIDUsage_GD_Rx, C.kHIDUsage_GD_Ry, C.kHIDUsage_GD_Rz,
|
C.kHIDUsage_GD_Rx, C.kHIDUsage_GD_Ry, C.kHIDUsage_GD_Rz,
|
||||||
C.kHIDUsage_GD_Slider, C.kHIDUsage_GD_Dial, C.kHIDUsage_GD_Wheel:
|
C.kHIDUsage_GD_Slider, C.kHIDUsage_GD_Dial, C.kHIDUsage_GD_Wheel:
|
||||||
gp.native.axes = append(gp.native.axes, element{
|
n.axes = append(n.axes, element{
|
||||||
native: native,
|
native: native,
|
||||||
usage: int(usage),
|
usage: int(usage),
|
||||||
index: len(gp.native.axes),
|
index: len(n.axes),
|
||||||
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
||||||
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
||||||
})
|
})
|
||||||
case C.kHIDUsage_GD_Hatswitch:
|
case C.kHIDUsage_GD_Hatswitch:
|
||||||
gp.native.hats = append(gp.native.hats, element{
|
n.hats = append(n.hats, element{
|
||||||
native: native,
|
native: native,
|
||||||
usage: int(usage),
|
usage: int(usage),
|
||||||
index: len(gp.native.hats),
|
index: len(n.hats),
|
||||||
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
||||||
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
||||||
})
|
})
|
||||||
case C.kHIDUsage_GD_DPadUp, C.kHIDUsage_GD_DPadRight, C.kHIDUsage_GD_DPadDown, C.kHIDUsage_GD_DPadLeft,
|
case C.kHIDUsage_GD_DPadUp, C.kHIDUsage_GD_DPadRight, C.kHIDUsage_GD_DPadDown, C.kHIDUsage_GD_DPadLeft,
|
||||||
C.kHIDUsage_GD_SystemMainMenu, C.kHIDUsage_GD_Select, C.kHIDUsage_GD_Start:
|
C.kHIDUsage_GD_SystemMainMenu, C.kHIDUsage_GD_Select, C.kHIDUsage_GD_Start:
|
||||||
gp.native.buttons = append(gp.native.buttons, element{
|
n.buttons = append(n.buttons, element{
|
||||||
native: native,
|
native: native,
|
||||||
usage: int(usage),
|
usage: int(usage),
|
||||||
index: len(gp.native.buttons),
|
index: len(n.buttons),
|
||||||
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
||||||
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
||||||
})
|
})
|
||||||
@ -264,28 +274,28 @@ func (g *nativeGamepads) addDevice(device C.IOHIDDeviceRef, gamepads *gamepads)
|
|||||||
case C.kHIDPage_Simulation:
|
case C.kHIDPage_Simulation:
|
||||||
switch usage {
|
switch usage {
|
||||||
case C.kHIDUsage_Sim_Accelerator, C.kHIDUsage_Sim_Brake, C.kHIDUsage_Sim_Throttle, C.kHIDUsage_Sim_Rudder, C.kHIDUsage_Sim_Steering:
|
case C.kHIDUsage_Sim_Accelerator, C.kHIDUsage_Sim_Brake, C.kHIDUsage_Sim_Throttle, C.kHIDUsage_Sim_Rudder, C.kHIDUsage_Sim_Steering:
|
||||||
gp.native.axes = append(gp.native.axes, element{
|
n.axes = append(n.axes, element{
|
||||||
native: native,
|
native: native,
|
||||||
usage: int(usage),
|
usage: int(usage),
|
||||||
index: len(gp.native.axes),
|
index: len(n.axes),
|
||||||
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
||||||
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
case C.kHIDPage_Button, C.kHIDPage_Consumer:
|
case C.kHIDPage_Button, C.kHIDPage_Consumer:
|
||||||
gp.native.buttons = append(gp.native.buttons, element{
|
n.buttons = append(n.buttons, element{
|
||||||
native: native,
|
native: native,
|
||||||
usage: int(usage),
|
usage: int(usage),
|
||||||
index: len(gp.native.buttons),
|
index: len(n.buttons),
|
||||||
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
||||||
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Stable(gp.native.axes)
|
sort.Stable(n.axes)
|
||||||
sort.Stable(gp.native.buttons)
|
sort.Stable(n.buttons)
|
||||||
sort.Stable(gp.native.hats)
|
sort.Stable(n.hats)
|
||||||
}
|
}
|
||||||
|
|
||||||
type element struct {
|
type element struct {
|
||||||
@ -316,7 +326,7 @@ func (e elements) Swap(i, j int) {
|
|||||||
e[i], e[j] = e[j], e[i]
|
e[i], e[j] = e[j], e[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
type nativeGamepad struct {
|
type nativeGamepadImpl struct {
|
||||||
device C.IOHIDDeviceRef
|
device C.IOHIDDeviceRef
|
||||||
axes elements
|
axes elements
|
||||||
buttons elements
|
buttons elements
|
||||||
@ -327,7 +337,7 @@ type nativeGamepad struct {
|
|||||||
hatValues []int
|
hatValues []int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) elementValue(e *element) int {
|
func (g *nativeGamepadImpl) elementValue(e *element) int {
|
||||||
var valueRef C.IOHIDValueRef
|
var valueRef C.IOHIDValueRef
|
||||||
if C.IOHIDDeviceGetValue(g.device, e.native, &valueRef) == C.kIOReturnSuccess {
|
if C.IOHIDDeviceGetValue(g.device, e.native, &valueRef) == C.kIOReturnSuccess {
|
||||||
return int(C.IOHIDValueGetIntegerValue(valueRef))
|
return int(C.IOHIDValueGetIntegerValue(valueRef))
|
||||||
@ -336,7 +346,7 @@ func (g *nativeGamepad) elementValue(e *element) int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) update(gamepads *gamepads) error {
|
func (g *nativeGamepadImpl) update(gamepads *gamepads) error {
|
||||||
if cap(g.axisValues) < len(g.axes) {
|
if cap(g.axisValues) < len(g.axes) {
|
||||||
g.axisValues = make([]float64, len(g.axes))
|
g.axisValues = make([]float64, len(g.axes))
|
||||||
}
|
}
|
||||||
@ -392,47 +402,47 @@ func (g *nativeGamepad) update(gamepads *gamepads) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hasOwnStandardLayoutMapping() bool {
|
func (g *nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisCount() int {
|
func (g *nativeGamepadImpl) axisCount() int {
|
||||||
return len(g.axisValues)
|
return len(g.axisValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) buttonCount() int {
|
func (g *nativeGamepadImpl) buttonCount() int {
|
||||||
return len(g.buttonValues)
|
return len(g.buttonValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hatCount() int {
|
func (g *nativeGamepadImpl) hatCount() int {
|
||||||
return len(g.hatValues)
|
return len(g.hatValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisValue(axis int) float64 {
|
func (g *nativeGamepadImpl) axisValue(axis int) float64 {
|
||||||
if axis < 0 || axis >= len(g.axisValues) {
|
if axis < 0 || axis >= len(g.axisValues) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return g.axisValues[axis]
|
return g.axisValues[axis]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) buttonValue(button int) float64 {
|
func (g *nativeGamepadImpl) buttonValue(button int) float64 {
|
||||||
panic("gamepad: buttonValue is not implemented")
|
panic("gamepad: buttonValue is not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) isButtonPressed(button int) bool {
|
func (g *nativeGamepadImpl) isButtonPressed(button int) bool {
|
||||||
if button < 0 || button >= len(g.buttonValues) {
|
if button < 0 || button >= len(g.buttonValues) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return g.buttonValues[button]
|
return g.buttonValues[button]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hatState(hat int) int {
|
func (g *nativeGamepadImpl) hatState(hat int) int {
|
||||||
if hat < 0 || hat >= len(g.hatValues) {
|
if hat < 0 || hat >= len(g.hatValues) {
|
||||||
return hatCentered
|
return hatCentered
|
||||||
}
|
}
|
||||||
return g.hatValues[hat]
|
return g.hatValues[hat]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
func (g *nativeGamepadImpl) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||||
// TODO: Implement this (#1452)
|
// TODO: Implement this (#1452)
|
||||||
}
|
}
|
||||||
|
@ -21,18 +21,22 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type nativeGamepads struct{}
|
type nativeGamepadsImpl struct{}
|
||||||
|
|
||||||
func (*nativeGamepads) init(gamepads *gamepads) error {
|
func newNativeGamepadsImpl() nativeGamepads {
|
||||||
|
return &nativeGamepadsImpl{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*nativeGamepadsImpl) init(gamepads *gamepads) error {
|
||||||
initializeIOSGamepads()
|
initializeIOSGamepads()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepads) update(gamepads *gamepads) error {
|
func (*nativeGamepadsImpl) update(gamepads *gamepads) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type nativeGamepad struct {
|
type nativeGamepadImpl struct {
|
||||||
controller uintptr
|
controller uintptr
|
||||||
buttonMask uint16
|
buttonMask uint16
|
||||||
hasDualshockTouchpad bool
|
hasDualshockTouchpad bool
|
||||||
@ -44,52 +48,52 @@ type nativeGamepad struct {
|
|||||||
hats []int
|
hats []int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) update(gamepad *gamepads) error {
|
func (g *nativeGamepadImpl) update(gamepad *gamepads) error {
|
||||||
g.updateIOSGamepad()
|
g.updateIOSGamepad()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepad) hasOwnStandardLayoutMapping() bool {
|
func (*nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisCount() int {
|
func (g *nativeGamepadImpl) axisCount() int {
|
||||||
return len(g.axes)
|
return len(g.axes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) buttonCount() int {
|
func (g *nativeGamepadImpl) buttonCount() int {
|
||||||
return len(g.buttons)
|
return len(g.buttons)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hatCount() int {
|
func (g *nativeGamepadImpl) hatCount() int {
|
||||||
return len(g.hats)
|
return len(g.hats)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisValue(axis int) float64 {
|
func (g *nativeGamepadImpl) axisValue(axis int) float64 {
|
||||||
if axis < 0 || axis >= len(g.axes) {
|
if axis < 0 || axis >= len(g.axes) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return g.axes[axis]
|
return g.axes[axis]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) isButtonPressed(button int) bool {
|
func (g *nativeGamepadImpl) isButtonPressed(button int) bool {
|
||||||
if button < 0 || button >= len(g.buttons) {
|
if button < 0 || button >= len(g.buttons) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return g.buttons[button]
|
return g.buttons[button]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepad) buttonValue(button int) float64 {
|
func (*nativeGamepadImpl) buttonValue(button int) float64 {
|
||||||
panic("gamepad: buttonValue is not implemented")
|
panic("gamepad: buttonValue is not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hatState(hat int) int {
|
func (g *nativeGamepadImpl) hatState(hat int) int {
|
||||||
if hat < 0 || hat >= len(g.hats) {
|
if hat < 0 || hat >= len(g.hats) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return g.hats[hat]
|
return g.hats[hat]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
func (g *nativeGamepadImpl) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||||
// TODO: Implement this (#1452)
|
// TODO: Implement this (#1452)
|
||||||
}
|
}
|
||||||
|
@ -25,15 +25,19 @@ var (
|
|||||||
go2cpp = js.Global().Get("go2cpp")
|
go2cpp = js.Global().Get("go2cpp")
|
||||||
)
|
)
|
||||||
|
|
||||||
type nativeGamepads struct {
|
type nativeGamepadsImpl struct {
|
||||||
indices map[int]struct{}
|
indices map[int]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) init(gamepads *gamepads) error {
|
func newNativeGamepadsImpl() nativeGamepads {
|
||||||
|
return &nativeGamepadsImpl{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *nativeGamepadsImpl) init(gamepads *gamepads) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) update(gamepads *gamepads) error {
|
func (g *nativeGamepadsImpl) update(gamepads *gamepads) error {
|
||||||
// TODO: Use the gamepad events instead of navigator.getGamepads after go2cpp is removed.
|
// TODO: Use the gamepad events instead of navigator.getGamepads after go2cpp is removed.
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -73,7 +77,7 @@ func (g *nativeGamepads) update(gamepads *gamepads) error {
|
|||||||
|
|
||||||
// The gamepad is not registered yet, register this.
|
// The gamepad is not registered yet, register this.
|
||||||
gamepad := gamepads.find(func(gamepad *Gamepad) bool {
|
gamepad := gamepads.find(func(gamepad *Gamepad) bool {
|
||||||
return index == gamepad.native.index
|
return index == gamepad.native.(*nativeGamepadImpl).index
|
||||||
})
|
})
|
||||||
if gamepad == nil {
|
if gamepad == nil {
|
||||||
name := gp.Get("id").String()
|
name := gp.Get("id").String()
|
||||||
@ -84,28 +88,30 @@ func (g *nativeGamepads) update(gamepads *gamepads) error {
|
|||||||
copy(sdlID[:], []byte(name))
|
copy(sdlID[:], []byte(name))
|
||||||
|
|
||||||
gamepad = gamepads.add(name, hex.EncodeToString(sdlID[:]))
|
gamepad = gamepads.add(name, hex.EncodeToString(sdlID[:]))
|
||||||
gamepad.native.index = index
|
gamepad.native = &nativeGamepadImpl{
|
||||||
gamepad.native.mapping = gp.Get("mapping").String()
|
index: index,
|
||||||
|
mapping: gp.Get("mapping").String(),
|
||||||
}
|
}
|
||||||
gamepad.native.value = gp
|
}
|
||||||
|
gamepad.native.(*nativeGamepadImpl).value = gp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove an unused gamepads.
|
// Remove an unused gamepads.
|
||||||
gamepads.remove(func(gamepad *Gamepad) bool {
|
gamepads.remove(func(gamepad *Gamepad) bool {
|
||||||
_, ok := g.indices[gamepad.native.index]
|
_, ok := g.indices[gamepad.native.(*nativeGamepadImpl).index]
|
||||||
return !ok
|
return !ok
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type nativeGamepad struct {
|
type nativeGamepadImpl struct {
|
||||||
value js.Value
|
value js.Value
|
||||||
index int
|
index int
|
||||||
mapping string
|
mapping string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hasOwnStandardLayoutMapping() bool {
|
func (g *nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
||||||
// With go2cpp, the controller must have the standard
|
// With go2cpp, the controller must have the standard
|
||||||
if go2cpp.Truthy() {
|
if go2cpp.Truthy() {
|
||||||
return true
|
return true
|
||||||
@ -113,23 +119,23 @@ func (g *nativeGamepad) hasOwnStandardLayoutMapping() bool {
|
|||||||
return g.mapping == "standard"
|
return g.mapping == "standard"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) update(gamepads *gamepads) error {
|
func (g *nativeGamepadImpl) update(gamepads *gamepads) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisCount() int {
|
func (g *nativeGamepadImpl) axisCount() int {
|
||||||
return g.value.Get("axes").Length()
|
return g.value.Get("axes").Length()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) buttonCount() int {
|
func (g *nativeGamepadImpl) buttonCount() int {
|
||||||
return g.value.Get("buttons").Length()
|
return g.value.Get("buttons").Length()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hatCount() int {
|
func (g *nativeGamepadImpl) hatCount() int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisValue(axis int) float64 {
|
func (g *nativeGamepadImpl) axisValue(axis int) float64 {
|
||||||
axes := g.value.Get("axes")
|
axes := g.value.Get("axes")
|
||||||
if axis < 0 || axis >= axes.Length() {
|
if axis < 0 || axis >= axes.Length() {
|
||||||
return 0
|
return 0
|
||||||
@ -137,7 +143,7 @@ func (g *nativeGamepad) axisValue(axis int) float64 {
|
|||||||
return axes.Index(axis).Float()
|
return axes.Index(axis).Float()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) buttonValue(button int) float64 {
|
func (g *nativeGamepadImpl) buttonValue(button int) float64 {
|
||||||
buttons := g.value.Get("buttons")
|
buttons := g.value.Get("buttons")
|
||||||
if button < 0 || button >= buttons.Length() {
|
if button < 0 || button >= buttons.Length() {
|
||||||
return 0
|
return 0
|
||||||
@ -145,7 +151,7 @@ func (g *nativeGamepad) buttonValue(button int) float64 {
|
|||||||
return buttons.Index(button).Get("value").Float()
|
return buttons.Index(button).Get("value").Float()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) isButtonPressed(button int) bool {
|
func (g *nativeGamepadImpl) isButtonPressed(button int) bool {
|
||||||
buttons := g.value.Get("buttons")
|
buttons := g.value.Get("buttons")
|
||||||
if button < 0 || button >= buttons.Length() {
|
if button < 0 || button >= buttons.Length() {
|
||||||
return false
|
return false
|
||||||
@ -153,11 +159,11 @@ func (g *nativeGamepad) isButtonPressed(button int) bool {
|
|||||||
return buttons.Index(button).Get("pressed").Bool()
|
return buttons.Index(button).Get("pressed").Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hatState(hat int) int {
|
func (g *nativeGamepadImpl) hatState(hat int) int {
|
||||||
return hatCentered
|
return hatCentered
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
func (g *nativeGamepadImpl) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||||
// vibrationActuator is avaialble on Chrome.
|
// vibrationActuator is avaialble on Chrome.
|
||||||
if va := g.value.Get("vibrationActuator"); va.Truthy() {
|
if va := g.value.Get("vibrationActuator"); va.Truthy() {
|
||||||
if !va.Get("playEffect").Truthy() {
|
if !va.Get("playEffect").Truthy() {
|
||||||
|
@ -37,12 +37,16 @@ func isBitSet(s []byte, bit int) bool {
|
|||||||
return s[bit/8]&(1<<(bit%8)) != 0
|
return s[bit/8]&(1<<(bit%8)) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
type nativeGamepads struct {
|
type nativeGamepadsImpl struct {
|
||||||
inotify int
|
inotify int
|
||||||
watch int
|
watch int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) init(gamepads *gamepads) error {
|
func newNativeGamepadsImpl() nativeGamepads {
|
||||||
|
return &nativeGamepadsImpl{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *nativeGamepadsImpl) init(gamepads *gamepads) error {
|
||||||
// Check the existence of the directory `dirName`.
|
// Check the existence of the directory `dirName`.
|
||||||
var stat unix.Stat_t
|
var stat unix.Stat_t
|
||||||
if err := unix.Stat(dirName, &stat); err != nil {
|
if err := unix.Stat(dirName, &stat); err != nil {
|
||||||
@ -90,9 +94,9 @@ func (g *nativeGamepads) init(gamepads *gamepads) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepads) openGamepad(gamepads *gamepads, path string) (err error) {
|
func (*nativeGamepadsImpl) openGamepad(gamepads *gamepads, path string) (err error) {
|
||||||
if gamepads.find(func(gamepad *Gamepad) bool {
|
if gamepads.find(func(gamepad *Gamepad) bool {
|
||||||
return gamepad.native.path == path
|
return gamepad.native.(*nativeGamepadImpl).path == path
|
||||||
}) != nil {
|
}) != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -164,11 +168,14 @@ func (*nativeGamepads) openGamepad(gamepads *gamepads, path string) (err error)
|
|||||||
bs[0], bs[1], bs[2], bs[3], bs[4], bs[5], bs[6], bs[7], bs[8], bs[9], bs[10], bs[11])
|
bs[0], bs[1], bs[2], bs[3], bs[4], bs[5], bs[6], bs[7], bs[8], bs[9], bs[10], bs[11])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n := &nativeGamepadImpl{
|
||||||
|
path: path,
|
||||||
|
fd: fd,
|
||||||
|
}
|
||||||
gp := gamepads.add(name, sdlID)
|
gp := gamepads.add(name, sdlID)
|
||||||
gp.native.path = path
|
gp.native = n
|
||||||
gp.native.fd = fd
|
|
||||||
runtime.SetFinalizer(gp, func(gp *Gamepad) {
|
runtime.SetFinalizer(gp, func(gp *Gamepad) {
|
||||||
gp.native.close()
|
n.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
var axisCount int
|
var axisCount int
|
||||||
@ -178,40 +185,40 @@ func (*nativeGamepads) openGamepad(gamepads *gamepads, path string) (err error)
|
|||||||
if !isBitSet(keyBits, code) {
|
if !isBitSet(keyBits, code) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
gp.native.keyMap[code-_BTN_MISC] = buttonCount
|
n.keyMap[code-_BTN_MISC] = buttonCount
|
||||||
buttonCount++
|
buttonCount++
|
||||||
}
|
}
|
||||||
for code := 0; code < _ABS_CNT; code++ {
|
for code := 0; code < _ABS_CNT; code++ {
|
||||||
gp.native.absMap[code] = -1
|
n.absMap[code] = -1
|
||||||
if !isBitSet(absBits, code) {
|
if !isBitSet(absBits, code) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if code >= _ABS_HAT0X && code <= _ABS_HAT3Y {
|
if code >= _ABS_HAT0X && code <= _ABS_HAT3Y {
|
||||||
gp.native.absMap[code] = hatCount
|
n.absMap[code] = hatCount
|
||||||
hatCount++
|
hatCount++
|
||||||
// Skip Y.
|
// Skip Y.
|
||||||
code++
|
code++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := ioctl(gp.native.fd, uint(_EVIOCGABS(uint(code))), unsafe.Pointer(&gp.native.absInfo[code])); err != nil {
|
if err := ioctl(n.fd, uint(_EVIOCGABS(uint(code))), unsafe.Pointer(&n.absInfo[code])); err != nil {
|
||||||
return fmt.Errorf("gamepad: ioctl for an abs at openGamepad failed: %w", err)
|
return fmt.Errorf("gamepad: ioctl for an abs at openGamepad failed: %w", err)
|
||||||
}
|
}
|
||||||
gp.native.absMap[code] = axisCount
|
n.absMap[code] = axisCount
|
||||||
axisCount++
|
axisCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
gp.native.axisCount_ = axisCount
|
n.axisCount_ = axisCount
|
||||||
gp.native.buttonCount_ = buttonCount
|
n.buttonCount_ = buttonCount
|
||||||
gp.native.hatCount_ = hatCount
|
n.hatCount_ = hatCount
|
||||||
|
|
||||||
if err := gp.native.pollAbsState(); err != nil {
|
if err := n.pollAbsState(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) update(gamepads *gamepads) error {
|
func (g *nativeGamepadsImpl) update(gamepads *gamepads) error {
|
||||||
if g.inotify <= 0 {
|
if g.inotify <= 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -248,9 +255,9 @@ func (g *nativeGamepads) update(gamepads *gamepads) error {
|
|||||||
}
|
}
|
||||||
if e.Mask&unix.IN_DELETE != 0 {
|
if e.Mask&unix.IN_DELETE != 0 {
|
||||||
if gp := gamepads.find(func(gamepad *Gamepad) bool {
|
if gp := gamepads.find(func(gamepad *Gamepad) bool {
|
||||||
return gamepad.native.path == path
|
return gamepad.native.(*nativeGamepadImpl).path == path
|
||||||
}); gp != nil {
|
}); gp != nil {
|
||||||
gp.native.close()
|
gp.native.(*nativeGamepadImpl).close()
|
||||||
gamepads.remove(func(gamepad *Gamepad) bool {
|
gamepads.remove(func(gamepad *Gamepad) bool {
|
||||||
return gamepad == gp
|
return gamepad == gp
|
||||||
})
|
})
|
||||||
@ -262,7 +269,7 @@ func (g *nativeGamepads) update(gamepads *gamepads) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type nativeGamepad struct {
|
type nativeGamepadImpl struct {
|
||||||
fd int
|
fd int
|
||||||
path string
|
path string
|
||||||
keyMap [_KEY_CNT - _BTN_MISC]int
|
keyMap [_KEY_CNT - _BTN_MISC]int
|
||||||
@ -279,14 +286,14 @@ type nativeGamepad struct {
|
|||||||
hatCount_ int
|
hatCount_ int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) close() {
|
func (g *nativeGamepadImpl) close() {
|
||||||
if g.fd != 0 {
|
if g.fd != 0 {
|
||||||
unix.Close(g.fd)
|
unix.Close(g.fd)
|
||||||
}
|
}
|
||||||
g.fd = 0
|
g.fd = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) update(gamepad *gamepads) error {
|
func (g *nativeGamepadImpl) update(gamepad *gamepads) error {
|
||||||
if g.fd == 0 {
|
if g.fd == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -344,7 +351,7 @@ func (g *nativeGamepad) update(gamepad *gamepads) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) pollAbsState() error {
|
func (g *nativeGamepadImpl) pollAbsState() error {
|
||||||
for code := 0; code < _ABS_CNT; code++ {
|
for code := 0; code < _ABS_CNT; code++ {
|
||||||
if g.absMap[code] < 0 {
|
if g.absMap[code] < 0 {
|
||||||
continue
|
continue
|
||||||
@ -357,7 +364,7 @@ func (g *nativeGamepad) pollAbsState() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) handleAbsEvent(code int, value int32) {
|
func (g *nativeGamepadImpl) handleAbsEvent(code int, value int32) {
|
||||||
index := g.absMap[code]
|
index := g.absMap[code]
|
||||||
|
|
||||||
if code >= _ABS_HAT0X && code <= _ABS_HAT3Y {
|
if code >= _ABS_HAT0X && code <= _ABS_HAT3Y {
|
||||||
@ -399,47 +406,47 @@ func (g *nativeGamepad) handleAbsEvent(code int, value int32) {
|
|||||||
g.axes[index] = v
|
g.axes[index] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepad) hasOwnStandardLayoutMapping() bool {
|
func (*nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisCount() int {
|
func (g *nativeGamepadImpl) axisCount() int {
|
||||||
return g.axisCount_
|
return g.axisCount_
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) buttonCount() int {
|
func (g *nativeGamepadImpl) buttonCount() int {
|
||||||
return g.buttonCount_
|
return g.buttonCount_
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hatCount() int {
|
func (g *nativeGamepadImpl) hatCount() int {
|
||||||
return g.hatCount_
|
return g.hatCount_
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisValue(axis int) float64 {
|
func (g *nativeGamepadImpl) axisValue(axis int) float64 {
|
||||||
if axis < 0 || axis >= g.axisCount_ {
|
if axis < 0 || axis >= g.axisCount_ {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return g.axes[axis]
|
return g.axes[axis]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) isButtonPressed(button int) bool {
|
func (g *nativeGamepadImpl) isButtonPressed(button int) bool {
|
||||||
if button < 0 || button >= g.buttonCount_ {
|
if button < 0 || button >= g.buttonCount_ {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return g.buttons[button]
|
return g.buttons[button]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepad) buttonValue(button int) float64 {
|
func (*nativeGamepadImpl) buttonValue(button int) float64 {
|
||||||
panic("gamepad: buttonValue is not implemented")
|
panic("gamepad: buttonValue is not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hatState(hat int) int {
|
func (g *nativeGamepadImpl) hatState(hat int) int {
|
||||||
if hat < 0 || hat >= g.hatCount_ {
|
if hat < 0 || hat >= g.hatCount_ {
|
||||||
return hatCentered
|
return hatCentered
|
||||||
}
|
}
|
||||||
return g.hats[hat]
|
return g.hats[hat]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
func (g *nativeGamepadImpl) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||||
// TODO: Implement this (#1452)
|
// TODO: Implement this (#1452)
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ var xinputButtons = []uint16{
|
|||||||
_XINPUT_GAMEPAD_RIGHT_THUMB,
|
_XINPUT_GAMEPAD_RIGHT_THUMB,
|
||||||
}
|
}
|
||||||
|
|
||||||
type nativeGamepads struct {
|
type nativeGamepadsImpl struct {
|
||||||
dinput8 windows.Handle
|
dinput8 windows.Handle
|
||||||
dinput8API *_IDirectInput8W
|
dinput8API *_IDirectInput8W
|
||||||
xinput windows.Handle
|
xinput windows.Handle
|
||||||
@ -118,6 +118,10 @@ type nativeGamepads struct {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newNativeGamepadsImpl() nativeGamepads {
|
||||||
|
return &nativeGamepadsImpl{}
|
||||||
|
}
|
||||||
|
|
||||||
type dinputObject struct {
|
type dinputObject struct {
|
||||||
objectType dinputObjectType
|
objectType dinputObjectType
|
||||||
index int
|
index int
|
||||||
@ -132,7 +136,7 @@ type enumObjectsContext struct {
|
|||||||
povCount int
|
povCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) init(gamepads *gamepads) error {
|
func (g *nativeGamepadsImpl) init(gamepads *gamepads) error {
|
||||||
// As there is no guarantee that the DLL exists, NewLazySystemDLL is not available.
|
// As there is no guarantee that the DLL exists, NewLazySystemDLL is not available.
|
||||||
// TODO: Is there a 'system' version of LoadLibrary?
|
// TODO: Is there a 'system' version of LoadLibrary?
|
||||||
if h, err := windows.LoadLibrary("dinput8.dll"); err == nil {
|
if h, err := windows.LoadLibrary("dinput8.dll"); err == nil {
|
||||||
@ -194,7 +198,7 @@ func (g *nativeGamepads) init(gamepads *gamepads) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) directInput8Create(hinst uintptr, dwVersion uint32, riidltf *windows.GUID, ppvOut **_IDirectInput8W, punkOuter unsafe.Pointer) error {
|
func (g *nativeGamepadsImpl) directInput8Create(hinst uintptr, dwVersion uint32, riidltf *windows.GUID, ppvOut **_IDirectInput8W, punkOuter unsafe.Pointer) error {
|
||||||
r, _, _ := syscall.Syscall6(g.procDirectInput8Create, 5,
|
r, _, _ := syscall.Syscall6(g.procDirectInput8Create, 5,
|
||||||
hinst, uintptr(dwVersion), uintptr(unsafe.Pointer(riidltf)), uintptr(unsafe.Pointer(ppvOut)), uintptr(punkOuter),
|
hinst, uintptr(dwVersion), uintptr(unsafe.Pointer(riidltf)), uintptr(unsafe.Pointer(ppvOut)), uintptr(punkOuter),
|
||||||
0)
|
0)
|
||||||
@ -204,7 +208,7 @@ func (g *nativeGamepads) directInput8Create(hinst uintptr, dwVersion uint32, rii
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) xinputGetCapabilities(dwUserIndex uint32, dwFlags uint32, pCapabilities *_XINPUT_CAPABILITIES) error {
|
func (g *nativeGamepadsImpl) xinputGetCapabilities(dwUserIndex uint32, dwFlags uint32, pCapabilities *_XINPUT_CAPABILITIES) error {
|
||||||
// XInputGetCapabilities doesn't call SetLastError and returns an error code directly.
|
// XInputGetCapabilities doesn't call SetLastError and returns an error code directly.
|
||||||
r, _, _ := syscall.Syscall(g.procXInputGetCapabilities, 3,
|
r, _, _ := syscall.Syscall(g.procXInputGetCapabilities, 3,
|
||||||
uintptr(dwUserIndex), uintptr(dwFlags), uintptr(unsafe.Pointer(pCapabilities)))
|
uintptr(dwUserIndex), uintptr(dwFlags), uintptr(unsafe.Pointer(pCapabilities)))
|
||||||
@ -214,7 +218,7 @@ func (g *nativeGamepads) xinputGetCapabilities(dwUserIndex uint32, dwFlags uint3
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) xinputGetState(dwUserIndex uint32, pState *_XINPUT_STATE) error {
|
func (g *nativeGamepadsImpl) xinputGetState(dwUserIndex uint32, pState *_XINPUT_STATE) error {
|
||||||
// XInputGetState doesn't call SetLastError and returns an error code directly.
|
// XInputGetState doesn't call SetLastError and returns an error code directly.
|
||||||
r, _, _ := syscall.Syscall(g.procXInputGetState, 2,
|
r, _, _ := syscall.Syscall(g.procXInputGetState, 2,
|
||||||
uintptr(dwUserIndex), uintptr(unsafe.Pointer(pState)), 0)
|
uintptr(dwUserIndex), uintptr(unsafe.Pointer(pState)), 0)
|
||||||
@ -224,7 +228,7 @@ func (g *nativeGamepads) xinputGetState(dwUserIndex uint32, pState *_XINPUT_STAT
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) detectConnection(gamepads *gamepads) error {
|
func (g *nativeGamepadsImpl) detectConnection(gamepads *gamepads) error {
|
||||||
if g.dinput8 != 0 {
|
if g.dinput8 != 0 {
|
||||||
if g.enumDevicesCallback == 0 {
|
if g.enumDevicesCallback == 0 {
|
||||||
g.enumDevicesCallback = windows.NewCallback(g.dinput8EnumDevicesCallback)
|
g.enumDevicesCallback = windows.NewCallback(g.dinput8EnumDevicesCallback)
|
||||||
@ -241,7 +245,8 @@ func (g *nativeGamepads) detectConnection(gamepads *gamepads) error {
|
|||||||
|
|
||||||
for i := 0; i < xuserMaxCount; i++ {
|
for i := 0; i < xuserMaxCount; i++ {
|
||||||
if gamepads.find(func(g *Gamepad) bool {
|
if gamepads.find(func(g *Gamepad) bool {
|
||||||
return g.native.dinputDevice == nil && g.native.xinputIndex == i
|
n := g.native.(*nativeGamepadImpl)
|
||||||
|
return n.dinputDevice == nil && n.xinputIndex == i
|
||||||
}) != nil {
|
}) != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -278,13 +283,15 @@ func (g *nativeGamepads) detectConnection(gamepads *gamepads) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gp := gamepads.add(name, sdlID)
|
gp := gamepads.add(name, sdlID)
|
||||||
gp.native.xinputIndex = i
|
gp.native = &nativeGamepadImpl{
|
||||||
|
xinputIndex: i,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) dinput8EnumDevicesCallback(lpddi *_DIDEVICEINSTANCEW, pvRef unsafe.Pointer) uintptr {
|
func (g *nativeGamepadsImpl) dinput8EnumDevicesCallback(lpddi *_DIDEVICEINSTANCEW, pvRef unsafe.Pointer) uintptr {
|
||||||
gamepads := (*gamepads)(pvRef)
|
gamepads := (*gamepads)(pvRef)
|
||||||
|
|
||||||
if g.err != nil {
|
if g.err != nil {
|
||||||
@ -292,7 +299,7 @@ func (g *nativeGamepads) dinput8EnumDevicesCallback(lpddi *_DIDEVICEINSTANCEW, p
|
|||||||
}
|
}
|
||||||
|
|
||||||
if gamepads.find(func(g *Gamepad) bool {
|
if gamepads.find(func(g *Gamepad) bool {
|
||||||
return g.native.dinputGUID == lpddi.guidInstance
|
return g.native.(*nativeGamepadImpl).dinputGUID == lpddi.guidInstance
|
||||||
}) != nil {
|
}) != nil {
|
||||||
return _DIENUM_CONTINUE
|
return _DIENUM_CONTINUE
|
||||||
}
|
}
|
||||||
@ -389,12 +396,14 @@ func (g *nativeGamepads) dinput8EnumDevicesCallback(lpddi *_DIDEVICEINSTANCEW, p
|
|||||||
}
|
}
|
||||||
|
|
||||||
gp := gamepads.add(name, sdlID)
|
gp := gamepads.add(name, sdlID)
|
||||||
gp.native.dinputDevice = device
|
gp.native = &nativeGamepadImpl{
|
||||||
gp.native.dinputObjects = ctx.objects
|
dinputDevice: device,
|
||||||
gp.native.dinputGUID = lpddi.guidInstance
|
dinputObjects: ctx.objects,
|
||||||
gp.native.dinputAxes = make([]float64, ctx.axisCount+ctx.sliderCount)
|
dinputGUID: lpddi.guidInstance,
|
||||||
gp.native.dinputButtons = make([]bool, ctx.buttonCount)
|
dinputAxes: make([]float64, ctx.axisCount+ctx.sliderCount),
|
||||||
gp.native.dinputHats = make([]int, ctx.povCount)
|
dinputButtons: make([]bool, ctx.buttonCount),
|
||||||
|
dinputHats: make([]int, ctx.povCount),
|
||||||
|
}
|
||||||
|
|
||||||
return _DIENUM_CONTINUE
|
return _DIENUM_CONTINUE
|
||||||
}
|
}
|
||||||
@ -443,7 +452,7 @@ func supportsXInput(guid windows.GUID) (bool, error) {
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) dinputDevice8EnumObjectsCallback(lpddoi *_DIDEVICEOBJECTINSTANCEW, pvRef unsafe.Pointer) uintptr {
|
func (g *nativeGamepadsImpl) dinputDevice8EnumObjectsCallback(lpddoi *_DIDEVICEOBJECTINSTANCEW, pvRef unsafe.Pointer) uintptr {
|
||||||
ctx := (*enumObjectsContext)(pvRef)
|
ctx := (*enumObjectsContext)(pvRef)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
@ -511,7 +520,7 @@ func (g *nativeGamepads) dinputDevice8EnumObjectsCallback(lpddoi *_DIDEVICEOBJEC
|
|||||||
return _DIENUM_CONTINUE
|
return _DIENUM_CONTINUE
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) update(gamepads *gamepads) error {
|
func (g *nativeGamepadsImpl) update(gamepads *gamepads) error {
|
||||||
if g.err != nil {
|
if g.err != nil {
|
||||||
return g.err
|
return g.err
|
||||||
}
|
}
|
||||||
@ -537,7 +546,7 @@ func (g *nativeGamepads) update(gamepads *gamepads) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) wndProc(hWnd uintptr, uMsg uint32, wParam, lParam uintptr) uintptr {
|
func (g *nativeGamepadsImpl) wndProc(hWnd uintptr, uMsg uint32, wParam, lParam uintptr) uintptr {
|
||||||
switch uMsg {
|
switch uMsg {
|
||||||
case _WM_DEVICECHANGE:
|
case _WM_DEVICECHANGE:
|
||||||
atomic.StoreInt32(&g.deviceChanged, 1)
|
atomic.StoreInt32(&g.deviceChanged, 1)
|
||||||
@ -545,11 +554,11 @@ func (g *nativeGamepads) wndProc(hWnd uintptr, uMsg uint32, wParam, lParam uintp
|
|||||||
return _CallWindowProcW(g.origWndProc, hWnd, uMsg, wParam, lParam)
|
return _CallWindowProcW(g.origWndProc, hWnd, uMsg, wParam, lParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepads) setNativeWindow(nativeWindow uintptr) {
|
func (g *nativeGamepadsImpl) setNativeWindow(nativeWindow uintptr) {
|
||||||
g.nativeWindow = windows.HWND(nativeWindow)
|
g.nativeWindow = windows.HWND(nativeWindow)
|
||||||
}
|
}
|
||||||
|
|
||||||
type nativeGamepad struct {
|
type nativeGamepadImpl struct {
|
||||||
dinputDevice *_IDirectInputDevice8W
|
dinputDevice *_IDirectInputDevice8W
|
||||||
dinputObjects []dinputObject
|
dinputObjects []dinputObject
|
||||||
dinputGUID windows.GUID
|
dinputGUID windows.GUID
|
||||||
@ -561,22 +570,22 @@ type nativeGamepad struct {
|
|||||||
xinputState _XINPUT_STATE
|
xinputState _XINPUT_STATE
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*nativeGamepad) hasOwnStandardLayoutMapping() bool {
|
func (*nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) usesDInput() bool {
|
func (g *nativeGamepadImpl) usesDInput() bool {
|
||||||
return g.dinputDevice != nil
|
return g.dinputDevice != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) update(gamepads *gamepads) (err error) {
|
func (g *nativeGamepadImpl) update(gamepads *gamepads) (err error) {
|
||||||
var disconnected bool
|
var disconnected bool
|
||||||
defer func() {
|
defer func() {
|
||||||
if !disconnected && err == nil {
|
if !disconnected && err == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gamepads.remove(func(gamepad *Gamepad) bool {
|
gamepads.remove(func(gamepad *Gamepad) bool {
|
||||||
return &gamepad.native == g
|
return gamepad.native == g
|
||||||
})
|
})
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -666,7 +675,7 @@ func (g *nativeGamepad) update(gamepads *gamepads) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var state _XINPUT_STATE
|
var state _XINPUT_STATE
|
||||||
if err := gamepads.native.xinputGetState(uint32(g.xinputIndex), &state); err != nil {
|
if err := gamepads.native.(*nativeGamepadsImpl).xinputGetState(uint32(g.xinputIndex), &state); err != nil {
|
||||||
if !errors.Is(err, windows.ERROR_DEVICE_NOT_CONNECTED) {
|
if !errors.Is(err, windows.ERROR_DEVICE_NOT_CONNECTED) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -677,28 +686,28 @@ func (g *nativeGamepad) update(gamepads *gamepads) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisCount() int {
|
func (g *nativeGamepadImpl) axisCount() int {
|
||||||
if g.usesDInput() {
|
if g.usesDInput() {
|
||||||
return len(g.dinputAxes)
|
return len(g.dinputAxes)
|
||||||
}
|
}
|
||||||
return 6
|
return 6
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) buttonCount() int {
|
func (g *nativeGamepadImpl) buttonCount() int {
|
||||||
if g.usesDInput() {
|
if g.usesDInput() {
|
||||||
return len(g.dinputButtons)
|
return len(g.dinputButtons)
|
||||||
}
|
}
|
||||||
return len(xinputButtons)
|
return len(xinputButtons)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hatCount() int {
|
func (g *nativeGamepadImpl) hatCount() int {
|
||||||
if g.usesDInput() {
|
if g.usesDInput() {
|
||||||
return len(g.dinputHats)
|
return len(g.dinputHats)
|
||||||
}
|
}
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) axisValue(axis int) float64 {
|
func (g *nativeGamepadImpl) axisValue(axis int) float64 {
|
||||||
if g.usesDInput() {
|
if g.usesDInput() {
|
||||||
if axis < 0 || axis >= len(g.dinputAxes) {
|
if axis < 0 || axis >= len(g.dinputAxes) {
|
||||||
return 0
|
return 0
|
||||||
@ -724,7 +733,7 @@ func (g *nativeGamepad) axisValue(axis int) float64 {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) isButtonPressed(button int) bool {
|
func (g *nativeGamepadImpl) isButtonPressed(button int) bool {
|
||||||
if g.usesDInput() {
|
if g.usesDInput() {
|
||||||
if button < 0 || button >= len(g.dinputButtons) {
|
if button < 0 || button >= len(g.dinputButtons) {
|
||||||
return false
|
return false
|
||||||
@ -738,11 +747,11 @@ func (g *nativeGamepad) isButtonPressed(button int) bool {
|
|||||||
return g.xinputState.Gamepad.wButtons&xinputButtons[button] != 0
|
return g.xinputState.Gamepad.wButtons&xinputButtons[button] != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) buttonValue(button int) float64 {
|
func (g *nativeGamepadImpl) buttonValue(button int) float64 {
|
||||||
panic("gamepad: buttonValue is not implemented")
|
panic("gamepad: buttonValue is not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) hatState(hat int) int {
|
func (g *nativeGamepadImpl) hatState(hat int) int {
|
||||||
if g.usesDInput() {
|
if g.usesDInput() {
|
||||||
if hat < 0 || hat >= len(g.dinputHats) {
|
if hat < 0 || hat >= len(g.dinputHats) {
|
||||||
return 0
|
return 0
|
||||||
@ -769,6 +778,6 @@ func (g *nativeGamepad) hatState(hat int) int {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *nativeGamepad) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
func (g *nativeGamepadImpl) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||||
// TODO: Implement this (#1452)
|
// TODO: Implement this (#1452)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user