Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
141 lines (123 sloc) 2.57 KB
package joystick
import (
"encoding/binary"
"fmt"
"os"
"time"
)
// Button and pad mappings:
//
// Buttons
//
// Square = 0
// Cross = 1
// Circle = 2
// Triangle = 3
// L1 = 4
// R1 = 5
// L2 = 6 (also an axis)
// R2 = 7 (also an axis)
// Share = 8
// Options = 9
// L stick = 10
// R stick = 11
// PS = 12
// Pad click = 13
//
// Axes
//
// D-pad u/d = 7 (up = -32767; down = +32767)
// l/r = 6 (left = -32767; right = +32767)
// L stick u/d = 1 (up = -32767; down = +32767)
// l/r = 0 (left = -32767; right = +32767)
// R stick u/d = 5 (up = -32767; down = +32767)
// l/r = 2 (left = -32767; right = +32767)
// L2 = 3 (unpressed = -32767; fully-pressed = 32767)
// R2 = 4 (unpressed = -32767; fully-pressed = 32767)
type EventType uint8
const (
EventTypeButton = 1
EventTypeAxis = 2
)
const (
ButtonSquare = 0
ButtonCross = 1
ButtonCircle = 2
ButtonTriangle = 3
ButtonL1 = 4
ButtonR1 = 5
ButtonL2 = 6
ButtonR2 = 7
ButtonShare = 8
ButtonOptions = 9
ButtonLStick = 10
ButtonRStick = 11
ButtonPS = 12
ButtonPadClick = 13
AxisLStickX = 0
AxisLStickY = 1
AxisRStickX = 2
AxisRStickY = 5
AxisDPadX = 6
AxisDPadY = 7
)
func (e EventType) String() string {
switch e {
case EventTypeAxis:
return "axis"
case EventTypeButton:
return "button"
default:
return fmt.Sprintf("unknown(%d)", uint8(e))
}
}
type Joystick struct {
device *os.File
readBuf [8]byte
deviceEpoch uint32
wallclockEpoch time.Time
}
type rawEvent struct {
Time uint32
Value int16
Type uint8
Number uint8
}
type Event struct {
Time time.Time
Value int16
Type EventType
Number uint8
}
func (e *Event) String() string {
return fmt.Sprintf("%v(%v)=%v", e.Type, e.Number, e.Value)
}
func NewJoystick(device string) (*Joystick, error) {
f, err := os.Open(device)
if err != nil {
return nil, err
}
return &Joystick{
device: f,
}, nil
}
func (j *Joystick) ReadEvent() (*Event, error) {
var rawEvent rawEvent
err := binary.Read(j.device, binary.LittleEndian, &rawEvent)
if err != nil {
return nil, err
}
if j.deviceEpoch == 0 {
j.deviceEpoch = rawEvent.Time
j.wallclockEpoch = time.Now()
}
return &Event{
Time: j.wallclockEpoch.Add(time.Duration(rawEvent.Time-j.deviceEpoch) * time.Millisecond),
Value: rawEvent.Value,
Type: EventType(rawEvent.Type & 0x7f),
Number: rawEvent.Number,
}, nil
}
func (j *Joystick) Close() error {
return j.device.Close()
}