izapple2/frontend/a2fyne/fyneJoysticks.go

113 lines
2.2 KiB
Go

package main
import (
"runtime"
"time"
"github.com/go-gl/glfw/v3.3/glfw"
)
/*
Apple 2 supports four paddles and 3 pushbuttons. The first two paddles are
the X, Y axis of the first joystick. The second two correspond the the second
joystick.
Button 0 is the primary button of joystick 0.
Button 1 is the secondary button of joystick 0 but also the primary button of
joystick 1.
Button 2 is the secondary button of Joystick 1.
*/
// TODO: key as buttons as on the IIe and mouse as joystick
type joystickInfo struct {
present bool
name string
paddles [2]uint8
buttons [2]bool
}
type joysticks struct {
s *state
info [2]*joystickInfo
}
const unplugged = uint8(255) // Max resistance when unplugged
func newJoysticks(s *state) *joysticks {
var j joysticks
j.s = s
return &j
}
func (j *joysticks) start() {
pool := time.NewTicker(time.Second / 50)
go func() {
runtime.LockOSThread()
for {
select {
case <-pool.C:
j.info[0] = j.queryJoystick(glfw.Joystick1)
j.info[1] = j.queryJoystick(glfw.Joystick2)
j.s.devices.joystick.updateJoy1(j.info[0])
j.s.devices.joystick.updateJoy2(j.info[1])
}
}
}()
}
func (j *joysticks) queryJoystick(joy glfw.Joystick) *joystickInfo {
if !joy.Present() {
return nil
}
var info joystickInfo
info.name = joy.GetName()
buttons := joy.GetButtons()
for i, b := range buttons {
if b == glfw.Press {
info.buttons[i%2] = true
}
}
axes := joy.GetAxes()
for i := 0; i < len(info.paddles); i++ {
info.paddles[i] = unplugged
if i < len(axes) {
v := uint16((axes[i] + 1.0) / 2.0 * 256.0)
if v > 255 {
v = 255
}
info.paddles[i] = uint8(v)
}
}
return &info
}
func (j *joysticks) ReadButton(i int) bool {
var value bool
i0 := j.info[0]
i1 := j.info[1]
switch i {
case 0:
value = (i0 != nil) && i0.buttons[0]
case 1:
// It can be secondary of first or primary of second
value = ((i0 != nil) && i0.buttons[1]) ||
(i1 != nil) && i1.buttons[0]
case 2:
value = (i1 != nil) && i1.buttons[0]
}
return value
}
func (j *joysticks) ReadPaddle(i int) (uint8, bool) {
var value = unplugged
info := j.info[i/2]
if info != nil {
value = info.paddles[i%2]
}
return value, value != unplugged
}