Implement Gamepad API for JavaScript (working on Firefox so far)

This commit is contained in:
Hajime Hoshi 2015-01-12 14:36:13 +09:00
parent a500d3a3f8
commit 8987f7a645
4 changed files with 64 additions and 13 deletions

View File

@ -29,6 +29,7 @@ const (
)
func update(screen *ebiten.Image) error {
// TODO: API to get the available, lowest ID
const gamepadID = 0
axes := []string{}
pressedButtons := []string{}

View File

@ -37,33 +37,33 @@ func (i *input) update(window *glfw.Window, scale int) error {
x, y := window.GetCursorPosition()
i.cursorX = int(math.Floor(x)) / scale
i.cursorY = int(math.Floor(y)) / scale
for j := glfw.Joystick(0); j < glfw.Joystick(len(i.gamepads)); j++ {
if !glfw.JoystickPresent(j) {
for id := glfw.Joystick(0); id < glfw.Joystick(len(i.gamepads)); id++ {
if !glfw.JoystickPresent(id) {
continue
}
axes32, err := glfw.GetJoystickAxes(j)
axes32, err := glfw.GetJoystickAxes(id)
if err != nil {
return err
}
i.gamepads[j].axisNum = len(axes32)
for a := 0; a < len(i.gamepads[j].axes); a++ {
i.gamepads[id].axisNum = len(axes32)
for a := 0; a < len(i.gamepads[id].axes); a++ {
if len(axes32) <= a {
i.gamepads[j].axes[a] = 0
i.gamepads[id].axes[a] = 0
continue
}
i.gamepads[j].axes[a] = float64(axes32[a])
i.gamepads[id].axes[a] = float64(axes32[a])
}
buttons, err := glfw.GetJoystickButtons(j)
buttons, err := glfw.GetJoystickButtons(id)
if err != nil {
return err
}
i.gamepads[j].buttonNum = len(buttons)
for b := 0; b < len(i.gamepads[j].buttonPressed); b++ {
i.gamepads[id].buttonNum = len(buttons)
for b := 0; b < len(i.gamepads[id].buttonPressed); b++ {
if len(buttons) <= b {
i.gamepads[j].buttonPressed[b] = false
i.gamepads[id].buttonPressed[b] = false
continue
}
i.gamepads[j].buttonPressed[b] = glfw.Action(buttons[b]) == glfw.Press
i.gamepads[id].buttonPressed[b] = glfw.Action(buttons[b]) == glfw.Press
}
}
return nil

View File

@ -16,6 +16,10 @@
package ui
import (
"github.com/gopherjs/gopherjs/js"
)
func (i *input) keyDown(key int) {
k, ok := keyCodeToKey[key]
if !ok {
@ -59,3 +63,36 @@ func (i *input) mouseUp(button int) {
func (i *input) mouseMove(x, y int) {
i.cursorX, i.cursorY = x, y
}
func (i *input) updateGamepads() {
gamepads := js.Global.Get("navigator").Call("getGamepads")
l := gamepads.Get("length").Int()
for id := 0; id < l; id++ {
gamepad := gamepads.Index(id)
if gamepad == js.Undefined || gamepad == nil {
continue
}
axes := gamepad.Get("axes")
axesNum := axes.Get("length").Int()
i.gamepads[id].axisNum = axesNum
for a := 0; a < len(i.gamepads[id].axes); a++ {
if axesNum <= a {
i.gamepads[id].axes[a] = 0
continue
}
i.gamepads[id].axes[a] = axes.Index(a).Float()
}
buttons := gamepad.Get("buttons")
buttonsNum := buttons.Get("length").Int()
i.gamepads[id].buttonNum = buttonsNum
for b := 0; b < len(i.gamepads[id].buttonPressed); b++ {
if buttonsNum <= b {
i.gamepads[id].buttonPressed[b] = false
continue
}
i.gamepads[id].buttonPressed[b] = buttons.Index(b).Get("pressed").Bool()
}
}
}

View File

@ -47,6 +47,7 @@ func DoEvents() error {
for !shown() {
vsync()
}
currentInput.updateGamepads()
return nil
}
@ -66,9 +67,10 @@ func init() {
// TODO: Implement this with node-webgl mainly for testing.
doc := js.Global.Get("document")
window := js.Global.Get("window")
if doc.Get("body") == nil {
ch := make(chan struct{})
js.Global.Get("window").Call("addEventListener", "load", func() {
window.Call("addEventListener", "load", func() {
close(ch)
})
<-ch
@ -127,6 +129,7 @@ func init() {
canvas.Call("setAttribute", "tabindex", 1)
canvas.Get("style").Set("outline", "none")
// Keyboard
canvas.Call("addEventListener", "keydown", func(e js.Object) bool {
code := e.Get("keyCode").Int()
currentInput.keyDown(code)
@ -137,6 +140,8 @@ func init() {
currentInput.keyUp(code)
return false
})
// Mouse
canvas.Call("addEventListener", "mousedown", func(e js.Object) bool {
button := e.Get("button").Int()
currentInput.mouseDown(button)
@ -150,6 +155,14 @@ func init() {
canvas.Call("addEventListener", "contextmenu", func(e js.Object) bool {
return false
})
// Gamepad
window.Call("addEventListener", "gamepadconnected", func(e js.Object) {
print(e)
})
window.Call("addEventListener", "gamepaddisconnected", func(e js.Object) {
print(e)
})
}
func devicePixelRatio() int {