diff --git a/examples/devices.yml b/examples/devices.yml new file mode 100644 index 0000000..16bb4d6 --- /dev/null +++ b/examples/devices.yml @@ -0,0 +1,11 @@ +devices: + - name: main + type: virtual + buttons: 56 + axes: 8 + - name: right-stick + type: physical + device_name: VIRPIL Controls 20220407 R-VPC Stick MT-50CM2 + - name: left-stick + type: physical + device_name: VIRPIL Controls 20220407 L-VPC Stick MT-50CM2 diff --git a/examples/rules.yml b/examples/rules.yml new file mode 100644 index 0000000..97c3469 --- /dev/null +++ b/examples/rules.yml @@ -0,0 +1,70 @@ +rules: + # A simple 1:1 mapping of 2 inputs + - name: basic mapping + type: simple + input: + device: right-stick + button: BTN_BASE6 + output: + device: main + button: BTN_BASE6 + # A couple of axis mappings + - name: x axis + type: simple + input: + device: right-stick + axis: ABS_X + output: + device: main + axis: ABS_X + - name: y axis + type: simple + input: + device: right-stick + axis: ABS_Y + output: + device: main + axis: ABS_Y + # 3-stage trigger for a VPC Constellation Alpha + # This only sends a trigger input when the + # flip trigger is pulled all the way in *and* the inner trigger + # is activated + - name: 3 stage trigger + type: combo + inputs: + - device: right-stick + button: BTN_TRIGGER + inverted: true + - device: right-stick + button: BTN_THUMB + - device: right-stick + button: BTN_THUMB2 + output: + device: main + button: BTN_TRIGGER + # Of course, BTN_TRIGGER above is unnecessary, because on the Constellation Alpha + # it's impossible to press BTN_THUMB without disabling BTN_TRIGGER. So this is a + # simpler form of the same rule for the left stick + - name: 2 stage trigger + type: combo + inputs: + - device: left-stick + button: BTN_THUMB + - device: left-stick + button: BTN_THUMB2 + output: + device: main + button: BTN_THUMB + # You can use the same input in multiple rules. Be careful with this! + # In this example we use the same 2-stage guard, but trigger an additional output + # when the final stage of the VPC's trigger is depressed + - name: alternate 2 stage trigger + type: combo + inputs: + - device: left-stick + button: BTN_THUMB + - device: left-stick + button: BTN_TOP + output: + device: main + button: BTN_THUMB2 diff --git a/internal/config/rules.go b/internal/config/rules.go index 8078a59..90e0ca4 100644 --- a/internal/config/rules.go +++ b/internal/config/rules.go @@ -21,6 +21,7 @@ func makeSimpleRule(ruleConfig RuleConfig, pDevs map[string]*evdev.InputDevice, return &mappingrules.SimpleMappingRule{ Input: input, Output: output, + Name: ruleConfig.Name, }, nil } @@ -42,6 +43,7 @@ func makeComboRule(ruleConfig RuleConfig, pDevs map[string]*evdev.InputDevice, v return &mappingrules.ComboMappingRule{ Inputs: inputs, Output: output, + Name: ruleConfig.Name, }, nil } @@ -61,6 +63,7 @@ func makeRuleTarget(targetConfig RuleTargetConfig, devs map[string]*evdev.InputD } ruleTarget.Type = eventType ruleTarget.Code = eventCode + ruleTarget.Inverted = targetConfig.Inverted return ruleTarget, nil } diff --git a/internal/logger/logger.go b/internal/logger/logger.go index 2d3d3f6..70f7f8b 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -10,7 +10,7 @@ func Log(msg string) { } func Logf(msg string, params ...interface{}) { - fmt.Printf(msg, params...) + fmt.Printf(msg+"\n", params...) } func LogError(err error, msg string) { diff --git a/internal/mappingrules/matching.go b/internal/mappingrules/matching.go index ab96f9a..6c1cad6 100644 --- a/internal/mappingrules/matching.go +++ b/internal/mappingrules/matching.go @@ -27,16 +27,16 @@ func valueFromTarget(rule RuleTarget, event *evdev.InputEvent) int32 { value = 0 } case evdev.EV_ABS: - // TODO: how would we invert axes? + logger.Logf("STUB: Inverting axes is not yet implemented.") default: - logger.Logf("Inverted rule for unknown event type '%d'. Not inverting value\n", event.Type) + logger.Logf("Inverted rule for unknown event type '%d'. Not inverting value", event.Type) } } return value } -func (rule SimpleMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev.InputEvent) *evdev.InputEvent { +func (rule *SimpleMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev.InputEvent) *evdev.InputEvent { if device != rule.Input.Device || event.Code != rule.Input.Code { return nil @@ -45,7 +45,7 @@ func (rule SimpleMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev return eventFromTarget(rule.Output, valueFromTarget(rule.Input, event)) } -func (rule ComboMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev.InputEvent) *evdev.InputEvent { +func (rule *ComboMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev.InputEvent) *evdev.InputEvent { // Check each of the inputs, and if we find a match, proceed var match *RuleTarget for _, input := range rule.Inputs { @@ -63,12 +63,13 @@ func (rule ComboMappingRule) MatchEvent(device *evdev.InputDevice, event *evdev. inputValue := valueFromTarget(*match, event) oldState := rule.State if inputValue == 0 { - rule.State-- + rule.State = max(rule.State-1, 0) } if inputValue == 1 { rule.State++ } targetState := len(rule.Inputs) + if oldState == targetState-1 && rule.State == targetState { return eventFromTarget(rule.Output, 1) } diff --git a/internal/mappingrules/types.go b/internal/mappingrules/types.go index b71bbfb..1589a54 100644 --- a/internal/mappingrules/types.go +++ b/internal/mappingrules/types.go @@ -10,12 +10,14 @@ type MappingRule interface { type SimpleMappingRule struct { Input RuleTarget Output RuleTarget + Name string } // A Combo Mapping Rule can require multiple physical button presses for a single output button type ComboMappingRule struct { Inputs []RuleTarget Output RuleTarget + Name string State int }