mirror of
https://github.com/ivanizag/izapple2.git
synced 2025-01-02 20:29:44 +00:00
Joystick support in Fyne with glfw
This commit is contained in:
parent
17f1121980
commit
9395c2ffb3
1
go.mod
1
go.mod
@ -4,6 +4,7 @@ go 1.12
|
||||
|
||||
require (
|
||||
fyne.io/fyne v1.3.3
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200625191551-73d3c3675aa3
|
||||
github.com/pkg/profile v1.4.0
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
|
||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
|
||||
|
109
izapple2fyne/fyneJoysticks.go
Normal file
109
izapple2fyne/fyneJoysticks.go
Normal file
@ -0,0 +1,109 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"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 {
|
||||
info [2]*joystickInfo
|
||||
}
|
||||
|
||||
const unplugged = uint8(255) // Max resistance when unplugged
|
||||
|
||||
func newJoysticks() *joysticks {
|
||||
var j joysticks
|
||||
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)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
fmt.Printf("%v, %v, %v\n", i, j.info[0], value)
|
||||
return value, value != unplugged
|
||||
}
|
@ -19,7 +19,9 @@ import (
|
||||
)
|
||||
|
||||
type state struct {
|
||||
a *izapple2.Apple2
|
||||
a *izapple2.Apple2
|
||||
app fyne.App
|
||||
win fyne.Window
|
||||
|
||||
showPages bool
|
||||
}
|
||||
@ -39,9 +41,9 @@ func main() {
|
||||
}
|
||||
|
||||
func fyneRun(s *state) {
|
||||
app := app.New()
|
||||
s.app = app.New()
|
||||
// app.SetIcon(xxx)
|
||||
window := app.NewWindow("iz-" + s.a.Name)
|
||||
s.win = s.app.NewWindow("iz-" + s.a.Name)
|
||||
// window.SetIcon(xxx)
|
||||
|
||||
bottom := widget.NewToolbar(
|
||||
@ -66,23 +68,25 @@ func fyneRun(s *state) {
|
||||
theme.NewThemedResource(resourceLayersTripleSvg, nil), func() {
|
||||
s.showPages = !s.showPages
|
||||
if !s.showPages {
|
||||
window.SetTitle("iz-" + s.a.Name)
|
||||
s.win.SetTitle("iz-" + s.a.Name)
|
||||
}
|
||||
}),
|
||||
widget.NewToolbarAction(
|
||||
theme.NewThemedResource(resourceCameraSvg, nil), func() {
|
||||
err := izapple2.SaveSnapshot(s.a, "snapshot.png")
|
||||
if err != nil {
|
||||
app.SendNotification(fyne.NewNotification(window.Title(),
|
||||
s.app.SendNotification(fyne.NewNotification(
|
||||
s.win.Title(),
|
||||
fmt.Sprintf("Error saving snapshoot: %v.\n.", err)))
|
||||
} else {
|
||||
app.SendNotification(fyne.NewNotification(window.Title(),
|
||||
s.app.SendNotification(fyne.NewNotification(
|
||||
s.win.Title(),
|
||||
"Saving snapshot on 'snapshot.png'"))
|
||||
}
|
||||
}),
|
||||
widget.NewToolbarSpacer(),
|
||||
widget.NewToolbarAction(theme.ViewFullScreenIcon(), func() {
|
||||
window.SetFullScreen(!window.FullScreen())
|
||||
s.win.SetFullScreen(!s.win.FullScreen())
|
||||
}),
|
||||
)
|
||||
|
||||
@ -92,10 +96,13 @@ func fyneRun(s *state) {
|
||||
layout.NewBorderLayout(nil, bottom, nil, nil),
|
||||
screen, bottom,
|
||||
)
|
||||
window.SetContent(container)
|
||||
window.SetPadded(false)
|
||||
s.win.SetContent(container)
|
||||
s.win.SetPadded(false)
|
||||
|
||||
registerKeyboardEvents(s, window.Canvas())
|
||||
registerKeyboardEvents(s)
|
||||
j := newJoysticks()
|
||||
j.start()
|
||||
s.a.SetJoysticksProvider(j)
|
||||
|
||||
go s.a.Run()
|
||||
|
||||
@ -111,7 +118,7 @@ func fyneRun(s *state) {
|
||||
var img *image.RGBA
|
||||
if s.showPages {
|
||||
img = s.a.SnapshotParts()
|
||||
window.SetTitle(fmt.Sprintf("%v %v %vx%v", s.a.Name, s.a.VideoModeName(), img.Rect.Dx()/2, img.Rect.Dy()/2))
|
||||
s.win.SetTitle(fmt.Sprintf("%v %v %vx%v", s.a.Name, s.a.VideoModeName(), img.Rect.Dx()/2, img.Rect.Dy()/2))
|
||||
} else {
|
||||
img = s.a.Snapshot()
|
||||
}
|
||||
@ -122,19 +129,20 @@ func fyneRun(s *state) {
|
||||
}
|
||||
}()
|
||||
|
||||
window.SetOnClosed(func() {
|
||||
s.win.SetOnClosed(func() {
|
||||
done <- true
|
||||
})
|
||||
|
||||
window.Show()
|
||||
app.Run()
|
||||
s.win.Show()
|
||||
s.app.Run()
|
||||
|
||||
}
|
||||
|
||||
func registerKeyboardEvents(s *state, canvas fyne.Canvas) {
|
||||
func registerKeyboardEvents(s *state) {
|
||||
kp := newKeyboard(s)
|
||||
canvas := s.win.Canvas()
|
||||
|
||||
// Koyboard events
|
||||
// Events
|
||||
canvas.SetOnTypedKey(func(ke *fyne.KeyEvent) {
|
||||
//fmt.Printf("Event: %v\n", ke.Name)
|
||||
kp.putKey(ke)
|
||||
|
Loading…
Reference in New Issue
Block a user