mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 19:28:57 +01:00
ebiten: add IsStandardGamepadAxisAvailable and IsStandardGamepadButtonAvailable (#2241)
Closes #2040
This commit is contained in:
parent
8f792fef45
commit
094726915b
@ -154,13 +154,17 @@ func standardMap(id ebiten.GamepadID) string {
|
|||||||
for b, str := range standardButtonToString {
|
for b, str := range standardButtonToString {
|
||||||
placeholder := "[" + str + strings.Repeat(" ", 4-len(str)) + "]"
|
placeholder := "[" + str + strings.Repeat(" ", 4-len(str)) + "]"
|
||||||
v := ebiten.StandardGamepadButtonValue(id, b)
|
v := ebiten.StandardGamepadButtonValue(id, b)
|
||||||
if ebiten.IsStandardGamepadButtonPressed(id, b) {
|
switch {
|
||||||
|
case !ebiten.IsStandardGamepadButtonAvailable(id, b):
|
||||||
|
m = strings.Replace(m, placeholder, " -- ", 1)
|
||||||
|
case ebiten.IsStandardGamepadButtonPressed(id, b):
|
||||||
m = strings.Replace(m, placeholder, fmt.Sprintf("[%0.2f]", v), 1)
|
m = strings.Replace(m, placeholder, fmt.Sprintf("[%0.2f]", v), 1)
|
||||||
} else {
|
default:
|
||||||
m = strings.Replace(m, placeholder, fmt.Sprintf(" %0.2f ", v), 1)
|
m = strings.Replace(m, placeholder, fmt.Sprintf(" %0.2f ", v), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Use ebiten.IsStandardGamepadAxisAvailable
|
||||||
m += fmt.Sprintf(" Left Stick: X: %+0.2f, Y: %+0.2f\n Right Stick: X: %+0.2f, Y: %+0.2f",
|
m += fmt.Sprintf(" Left Stick: X: %+0.2f, Y: %+0.2f\n Right Stick: X: %+0.2f, Y: %+0.2f",
|
||||||
ebiten.StandardGamepadAxisValue(id, ebiten.StandardGamepadAxisLeftStickHorizontal),
|
ebiten.StandardGamepadAxisValue(id, ebiten.StandardGamepadAxisLeftStickHorizontal),
|
||||||
ebiten.StandardGamepadAxisValue(id, ebiten.StandardGamepadAxisLeftStickVertical),
|
ebiten.StandardGamepadAxisValue(id, ebiten.StandardGamepadAxisLeftStickVertical),
|
||||||
|
22
input.go
22
input.go
@ -303,6 +303,28 @@ func IsStandardGamepadLayoutAvailable(id GamepadID) bool {
|
|||||||
return g.IsStandardLayoutAvailable()
|
return g.IsStandardLayoutAvailable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsStandardGamepadAxisAvailable reports whether the standard gamepad axis is available on the gamepad (id).
|
||||||
|
//
|
||||||
|
// IsStandardGamepadAxisAvailable is concurrent-safe.
|
||||||
|
func IsStandardGamepadAxisAvailable(id GamepadID, axis StandardGamepadAxis) bool {
|
||||||
|
g := gamepad.Get(id)
|
||||||
|
if g == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return g.IsStandardAxisAvailable(axis)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsStandardGamepadButtonAvailable reports whether the standard gamepad button is available on the gamepad (id).
|
||||||
|
//
|
||||||
|
// IsStandardGamepadButtonAvailable is concurrent-safe.
|
||||||
|
func IsStandardGamepadButtonAvailable(id GamepadID, button StandardGamepadButton) bool {
|
||||||
|
g := gamepad.Get(id)
|
||||||
|
if g == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return g.IsStandardButtonAvailable(button)
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateStandardGamepadLayoutMappings parses the specified string mappings in SDL_GameControllerDB format and
|
// UpdateStandardGamepadLayoutMappings parses the specified string mappings in SDL_GameControllerDB format and
|
||||||
// updates the gamepad layout definitions.
|
// updates the gamepad layout definitions.
|
||||||
//
|
//
|
||||||
|
@ -190,6 +190,8 @@ type Gamepad struct {
|
|||||||
type nativeGamepad interface {
|
type nativeGamepad interface {
|
||||||
update(gamepads *gamepads) error
|
update(gamepads *gamepads) error
|
||||||
hasOwnStandardLayoutMapping() bool
|
hasOwnStandardLayoutMapping() bool
|
||||||
|
isStandardAxisAvailableInOwnMapping(axis gamepaddb.StandardAxis) bool
|
||||||
|
isStandardButtonAvailableInOwnMapping(button gamepaddb.StandardButton) bool
|
||||||
axisCount() int
|
axisCount() int
|
||||||
buttonCount() int
|
buttonCount() int
|
||||||
hatCount() int
|
hatCount() int
|
||||||
@ -281,6 +283,28 @@ func (g *Gamepad) IsStandardLayoutAvailable() bool {
|
|||||||
return g.native.hasOwnStandardLayoutMapping()
|
return g.native.hasOwnStandardLayoutMapping()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsStandardAxisAvailable is concurrent safe.
|
||||||
|
func (g *Gamepad) IsStandardAxisAvailable(button gamepaddb.StandardAxis) bool {
|
||||||
|
g.m.Lock()
|
||||||
|
defer g.m.Unlock()
|
||||||
|
|
||||||
|
if gamepaddb.HasStandardLayoutMapping(g.sdlID) {
|
||||||
|
return gamepaddb.HasStandardAxis(g.sdlID, button)
|
||||||
|
}
|
||||||
|
return g.native.isStandardAxisAvailableInOwnMapping(button)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsStandardButtonAvailable is concurrent safe.
|
||||||
|
func (g *Gamepad) IsStandardButtonAvailable(button gamepaddb.StandardButton) bool {
|
||||||
|
g.m.Lock()
|
||||||
|
defer g.m.Unlock()
|
||||||
|
|
||||||
|
if gamepaddb.HasStandardLayoutMapping(g.sdlID) {
|
||||||
|
return gamepaddb.HasStandardButton(g.sdlID, button)
|
||||||
|
}
|
||||||
|
return g.native.isStandardButtonAvailableInOwnMapping(button)
|
||||||
|
}
|
||||||
|
|
||||||
// StandardAxisValue is concurrent-safe.
|
// StandardAxisValue is concurrent-safe.
|
||||||
func (g *Gamepad) StandardAxisValue(axis gamepaddb.StandardAxis) float64 {
|
func (g *Gamepad) StandardAxisValue(axis gamepaddb.StandardAxis) float64 {
|
||||||
if gamepaddb.HasStandardLayoutMapping(g.sdlID) {
|
if gamepaddb.HasStandardLayoutMapping(g.sdlID) {
|
||||||
|
@ -19,6 +19,8 @@ package gamepad
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/gamepaddb"
|
||||||
)
|
)
|
||||||
|
|
||||||
type nativeGamepadsImpl struct{}
|
type nativeGamepadsImpl struct{}
|
||||||
@ -52,6 +54,14 @@ func (*nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*nativeGamepadImpl) isStandardAxisAvailableInOwnMapping(axis gamepaddb.StandardAxis) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*nativeGamepadImpl) isStandardButtonAvailableInOwnMapping(button gamepaddb.StandardButton) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (g *nativeGamepadImpl) axisCount() int {
|
func (g *nativeGamepadImpl) axisCount() int {
|
||||||
return len(g.axes)
|
return len(g.axes)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/cbackend"
|
"github.com/hajimehoshi/ebiten/v2/internal/cbackend"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/gamepaddb"
|
||||||
)
|
)
|
||||||
|
|
||||||
type nativeGamepadsImpl struct {
|
type nativeGamepadsImpl struct {
|
||||||
@ -98,6 +99,16 @@ func (g *nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
|||||||
return g.standard
|
return g.standard
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *nativeGamepadImpl) isStandardAxisAvailableInOwnMapping(axis gamepaddb.StandardAxis) bool {
|
||||||
|
// TODO: Implement this on the C side.
|
||||||
|
return axis >= 0 && int(axis) < len(g.axisValues)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *nativeGamepadImpl) isStandardButtonAvailableInOwnMapping(button gamepaddb.StandardButton) bool {
|
||||||
|
// TODO: Implement this on the C side.
|
||||||
|
return button >= 0 && int(button) < len(g.buttonValues)
|
||||||
|
}
|
||||||
|
|
||||||
func (g *nativeGamepadImpl) axisCount() int {
|
func (g *nativeGamepadImpl) axisCount() int {
|
||||||
return len(g.axisValues)
|
return len(g.axisValues)
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/gamepaddb"
|
||||||
)
|
)
|
||||||
|
|
||||||
// #cgo LDFLAGS: -framework CoreFoundation -framework IOKit
|
// #cgo LDFLAGS: -framework CoreFoundation -framework IOKit
|
||||||
@ -406,6 +408,14 @@ func (g *nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *nativeGamepadImpl) isStandardAxisAvailableInOwnMapping(axis gamepaddb.StandardAxis) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *nativeGamepadImpl) isStandardButtonAvailableInOwnMapping(button gamepaddb.StandardButton) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (g *nativeGamepadImpl) axisCount() int {
|
func (g *nativeGamepadImpl) axisCount() int {
|
||||||
return len(g.axisValues)
|
return len(g.axisValues)
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,8 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/gamepaddb"
|
||||||
)
|
)
|
||||||
|
|
||||||
type dinputObjectType int
|
type dinputObjectType int
|
||||||
@ -571,6 +573,14 @@ func (*nativeGamepadDesktop) hasOwnStandardLayoutMapping() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*nativeGamepadDesktop) isStandardAxisAvailableInOwnMapping(axis gamepaddb.StandardAxis) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*nativeGamepadDesktop) isStandardButtonAvailableInOwnMapping(button gamepaddb.StandardButton) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (g *nativeGamepadDesktop) usesDInput() bool {
|
func (g *nativeGamepadDesktop) usesDInput() bool {
|
||||||
return g.dinputDevice != nil
|
return g.dinputDevice != nil
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ package gamepad
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/gamepaddb"
|
||||||
)
|
)
|
||||||
|
|
||||||
type nativeGamepadsImpl struct{}
|
type nativeGamepadsImpl struct{}
|
||||||
@ -57,6 +59,14 @@ func (*nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*nativeGamepadImpl) isStandardAxisAvailableInOwnMapping(axis gamepaddb.StandardAxis) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*nativeGamepadImpl) isStandardButtonAvailableInOwnMapping(button gamepaddb.StandardButton) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (g *nativeGamepadImpl) axisCount() int {
|
func (g *nativeGamepadImpl) axisCount() int {
|
||||||
return len(g.axes)
|
return len(g.axes)
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/gamepaddb"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -114,6 +116,20 @@ func (g *nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
|||||||
return g.mapping == "standard"
|
return g.mapping == "standard"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *nativeGamepadImpl) isStandardAxisAvailableInOwnMapping(axis gamepaddb.StandardAxis) bool {
|
||||||
|
if !g.hasOwnStandardLayoutMapping() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return axis >= 0 && int(axis) < g.axisCount()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *nativeGamepadImpl) isStandardButtonAvailableInOwnMapping(button gamepaddb.StandardButton) bool {
|
||||||
|
if !g.hasOwnStandardLayoutMapping() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return button >= 0 && int(button) < g.buttonCount()
|
||||||
|
}
|
||||||
|
|
||||||
func (g *nativeGamepadImpl) update(gamepads *gamepads) error {
|
func (g *nativeGamepadImpl) update(gamepads *gamepads) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,8 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/gamepaddb"
|
||||||
)
|
)
|
||||||
|
|
||||||
const dirName = "/dev/input"
|
const dirName = "/dev/input"
|
||||||
@ -410,6 +412,14 @@ func (*nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*nativeGamepadImpl) isStandardAxisAvailableInOwnMapping(axis gamepaddb.StandardAxis) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*nativeGamepadImpl) isStandardButtonAvailableInOwnMapping(button gamepaddb.StandardButton) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (g *nativeGamepadImpl) axisCount() int {
|
func (g *nativeGamepadImpl) axisCount() int {
|
||||||
return g.axisCount_
|
return g.axisCount_
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ package gamepad
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/gamepaddb"
|
||||||
)
|
)
|
||||||
|
|
||||||
type nativeGamepadsImpl struct{}
|
type nativeGamepadsImpl struct{}
|
||||||
@ -45,6 +47,14 @@ func (*nativeGamepadImpl) hasOwnStandardLayoutMapping() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*nativeGamepadImpl) isStandardAxisAvailableInOwnMapping(axis gamepaddb.StandardAxis) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*nativeGamepadImpl) isStandardButtonAvailableInOwnMapping(button gamepaddb.StandardButton) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (*nativeGamepadImpl) axisCount() int {
|
func (*nativeGamepadImpl) axisCount() int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -158,6 +158,27 @@ func (n *nativeGamepadXbox) hasOwnStandardLayoutMapping() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *nativeGamepadXbox) isStandardAxisAvailableInOwnMapping(axis gamepaddb.StandardAxis) bool {
|
||||||
|
switch gamepaddb.StandardAxis(axis) {
|
||||||
|
case gamepaddb.StandardAxisLeftStickHorizontal,
|
||||||
|
gamepaddb.StandardAxisLeftStickVertical,
|
||||||
|
gamepaddb.StandardAxisRightStickHorizontal,
|
||||||
|
gamepaddb.StandardAxisRightStickVertical:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nativeGamepadXbox) isStandardButtonAvailableInOwnMapping(button gamepaddb.StandardButton) bool {
|
||||||
|
switch gamepaddb.StandardButton(button) {
|
||||||
|
case gamepaddb.StandardButtonFrontBottomLeft,
|
||||||
|
gamepaddb.StandardButtonFrontBottomRight:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
_, ok := standardButtonToGamepadInputGamepadButton(button)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
func (n *nativeGamepadXbox) axisCount() int {
|
func (n *nativeGamepadXbox) axisCount() int {
|
||||||
return int(gamepaddb.StandardAxisMax) + 1
|
return int(gamepaddb.StandardAxisMax) + 1
|
||||||
}
|
}
|
||||||
|
@ -389,6 +389,23 @@ func Name(id string) string {
|
|||||||
return gamepadNames[id]
|
return gamepadNames[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HasStandardAxis(id string, axis StandardAxis) bool {
|
||||||
|
mappingsM.RLock()
|
||||||
|
defer mappingsM.RUnlock()
|
||||||
|
|
||||||
|
mappings := axisMappings(id)
|
||||||
|
if mappings == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
mapping := mappings[axis]
|
||||||
|
if mapping == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func AxisValue(id string, axis StandardAxis, state GamepadState) float64 {
|
func AxisValue(id string, axis StandardAxis, state GamepadState) float64 {
|
||||||
mappingsM.RLock()
|
mappingsM.RLock()
|
||||||
defer mappingsM.RUnlock()
|
defer mappingsM.RUnlock()
|
||||||
@ -429,6 +446,23 @@ func AxisValue(id string, axis StandardAxis, state GamepadState) float64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HasStandardButton(id string, button StandardButton) bool {
|
||||||
|
mappingsM.RLock()
|
||||||
|
defer mappingsM.RUnlock()
|
||||||
|
|
||||||
|
mappings := buttonMappings(id)
|
||||||
|
if mappings == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
mapping := mappings[button]
|
||||||
|
if mapping == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func ButtonValue(id string, button StandardButton, state GamepadState) float64 {
|
func ButtonValue(id string, button StandardButton, state GamepadState) float64 {
|
||||||
mappingsM.RLock()
|
mappingsM.RLock()
|
||||||
defer mappingsM.RUnlock()
|
defer mappingsM.RUnlock()
|
||||||
|
Loading…
Reference in New Issue
Block a user