From c17946bb822c850792b9e6dc23ca46aff3468254 Mon Sep 17 00:00:00 2001 From: Jake Bentvelzen Date: Fri, 10 Jan 2020 00:11:32 +1100 Subject: [PATCH] ui: Add GamepadGUID and GamepadName functions (#1035) Fixes #1034 --- input.go | 23 +++++++++++++++++++++ internal/driver/input.go | 2 ++ internal/glfw/glfw_notwindows.go | 8 ++++++++ internal/glfw/glfw_windows.go | 34 +++++++++++++++++++++++++++++++ internal/uidriver/glfw/input.go | 34 +++++++++++++++++++++++++++++++ internal/uidriver/js/input.go | 16 +++++++++++++++ internal/uidriver/mobile/input.go | 8 ++++++++ 7 files changed, 125 insertions(+) diff --git a/input.go b/input.go index 3baa3991f..ef371dfb9 100644 --- a/input.go +++ b/input.go @@ -92,6 +92,29 @@ func IsMouseButtonPressed(mouseButton MouseButton) bool { return uiDriver().Input().IsMouseButtonPressed(driver.MouseButton(mouseButton)) } +// GamepadGUID returns a string with the uuid. +// +// GamepadGUID is concurrent-safe. +// +// GamepadGUID always returns an empty string on browsers and mobiles. +func GamepadGUID(id int) string { + return uiDriver().Input().GamepadGUID(id) +} + +// GamepadName returns a string with the name. +// This function may vary in how it returns descriptions for the same device across platforms +// for example the following drivers/platforms see a Xbox One controller as the following: +// - Windows: "Xbox Controller" +// - Chrome: "Xbox 360 Controller (XInput STANDARD GAMEPAD)" +// - Firefox: "xinput" +// +// GamepadName is concurrent-safe. +// +// GamepadName always returns an empty string on mobiles. +func GamepadName(id int) string { + return uiDriver().Input().GamepadName(id) +} + // GamepadIDs returns a slice indicating available gamepad IDs. // // GamepadIDs is concurrent-safe. diff --git a/internal/driver/input.go b/internal/driver/input.go index ddbe0deb6..7567ba7a9 100644 --- a/internal/driver/input.go +++ b/internal/driver/input.go @@ -16,6 +16,8 @@ package driver type Input interface { CursorPosition() (x, y int) + GamepadGUID(id int) string + GamepadName(id int) string GamepadAxis(id int, axis int) float64 GamepadAxisNum(id int) int GamepadButtonNum(id int) int diff --git a/internal/glfw/glfw_notwindows.go b/internal/glfw/glfw_notwindows.go index 30080ced7..c643d04d7 100644 --- a/internal/glfw/glfw_notwindows.go +++ b/internal/glfw/glfw_notwindows.go @@ -235,6 +235,14 @@ func CreateWindow(width, height int, title string, monitor *Monitor, share *Wind return theWindows.add(w), nil } +func (j Joystick) GetGUID() string { + return glfw.Joystick(j).GetGUID() +} + +func (j Joystick) GetName() string { + return glfw.Joystick(j).GetName() +} + func (j Joystick) GetAxes() []float32 { return glfw.Joystick(j).GetAxes() } diff --git a/internal/glfw/glfw_windows.go b/internal/glfw/glfw_windows.go index 181a5bbda..182587129 100644 --- a/internal/glfw/glfw_windows.go +++ b/internal/glfw/glfw_windows.go @@ -311,6 +311,40 @@ func CreateWindow(width, height int, title string, monitor *Monitor, share *Wind return theGLFWWindows.add(w), nil } +func (j Joystick) GetGUID() string { + ptr := glfwDLL.call("glfwGetJoystickGUID", uintptr(j)) + panicError() + var backed [256]byte + as := backed[:0] + for i := int32(0); ; i++ { + b := *(*byte)(unsafe.Pointer(ptr)) + ptr += unsafe.Sizeof(byte(0)) + if b == 0 { + break + } + as = append(as, b) + } + r := string(as) + return r +} + +func (j Joystick) GetName() string { + ptr := glfwDLL.call("glfwGetJoystickName", uintptr(j)) + panicError() + var backed [256]byte + as := backed[:0] + for i := int32(0); ; i++ { + b := *(*byte)(unsafe.Pointer(ptr)) + ptr += unsafe.Sizeof(byte(0)) + if b == 0 { + break + } + as = append(as, b) + } + r := string(as) + return r +} + func (j Joystick) GetAxes() []float32 { var l int32 ptr := glfwDLL.call("glfwGetJoystickAxes", uintptr(j), uintptr(unsafe.Pointer(&l))) diff --git a/internal/uidriver/glfw/input.go b/internal/uidriver/glfw/input.go index 20b2bd634..9ed72c730 100644 --- a/internal/uidriver/glfw/input.go +++ b/internal/uidriver/glfw/input.go @@ -29,6 +29,8 @@ import ( type gamePad struct { valid bool + guid string + name string axisNum int axes [16]float64 buttonNum int @@ -85,6 +87,36 @@ func (i *Input) GamepadIDs() []int { return r } +func (i *Input) GamepadGUID(id int) string { + if !i.ui.isRunning() { + return "" + } + var r string + _ = i.ui.t.Call(func() error { + if len(i.gamepads) <= id { + return nil + } + r = i.gamepads[id].guid + return nil + }) + return r +} + +func (i *Input) GamepadName(id int) string { + if !i.ui.isRunning() { + return "" + } + var r string + _ = i.ui.t.Call(func() error { + if len(i.gamepads) <= id { + return nil + } + r = i.gamepads[id].name + return nil + }) + return r +} + func (i *Input) GamepadAxisNum(id int) int { if !i.ui.isRunning() { return 0 @@ -324,6 +356,8 @@ func (i *Input) update(window *glfw.Window, context driver.UIContext) { continue } i.gamepads[id].valid = true + i.gamepads[id].guid = id.GetGUID() + i.gamepads[id].name = id.GetName() axes32 := id.GetAxes() i.gamepads[id].axisNum = len(axes32) diff --git a/internal/uidriver/js/input.go b/internal/uidriver/js/input.go index 2976f4f8e..6d1dc4bc0 100644 --- a/internal/uidriver/js/input.go +++ b/internal/uidriver/js/input.go @@ -31,6 +31,7 @@ type pos struct { type gamePad struct { valid bool + name string axisNum int axes [16]float64 buttonNum int @@ -56,6 +57,20 @@ func (i *Input) CursorPosition() (x, y int) { return int(xf), int(yf) } +func (i *Input) GamepadGUID(id int) string { + return "" +} + +// 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 int) string { + if len(i.gamepads) <= id { + return "" + } + return i.gamepads[id].name +} + func (i *Input) GamepadIDs() []int { if len(i.gamepads) == 0 { return nil @@ -233,6 +248,7 @@ func (i *Input) UpdateGamepads() { continue } i.gamepads[id].valid = true + i.gamepads[id].name = gamepad.Get("id").String() axes := gamepad.Get("axes") axesNum := axes.Get("length").Int() diff --git a/internal/uidriver/mobile/input.go b/internal/uidriver/mobile/input.go index 558531599..13a497a8a 100644 --- a/internal/uidriver/mobile/input.go +++ b/internal/uidriver/mobile/input.go @@ -42,6 +42,14 @@ func (i *Input) GamepadIDs() []int { return nil } +func (i *Input) GamepadGUID(id int) string { + return "" +} + +func (i *Input) GamepadName(id int) string { + return "" +} + func (i *Input) GamepadAxisNum(id int) int { return 0 }