Allow all buttons and axes on virtual devices to be specified by either number or an explicit list. (#5)
Reviewed-on: #5 Co-authored-by: Anna Rose Wiggins <annabunches@gmail.com> Co-committed-by: Anna Rose Wiggins <annabunches@gmail.com>
This commit is contained in:
parent
712dcdbc07
commit
6ef0cbd07c
11 changed files with 1114 additions and 130 deletions
|
@ -68,9 +68,12 @@ func main() {
|
||||||
|
|
||||||
// initialize the mode variable
|
// initialize the mode variable
|
||||||
mode := config.GetModes()[0]
|
mode := config.GetModes()[0]
|
||||||
logger.Logf("Initial mode set to '%s'", mode)
|
|
||||||
|
|
||||||
fmt.Println("Joyful Running! Press Ctrl+C to quit.")
|
fmt.Println("Joyful Running! Press Ctrl+C to quit. Press Enter to reload rules.")
|
||||||
|
if len(config.GetModes()) > 1 {
|
||||||
|
logger.Logf("Initial mode set to '%s'", mode)
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
// Get an event (blocks if necessary)
|
// Get an event (blocks if necessary)
|
||||||
channelEvent := <-eventChannel
|
channelEvent := <-eventChannel
|
||||||
|
|
|
@ -1,56 +1,218 @@
|
||||||
rules:
|
rules:
|
||||||
- type: simple
|
### Rotational Controls
|
||||||
|
- type: axis
|
||||||
|
name: pitch
|
||||||
input:
|
input:
|
||||||
device: right-stick
|
device: right-stick
|
||||||
axis: ABS_X
|
axis: Y
|
||||||
|
deadzone_start: 29000
|
||||||
|
deadzone_end: 31000
|
||||||
output:
|
output:
|
||||||
device: main
|
device: primary
|
||||||
axis: ABS_X
|
axis: Y
|
||||||
|
|
||||||
- type: simple
|
- type: axis
|
||||||
|
name: roll (turret yaw)
|
||||||
input:
|
input:
|
||||||
device: right-stick
|
device: right-stick
|
||||||
axis: ABS_Y
|
axis: X
|
||||||
|
deadzone_start: 30000
|
||||||
|
deadzone_end: 32000
|
||||||
output:
|
output:
|
||||||
device: main
|
device: primary
|
||||||
axis: ABS_Y
|
axis: X
|
||||||
|
|
||||||
- type: simple
|
- type: axis
|
||||||
input:
|
name: yaw
|
||||||
device: right-stick
|
|
||||||
axis: ABS_THROTTLE
|
|
||||||
output:
|
|
||||||
device: main
|
|
||||||
axis: ABS_THROTTLE
|
|
||||||
|
|
||||||
- type: simple
|
|
||||||
input:
|
|
||||||
device: left-stick
|
|
||||||
axis: ABS_X
|
|
||||||
output:
|
|
||||||
device: main
|
|
||||||
axis: ABS_RX
|
|
||||||
|
|
||||||
- type: simple
|
|
||||||
input:
|
|
||||||
device: left-stick
|
|
||||||
axis: ABS_Y
|
|
||||||
output:
|
|
||||||
device: main
|
|
||||||
axis: ABS_RY
|
|
||||||
|
|
||||||
- type: simple
|
|
||||||
input:
|
|
||||||
device: left-stick
|
|
||||||
axis: ABS_THROTTLE
|
|
||||||
output:
|
|
||||||
device: main
|
|
||||||
axis: ABS_RUDDER
|
|
||||||
|
|
||||||
- type: simple
|
|
||||||
input:
|
input:
|
||||||
device: pedals
|
device: pedals
|
||||||
axis: ABS_Z
|
axis: Z
|
||||||
|
deadzone_start: 124
|
||||||
|
deadzone_end: 132
|
||||||
output:
|
output:
|
||||||
device: main
|
device: primary
|
||||||
axis: ABS_Z
|
axis: Z
|
||||||
|
|
||||||
|
### Translation Controls
|
||||||
|
- type: axis
|
||||||
|
name: throttle
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
axis: Y
|
||||||
|
deadzone_start: 29500
|
||||||
|
deadzone_end: 31000
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
axis: RY
|
||||||
|
|
||||||
|
- type: axis
|
||||||
|
name: translation lateral
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
axis: X
|
||||||
|
deadzone_start: 29000
|
||||||
|
deadzone_end: 30500
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
axis: RX
|
||||||
|
|
||||||
|
### Freelook controls
|
||||||
|
- type: axis
|
||||||
|
name: Freelook X
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
axis: RX
|
||||||
|
deadzone_start: 29500
|
||||||
|
deadzone_end: 30250
|
||||||
|
output:
|
||||||
|
device: secondary
|
||||||
|
axis: X
|
||||||
|
- type: axis
|
||||||
|
name: Freelook Y
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
axis: RY
|
||||||
|
deadzone_start: 29500
|
||||||
|
deadzone_end: 30250
|
||||||
|
output:
|
||||||
|
device: secondary
|
||||||
|
axis: Y
|
||||||
|
|
||||||
|
|
||||||
|
# Vertical thrust is on the VPC "paddles" in the main flight mode
|
||||||
|
- type: axis
|
||||||
|
name: translation up
|
||||||
|
modes:
|
||||||
|
- main
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
axis: ABS_THROTTLE
|
||||||
|
deadzone_start: 0
|
||||||
|
deadzone_end: 500
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
axis: ABS_THROTTLE
|
||||||
|
|
||||||
|
- type: axis
|
||||||
|
name: translation down
|
||||||
|
modes:
|
||||||
|
- main
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
axis: ABS_THROTTLE
|
||||||
|
deadzone_start: 0
|
||||||
|
deadzone_end: 500
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
axis: ABS_RUDDER
|
||||||
|
|
||||||
|
# By default, the left thumbstick controls tractor beam via mousewheel
|
||||||
|
- type: axis-to-relaxis
|
||||||
|
name: tractor in
|
||||||
|
modes:
|
||||||
|
- main
|
||||||
|
repeat_rate_max: 10
|
||||||
|
repeat_rate_min: 100
|
||||||
|
increment: -1
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
axis: RY
|
||||||
|
deadzone_start: 0
|
||||||
|
deadzone_end: 30500
|
||||||
|
output:
|
||||||
|
device: mouse
|
||||||
|
axis: REL_WHEEL
|
||||||
|
|
||||||
|
- type: axis-to-relaxis
|
||||||
|
name: tractor out
|
||||||
|
modes:
|
||||||
|
- main
|
||||||
|
repeat_rate_max: 10
|
||||||
|
repeat_rate_min: 100
|
||||||
|
increment: 1
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
axis: RY
|
||||||
|
deadzone_start: 29500
|
||||||
|
deadzone_end: 64000
|
||||||
|
inverted: true
|
||||||
|
output:
|
||||||
|
device: mouse
|
||||||
|
axis: REL_WHEEL
|
||||||
|
|
||||||
|
# In Mining mode, we move vertical thrust to the left thumbstick
|
||||||
|
# and remap the right paddle to be mining laser power
|
||||||
|
- type: axis
|
||||||
|
name: translation up alternate
|
||||||
|
modes:
|
||||||
|
- mining
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
axis: RY
|
||||||
|
deadzone_start: 29250
|
||||||
|
deadzone_end: 64000
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
axis: ABS_THROTTLE
|
||||||
|
|
||||||
|
- type: axis
|
||||||
|
name: translation down alternate
|
||||||
|
modes:
|
||||||
|
- mining
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
axis: RY
|
||||||
|
deadzone_start: 0
|
||||||
|
deadzone_end: 30500
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
axis: ABS_RUDDER
|
||||||
|
|
||||||
|
- type: axis
|
||||||
|
name: mining laser
|
||||||
|
modes:
|
||||||
|
- mining
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
axis: ABS_THROTTLE
|
||||||
|
deadzone_start: 0
|
||||||
|
deadzone_end: 500
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
axis: RZ
|
||||||
|
|
||||||
|
# In tractor mode, most flight controls are disabled to prevent us
|
||||||
|
# from accidentally trying to fly off without throttle control
|
||||||
|
# - type: axis-to-relaxis
|
||||||
|
# name: tractor in
|
||||||
|
# modes:
|
||||||
|
# - tractor
|
||||||
|
# repeat_rate_max: 10
|
||||||
|
# repeat_rate_min: 100
|
||||||
|
# increment: -1
|
||||||
|
# input:
|
||||||
|
# device: left-stick
|
||||||
|
# axis: Y
|
||||||
|
# deadzone_start: 0
|
||||||
|
# deadzone_end: 30250
|
||||||
|
# output:
|
||||||
|
# device: mouse
|
||||||
|
# axis: REL_WHEEL
|
||||||
|
|
||||||
|
# - type: axis-to-relaxis
|
||||||
|
# name: tractor out
|
||||||
|
# modes:
|
||||||
|
# - tractor
|
||||||
|
# repeat_rate_max: 10
|
||||||
|
# repeat_rate_min: 100
|
||||||
|
# increment: 1
|
||||||
|
# input:
|
||||||
|
# device: left-stick
|
||||||
|
# axis: Y
|
||||||
|
# deadzone_start: 29500
|
||||||
|
# deadzone_end: 64000
|
||||||
|
# inverted: true
|
||||||
|
# output:
|
||||||
|
# device: mouse
|
||||||
|
# axis: REL_WHEEL
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,706 @@
|
||||||
rules:
|
rules:
|
||||||
- name: Trigger
|
# Special Rules
|
||||||
type: combo
|
- name: Right Trigger
|
||||||
|
type: button-combo
|
||||||
inputs:
|
inputs:
|
||||||
- device: right-stick
|
- device: right-stick
|
||||||
button: BTN_THUMB
|
button: BTN_THUMB
|
||||||
- device: right-stick
|
- device: right-stick
|
||||||
button: BTN_THUMB2
|
button: BTN_THUMB2
|
||||||
output:
|
output:
|
||||||
device: main
|
device: primary
|
||||||
|
button: 0
|
||||||
|
|
||||||
|
- name: Left Trigger
|
||||||
|
type: button-combo
|
||||||
|
inputs:
|
||||||
|
- device: left-stick
|
||||||
|
button: BTN_THUMB
|
||||||
|
- device: left-stick
|
||||||
|
button: BTN_THUMB2
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 1
|
||||||
|
|
||||||
|
- name: ButtonBoxModeShift
|
||||||
|
type: mode-select
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_BASE2
|
||||||
|
output:
|
||||||
|
modes:
|
||||||
|
- main
|
||||||
|
- mining
|
||||||
|
|
||||||
|
# Right Stick
|
||||||
|
- name: R Red Button
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_BASE6
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 2
|
||||||
|
- name: R Black Button
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_PINKIE
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 3
|
||||||
|
- name: R Pinkie Button
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY14
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 4
|
||||||
|
|
||||||
|
- name: R Side Button
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY2
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 5
|
||||||
|
- name: R Side Up
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY3
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 6
|
||||||
|
- name: R Side Down
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY4
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 7
|
||||||
|
|
||||||
|
- name: R High Hat
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: "0x12c"
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 8
|
||||||
|
- name: R High Hat Up
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: "0x12d"
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 9
|
||||||
|
- name: R High Hat Right
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: "0x12e"
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 10
|
||||||
|
- name: R High Hat Down
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_DEAD
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 11
|
||||||
|
- name: R High Hat Left
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY1
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 12
|
||||||
|
|
||||||
|
- name: R Low Hat
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_BASE
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 13
|
||||||
|
- name: R Low Hat Up
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_BASE2
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 14
|
||||||
|
- name: R Low Hat Right
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_BASE3
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 15
|
||||||
|
- name: R Low Hat Down
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_BASE4
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 16
|
||||||
|
- name: R Low Hat Left
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_BASE5
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 17
|
||||||
|
|
||||||
|
- name: R Thumb Hat
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY9
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 18
|
||||||
|
- name: R Thumb Hat Up
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY10
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 19
|
||||||
|
- name: R Thumb Hat Right
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY11
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 20
|
||||||
|
- name: R Thumb Hat Down
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY12
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 21
|
||||||
|
- name: R Thumb Hat Left
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY13
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 22
|
||||||
|
|
||||||
|
- name: R Wheel
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY5
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 23
|
||||||
|
- name: R Wheel Stage2
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY6
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 24
|
||||||
|
- name: R Wheel Down
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY7
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 25
|
||||||
|
- name: R Wheel Up
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY8
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 26
|
||||||
|
|
||||||
|
- name: R Thumbstick
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: right-stick
|
||||||
|
button: BTN_TOP2
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 27
|
||||||
|
|
||||||
|
# Left Stick
|
||||||
|
- name: L Red Button
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_BASE6
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 28
|
||||||
|
- name: L Black Button
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_PINKIE
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 29
|
||||||
|
- name: L Pinkie Button
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY14
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 30
|
||||||
|
|
||||||
|
- name: L Side Button
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY2
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 31
|
||||||
|
- name: L Side Up
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY3
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 32
|
||||||
|
- name: L Side Down
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY4
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 33
|
||||||
|
|
||||||
|
- name: L High Hat
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: "0x12c"
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 34
|
||||||
|
- name: L High Hat Up
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: "0x12d"
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 35
|
||||||
|
- name: L High Hat Right
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: "0x12e"
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 36
|
||||||
|
- name: L High Hat Down
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_DEAD
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 37
|
||||||
|
- name: L High Hat Left
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY1
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 38
|
||||||
|
|
||||||
|
- name: L Low Hat
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_BASE
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 39
|
||||||
|
- name: L Low Hat Up
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_BASE2
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 40
|
||||||
|
- name: L Low Hat Right
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_BASE3
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 41
|
||||||
|
- name: L Low Hat Down
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_BASE4
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 42
|
||||||
|
- name: L Low Hat Left
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_BASE5
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 43
|
||||||
|
|
||||||
|
- name: L Thumb Hat
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY9
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 44
|
||||||
|
- name: L Thumb Hat Up
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY10
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 45
|
||||||
|
- name: L Thumb Hat Right
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY11
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 46
|
||||||
|
- name: L Thumb Hat Down
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY12
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 47
|
||||||
|
- name: L Thumb Hat Left
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY13
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 48
|
||||||
|
|
||||||
|
- name: L Wheel
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY5
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 49
|
||||||
|
- name: L Wheel Stage2
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY6
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 50
|
||||||
|
- name: L Wheel Down
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY7
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 51
|
||||||
|
- name: L Wheel Up
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TRIGGER_HAPPY8
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 52
|
||||||
|
|
||||||
|
- name: L Thumbstick
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: left-stick
|
||||||
|
button: BTN_TOP2
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 53
|
||||||
|
|
||||||
|
# Button Box
|
||||||
|
- name: BB Power1 On
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY12
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 54
|
||||||
|
- name: BB Power1 Off
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY13
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 55
|
||||||
|
- name: BB Power2 On
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY10
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 56
|
||||||
|
- name: BB Power2 Off
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY11
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 57
|
||||||
|
- name: BB Power3 On
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY8
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 58
|
||||||
|
- name: BB Power3 Off
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY9
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 59
|
||||||
|
- name: BB Power4 On
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY6
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 60
|
||||||
|
- name: BB Power4 Off
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY7
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 61
|
||||||
|
|
||||||
|
|
||||||
|
- name: BB Top Row1
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY3
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 62
|
||||||
|
- name: BB Top Row2
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY4
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 63
|
||||||
|
- name: BB Top Row3
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY2
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 64
|
||||||
|
|
||||||
|
- name: BB Side1
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY1
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 65
|
||||||
|
- name: BB Side2
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: "0x12e"
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 66
|
||||||
|
- name: BB Side3
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: "0x12d"
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 67
|
||||||
|
|
||||||
|
- name: BB Toggle1
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_BASE3
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 68
|
||||||
|
- name: BB Toggle2 On
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_BASE6
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 69
|
||||||
|
- name: BB Toggle2 Off
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: "0x12c"
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 70
|
||||||
|
- name: BB Toggle3 On
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_BASE4
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 71
|
||||||
|
- name: BB Toggle3 Off
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_BASE5
|
||||||
|
output:
|
||||||
|
device: primary
|
||||||
|
button: 72
|
||||||
|
|
||||||
|
- name: BB Middle Row1
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_BASE
|
||||||
|
output:
|
||||||
|
device: secondary
|
||||||
|
button: 0
|
||||||
|
- name: BB Middle Row2
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_PINKIE
|
||||||
|
output:
|
||||||
|
device: secondary
|
||||||
|
button: 1
|
||||||
|
- name: BB Middle Row3
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TOP2
|
||||||
|
output:
|
||||||
|
device: secondary
|
||||||
|
button: 2
|
||||||
|
|
||||||
|
- name: BB Bottom Row1
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_DEAD
|
||||||
|
output:
|
||||||
|
device: secondary
|
||||||
|
button: 3
|
||||||
|
- name: BB Bottom Row2
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY5
|
||||||
|
output:
|
||||||
|
device: secondary
|
||||||
|
button: 4
|
||||||
|
- name: BB Bottom Row3
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TRIGGER_HAPPY14
|
||||||
|
output:
|
||||||
|
device: secondary
|
||||||
|
button: 5
|
||||||
|
|
||||||
|
- name: BB Dial1 Right
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_THUMB2
|
||||||
|
output:
|
||||||
|
device: secondary
|
||||||
|
button: 6
|
||||||
|
- name: BB Dial1 Left
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
|
button: BTN_TOP
|
||||||
|
output:
|
||||||
|
device: secondary
|
||||||
|
button: 7
|
||||||
|
- name: BB Dial2 Right
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
button: BTN_TRIGGER
|
button: BTN_TRIGGER
|
||||||
- name: Trigger2
|
|
||||||
type: combo
|
|
||||||
inputs:
|
|
||||||
- device: left-stick
|
|
||||||
button: BTN_THUMB
|
|
||||||
- device: left-stick
|
|
||||||
button: BTN_THUMB2
|
|
||||||
output:
|
output:
|
||||||
device: main
|
device: secondary
|
||||||
|
button: 8
|
||||||
|
- name: BB Dial2 Left
|
||||||
|
type: button
|
||||||
|
input:
|
||||||
|
device: button-box
|
||||||
button: BTN_THUMB
|
button: BTN_THUMB
|
||||||
|
output:
|
||||||
|
device: secondary
|
||||||
|
button: 9
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
devices:
|
devices:
|
||||||
- name: main
|
- name: primary
|
||||||
type: virtual
|
type: virtual
|
||||||
buttons: 56
|
num_buttons: 74
|
||||||
axes: 8
|
num_axes: 8
|
||||||
|
- name: secondary
|
||||||
|
type: virtual
|
||||||
|
num_buttons: 74
|
||||||
|
num_axes: 2
|
||||||
|
- name: mouse
|
||||||
|
type: virtual
|
||||||
|
num_buttons: 0
|
||||||
|
num_axes: 0
|
||||||
|
rel_axes:
|
||||||
|
- REL_WHEEL
|
||||||
- name: right-stick
|
- name: right-stick
|
||||||
type: physical
|
type: physical
|
||||||
device_name: VIRPIL Controls 20220407 R-VPC Stick MT-50CM2
|
device_name: VIRPIL Controls 20220407 R-VPC Stick MT-50CM2
|
||||||
|
|
3
docs/examples/multiple_files/modes.yml
Normal file
3
docs/examples/multiple_files/modes.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
modes:
|
||||||
|
- main
|
||||||
|
- mining
|
|
@ -1,7 +1,7 @@
|
||||||
## multi-file configuration example
|
## multi-file configuration example
|
||||||
|
|
||||||
This directory demonstrates how to split your configuration across multiple files.
|
This directory demonstrates how to split your configuration across multiple files.
|
||||||
Note that we re-define the top-level `rules` element; this is by design.
|
Note that we re-define the top-level `rules` element in two different files; this is by design.
|
||||||
|
|
||||||
It also serves as a real-world example demonstrating many of the available features of the system.
|
It also serves as a real-world example demonstrating many of the available features of the system.
|
||||||
It is based on the author's actual mappings for Star Citizen.
|
It is copied from the author's actual mappings for Star Citizen.
|
|
@ -5,16 +5,15 @@ devices:
|
||||||
device_name: Flightstick Name From evlist
|
device_name: Flightstick Name From evlist
|
||||||
- name: main
|
- name: main
|
||||||
type: virtual
|
type: virtual
|
||||||
axes: 8
|
num_axes: 8
|
||||||
buttons: 80
|
num_buttons: 80
|
||||||
- name: mouse
|
- name: mouse
|
||||||
type: virtual
|
type: virtual
|
||||||
axes: 0
|
|
||||||
buttons: 0
|
|
||||||
relative_axes:
|
relative_axes:
|
||||||
- REL_WHEEL
|
- REL_WHEEL
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
|
# Straightforward axis mapping
|
||||||
- type: axis
|
- type: axis
|
||||||
input:
|
input:
|
||||||
device: flightstick
|
device: flightstick
|
||||||
|
@ -58,6 +57,7 @@ rules:
|
||||||
device: main
|
device: main
|
||||||
button: BTN_BASE3
|
button: BTN_BASE3
|
||||||
|
|
||||||
|
# The specified axis will output button presses, and repeat them faster the more the axis is engaged.
|
||||||
- type: axis-to-button
|
- type: axis-to-button
|
||||||
# The repeat rates look backwards because they are the time between repeats in milliseconds.
|
# The repeat rates look backwards because they are the time between repeats in milliseconds.
|
||||||
# So this example will produce a button press every second at the axis' minimum value,
|
# So this example will produce a button press every second at the axis' minimum value,
|
||||||
|
@ -73,10 +73,12 @@ rules:
|
||||||
device: main
|
device: main
|
||||||
button: BTN_BASE4
|
button: BTN_BASE4
|
||||||
|
|
||||||
|
# The specified axis will output "relative" axis events, commonly used in mice. This example
|
||||||
|
# simulates a mouse scrollwheel, though only in one direction.
|
||||||
- type: axis-to-relaxis
|
- type: axis-to-relaxis
|
||||||
repeat_rate_min: 100
|
repeat_rate_min: 100
|
||||||
repeat_rate_max: 10
|
repeat_rate_max: 10
|
||||||
# This is the value to write for the axis for each repetition. If you wanted to scroll the other
|
# This is the value to emit for the axis on each repetition. If you wanted to scroll the other
|
||||||
# direction, use a negative value. It is useful to use 2 rules on the same input axis with
|
# direction, use a negative value. It is useful to use 2 rules on the same input axis with
|
||||||
# "overlapping" deadzones to scroll a mousewheel in both directions.
|
# "overlapping" deadzones to scroll a mousewheel in both directions.
|
||||||
increment: 1
|
increment: 1
|
||||||
|
|
|
@ -13,12 +13,16 @@ Each entry in `devices` must have a couple of parameters:
|
||||||
|
|
||||||
* `device_name` - The name of the device as reported by the included `evlist` command. If your device name ends with a space, use quotation marks (`""`) around the name.
|
* `device_name` - The name of the device as reported by the included `evlist` command. If your device name ends with a space, use quotation marks (`""`) around the name.
|
||||||
|
|
||||||
`virtual` devices must additionally define these parameters:
|
`virtual` devices can additionally define these parameters:
|
||||||
|
|
||||||
* `buttons` - a number between 0 and 74. Linux may not recognize buttons greater than 56.
|
* `buttons` or `num_buttons` - Either a list of explicit buttons or a number of buttons to create. (max 74 buttons) Linux-native games may not recognize all buttons created by Joyful.
|
||||||
* `axes` - a number between 0 and 8.
|
* `axes` or `num_axes` - An explicit list of `ABS_` axes or a number to create.
|
||||||
|
* `relative_axes` or `num_relative_axes` - As above, but for `REL_` axes.
|
||||||
|
|
||||||
Virtual devices can also define a `relative_axes` parameter; this must be a list of `REL_` event keycodes, and can be useful for a simulated mouse device. Some environments will only register mouse events if the device *only* supports mouse-like events, so it can be useful to isolate your `relative_axes` to their own virtual device.
|
A couple of additional notes on virtual devices:
|
||||||
|
|
||||||
|
* For all 3 of the above options, an explicit list will override the `num_` parameters if both are present.
|
||||||
|
* Some environments will only register mouse events if the device *only* supports mouse-like events, so it can be useful to isolate your `relative_axes` to their own virtual device and explicitly define the axes.
|
||||||
|
|
||||||
### Rules configuration
|
### Rules configuration
|
||||||
|
|
||||||
|
@ -33,26 +37,24 @@ All `rules` must have a `type` parameter. Valid values for this parameter are:
|
||||||
|
|
||||||
Configuration options for each rule type vary. See <examples/ruletypes.yml> for an example of each type with all options specified.
|
Configuration options for each rule type vary. See <examples/ruletypes.yml> for an example of each type with all options specified.
|
||||||
|
|
||||||
### Keycodes
|
### Event Codes
|
||||||
|
|
||||||
Keycodes are the values that identify buttons and axes. There are several ways to configure keycodes. All of them are case-insensitive.
|
Event codes are the values that identify buttons and axes. There are several ways to configure these codes. All of them are case-insensitive, so `abs_x` and `ABS_X`.
|
||||||
|
|
||||||
Ways to specify keycodes are:
|
Ways to specify event codes are:
|
||||||
|
|
||||||
* Using evdev's Keycodes. This is the best way to be absolutely certain about which axis you're referencing. You can specify these keycodes in two forms:
|
* Using evdev's identifiers. This is the best way to be absolutely certain about which axis you're referencing. You can specify these in two forms:
|
||||||
* Using the code's identifier from <https://github.com/holoplot/go-evdev/blob/master/codes.go>. e.g., `ABS_X`, `REL_WHEEL`, `BTN_TRIGGER`.
|
* Using the code's identifier from <https://github.com/holoplot/go-evdev/blob/master/codes.go>. e.g., `ABS_X`, `REL_WHEEL`, `BTN_TRIGGER`.
|
||||||
* Alternately, you can omit the `ABS_` type prefix, and Joyful will automatically add it from context. So for a button input, you can simply specify `button: trigger` instead of `BTN_TRIGGER`.
|
* Alternately, you can omit the `ABS_` type prefix, and Joyful will automatically add it from context. So for a button input, you can simply specify `button: trigger` instead of `BTN_TRIGGER`.
|
||||||
* You can use the hexadecimal value of the keycode directly, via `"0x<hex value>"`. This can be useful if you want to force a specific numeric value that isn't represented by a Linux keycode directly. Note however that not all keycodes will work. Only the first 8 axes are available, and see <internal/config/variables.go> for a list of valid button outputs. This is most useful with input configurations. **Note: You must use quotation marks around the hex value to prevent the yaml parser from automatically converting it to decimal.**
|
* You can use the hexadecimal value of the code directly, via `"0x<hex value>"`. This can be useful if you want to force a specific numeric value that isn't represented by a Linux event code directly. Note however that not all output codes will work, especially in Windows games. Therefore, this option is most useful with input configurations. **Note: You must use quotation marks around the hex value to prevent the yaml parser from automatically converting it to decimal.**
|
||||||
* For buttons, you can specify the button number, as in `button: 3`. There are 74 buttons available, and the first button is button number `0`. As a result, valid values are 0-73. Note that buttons 12-14 and buttons 55-73 may not work in all Linux-native games.
|
* For buttons, you can specify them with the above methods, or use an integer index, as in `button: 3`. There are 74 buttons available, and the first button is button number `0`. As a result, valid values are 0-73. Note that buttons 12-14 and buttons 55-73 may not work in all Linux-native games.
|
||||||
|
|
||||||
For input, you can figure out what keycodes your device is emitting by running the Linux utility `evtest`. `evtest` works well with `grep`, so if you just want to see button inputs, you can do:
|
For input, you can figure out what event codes your device is emitting by running the Linux utility `evtest`. `evtest` works well with `grep`, so if you just want to see button inputs, you can do:
|
||||||
|
|
||||||
```
|
```
|
||||||
evtest | grep BTN_
|
evtest | grep BTN_
|
||||||
```
|
```
|
||||||
|
|
||||||
The authors of this tool recognize that this is currently a pain in the ass. Easier ways to represent keycodes (as well as outputting additional keycodes) is planned for the future.
|
|
||||||
|
|
||||||
## Modes
|
## Modes
|
||||||
|
|
||||||
Modes are optional, and also have the simplest configuration. To define modes, add this to your configuration:
|
Modes are optional, and also have the simplest configuration. To define modes, add this to your configuration:
|
||||||
|
|
|
@ -23,6 +23,12 @@ func (parser *ConfigParser) CreateVirtualDevices() map[string]*evdev.InputDevice
|
||||||
}
|
}
|
||||||
|
|
||||||
name := fmt.Sprintf("joyful-%s", deviceConfig.Name)
|
name := fmt.Sprintf("joyful-%s", deviceConfig.Name)
|
||||||
|
capabilities := map[evdev.EvType][]evdev.EvCode{
|
||||||
|
evdev.EV_KEY: makeButtons(deviceConfig.NumButtons, deviceConfig.Buttons),
|
||||||
|
evdev.EV_ABS: makeAxes(deviceConfig.NumAxes, deviceConfig.Axes),
|
||||||
|
evdev.EV_REL: makeRelativeAxes(deviceConfig.NumRelativeAxes, deviceConfig.RelativeAxes),
|
||||||
|
}
|
||||||
|
|
||||||
device, err := evdev.CreateDevice(
|
device, err := evdev.CreateDevice(
|
||||||
name,
|
name,
|
||||||
// TODO: who knows what these should actually be
|
// TODO: who knows what these should actually be
|
||||||
|
@ -32,11 +38,7 @@ func (parser *ConfigParser) CreateVirtualDevices() map[string]*evdev.InputDevice
|
||||||
Product: 0x0816,
|
Product: 0x0816,
|
||||||
Version: 1,
|
Version: 1,
|
||||||
},
|
},
|
||||||
map[evdev.EvType][]evdev.EvCode{
|
capabilities,
|
||||||
evdev.EV_KEY: makeButtons(int(deviceConfig.Buttons)),
|
|
||||||
evdev.EV_ABS: makeAxes(int(deviceConfig.Axes)),
|
|
||||||
evdev.EV_REL: makeRelativeAxes(deviceConfig.RelativeAxes),
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -45,7 +47,13 @@ func (parser *ConfigParser) CreateVirtualDevices() map[string]*evdev.InputDevice
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceMap[deviceConfig.Name] = device
|
deviceMap[deviceConfig.Name] = device
|
||||||
logger.Log(fmt.Sprintf("Created virtual device '%s'", name))
|
logger.Log(fmt.Sprintf(
|
||||||
|
"Created virtual device '%s' with %d buttons, %d axes, and %d relative axes",
|
||||||
|
name,
|
||||||
|
len(capabilities[evdev.EV_KEY]),
|
||||||
|
len(capabilities[evdev.EV_ABS]),
|
||||||
|
len(capabilities[evdev.EV_REL]),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
return deviceMap
|
return deviceMap
|
||||||
|
@ -81,12 +89,31 @@ func (parser *ConfigParser) ConnectPhysicalDevices() map[string]*evdev.InputDevi
|
||||||
return deviceMap
|
return deviceMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeButtons(numButtons int) []evdev.EvCode {
|
// TODO: these functions have a lot of duplication; we need to figure out how to refactor it cleanly
|
||||||
|
// without losing logging context...
|
||||||
|
func makeButtons(numButtons int, buttonList []string) []evdev.EvCode {
|
||||||
|
if numButtons > 0 && len(buttonList) > 0 {
|
||||||
|
logger.Log("'num_buttons' and 'buttons' both specified, ignoring 'num_buttons'")
|
||||||
|
}
|
||||||
|
|
||||||
if numButtons > VirtualDeviceMaxButtons {
|
if numButtons > VirtualDeviceMaxButtons {
|
||||||
numButtons = VirtualDeviceMaxButtons
|
numButtons = VirtualDeviceMaxButtons
|
||||||
logger.Logf("Limiting virtual device buttons to %d", VirtualDeviceMaxButtons)
|
logger.Logf("Limiting virtual device buttons to %d", VirtualDeviceMaxButtons)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(buttonList) > 0 {
|
||||||
|
buttons := make([]evdev.EvCode, 0, len(buttonList))
|
||||||
|
for _, codeStr := range buttonList {
|
||||||
|
code, err := parseCode(codeStr, "BTN")
|
||||||
|
if err != nil {
|
||||||
|
logger.LogError(err, "Failed to create button, skipping")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
buttons = append(buttons, code)
|
||||||
|
}
|
||||||
|
return buttons
|
||||||
|
}
|
||||||
|
|
||||||
buttons := make([]evdev.EvCode, numButtons)
|
buttons := make([]evdev.EvCode, numButtons)
|
||||||
|
|
||||||
startCode := 0x120
|
startCode := 0x120
|
||||||
|
@ -104,7 +131,24 @@ func makeButtons(numButtons int) []evdev.EvCode {
|
||||||
return buttons
|
return buttons
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeAxes(numAxes int) []evdev.EvCode {
|
func makeAxes(numAxes int, axisList []string) []evdev.EvCode {
|
||||||
|
if numAxes > 0 && len(axisList) > 0 {
|
||||||
|
logger.Log("'num_axes' and 'axes' both specified, ignoring 'num_axes'")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(axisList) > 0 {
|
||||||
|
axes := make([]evdev.EvCode, 0, len(axisList))
|
||||||
|
for _, codeStr := range axisList {
|
||||||
|
code, err := parseCode(codeStr, "ABS")
|
||||||
|
if err != nil {
|
||||||
|
logger.LogError(err, "Failed to create axis, skipping")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
axes = append(axes, code)
|
||||||
|
}
|
||||||
|
return axes
|
||||||
|
}
|
||||||
|
|
||||||
if numAxes > 8 {
|
if numAxes > 8 {
|
||||||
numAxes = 8
|
numAxes = 8
|
||||||
logger.Log("Limiting virtual device axes to 8")
|
logger.Log("Limiting virtual device axes to 8")
|
||||||
|
@ -118,19 +162,33 @@ func makeAxes(numAxes int) []evdev.EvCode {
|
||||||
return axes
|
return axes
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeRelativeAxes(axes []string) []evdev.EvCode {
|
func makeRelativeAxes(numAxes int, axisList []string) []evdev.EvCode {
|
||||||
codes := make([]evdev.EvCode, 0)
|
if numAxes > 0 && len(axisList) > 0 {
|
||||||
|
logger.Log("'num_rel_axes' and 'rel_axes' both specified, ignoring 'num_rel_axes'")
|
||||||
for _, axis := range axes {
|
|
||||||
code, ok := evdev.RELFromString[axis]
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
logger.Logf("Relative axis '%s' invalid. Skipping.", axis)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
codes = append(codes, code)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return codes
|
if len(axisList) > 0 {
|
||||||
|
axes := make([]evdev.EvCode, 0, len(axisList))
|
||||||
|
for _, codeStr := range axisList {
|
||||||
|
code, err := parseCode(codeStr, "REL")
|
||||||
|
if err != nil {
|
||||||
|
logger.LogError(err, "Failed to create axis, skipping")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
axes = append(axes, code)
|
||||||
|
}
|
||||||
|
return axes
|
||||||
|
}
|
||||||
|
|
||||||
|
if numAxes > 10 {
|
||||||
|
numAxes = 10
|
||||||
|
logger.Log("Limiting virtual device relative axes to 10")
|
||||||
|
}
|
||||||
|
|
||||||
|
axes := make([]evdev.EvCode, numAxes)
|
||||||
|
for i := 0; i < numAxes; i++ {
|
||||||
|
axes[i] = evdev.EvCode(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return axes
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,38 @@ func TestRunnerDevicesConfig(t *testing.T) {
|
||||||
suite.Run(t, new(DevicesConfigTests))
|
suite.Run(t, new(DevicesConfigTests))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *DevicesConfigTests) TestMakeButtons() {
|
||||||
|
t.Run("Maximum buttons", func() {
|
||||||
|
buttons := makeButtons(VirtualDeviceMaxButtons, []string{})
|
||||||
|
t.Equal(VirtualDeviceMaxButtons, len(buttons))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Truncated buttons", func() {
|
||||||
|
buttons := makeButtons(VirtualDeviceMaxButtons+1, []string{})
|
||||||
|
t.Equal(VirtualDeviceMaxButtons, len(buttons))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("16 buttons", func() {
|
||||||
|
buttons := makeButtons(16, []string{})
|
||||||
|
t.Equal(16, len(buttons))
|
||||||
|
t.Contains(buttons, evdev.EvCode(evdev.BTN_DEAD))
|
||||||
|
t.NotContains(buttons, evdev.EvCode(evdev.BTN_TRIGGER_HAPPY))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Explicit buttons", func() {
|
||||||
|
buttonConfig := []string{"BTN_THUMB", "top", "btn_top2", "0x2fe", "0x300", "15"}
|
||||||
|
buttons := makeButtons(0, buttonConfig)
|
||||||
|
t.Equal(len(buttonConfig), len(buttons))
|
||||||
|
t.Contains(buttons, evdev.EvCode(0x2fe))
|
||||||
|
t.Contains(buttons, evdev.EvCode(0x300))
|
||||||
|
t.Contains(buttons, evdev.EvCode(evdev.BTN_TOP))
|
||||||
|
t.Contains(buttons, evdev.EvCode(evdev.BTN_DEAD))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (t *DevicesConfigTests) TestMakeAxes() {
|
func (t *DevicesConfigTests) TestMakeAxes() {
|
||||||
t.Run("8 axes", func() {
|
t.Run("8 axes", func() {
|
||||||
axes := makeAxes(8)
|
axes := makeAxes(8, []string{})
|
||||||
t.Equal(8, len(axes))
|
t.Equal(8, len(axes))
|
||||||
t.Contains(axes, evdev.EvCode(evdev.ABS_X))
|
t.Contains(axes, evdev.EvCode(evdev.ABS_X))
|
||||||
t.Contains(axes, evdev.EvCode(evdev.ABS_Y))
|
t.Contains(axes, evdev.EvCode(evdev.ABS_Y))
|
||||||
|
@ -30,34 +59,61 @@ func (t *DevicesConfigTests) TestMakeAxes() {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("9 axes is truncated", func() {
|
t.Run("9 axes is truncated", func() {
|
||||||
axes := makeAxes(9)
|
axes := makeAxes(9, []string{})
|
||||||
t.Equal(8, len(axes))
|
t.Equal(8, len(axes))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("3 axes", func() {
|
t.Run("3 axes", func() {
|
||||||
axes := makeAxes(3)
|
axes := makeAxes(3, []string{})
|
||||||
t.Equal(3, len(axes))
|
t.Equal(3, len(axes))
|
||||||
t.Contains(axes, evdev.EvCode(evdev.ABS_X))
|
t.Contains(axes, evdev.EvCode(evdev.ABS_X))
|
||||||
t.Contains(axes, evdev.EvCode(evdev.ABS_Y))
|
t.Contains(axes, evdev.EvCode(evdev.ABS_Y))
|
||||||
t.Contains(axes, evdev.EvCode(evdev.ABS_Z))
|
t.Contains(axes, evdev.EvCode(evdev.ABS_Z))
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
func (t *DevicesConfigTests) TestMakeButtons() {
|
t.Run("4 explicit axis", func() {
|
||||||
t.Run("Maximum buttons", func() {
|
axes := makeAxes(0, []string{"x", "y", "throttle", "rudder"})
|
||||||
buttons := makeButtons(VirtualDeviceMaxButtons)
|
t.Equal(4, len(axes))
|
||||||
t.Equal(VirtualDeviceMaxButtons, len(buttons))
|
t.Contains(axes, evdev.EvCode(evdev.ABS_X))
|
||||||
})
|
t.Contains(axes, evdev.EvCode(evdev.ABS_Y))
|
||||||
|
t.Contains(axes, evdev.EvCode(evdev.ABS_THROTTLE))
|
||||||
t.Run("Truncated buttons", func() {
|
t.Contains(axes, evdev.EvCode(evdev.ABS_RUDDER))
|
||||||
buttons := makeButtons(VirtualDeviceMaxButtons + 1)
|
})
|
||||||
t.Equal(VirtualDeviceMaxButtons, len(buttons))
|
}
|
||||||
})
|
|
||||||
|
func (t *DevicesConfigTests) TestMakeRelativeAxes() {
|
||||||
t.Run("16 buttons", func() {
|
t.Run("10 axes", func() {
|
||||||
buttons := makeButtons(16)
|
axes := makeRelativeAxes(10, []string{})
|
||||||
t.Equal(16, len(buttons))
|
t.Equal(10, len(axes))
|
||||||
t.Contains(buttons, evdev.EvCode(evdev.BTN_DEAD))
|
t.Contains(axes, evdev.EvCode(evdev.REL_X))
|
||||||
t.NotContains(buttons, evdev.EvCode(evdev.BTN_TRIGGER_HAPPY))
|
t.Contains(axes, evdev.EvCode(evdev.REL_MISC))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("11 axes", func() {
|
||||||
|
axes := makeRelativeAxes(11, []string{})
|
||||||
|
t.Equal(10, len(axes))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("3 axes", func() {
|
||||||
|
axes := makeRelativeAxes(3, []string{})
|
||||||
|
t.Equal(3, len(axes))
|
||||||
|
t.Contains(axes, evdev.EvCode(evdev.REL_X))
|
||||||
|
t.Contains(axes, evdev.EvCode(evdev.REL_Y))
|
||||||
|
t.Contains(axes, evdev.EvCode(evdev.REL_Z))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("1 explicit axis", func() {
|
||||||
|
axes := makeRelativeAxes(0, []string{"wheel"})
|
||||||
|
t.Equal(1, len(axes))
|
||||||
|
t.Contains(axes, evdev.EvCode(evdev.REL_WHEEL))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("4 explicit axis", func() {
|
||||||
|
axes := makeRelativeAxes(0, []string{"x", "y", "wheel", "hwheel"})
|
||||||
|
t.Equal(4, len(axes))
|
||||||
|
t.Contains(axes, evdev.EvCode(evdev.REL_X))
|
||||||
|
t.Contains(axes, evdev.EvCode(evdev.REL_Y))
|
||||||
|
t.Contains(axes, evdev.EvCode(evdev.REL_WHEEL))
|
||||||
|
t.Contains(axes, evdev.EvCode(evdev.REL_HWHEEL))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,16 @@ type Config struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeviceConfig struct {
|
type DeviceConfig struct {
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
Type string `yaml:"type"`
|
Type string `yaml:"type"`
|
||||||
DeviceName string `yaml:"device_name,omitempty"`
|
DeviceName string `yaml:"device_name,omitempty"`
|
||||||
Uuid string `yaml:"uuid,omitempty"`
|
Uuid string `yaml:"uuid,omitempty"`
|
||||||
Buttons int `yaml:"buttons,omitempty"`
|
NumButtons int `yaml:"num_buttons,omitempty"`
|
||||||
Axes int `yaml:"axes,omitempty"`
|
NumAxes int `yaml:"num_axes,omitempty"`
|
||||||
RelativeAxes []string `yaml:"rel_axes,omitempty"`
|
NumRelativeAxes int `yaml:"num_rel_axes"`
|
||||||
|
Buttons []string `yaml:"buttons,omitempty"`
|
||||||
|
Axes []string `yaml:"axes,omitempty"`
|
||||||
|
RelativeAxes []string `yaml:"rel_axes,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RuleConfig struct {
|
type RuleConfig struct {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue