Documentation ¶
Index ¶
Constants ¶
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 )
const ( SideInvalid JoyConSide = iota SideLeft = 1 SideRight = 2 SideBoth = 3 )
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 ¶
var ( // Movement event only fired if > this tolerance SpinNeutralThreshold float64 = 0.08 // Rotation event only fired if > this tolerance SpinEdgeThreshhold float64 = 0.70 )
var EmptyCalibrationData = CalibrationData{}
var NeutralRatio = Ratio{}
var ReverseDirectionMap = map[SpinDirection]SpinDirection{ Spin_Up: Spin_Up_Leave, Spin_Right: Spin_Right_Leave, Spin_Down: Spin_Down_Leave, Spin_Left: Spin_Left_Leave, }
var SideMap = map[string]JoyConSide{ "Left": SideLeft, "Right": SideRight, }
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 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 ¶
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 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 Ratio ¶
func (*Ratio) AtEdge ¶
func (r *Ratio) AtEdge(dir SpinDirection) bool
if the Ratio is at edge meaning it exceeds the `SpinEdgeThreshhold` in that direction
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 )