ebiten: Add StandardGamepadButtonValue

Closes #1721
This commit is contained in:
Hajime Hoshi 2021-09-12 20:13:23 +09:00
parent 7422a3353a
commit ea12ede127
7 changed files with 116 additions and 101 deletions

View File

@ -98,99 +98,44 @@ func (g *Game) Update() error {
return nil
}
func standardMap(id ebiten.GamepadID) string {
m := ` [FBL] [FBR]
[FTL] [FTR]
var standardButtonToString = map[ebiten.StandardGamepadButton]string{
ebiten.StandardGamepadButtonRightBottom: "RB",
ebiten.StandardGamepadButtonRightRight: "RR",
ebiten.StandardGamepadButtonRightLeft: "RL",
ebiten.StandardGamepadButtonRightTop: "RT",
ebiten.StandardGamepadButtonFrontTopLeft: "FTL",
ebiten.StandardGamepadButtonFrontTopRight: "FTR",
ebiten.StandardGamepadButtonFrontBottomLeft: "FBL",
ebiten.StandardGamepadButtonFrontBottomRight: "FBR",
ebiten.StandardGamepadButtonCenterLeft: "CL",
ebiten.StandardGamepadButtonCenterRight: "CR",
ebiten.StandardGamepadButtonLeftStick: "LS",
ebiten.StandardGamepadButtonRightStick: "RS",
ebiten.StandardGamepadButtonLeftBottom: "LB",
ebiten.StandardGamepadButtonLeftRight: "LR",
ebiten.StandardGamepadButtonLeftLeft: "LL",
ebiten.StandardGamepadButtonLeftTop: "LT",
ebiten.StandardGamepadButtonCenterCenter: "CC",
}
[LT] [CC] [RT]
[LL][LR] [CL][CR] [RL][RR]
[LB] [RB]
(LS) (RS)
func standardMap(id ebiten.GamepadID) string {
m := ` [FBL ] [FBR ]
[FTL ] [FTR ]
[LT ] [CC ] [RT ]
[LL ][LR ] [CL ][CR ] [RL ][RR ]
[LB ] [RB ]
[LS ] [RS ]
`
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonRightBottom) {
m = strings.Replace(m, "[RB]", "[**]", 1)
} else {
m = strings.Replace(m, "[RB]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonRightRight) {
m = strings.Replace(m, "[RR]", "[**]", 1)
} else {
m = strings.Replace(m, "[RR]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonRightLeft) {
m = strings.Replace(m, "[RL]", "[**]", 1)
} else {
m = strings.Replace(m, "[RL]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonRightTop) {
m = strings.Replace(m, "[RT]", "[**]", 1)
} else {
m = strings.Replace(m, "[RT]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonFrontTopLeft) {
m = strings.Replace(m, "[FTL]", "[**]", 1)
} else {
m = strings.Replace(m, "[FTL]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonFrontTopRight) {
m = strings.Replace(m, "[FTR]", "[**]", 1)
} else {
m = strings.Replace(m, "[FTR]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonFrontBottomLeft) {
m = strings.Replace(m, "[FBL]", "[**]", 1)
} else {
m = strings.Replace(m, "[FBL]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonFrontBottomRight) {
m = strings.Replace(m, "[FBR]", "[**]", 1)
} else {
m = strings.Replace(m, "[FBR]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonCenterLeft) {
m = strings.Replace(m, "[CL]", "[**]", 1)
} else {
m = strings.Replace(m, "[CL]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonCenterRight) {
m = strings.Replace(m, "[CR]", "[**]", 1)
} else {
m = strings.Replace(m, "[CR]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonLeftStick) {
m = strings.Replace(m, "(LS)", "[**]", 1)
} else {
m = strings.Replace(m, "(LS)", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonRightStick) {
m = strings.Replace(m, "(RS)", "[**]", 1)
} else {
m = strings.Replace(m, "(RS)", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonLeftBottom) {
m = strings.Replace(m, "[LB]", "[**]", 1)
} else {
m = strings.Replace(m, "[LB]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonLeftRight) {
m = strings.Replace(m, "[LR]", "[**]", 1)
} else {
m = strings.Replace(m, "[LR]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonLeftLeft) {
m = strings.Replace(m, "[LL]", "[**]", 1)
} else {
m = strings.Replace(m, "[LL]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonLeftTop) {
m = strings.Replace(m, "[LT]", "[**]", 1)
} else {
m = strings.Replace(m, "[LT]", "[ ]", 1)
}
if ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonCenterCenter) {
m = strings.Replace(m, "[CC]", "[**]", 1)
} else {
m = strings.Replace(m, "[CC]", "[ ]", 1)
for b, str := range standardButtonToString {
placeholder := "[" + str + strings.Repeat(" ", 4-len(str)) + "]"
v := ebiten.StandardGamepadButtonValue(id, b)
if ebiten.IsStandardGamepadButtonPressed(id, b) {
m = strings.Replace(m, placeholder, fmt.Sprintf("[%0.2f]", v), 1)
} else {
m = strings.Replace(m, placeholder, fmt.Sprintf(" %0.2f ", v), 1)
}
}
m += fmt.Sprintf(" Left Stick: X: %+0.2f, Y: %+0.2f\n Right Stick: X: %+0.2f, Y: %+0.2f",
@ -222,7 +167,7 @@ func (g *Game) Draw(screen *ebiten.Image) {
str += fmt.Sprintf(" Buttons: %s\n", strings.Join(g.pressedButtons[id], ", "))
if ebiten.IsStandardGamepadLayoutAvailable(id) {
str += "\n"
str += standardMap(id)
str += standardMap(id) + "\n"
str += "\n"
}
str += "\n"

View File

@ -219,6 +219,15 @@ func StandardGamepadAxisValue(id GamepadID, axis StandardGamepadAxis) float64 {
return uiDriver().Input().StandardGamepadAxisValue(id, axis)
}
// StandardGamepadButtonValue returns a float value [0.0 - 1.0] of the given gamepad (id)'s standard button (button).
//
// StandardGamepadButtonValue returns 0 when the gamepad doesn't have a standard gamepad layout mapping.
//
// StandardGamepadButtonValue is concurrent safe.
func StandardGamepadButtonValue(id GamepadID, button StandardGamepadButton) float64 {
return uiDriver().Input().StandardGamepadButtonValue(id, button)
}
// IsStandardGamepadButtonPressed reports whether the given gamepad (id)'s standard gamepad button (button) is pressed.
//
// IsStandardGamepadButtonPressed returns false when the gamepad doesn't have a standard gamepad layout mapping.

View File

@ -34,6 +34,7 @@ type Input interface {
IsStandardGamepadButtonPressed(id GamepadID, button StandardGamepadButton) bool
IsStandardGamepadLayoutAvailable(id GamepadID) bool
StandardGamepadAxisValue(id GamepadID, button StandardGamepadAxis) float64
StandardGamepadButtonValue(id GamepadID, button StandardGamepadButton) float64
TouchPosition(id TouchID) (x, y int)
Wheel() (xoff, yoff float64)
}

View File

@ -394,6 +394,40 @@ func AxisValue(id string, axis driver.StandardGamepadAxis, state GamepadState) f
return 0
}
func ButtonValue(id string, button driver.StandardGamepadButton, state GamepadState) float64 {
mappingsM.RLock()
defer mappingsM.RUnlock()
mappings, ok := gamepadButtonMappings[id]
if !ok {
return 0
}
switch m := mappings[button]; m.Type {
case mappingTypeAxis:
v := state.Axis(m.Index)*float64(m.AxisScale) + float64(m.AxisOffset)
if v > 1 {
return 1
} else if v < -1 {
return -1
}
// Adjust [-1, 1] to [0, 1]
return (v + 1) / 2
case mappingTypeButton:
if state.Button(m.Index) {
return 1
}
return 0
case mappingTypeHat:
if state.Hat(m.Index)&m.HatState != 0 {
return 1
}
return 0
}
return 0
}
func IsButtonPressed(id string, button driver.StandardGamepadButton, state GamepadState) bool {
mappingsM.RLock()
defer mappingsM.RUnlock()

View File

@ -388,6 +388,17 @@ func (i *Input) StandardGamepadAxisValue(id driver.GamepadID, axis driver.Standa
return gamepaddb.AxisValue(g.guid, axis, gamepadState{&g})
}
func (i *Input) StandardGamepadButtonValue(id driver.GamepadID, button driver.StandardGamepadButton) float64 {
i.ui.m.Lock()
defer i.ui.m.Unlock()
if len(i.gamepads) <= int(id) {
return 0
}
g := i.gamepads[int(id)]
return gamepaddb.ButtonValue(g.guid, button, gamepadState{&g})
}
func (i *Input) IsStandardGamepadButtonPressed(id driver.GamepadID, button driver.StandardGamepadButton) bool {
i.ui.m.Lock()
defer i.ui.m.Unlock()

View File

@ -66,8 +66,10 @@ type gamepad struct {
axes [16]float64
buttonNum int
buttonPressed [256]bool
buttonValues [256]float64
standardButtonPressed [driver.StandardGamepadButtonMax + 1]bool
standardButtonValues [driver.StandardGamepadButtonMax + 1]float64
standardAxisValues [driver.StandardGamepadAxisMax + 1]float64
}
@ -315,27 +317,24 @@ func (i *Input) updateGamepads() {
axes := gp.Get("axes")
axesNum := axes.Length()
g.axisNum = axesNum
for a := 0; a < len(g.axes); a++ {
if axesNum <= a {
break
}
for a := 0; a < axesNum; a++ {
g.axes[a] = axes.Index(a).Float()
}
buttons := gp.Get("buttons")
buttonsNum := buttons.Length()
g.buttonNum = buttonsNum
for b := 0; b < len(g.buttonPressed); b++ {
if buttonsNum <= b {
break
}
g.buttonPressed[b] = buttons.Index(b).Get("pressed").Bool()
for b := 0; b < buttonsNum; b++ {
btn := buttons.Index(b)
g.buttonPressed[b] = btn.Get("pressed").Bool()
g.buttonValues[b] = btn.Get("value").Float()
}
if g.mapping == "standard" {
// When the gamepad's mapping is "standard", the button and axis IDs are already mapped as the standard layout.
// See https://www.w3.org/TR/gamepad/#remapping.
copy(g.standardButtonPressed[:], g.buttonPressed[:])
copy(g.standardButtonValues[:], g.buttonValues[:])
copy(g.standardAxisValues[:], g.axes[:])
}
@ -486,6 +485,17 @@ func (i *Input) StandardGamepadAxisValue(id driver.GamepadID, axis driver.Standa
return g.standardAxisValues[axis]
}
func (i *Input) StandardGamepadButtonValue(id driver.GamepadID, button driver.StandardGamepadButton) float64 {
g, ok := i.gamepads[id]
if !ok {
return 0
}
if !g.hasStandardLayoutMapping() {
return 0
}
return g.standardButtonValues[button]
}
func (i *Input) IsStandardGamepadButtonPressed(id driver.GamepadID, button driver.StandardGamepadButton) bool {
g, ok := i.gamepads[id]
if !ok {

View File

@ -142,6 +142,11 @@ func (i *Input) IsStandardGamepadButtonPressed(id driver.GamepadID, button drive
return false
}
func (i *Input) StandardGamepadButtonValue(id driver.GamepadID, button driver.StandardGamepadButton) float64 {
// TODO: Implement this (#1557)
return 0
}
func (i *Input) StandardGamepadAxisValue(id driver.GamepadID, axis driver.StandardGamepadAxis) float64 {
// TODO: Implement this (#1557)
return 0