Loading joysticks.go +68 −51 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ type button struct { value bool } type eventType uint8 const ( Loading @@ -43,15 +42,16 @@ const ( hatRadius hatCentered hatEdge hatVelocityX hatVelocityY ) // signature of an event type eventSignature struct { typ eventType eventType number uint8 } // HID holds the in-coming event channel, available button and hat indexes, and registered events, for a human interface device. // has methods to control and adjust behaviour. type HID struct { Loading Loading @@ -96,7 +96,7 @@ type CoordsEvent struct { } // Hat Axis event type. V{-1...1} type PanEvent struct { type AxisEvent struct { when V float32 } Loading Loading @@ -154,36 +154,42 @@ func (d HID) ParcelOutEvents() { c <- HatEvent{when{toDuration(evt.Time)}, h.number, h.axis, v} } switch h.axis { case 1: case 2: if c, ok := d.Events[eventSignature{hatPanX, h.number}]; ok { c <- PanEvent{when{toDuration(evt.Time)}, v} c <- AxisEvent{when{toDuration(evt.Time)}, v} } case 2: if c, ok := d.Events[eventSignature{hatVelocityX, h.number}]; ok { c <- AxisEvent{when{toDuration(evt.Time)}, (v-d.HatAxes[evt.Index].value)/float32((toDuration(evt.Time)-d.HatAxes[evt.Index].time).Seconds())} } case 1: if c, ok := d.Events[eventSignature{hatPanY, h.number}]; ok { c <- PanEvent{when{toDuration(evt.Time)}, v} c <- AxisEvent{when{toDuration(evt.Time)}, v} } if c, ok := d.Events[eventSignature{hatVelocityY, h.number}]; ok { c <- AxisEvent{when{toDuration(evt.Time)}, (v-d.HatAxes[evt.Index].value)/float32((toDuration(evt.Time)-d.HatAxes[evt.Index].time).Seconds())} } } if c, ok := d.Events[eventSignature{hatPosition, h.number}]; ok { switch h.axis { case 1: c <- CoordsEvent{when{toDuration(evt.Time)}, v, d.HatAxes[evt.Index+1].value} case 2: c <- CoordsEvent{when{toDuration(evt.Time)}, v, d.HatAxes[evt.Index+1].value} case 1: c <- CoordsEvent{when{toDuration(evt.Time)}, d.HatAxes[evt.Index-1].value, v} } } if c, ok := d.Events[eventSignature{hatAngle, h.number}]; ok { switch h.axis { case 1: c <- AngleEvent{when{toDuration(evt.Time)}, float32(math.Atan2(float64(v), float64(d.HatAxes[evt.Index+1].value)))} case 2: c <- AngleEvent{when{toDuration(evt.Time)}, float32(math.Atan2(float64(v), float64(d.HatAxes[evt.Index+1].value)))} case 1: c <- AngleEvent{when{toDuration(evt.Time)}, float32(math.Atan2(float64(d.HatAxes[evt.Index-1].value), float64(v)))} } } if c, ok := d.Events[eventSignature{hatRadius, h.number}]; ok { switch h.axis { case 1: c <- RadiusEvent{when{toDuration(evt.Time)}, float32(math.Sqrt(float64(v)*float64(v) + float64(d.HatAxes[evt.Index+1].value)*float64(d.HatAxes[evt.Index+1].value)))} case 2: c <- RadiusEvent{when{toDuration(evt.Time)}, float32(math.Sqrt(float64(v)*float64(v) + float64(d.HatAxes[evt.Index+1].value)*float64(d.HatAxes[evt.Index+1].value)))} case 1: c <- RadiusEvent{when{toDuration(evt.Time)}, float32(math.Sqrt(float64(d.HatAxes[evt.Index-1].value)*float64(d.HatAxes[evt.Index-1].value) + float64(v)*float64(v)))} } } Loading @@ -191,9 +197,9 @@ func (d HID) ParcelOutEvents() { // fmt.Println(v,h) if (v == 1 || v == -1) && h.value != 1 && h.value != -1 { switch h.axis { case 1: c <- AngleEvent{when{toDuration(evt.Time)}, float32(math.Atan2(float64(v), float64(d.HatAxes[evt.Index+1].value)))} case 2: c <- AngleEvent{when{toDuration(evt.Time)}, float32(math.Atan2(float64(v), float64(d.HatAxes[evt.Index+1].value)))} case 1: c <- AngleEvent{when{toDuration(evt.Time)}, float32(math.Atan2(float64(d.HatAxes[evt.Index-1].value), float64(v)))} } } Loading @@ -201,11 +207,11 @@ func (d HID) ParcelOutEvents() { if c, ok := d.Events[eventSignature{hatCentered, h.number}]; ok { if v == 0 && h.value != 0 { switch h.axis { case 1: case 2: if d.HatAxes[evt.Index+1].value == 0 { c <- when{toDuration(evt.Time)} } case 2: case 1: if d.HatAxes[evt.Index-1].value == 0 { c <- when{toDuration(evt.Time)} } Loading @@ -228,7 +234,6 @@ type Channel struct { Method func(HID, uint8) chan Event } // Capture is highlevel automation of the setup of event channels. // returned are matching chan's for each registree, which then receive events of the type and index the registree indicated. // It uses the first available joystick, from a max of 4. Loading @@ -249,7 +254,6 @@ func Capture(registrees ...Channel) []chan Event { return chans } // button changes event channel. func (d HID) OnButton(button uint8) chan Event { c := make(chan Event) Loading Loading @@ -313,6 +317,20 @@ func (d HID) OnPanY(hat uint8) chan Event { return c } // hat axis-X moved event channel. func (d HID) OnSpeedX(hat uint8) chan Event { c := make(chan Event) d.Events[eventSignature{hatVelocityX, hat}] = c return c } // hat axis-Y moved event channel. func (d HID) OnSpeedY(hat uint8) chan Event { c := make(chan Event) d.Events[eventSignature{hatVelocityY, hat}] = c return c } // hat angle changed event channel. func (d HID) OnRotate(hat uint8) chan Event { c := make(chan Event) Loading Loading @@ -373,4 +391,3 @@ func (d HID) HatCoords(hat uint8, coords []float32) { func (d HID) InsertSyntheticEvent(v int16, t uint8, i uint8) { d.OSEvents <- osEventRecord{Value: v, Type: t, Index: i} } joysticks_test.go +24 −27 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ func TestHIDsAdvanced(t *testing.T) { b3 := js1.OnClose(3) b4 := js1.OnClose(4) b5 := js1.OnClose(5) coord := make([]float32, 2) quit := js1.OnOpen(10) h4 := js1.OnPanX(2) h5 := js1.OnPanY(2) Loading @@ -50,14 +49,15 @@ func TestHIDsAdvanced(t *testing.T) { case <-b4: play(NewSound(NewTone(time.Second/150, 1), time.Second/3)) case <-b5: coord := make([]float32, 2) js1.HatCoords(1, coord) fmt.Println(coord) case h := <-h3: fmt.Println("hat 3 moved", h) fmt.Printf("hat 3 moved %+v\n", h) case h := <-h4: fmt.Println("hat 2 X moved", h.(PanEvent).V) fmt.Println("hat 2 X moved", h.(AxisEvent).V) case h := <-h5: fmt.Println("hat 2 Y moved", h) fmt.Printf("hat 2 Y moved %+v\n", h) case h := <-h6: fmt.Println("hat 1 edged", h.(AngleEvent).Angle) } Loading Loading @@ -90,34 +90,29 @@ func TestHIDsCapture(t *testing.T) { } func TestHIDsMutipleCapture(t *testing.T) { events1 := Capture( Channel{10, HID.OnLong}, // event[0] button #10 long pressed Channel{1, HID.OnClose}, // event[1] button #1 closes Channel{1, HID.OnMove}, // event[2] hat #1 moves buttonEvents := Capture( Channel{10, HID.OnLong}, // button #10 long pressed Channel{1, HID.OnClose}, ) events2 := Capture( Channel{10, HID.OnLong}, // event[0] button #10 long pressed Channel{1, HID.OnClose}, // event[1] button #1 closes Channel{1, HID.OnMove}, // event[2] hat #1 moves hatEvents := Capture( Channel{1, HID.OnMove}, Channel{2, HID.OnSpeedX}, Channel{2, HID.OnPanX}, ) var x float32 = .5 var f time.Duration = time.Second / 440 for { select { case <-events1[0]: return case <-events2[0]: case <-buttonEvents[0]: return case <-events1[1]: case <-buttonEvents[1]: play(NewSound(NewTone(f, float64(x)), time.Second/3)) case <-events2[1]: play(NewSound(NewTone(f, float64(x)), time.Second/3)) case h := <-events1[2]: x = h.(CoordsEvent).X/2 + .5 f = time.Duration(100*math.Pow(2, float64(h.(CoordsEvent).Y))) * time.Second / 44000 case h := <-events2[2]: x = h.(CoordsEvent).X/2 + .5 case h := <-hatEvents[0]: f = time.Duration(100*math.Pow(2, float64(h.(CoordsEvent).Y))) * time.Second / 44000 case h := <-hatEvents[1]: fmt.Printf("hat 2 X speed %+v\n",h.(AxisEvent).V) case h := <-hatEvents[2]: fmt.Printf("hat 2 X pan %+v\n",h.(AxisEvent).V) } } } Loading @@ -135,3 +130,5 @@ func play(s Sound) { panic(err) } } doc.go +1 −1 File changed.Contains only whitespace changes. Show changes Loading
joysticks.go +68 −51 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ type button struct { value bool } type eventType uint8 const ( Loading @@ -43,15 +42,16 @@ const ( hatRadius hatCentered hatEdge hatVelocityX hatVelocityY ) // signature of an event type eventSignature struct { typ eventType eventType number uint8 } // HID holds the in-coming event channel, available button and hat indexes, and registered events, for a human interface device. // has methods to control and adjust behaviour. type HID struct { Loading Loading @@ -96,7 +96,7 @@ type CoordsEvent struct { } // Hat Axis event type. V{-1...1} type PanEvent struct { type AxisEvent struct { when V float32 } Loading Loading @@ -154,36 +154,42 @@ func (d HID) ParcelOutEvents() { c <- HatEvent{when{toDuration(evt.Time)}, h.number, h.axis, v} } switch h.axis { case 1: case 2: if c, ok := d.Events[eventSignature{hatPanX, h.number}]; ok { c <- PanEvent{when{toDuration(evt.Time)}, v} c <- AxisEvent{when{toDuration(evt.Time)}, v} } case 2: if c, ok := d.Events[eventSignature{hatVelocityX, h.number}]; ok { c <- AxisEvent{when{toDuration(evt.Time)}, (v-d.HatAxes[evt.Index].value)/float32((toDuration(evt.Time)-d.HatAxes[evt.Index].time).Seconds())} } case 1: if c, ok := d.Events[eventSignature{hatPanY, h.number}]; ok { c <- PanEvent{when{toDuration(evt.Time)}, v} c <- AxisEvent{when{toDuration(evt.Time)}, v} } if c, ok := d.Events[eventSignature{hatVelocityY, h.number}]; ok { c <- AxisEvent{when{toDuration(evt.Time)}, (v-d.HatAxes[evt.Index].value)/float32((toDuration(evt.Time)-d.HatAxes[evt.Index].time).Seconds())} } } if c, ok := d.Events[eventSignature{hatPosition, h.number}]; ok { switch h.axis { case 1: c <- CoordsEvent{when{toDuration(evt.Time)}, v, d.HatAxes[evt.Index+1].value} case 2: c <- CoordsEvent{when{toDuration(evt.Time)}, v, d.HatAxes[evt.Index+1].value} case 1: c <- CoordsEvent{when{toDuration(evt.Time)}, d.HatAxes[evt.Index-1].value, v} } } if c, ok := d.Events[eventSignature{hatAngle, h.number}]; ok { switch h.axis { case 1: c <- AngleEvent{when{toDuration(evt.Time)}, float32(math.Atan2(float64(v), float64(d.HatAxes[evt.Index+1].value)))} case 2: c <- AngleEvent{when{toDuration(evt.Time)}, float32(math.Atan2(float64(v), float64(d.HatAxes[evt.Index+1].value)))} case 1: c <- AngleEvent{when{toDuration(evt.Time)}, float32(math.Atan2(float64(d.HatAxes[evt.Index-1].value), float64(v)))} } } if c, ok := d.Events[eventSignature{hatRadius, h.number}]; ok { switch h.axis { case 1: c <- RadiusEvent{when{toDuration(evt.Time)}, float32(math.Sqrt(float64(v)*float64(v) + float64(d.HatAxes[evt.Index+1].value)*float64(d.HatAxes[evt.Index+1].value)))} case 2: c <- RadiusEvent{when{toDuration(evt.Time)}, float32(math.Sqrt(float64(v)*float64(v) + float64(d.HatAxes[evt.Index+1].value)*float64(d.HatAxes[evt.Index+1].value)))} case 1: c <- RadiusEvent{when{toDuration(evt.Time)}, float32(math.Sqrt(float64(d.HatAxes[evt.Index-1].value)*float64(d.HatAxes[evt.Index-1].value) + float64(v)*float64(v)))} } } Loading @@ -191,9 +197,9 @@ func (d HID) ParcelOutEvents() { // fmt.Println(v,h) if (v == 1 || v == -1) && h.value != 1 && h.value != -1 { switch h.axis { case 1: c <- AngleEvent{when{toDuration(evt.Time)}, float32(math.Atan2(float64(v), float64(d.HatAxes[evt.Index+1].value)))} case 2: c <- AngleEvent{when{toDuration(evt.Time)}, float32(math.Atan2(float64(v), float64(d.HatAxes[evt.Index+1].value)))} case 1: c <- AngleEvent{when{toDuration(evt.Time)}, float32(math.Atan2(float64(d.HatAxes[evt.Index-1].value), float64(v)))} } } Loading @@ -201,11 +207,11 @@ func (d HID) ParcelOutEvents() { if c, ok := d.Events[eventSignature{hatCentered, h.number}]; ok { if v == 0 && h.value != 0 { switch h.axis { case 1: case 2: if d.HatAxes[evt.Index+1].value == 0 { c <- when{toDuration(evt.Time)} } case 2: case 1: if d.HatAxes[evt.Index-1].value == 0 { c <- when{toDuration(evt.Time)} } Loading @@ -228,7 +234,6 @@ type Channel struct { Method func(HID, uint8) chan Event } // Capture is highlevel automation of the setup of event channels. // returned are matching chan's for each registree, which then receive events of the type and index the registree indicated. // It uses the first available joystick, from a max of 4. Loading @@ -249,7 +254,6 @@ func Capture(registrees ...Channel) []chan Event { return chans } // button changes event channel. func (d HID) OnButton(button uint8) chan Event { c := make(chan Event) Loading Loading @@ -313,6 +317,20 @@ func (d HID) OnPanY(hat uint8) chan Event { return c } // hat axis-X moved event channel. func (d HID) OnSpeedX(hat uint8) chan Event { c := make(chan Event) d.Events[eventSignature{hatVelocityX, hat}] = c return c } // hat axis-Y moved event channel. func (d HID) OnSpeedY(hat uint8) chan Event { c := make(chan Event) d.Events[eventSignature{hatVelocityY, hat}] = c return c } // hat angle changed event channel. func (d HID) OnRotate(hat uint8) chan Event { c := make(chan Event) Loading Loading @@ -373,4 +391,3 @@ func (d HID) HatCoords(hat uint8, coords []float32) { func (d HID) InsertSyntheticEvent(v int16, t uint8, i uint8) { d.OSEvents <- osEventRecord{Value: v, Type: t, Index: i} }
joysticks_test.go +24 −27 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ func TestHIDsAdvanced(t *testing.T) { b3 := js1.OnClose(3) b4 := js1.OnClose(4) b5 := js1.OnClose(5) coord := make([]float32, 2) quit := js1.OnOpen(10) h4 := js1.OnPanX(2) h5 := js1.OnPanY(2) Loading @@ -50,14 +49,15 @@ func TestHIDsAdvanced(t *testing.T) { case <-b4: play(NewSound(NewTone(time.Second/150, 1), time.Second/3)) case <-b5: coord := make([]float32, 2) js1.HatCoords(1, coord) fmt.Println(coord) case h := <-h3: fmt.Println("hat 3 moved", h) fmt.Printf("hat 3 moved %+v\n", h) case h := <-h4: fmt.Println("hat 2 X moved", h.(PanEvent).V) fmt.Println("hat 2 X moved", h.(AxisEvent).V) case h := <-h5: fmt.Println("hat 2 Y moved", h) fmt.Printf("hat 2 Y moved %+v\n", h) case h := <-h6: fmt.Println("hat 1 edged", h.(AngleEvent).Angle) } Loading Loading @@ -90,34 +90,29 @@ func TestHIDsCapture(t *testing.T) { } func TestHIDsMutipleCapture(t *testing.T) { events1 := Capture( Channel{10, HID.OnLong}, // event[0] button #10 long pressed Channel{1, HID.OnClose}, // event[1] button #1 closes Channel{1, HID.OnMove}, // event[2] hat #1 moves buttonEvents := Capture( Channel{10, HID.OnLong}, // button #10 long pressed Channel{1, HID.OnClose}, ) events2 := Capture( Channel{10, HID.OnLong}, // event[0] button #10 long pressed Channel{1, HID.OnClose}, // event[1] button #1 closes Channel{1, HID.OnMove}, // event[2] hat #1 moves hatEvents := Capture( Channel{1, HID.OnMove}, Channel{2, HID.OnSpeedX}, Channel{2, HID.OnPanX}, ) var x float32 = .5 var f time.Duration = time.Second / 440 for { select { case <-events1[0]: return case <-events2[0]: case <-buttonEvents[0]: return case <-events1[1]: case <-buttonEvents[1]: play(NewSound(NewTone(f, float64(x)), time.Second/3)) case <-events2[1]: play(NewSound(NewTone(f, float64(x)), time.Second/3)) case h := <-events1[2]: x = h.(CoordsEvent).X/2 + .5 f = time.Duration(100*math.Pow(2, float64(h.(CoordsEvent).Y))) * time.Second / 44000 case h := <-events2[2]: x = h.(CoordsEvent).X/2 + .5 case h := <-hatEvents[0]: f = time.Duration(100*math.Pow(2, float64(h.(CoordsEvent).Y))) * time.Second / 44000 case h := <-hatEvents[1]: fmt.Printf("hat 2 X speed %+v\n",h.(AxisEvent).V) case h := <-hatEvents[2]: fmt.Printf("hat 2 X pan %+v\n",h.(AxisEvent).V) } } } Loading @@ -135,3 +130,5 @@ func play(s Sound) { panic(err) } }