aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristine Dodrill <me@christine.website>2017-10-13 01:23:39 -0700
committerChristine Dodrill <me@christine.website>2017-10-13 01:23:39 -0700
commitd4d25a0ba245bab9f54e929c4a56e03e28ac9cb7 (patch)
tree90425df1e360c80ac0ca9faafb9ba5d58e59c420
parenta1c962faa304eee9d6fc30c8c4a4382fbdabcc05 (diff)
downloadx-d4d25a0ba245bab9f54e929c4a56e03e28ac9cb7.tar.xz
x-d4d25a0ba245bab9f54e929c4a56e03e28ac9cb7.zip
sdl: add start of zerohackr
-rw-r--r--sdl/joypad/8bitdo_zero.go116
-rw-r--r--sdl/joypad/direction_string.go16
-rw-r--r--sdl/joypad/interface.go62
-rw-r--r--sdl/zerohackr/main.go71
4 files changed, 265 insertions, 0 deletions
diff --git a/sdl/joypad/8bitdo_zero.go b/sdl/joypad/8bitdo_zero.go
new file mode 100644
index 0000000..5792717
--- /dev/null
+++ b/sdl/joypad/8bitdo_zero.go
@@ -0,0 +1,116 @@
+package joypad
+
+import (
+ "log"
+
+ "github.com/veandco/go-sdl2/sdl"
+)
+
+// from manual testing, set as constants to ease readability.
+const (
+ eightBitdoZeroA = 0
+ eightBitdoZeroB = 1
+ eightBitdoZeroX = 3
+ eightBitdoZeroY = 4
+ eightBitdoZeroL = 6
+ eightBitdoZeroR = 7
+ eightBitdoZeroStart = 11
+ eightBitdoZeroSelect = 10
+
+ eightBitdoZeroDpadYAxis = 1
+ eightBitdoZeroDpadXAxis = 0
+
+ eightBitdoZeroName = "8Bitdo Zero GamePad"
+)
+
+// EightBitdoZero adapts an 8bitdo zero controller into the Gamepad type.
+type EightBitdoZero struct {
+ j *sdl.Joystick
+}
+
+func NewEightBitdoZero(j *sdl.Joystick) Gamepad {
+ if j.Name() != eightBitdoZeroName {
+ return nil
+ }
+
+ return &EightBitdoZero{j: j}
+}
+
+// NumFaceButtons refers to the number of buttons on the "face" of the controller.
+// These buttons are normally used by the right thumb.
+func (e *EightBitdoZero) NumFaceButtons() int {
+ return 4
+}
+
+// NumShoulderButtons refers to the number of buttons on the "shoulder" of the controller.
+// These buttons are normally used by either pointer finger.
+func (e *EightBitdoZero) NumShoulderButtons() int {
+ return 2
+}
+
+// FaceButtons returns the values of every face button in the order
+// A, B, X, Y.
+func (e *EightBitdoZero) FaceButtons() (bool, bool, bool, bool) {
+ a := e.j.GetButton(eightBitdoZeroA) == 1
+ b := e.j.GetButton(eightBitdoZeroB) == 1
+ x := e.j.GetButton(eightBitdoZeroX) == 1
+ y := e.j.GetButton(eightBitdoZeroY) == 1
+
+ return a, b, x, y
+}
+
+// ShoulderButtons returns the values of the shoulder buttons in the order
+// L, R.
+func (e *EightBitdoZero) ShoulderButtons() (bool, bool) {
+ l := e.j.GetButton(eightBitdoZeroL)
+ r := e.j.GetButton(eightBitdoZeroR)
+
+ log.Printf("l: %v, r: %v", l, r)
+
+ return l == 1, r == 1
+}
+
+func (e *EightBitdoZero) PauseButtons() (bool, bool) {
+ start := e.j.GetButton(eightBitdoZeroStart) == 1
+ selectB := e.j.GetButton(eightBitdoZeroSelect) == 1
+
+ return start, selectB
+}
+
+func (e *EightBitdoZero) Dpad() Direction {
+ x := e.j.GetAxis(eightBitdoZeroDpadXAxis)
+ y := e.j.GetAxis(eightBitdoZeroDpadYAxis)
+
+ // Dpad up: negative axis 1
+ // Dpad down: positive axis 1
+ // Dpad left: negative axis 0
+ // Dpad right: positive axis 0
+
+ noUp := x == 0
+ noLeft := y == 0
+ up := x < 0
+ left := y < 0
+
+ switch {
+ // simple
+ case up && noLeft:
+ return Up
+ case !up && noLeft:
+ return Down
+ case left && noUp:
+ return Left
+ case !left && noUp:
+ return Right
+
+ case up && left:
+ return UpLeft
+ case up && !left:
+ return UpRight
+ case !up && left:
+ return DownLeft
+ case !up && !left:
+ return DownRight
+ }
+
+ return None
+}
diff --git a/sdl/joypad/direction_string.go b/sdl/joypad/direction_string.go
new file mode 100644
index 0000000..9c11a89
--- /dev/null
+++ b/sdl/joypad/direction_string.go
@@ -0,0 +1,16 @@
+// Code generated by "stringer -type=Direction"; DO NOT EDIT.
+
+package joypad
+
+import "fmt"
+
+const _Direction_name = "NoneUpUpRightRightDownRightDownDownLeftLeftUpLeft"
+
+var _Direction_index = [...]uint8{0, 4, 6, 13, 18, 27, 31, 39, 43, 49}
+
+func (i Direction) String() string {
+ if i < 0 || i >= Direction(len(_Direction_index)-1) {
+ return fmt.Sprintf("Direction(%d)", i)
+ }
+ return _Direction_name[_Direction_index[i]:_Direction_index[i+1]]
+}
diff --git a/sdl/joypad/interface.go b/sdl/joypad/interface.go
new file mode 100644
index 0000000..ef13da0
--- /dev/null
+++ b/sdl/joypad/interface.go
@@ -0,0 +1,62 @@
+// Package joypad offers a simpler interface to joystick/gamepad data.
+package joypad
+
+// Button constants
+const (
+ // "face" buttons
+ A = iota // A is the primary action button. This should be "okay" in menus.
+ B // B is the secondary action button. This should be "cancel" in menus.
+ X
+ Y
+
+ // "shoulder" buttons
+ L // L is present on the left shoulder of the controller
+ R // R is present on the right shoulder of the controller
+ L2 // L2 is the second left shoulder button
+ R2 // R2 is the second right shoulder button
+
+ Start // Start typically pauses or resumes the game. This should be "okay" in menus.
+ Select // Select typically manipulates options.
+
+ L3 // L3 is the left stick click button
+ R3 // R3 is the right stick click button
+
+ Capture // Capture takes a screenshot.
+ Home // Home returns the game to the system menu.
+)
+
+//go:generate stringer -type=Direction
+
+// Direction is a cardinal direction derived from a dpad position
+type Direction int
+
+// Direction constants
+const (
+ None Direction = iota
+ Up
+ UpRight
+ Right
+ DownRight
+ Down
+ DownLeft
+ Left
+ UpLeft
+)
+
+// Gamepad refers to any device that only has a directional pad and a small set of buttons.
+// Gamepad is the base interface.
+type Gamepad interface {
+ // NumFaceButtons refers to the number of buttons on the "face" of the controller.
+ // These buttons are normally used by the right thumb.
+ NumFaceButtons() int
+
+ // NumShoulderButtons refers to the number of buttons on the "shoulder" of the controller.
+ // These buttons are normally used by either pointer finger.
+ NumShoulderButtons() int
+
+ FaceButtons() (a, b, x, y bool)
+ ShoulderButtons() (l, r bool)
+ PauseButtons() (start, selectB bool)
+
+ Dpad() Direction
+}
diff --git a/sdl/zerohackr/main.go b/sdl/zerohackr/main.go
new file mode 100644
index 0000000..9f31002
--- /dev/null
+++ b/sdl/zerohackr/main.go
@@ -0,0 +1,71 @@
+package main
+
+import (
+ "context"
+ "log"
+ "time"
+
+ "github.com/Xe/x/sdl/joypad"
+ "github.com/veandco/go-sdl2/sdl"
+)
+
+func main() {
+ if err := sdl.Init(sdl.INIT_EVERYTHING); err != nil {
+ panic(err)
+ }
+ defer sdl.Quit()
+
+ // XXX: ASSUMPTION: only the 8bitdo zero controller is connected and it is id 0
+ if sdl.NumJoysticks() != 1 {
+ log.Fatal("please make sure the 8bitdo zero is the only controller connected.")
+ }
+
+ window, err := sdl.CreateWindow("test", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
+ 800, 600, sdl.WINDOW_SHOWN)
+ if err != nil {
+ panic(err)
+ }
+ defer window.Destroy()
+
+ surface, err := window.GetSurface()
+ if err != nil {
+ panic(err)
+ }
+
+ rect := sdl.Rect{0, 0, 800, 600}
+ surface.FillRect(&rect, 0xffff0000)
+ window.UpdateSurface()
+
+ j := sdl.JoystickOpen(sdl.JoystickID(0))
+ defer j.Close()
+ ez := joypad.NewEightBitdoZero(j)
+
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+
+ loopInputs(ctx, ez)
+}
+
+func loopInputs(ctx context.Context, gp joypad.Gamepad) {
+ t := time.NewTicker(time.Second / 60)
+ defer t.Stop()
+
+ for {
+ select {
+ case <-ctx.Done():
+ return
+ case <-t.C:
+ l, r := gp.ShoulderButtons()
+
+ if l {
+ log.Println("switch to virtual desktop to the left")
+ continue
+ }
+
+ if r {
+ log.Println("switch to virtual desktop to the right")
+ continue
+ }
+ }
+ }
+}