mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 11:18:54 +01:00
internal/gamepad: move the implementation of gamepad for GOOS=js
Updates #1957
This commit is contained in:
parent
82298edfae
commit
5edfd1b743
@ -12,13 +12,14 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build darwin && !ios
|
||||
// +build darwin,!ios
|
||||
//go:build (darwin && !ios) || js
|
||||
// +build darwin,!ios js
|
||||
|
||||
package gamepad
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/driver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/gamepaddb"
|
||||
@ -47,6 +48,7 @@ var theGamepads gamepads
|
||||
|
||||
func init() {
|
||||
theGamepads.nativeGamepads.init()
|
||||
theGamepads.nativeGamepads.gamepads = &theGamepads
|
||||
}
|
||||
|
||||
func AppendGamepadIDs(ids []driver.GamepadID) []driver.GamepadID {
|
||||
@ -62,9 +64,6 @@ func Get(id driver.GamepadID) *Gamepad {
|
||||
}
|
||||
|
||||
func (g *gamepads) appendGamepadIDs(ids []driver.GamepadID) []driver.GamepadID {
|
||||
g.m.Lock()
|
||||
defer g.m.Unlock()
|
||||
|
||||
for i, gp := range g.gamepads {
|
||||
if gp != nil && gp.present() {
|
||||
ids = append(ids, driver.GamepadID(i))
|
||||
@ -77,6 +76,7 @@ func (g *gamepads) update() {
|
||||
g.m.Lock()
|
||||
defer g.m.Unlock()
|
||||
|
||||
g.nativeGamepads.update()
|
||||
for _, gp := range g.gamepads {
|
||||
if gp != nil {
|
||||
gp.update()
|
||||
@ -87,7 +87,10 @@ func (g *gamepads) update() {
|
||||
func (g *gamepads) get(id driver.GamepadID) *Gamepad {
|
||||
g.m.Lock()
|
||||
defer g.m.Unlock()
|
||||
return g.getImpl(id)
|
||||
}
|
||||
|
||||
func (g *gamepads) getImpl(id driver.GamepadID) *Gamepad {
|
||||
if id < 0 || int(id) >= len(g.gamepads) {
|
||||
return nil
|
||||
}
|
||||
@ -97,7 +100,10 @@ func (g *gamepads) get(id driver.GamepadID) *Gamepad {
|
||||
func (g *gamepads) find(cond func(*Gamepad) bool) *Gamepad {
|
||||
g.m.Lock()
|
||||
defer g.m.Unlock()
|
||||
return g.findImpl(cond)
|
||||
}
|
||||
|
||||
func (g *gamepads) findImpl(cond func(*Gamepad) bool) *Gamepad {
|
||||
for _, gp := range g.gamepads {
|
||||
if gp == nil {
|
||||
continue
|
||||
@ -112,7 +118,10 @@ func (g *gamepads) find(cond func(*Gamepad) bool) *Gamepad {
|
||||
func (g *gamepads) add(name, sdlID string) *Gamepad {
|
||||
g.m.Lock()
|
||||
defer g.m.Unlock()
|
||||
return g.addImpl(name, sdlID)
|
||||
}
|
||||
|
||||
func (g *gamepads) addImpl(name, sdlID string) *Gamepad {
|
||||
for i, gp := range g.gamepads {
|
||||
if gp == nil {
|
||||
gp := &Gamepad{
|
||||
@ -135,7 +144,10 @@ func (g *gamepads) add(name, sdlID string) *Gamepad {
|
||||
func (g *gamepads) remove(cond func(*Gamepad) bool) {
|
||||
g.m.Lock()
|
||||
defer g.m.Unlock()
|
||||
g.removeImpl(cond)
|
||||
}
|
||||
|
||||
func (g *gamepads) removeImpl(cond func(*Gamepad) bool) {
|
||||
for i, gp := range g.gamepads {
|
||||
if gp == nil {
|
||||
continue
|
||||
@ -220,17 +232,42 @@ func (g *Gamepad) IsStandardLayoutAvailable() bool {
|
||||
g.m.Lock()
|
||||
defer g.m.Unlock()
|
||||
|
||||
return gamepaddb.HasStandardLayoutMapping(g.sdlID)
|
||||
if gamepaddb.HasStandardLayoutMapping(g.sdlID) {
|
||||
return true
|
||||
}
|
||||
return g.hasOwnStandardLayoutMapping()
|
||||
}
|
||||
|
||||
func (g *Gamepad) StandardAxisValue(axis driver.StandardGamepadAxis) float64 {
|
||||
return gamepaddb.AxisValue(g.sdlID, axis, g)
|
||||
if gamepaddb.HasStandardLayoutMapping(g.sdlID) {
|
||||
return gamepaddb.AxisValue(g.sdlID, axis, g)
|
||||
}
|
||||
if g.hasOwnStandardLayoutMapping() {
|
||||
return g.nativeGamepad.axisValue(int(axis))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (g *Gamepad) StandardButtonValue(button driver.StandardGamepadButton) float64 {
|
||||
return gamepaddb.ButtonValue(g.sdlID, button, g)
|
||||
if gamepaddb.HasStandardLayoutMapping(g.sdlID) {
|
||||
return gamepaddb.ButtonValue(g.sdlID, button, g)
|
||||
}
|
||||
if g.hasOwnStandardLayoutMapping() {
|
||||
return g.nativeGamepad.buttonValue(int(button))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (g *Gamepad) IsStandardButtonPressed(button driver.StandardGamepadButton) bool {
|
||||
return gamepaddb.IsButtonPressed(g.sdlID, button, g)
|
||||
if gamepaddb.HasStandardLayoutMapping(g.sdlID) {
|
||||
return gamepaddb.IsButtonPressed(g.sdlID, button, g)
|
||||
}
|
||||
if g.hasOwnStandardLayoutMapping() {
|
||||
return g.nativeGamepad.isButtonPressed(int(button))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *Gamepad) Vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||
g.nativeGamepad.vibrate(duration, strongMagnitude, weakMagnitude)
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ package gamepad
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@ -57,6 +58,8 @@ import (
|
||||
import "C"
|
||||
|
||||
type nativeGamepads struct {
|
||||
gamepads *gamepads
|
||||
|
||||
hidManager C.IOHIDManagerRef
|
||||
}
|
||||
|
||||
@ -170,6 +173,10 @@ func (g *nativeGamepad) update() {
|
||||
}
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) hasOwnStandardLayoutMapping() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) axisNum() int {
|
||||
return len(g.axisValues)
|
||||
}
|
||||
@ -189,6 +196,10 @@ func (g *nativeGamepad) axisValue(axis int) float64 {
|
||||
return g.axisValues[axis]
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) buttonValue(button int) float64 {
|
||||
panic("gamepad: buttonValue is not implemented")
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) isButtonPressed(button int) bool {
|
||||
if button < 0 || button >= len(g.buttonValues) {
|
||||
return false
|
||||
@ -203,6 +214,10 @@ func (g *nativeGamepad) hatState(hat int) int {
|
||||
return g.hatValues[hat]
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||
// TODO: Implement this (#1452)
|
||||
}
|
||||
|
||||
func (g *nativeGamepads) init() {
|
||||
var dicts []C.CFDictionaryRef
|
||||
|
||||
@ -399,3 +414,6 @@ func ebitenGamepadRemovalCallback(ctx unsafe.Pointer, res C.IOReturn, sender uns
|
||||
return g.device == device
|
||||
})
|
||||
}
|
||||
|
||||
func (g *nativeGamepads) update() {
|
||||
}
|
||||
|
183
internal/gamepad/gamepad_js.go
Normal file
183
internal/gamepad/gamepad_js.go
Normal file
@ -0,0 +1,183 @@
|
||||
// Copyright 2022 The Ebiten Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gamepad
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"syscall/js"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
object = js.Global().Get("Object")
|
||||
go2cpp = js.Global().Get("go2cpp")
|
||||
)
|
||||
|
||||
type nativeGamepads struct {
|
||||
gamepads *gamepads
|
||||
|
||||
indices map[int]struct{}
|
||||
}
|
||||
|
||||
func (g *nativeGamepads) init() {
|
||||
}
|
||||
|
||||
func (g *nativeGamepads) update() {
|
||||
// TODO: Use the gamepad events instead of navigator.getGamepads after go2cpp is removed.
|
||||
|
||||
defer func() {
|
||||
for k := range g.indices {
|
||||
delete(g.indices, k)
|
||||
}
|
||||
}()
|
||||
|
||||
nav := js.Global().Get("navigator")
|
||||
if !nav.Truthy() {
|
||||
return
|
||||
}
|
||||
|
||||
gps := nav.Call("getGamepads")
|
||||
if !gps.Truthy() {
|
||||
return
|
||||
}
|
||||
|
||||
l := gps.Length()
|
||||
for idx := 0; idx < l; idx++ {
|
||||
gp := gps.Index(idx)
|
||||
if !gp.Truthy() {
|
||||
continue
|
||||
}
|
||||
index := gp.Get("index").Int()
|
||||
|
||||
if g.indices == nil {
|
||||
g.indices = map[int]struct{}{}
|
||||
}
|
||||
g.indices[index] = struct{}{}
|
||||
|
||||
// The gamepad is not registered yet, register this.
|
||||
gamepad := g.gamepads.findImpl(func(gamepad *Gamepad) bool {
|
||||
return index == gamepad.index
|
||||
})
|
||||
if gamepad == nil {
|
||||
name := gp.Get("id").String()
|
||||
|
||||
// This emulates the implementation of EMSCRIPTEN_JoystickGetDeviceGUID.
|
||||
// https://github.com/libsdl-org/SDL/blob/0e9560aea22818884921e5e5064953257bfe7fa7/src/joystick/emscripten/SDL_sysjoystick.c#L385
|
||||
var sdlID [16]byte
|
||||
copy(sdlID[:], []byte(name))
|
||||
|
||||
gamepad = g.gamepads.addImpl(name, hex.EncodeToString(sdlID[:]))
|
||||
gamepad.index = index
|
||||
gamepad.mapping = gp.Get("mapping").String()
|
||||
}
|
||||
gamepad.value = gp
|
||||
}
|
||||
|
||||
// Remove an unused gamepads.
|
||||
g.gamepads.removeImpl(func(gamepad *Gamepad) bool {
|
||||
_, ok := g.indices[gamepad.index]
|
||||
return !ok
|
||||
})
|
||||
}
|
||||
|
||||
type nativeGamepad struct {
|
||||
value js.Value
|
||||
index int
|
||||
mapping string
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) present() bool {
|
||||
return g.value.Truthy()
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) hasOwnStandardLayoutMapping() bool {
|
||||
// With go2cpp, the controller must have the standard
|
||||
if go2cpp.Truthy() {
|
||||
return true
|
||||
}
|
||||
return g.mapping == "standard"
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) update() {
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) axisNum() int {
|
||||
return g.value.Get("axes").Length()
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) buttonNum() int {
|
||||
return g.value.Get("buttons").Length()
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) hatNum() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) axisValue(axis int) float64 {
|
||||
axes := g.value.Get("axes")
|
||||
if axis < 0 || axis >= axes.Length() {
|
||||
return 0
|
||||
}
|
||||
return axes.Index(axis).Float()
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) buttonValue(button int) float64 {
|
||||
buttons := g.value.Get("buttons")
|
||||
if button < 0 || button >= buttons.Length() {
|
||||
return 0
|
||||
}
|
||||
return buttons.Index(button).Get("value").Float()
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) isButtonPressed(button int) bool {
|
||||
buttons := g.value.Get("buttons")
|
||||
if button < 0 || button >= buttons.Length() {
|
||||
return false
|
||||
}
|
||||
return buttons.Index(button).Get("pressed").Bool()
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) hatState(hat int) int {
|
||||
return hatCentered
|
||||
}
|
||||
|
||||
func (g *nativeGamepad) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||
// vibrationActuator is avaialble on Chrome.
|
||||
if va := g.value.Get("vibrationActuator"); va.Truthy() {
|
||||
if !va.Get("playEffect").Truthy() {
|
||||
return
|
||||
}
|
||||
|
||||
prop := object.New()
|
||||
prop.Set("startDelay", 0)
|
||||
prop.Set("duration", float64(duration/time.Millisecond))
|
||||
prop.Set("strongMagnitude", strongMagnitude)
|
||||
prop.Set("weakMagnitude", weakMagnitude)
|
||||
va.Call("playEffect", "dual-rumble", prop)
|
||||
return
|
||||
}
|
||||
|
||||
// hapticActuators is available on Firefox.
|
||||
if ha := g.value.Get("hapticActuators"); ha.Truthy() {
|
||||
// TODO: Is this order correct?
|
||||
if ha.Length() > 0 {
|
||||
ha.Index(0).Call("pulse", strongMagnitude, float64(duration/time.Millisecond))
|
||||
}
|
||||
if ha.Length() > 1 {
|
||||
ha.Index(1).Call("pulse", weakMagnitude, float64(duration/time.Millisecond))
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
@ -129,5 +129,9 @@ func (i *Input) IsStandardGamepadButtonPressed(id driver.GamepadID, button drive
|
||||
}
|
||||
|
||||
func (i *Input) VibrateGamepad(id driver.GamepadID, duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||
// TODO: Implement this (#1452)
|
||||
g := gamepadpkg.Get(id)
|
||||
if g == nil {
|
||||
return
|
||||
}
|
||||
g.Vibrate(duration, strongMagnitude, weakMagnitude)
|
||||
}
|
||||
|
@ -15,16 +15,14 @@
|
||||
package js
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"syscall/js"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/driver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/gamepad"
|
||||
)
|
||||
|
||||
var object = js.Global().Get("Object")
|
||||
|
||||
var (
|
||||
stringKeydown = js.ValueOf("keydown")
|
||||
stringKeypress = js.ValueOf("keypress")
|
||||
@ -62,30 +60,6 @@ type pos struct {
|
||||
Y int
|
||||
}
|
||||
|
||||
type gamepad struct {
|
||||
value js.Value
|
||||
|
||||
name string
|
||||
mapping string
|
||||
axisNum int
|
||||
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
|
||||
}
|
||||
|
||||
func (g *gamepad) hasStandardLayoutMapping() bool {
|
||||
// With go2cpp, the controller must have the standard
|
||||
if go2cpp.Truthy() {
|
||||
return true
|
||||
}
|
||||
return g.mapping == "standard"
|
||||
}
|
||||
|
||||
type Input struct {
|
||||
keyPressed map[int]bool
|
||||
keyPressedEdge map[int]bool
|
||||
@ -96,7 +70,6 @@ type Input struct {
|
||||
origCursorY int
|
||||
wheelX float64
|
||||
wheelY float64
|
||||
gamepads map[driver.GamepadID]gamepad
|
||||
touches map[driver.TouchID]pos
|
||||
runeBuffer []rune
|
||||
ui *UserInterface
|
||||
@ -111,71 +84,58 @@ func (i *Input) CursorPosition() (x, y int) {
|
||||
}
|
||||
|
||||
func (i *Input) GamepadSDLID(id driver.GamepadID) string {
|
||||
// This emulates the implementation of EMSCRIPTEN_JoystickGetDeviceGUID.
|
||||
// https://github.com/libsdl-org/SDL/blob/0e9560aea22818884921e5e5064953257bfe7fa7/src/joystick/emscripten/SDL_sysjoystick.c#L385
|
||||
g, ok := i.gamepads[id]
|
||||
if !ok {
|
||||
g := gamepad.Get(id)
|
||||
if g == nil {
|
||||
return ""
|
||||
}
|
||||
var sdlid [16]byte
|
||||
copy(sdlid[:], []byte(g.name))
|
||||
return hex.EncodeToString(sdlid[:])
|
||||
return g.SDLID()
|
||||
}
|
||||
|
||||
// GamepadName returns a string containing some information about the controller.
|
||||
// A PS2 controller returned "810-3-USB Gamepad" on Firefox
|
||||
// A Xbox 360 controller returned "xinput" on Firefox and "Xbox 360 Controller (XInput STANDARD GAMEPAD)" on Chrome
|
||||
func (i *Input) GamepadName(id driver.GamepadID) string {
|
||||
g, ok := i.gamepads[id]
|
||||
if !ok {
|
||||
g := gamepad.Get(id)
|
||||
if g == nil {
|
||||
return ""
|
||||
}
|
||||
return g.name
|
||||
return g.Name()
|
||||
}
|
||||
|
||||
func (i *Input) AppendGamepadIDs(gamepadIDs []driver.GamepadID) []driver.GamepadID {
|
||||
for id := range i.gamepads {
|
||||
gamepadIDs = append(gamepadIDs, id)
|
||||
}
|
||||
return gamepadIDs
|
||||
return gamepad.AppendGamepadIDs(gamepadIDs)
|
||||
}
|
||||
|
||||
func (i *Input) GamepadAxisNum(id driver.GamepadID) int {
|
||||
g, ok := i.gamepads[id]
|
||||
if !ok {
|
||||
g := gamepad.Get(id)
|
||||
if g == nil {
|
||||
return 0
|
||||
}
|
||||
return g.axisNum
|
||||
return g.AxisNum()
|
||||
}
|
||||
|
||||
func (i *Input) GamepadAxisValue(id driver.GamepadID, axis int) float64 {
|
||||
g, ok := i.gamepads[id]
|
||||
if !ok {
|
||||
g := gamepad.Get(id)
|
||||
if g == nil {
|
||||
return 0
|
||||
}
|
||||
if g.axisNum <= axis {
|
||||
return 0
|
||||
}
|
||||
return g.axes[axis]
|
||||
return g.Axis(axis)
|
||||
}
|
||||
|
||||
func (i *Input) GamepadButtonNum(id driver.GamepadID) int {
|
||||
g, ok := i.gamepads[id]
|
||||
if !ok {
|
||||
g := gamepad.Get(id)
|
||||
if g == nil {
|
||||
return 0
|
||||
}
|
||||
return g.buttonNum
|
||||
return g.ButtonNum()
|
||||
}
|
||||
|
||||
func (i *Input) IsGamepadButtonPressed(id driver.GamepadID, button driver.GamepadButton) bool {
|
||||
g, ok := i.gamepads[id]
|
||||
if !ok {
|
||||
g := gamepad.Get(id)
|
||||
if g == nil {
|
||||
return false
|
||||
}
|
||||
if g.buttonNum <= int(button) {
|
||||
return false
|
||||
}
|
||||
return g.buttonPressed[button]
|
||||
return g.Button(int(button))
|
||||
}
|
||||
|
||||
func (i *Input) AppendTouchIDs(touchIDs []driver.TouchID) []driver.TouchID {
|
||||
@ -293,63 +253,7 @@ func (i *Input) mouseUp(code int) {
|
||||
}
|
||||
|
||||
func (i *Input) updateGamepads() {
|
||||
nav := js.Global().Get("navigator")
|
||||
if !nav.Truthy() {
|
||||
return
|
||||
}
|
||||
|
||||
gamepads := nav.Call("getGamepads")
|
||||
if !gamepads.Truthy() {
|
||||
return
|
||||
}
|
||||
|
||||
for k := range i.gamepads {
|
||||
delete(i.gamepads, k)
|
||||
}
|
||||
|
||||
l := gamepads.Length()
|
||||
for idx := 0; idx < l; idx++ {
|
||||
gp := gamepads.Index(idx)
|
||||
if !gp.Truthy() {
|
||||
continue
|
||||
}
|
||||
|
||||
id := driver.GamepadID(gp.Get("index").Int())
|
||||
g := gamepad{
|
||||
value: gp,
|
||||
}
|
||||
g.name = gp.Get("id").String()
|
||||
g.mapping = gp.Get("mapping").String()
|
||||
|
||||
axes := gp.Get("axes")
|
||||
axesNum := axes.Length()
|
||||
g.axisNum = axesNum
|
||||
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 < 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[:])
|
||||
}
|
||||
|
||||
if i.gamepads == nil {
|
||||
i.gamepads = map[driver.GamepadID]gamepad{}
|
||||
}
|
||||
i.gamepads[id] = g
|
||||
}
|
||||
gamepad.Update()
|
||||
}
|
||||
|
||||
func (i *Input) updateFromEvent(e js.Value) {
|
||||
@ -474,76 +378,41 @@ func (i *Input) updateForGo2Cpp() {
|
||||
}
|
||||
|
||||
func (i *Input) IsStandardGamepadLayoutAvailable(id driver.GamepadID) bool {
|
||||
g, ok := i.gamepads[id]
|
||||
if !ok {
|
||||
g := gamepad.Get(id)
|
||||
if g == nil {
|
||||
return false
|
||||
}
|
||||
return g.hasStandardLayoutMapping()
|
||||
return g.IsStandardLayoutAvailable()
|
||||
}
|
||||
|
||||
func (i *Input) StandardGamepadAxisValue(id driver.GamepadID, axis driver.StandardGamepadAxis) float64 {
|
||||
g, ok := i.gamepads[id]
|
||||
if !ok {
|
||||
g := gamepad.Get(id)
|
||||
if g == nil {
|
||||
return 0
|
||||
}
|
||||
if !g.hasStandardLayoutMapping() {
|
||||
return 0
|
||||
}
|
||||
return g.standardAxisValues[axis]
|
||||
return g.StandardAxisValue(axis)
|
||||
}
|
||||
|
||||
func (i *Input) StandardGamepadButtonValue(id driver.GamepadID, button driver.StandardGamepadButton) float64 {
|
||||
g, ok := i.gamepads[id]
|
||||
if !ok {
|
||||
g := gamepad.Get(id)
|
||||
if g == nil {
|
||||
return 0
|
||||
}
|
||||
if !g.hasStandardLayoutMapping() {
|
||||
return 0
|
||||
}
|
||||
return g.standardButtonValues[button]
|
||||
return g.StandardButtonValue(button)
|
||||
}
|
||||
|
||||
func (i *Input) IsStandardGamepadButtonPressed(id driver.GamepadID, button driver.StandardGamepadButton) bool {
|
||||
g, ok := i.gamepads[id]
|
||||
if !ok {
|
||||
g := gamepad.Get(id)
|
||||
if g == nil {
|
||||
return false
|
||||
}
|
||||
if !g.hasStandardLayoutMapping() {
|
||||
return false
|
||||
}
|
||||
return g.standardButtonPressed[button]
|
||||
return g.IsStandardButtonPressed(button)
|
||||
}
|
||||
|
||||
func (i *Input) VibrateGamepad(id driver.GamepadID, duration time.Duration, strongMagnitude float64, weakMagnitude float64) {
|
||||
g, ok := i.gamepads[id]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// vibrationActuator is avaialble on Chrome.
|
||||
if va := g.value.Get("vibrationActuator"); va.Truthy() {
|
||||
if !va.Get("playEffect").Truthy() {
|
||||
return
|
||||
}
|
||||
|
||||
prop := object.New()
|
||||
prop.Set("startDelay", 0)
|
||||
prop.Set("duration", float64(duration/time.Millisecond))
|
||||
prop.Set("strongMagnitude", strongMagnitude)
|
||||
prop.Set("weakMagnitude", weakMagnitude)
|
||||
va.Call("playEffect", "dual-rumble", prop)
|
||||
return
|
||||
}
|
||||
|
||||
// hapticActuators is available on Firefox.
|
||||
if ha := g.value.Get("hapticActuators"); ha.Truthy() {
|
||||
// TODO: Is this order correct?
|
||||
if ha.Length() > 0 {
|
||||
ha.Index(0).Call("pulse", strongMagnitude, float64(duration/time.Millisecond))
|
||||
}
|
||||
if ha.Length() > 1 {
|
||||
ha.Index(1).Call("pulse", weakMagnitude, float64(duration/time.Millisecond))
|
||||
}
|
||||
g := gamepad.Get(id)
|
||||
if g == nil {
|
||||
return
|
||||
}
|
||||
g.Vibrate(duration, strongMagnitude, weakMagnitude)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user