joycon

package
v0.0.0-...-23a661a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 23, 2022 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	VENDOR_NINTENDO           uint16 = 0x057e
	JOYCON_PRODUCT_L          uint16 = 0x2006
	JOYCON_PRODUCT_R          uint16 = 0x2007
	JOYCON_PRODUCT_FAKE       uint16 = 0x2008
	JOYCON_PRODUCT_PRO        uint16 = 0x2009
	JOYCON_PRODUCT_CHARGEGRIP uint16 = 0x200e
)
View Source
const (
	SideInvalid JoyConSide = iota
	SideLeft               = 1
	SideRight              = 2
	SideBoth               = 3
)
View Source
const (
	// When Joycon is in this mode, packets are pushed from Joycon at 60Hz
	// for all button/stick/gyro events.
	// Linux enters this mode automatically when BT connected, Windows doesn't, see below.
	StandardFull byte = 0x30

	// Default mode on Windows, need to switch to StandardFull manually
	// it only push packet on button press, no stick/gyro events.
	SimpleHid byte = 0x3F
)

Variables

View Source
var (
	// Movement event only fired if > this tolerance
	SpinNeutralThreshold float64 = 0.08
	// Rotation event only fired if > this tolerance
	SpinEdgeThreshhold float64 = 0.70
)
View Source
var EmptyCalibrationData = CalibrationData{}
View Source
var NeutralRatio = Ratio{}
View Source
var SideMap = map[string]JoyConSide{
	"Left":  SideLeft,
	"Right": SideRight,
}
View Source
var SpinDirectionMap = map[string]SpinDirection{
	"Up":           Spin_Up,
	"UpLeave":      Spin_Up_Leave,
	"Right":        Spin_Right,
	"RightLeave":   Spin_Right_Leave,
	"Down":         Spin_Down,
	"DownLeave":    Spin_Down_Leave,
	"Left":         Spin_Left,
	"LeftLeave":    Spin_Left_Leave,
	"Neutral":      Spin_Neutral,
	"NeutralLeave": Spin_Neutral_Leave,
}

Functions

This section is empty.

Types

type Acceleration

type Acceleration struct {
	Roll, Pitch, Yaw int16
}

type Axis2D

type Axis2D[T uint16 | float64] struct {
	X, Y T
}

type ButtonID

type ButtonID uint16
const (
	Button_R_Y ButtonID = 0x000 + (1 << iota)
	Button_R_X
	Button_R_B
	Button_R_A
	Button_R_SR
	Button_R_SL
	Button_R_R
	Button_R_ZR
)

First byte of ButtonState.

const (
	Button_Minus ButtonID = 0x100 + (1 << iota)
	Button_Plus
	Button_R_Stick
	Button_L_Stick
	Button_Home
	Button_Capture
	Button_Unused1
	Button_IsChargeGrip
)

Middle byte of ButtonState.

const (
	Button_L_Down ButtonID = 0x200 + (1 << iota)
	Button_L_Up
	Button_L_Right
	Button_L_Left
	Button_L_SR
	Button_L_SL
	Button_L_L
	Button_L_ZL
)

Last byte of ButtonState.

func ButtonFromString

func ButtonFromString(s string) (ButtonID, bool)

func (ButtonID) String

func (b ButtonID) String() string

type ButtonState

type ButtonState [3]byte

func ButtonsFromSlice

func ButtonsFromSlice(b []byte) ButtonState

ButtonsFromSlice copies the provided slice from a standard input report into a ButtonState.

func (ButtonState) DownMask

func (b ButtonState) DownMask(other ButtonState) ButtonState

DownMask returns buttons that being pressed down

func (ButtonState) Has

func (b ButtonState) Has(i ButtonID) bool

Has the state of a single ButtonID.

func (ButtonState) IsZero

func (b ButtonState) IsZero() bool

IsZero returns true if all key is zero

func (ButtonState) UpMask

func (b ButtonState) UpMask(other ButtonState) ButtonState

DownMask returns buttons that being released up

type CalibrationData

type CalibrationData struct {
	// contains filtered or unexported fields
}

func (*CalibrationData) Adjust

func (c *CalibrationData) Adjust(rawXY *Point) (ret Ratio)

Transform raw stick values into -1.0~1.0 float64. 0 == center, -1.0 == most left, 1.0 == most right

func (*CalibrationData) Parse

func (c *CalibrationData) Parse(b []byte, side JoyConSide)

side must be TypeLeft or TypeRight; TypeBoth controllers should call this twice

type Controller

type Controller interface {
	Mac() string
	Side() JoyConSide

	Disconnect()
	ShutdownBT() error

	// Bind events to listener,
	// Call the returned function to unbind.
	SetListener(EventListener) RemoveListenerFn

	Battery() (level int8, charging bool) // 4=full, 3, 2, 1=critical, 0=empty
	EnableGyro(isOn bool) error
	Rumble(*RumbleFrequency) error
	SetLights(pattern byte)

	CalibrateStick() error

	Test()
}

func NewJoycon

func NewJoycon(
	hidDev *hid.Device,
	side JoyConSide,
	mac string,
) Controller

type EventListener

type EventListener interface {
	// fail read/write to hid, BT connection broken
	OnReadWriteError(Controller, error)
	// button down/up
	OnButton(jc Controller, down, up, curr *ButtonState)
	// stick spinning around
	OnStick(jc Controller, t JoyConSide, curr, prev *Ratio)
	// stick calibrated successfylly
	OnStickCalib(Controller, *[2]CalibrationData)
	// gyro motion, todo
	OnGyro(Controller, *GyroFrame)
	// battery level change
	OnBattery(jc Controller, level int8, charging bool)
}

type Gyro3D

type Gyro3D struct {
	X, Y, Z int16
}

func (*Gyro3D) Adjust

func (g *Gyro3D) Adjust(endPos *Gyro3D) Gyro3D

type GyroFrame

type GyroFrame struct {
	Gyro3D       // absolute value
	Acceleration // reletive value
}

from: https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/imu_sensor_notes.md The 6-Axis data is repeated 3 times. On Joy-con with a 15ms packet push, this is translated to 5ms difference sampling. E.g. 1st sample 0ms, 2nd 5ms, 3rd 10ms. Using all 3 samples let you have a 5ms precision instead of 15ms.

var GyroFrame_Nil GyroFrame

type JoyConSide

type JoyConSide int

func (JoyConSide) IsLeft

func (s JoyConSide) IsLeft() bool

func (JoyConSide) IsRight

func (s JoyConSide) IsRight() bool

func (JoyConSide) String

func (s JoyConSide) String() string

type Point

type Point Axis2D[uint16]

type Ratio

type Ratio Axis2D[float64]

func (*Ratio) AtEdge

func (r *Ratio) AtEdge(dir SpinDirection) bool

if the Ratio is at edge meaning it exceeds the `SpinEdgeThreshhold` in that direction

func (*Ratio) AtNeutral

func (r *Ratio) AtNeutral() bool

func (*Ratio) String

func (r *Ratio) String() string

type RemoveListenerFn

type RemoveListenerFn func()

type RumbleFrequency

type RumbleFrequency [8]byte

NOTE ---- FBI WARNING ---- Don't use real maximum values for Amplitude. Otherwise, they can damage the linear actuators. Ref: https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/bluetooth_hid_notes.md#rumble-data

var RumbleFrequencyNeutral RumbleFrequency = [8]byte{0, 1, 0x40, 0x40, 0, 1, 0x40, 0x40}

(320Hz 0.0f 160Hz 0.0f) is neutral, it doesn't vibrate.

var RumbleFrequencySample RumbleFrequency = [8]byte{0, 4, 0x1, 0xfc, 0, 4, 0x01, 0xfc}

a frequency sample that vibrates

type SpinDirection

type SpinDirection int
const (
	SpinDirection_None SpinDirection = iota
	Spin_Neutral
	Spin_Neutral_Leave
	Spin_Up
	Spin_Up_Leave
	Spin_Right
	Spin_Right_Leave
	Spin_Down
	Spin_Down_Leave
	Spin_Left
	Spin_Left_Leave
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL