From 4ebcbb4dc9fba6d32d208e1532bc39a28e721d6c Mon Sep 17 00:00:00 2001 From: Anna Rose Wiggins Date: Tue, 15 Jul 2025 16:32:02 -0400 Subject: [PATCH] Update documentation. --- .../examples}/multiple_files/axes.yml | 0 .../examples}/multiple_files/buttons.yml | 0 .../examples}/multiple_files/devices.yml | 0 .../examples}/multiple_files/readme.md | 0 docs/examples/readme.md | 77 ++++++++++++++++ docs/examples/ruletypes.yml | 90 +++++++++++++++++++ examples/all_types.yml | 45 ---------- readme.md | 81 +++-------------- 8 files changed, 181 insertions(+), 112 deletions(-) rename {examples => docs/examples}/multiple_files/axes.yml (100%) rename {examples => docs/examples}/multiple_files/buttons.yml (100%) rename {examples => docs/examples}/multiple_files/devices.yml (100%) rename {examples => docs/examples}/multiple_files/readme.md (100%) create mode 100644 docs/examples/readme.md create mode 100644 docs/examples/ruletypes.yml delete mode 100644 examples/all_types.yml diff --git a/examples/multiple_files/axes.yml b/docs/examples/multiple_files/axes.yml similarity index 100% rename from examples/multiple_files/axes.yml rename to docs/examples/multiple_files/axes.yml diff --git a/examples/multiple_files/buttons.yml b/docs/examples/multiple_files/buttons.yml similarity index 100% rename from examples/multiple_files/buttons.yml rename to docs/examples/multiple_files/buttons.yml diff --git a/examples/multiple_files/devices.yml b/docs/examples/multiple_files/devices.yml similarity index 100% rename from examples/multiple_files/devices.yml rename to docs/examples/multiple_files/devices.yml diff --git a/examples/multiple_files/readme.md b/docs/examples/multiple_files/readme.md similarity index 100% rename from examples/multiple_files/readme.md rename to docs/examples/multiple_files/readme.md diff --git a/docs/examples/readme.md b/docs/examples/readme.md new file mode 100644 index 0000000..a38bd89 --- /dev/null +++ b/docs/examples/readme.md @@ -0,0 +1,77 @@ +# Joyful Configuration + +Configuration is divided into three sections: `devices`, `modes`, and `rules`. Each yaml file can have any number of these sections; joyful will combine the configuration from all files at runtime. + +### Device configuration + +Each entry in `devices` must have a couple of parameters: + +* `name` - This is an identifier that your rules will use to refer to the device. It is recommended to avoid spaces or special characters. +* `type` - Should be `physical` for an input device, and `virtual` for an output device. + +`physical` devices must additionally define these 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. + +`virtual` devices must additionally define these parameters: + +* `buttons` - a number between 0 and 80. Linux may not recognize buttons greater than 56. +* `axes` - a number between 0 and 8. + +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. + +### Rules configuration + +All `rules` must have a `type` parameter. Valid values for this parameter are: + +* `button` - a single button mapping +* `button-combo` - multiple input buttons mapped to a single output. The output event will trigger when all the input conditions are met. +* `button-latched` - a single button mapped to a single output, but each time the input is pressed, the output will toggle. +* `axis` - a simple axis mapping +* `axis-to-button` - causes an axis input to produce a button output. This can be repeated with variable speed proportional to the axis' input value +* `axis-to-relaxis` - like axis-to-button, but produces a "relative axis" output value. This is useful for simulating mouse scrollwheel and movement events. + +Configuration options for each rule type vary. See for an example of each type with all options specified. + +### Keycodes + +Currently, there is only one way to specify a button or axis: using evdev's Keycodes. These look like `ABS_X` for axes and `BTN_TRIGGER` +for buttons. See for a full list of these codes, but note that Joyful's virtual devices currently only uses a subset. Specifically, the axes from `ABS_X` to `ABS_RUDDER`, and the buttons from `BTN_JOYSTICK` to `BTN_DEAD`, as well as all of the `BTN_TRIGGER_HAPPY*` codes. + +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: + +``` +evtest | grep KEY_ +``` + +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 are optional, and also have the simplest configuration. To define modes, add this to your configuration: + +``` +modes: + - mode1 + - mode2 + - mode3 +``` + +The first mode that Joyful reads will be the mode that Joyful starts up in. For that reason, it is recommended to define all your modes in the same file. + +Once modes are defined, each rule may specify a `modes` parameter. That rule will only be processed if a matching mode is active. If a rule omits the `modes` parameter, it will be processed in all modes. + +For example: + +``` +rules: + - name: Test Rule 1 # This rule will be used when we are in mode1 or mode2 + modes: + - mode1 + - mode2 + # define the rest of the rule here... + - name: Test Rule 2 # This rule will be used when we are in mode3 + modes: + - mode3 + # define the rest of the rule here... +``` diff --git a/docs/examples/ruletypes.yml b/docs/examples/ruletypes.yml new file mode 100644 index 0000000..9f63ca4 --- /dev/null +++ b/docs/examples/ruletypes.yml @@ -0,0 +1,90 @@ +# +devices: + - name: flightstick + type: physical + device_name: Flightstick Name From evlist + - name: main + type: virtual + axes: 8 + buttons: 80 + - name: mouse + type: virtual + axes: 0 + buttons: 0 + relative_axes: + - REL_WHEEL + +rules: + - type: axis + input: + device: flightstick + # To find reasonable values for your device's deadzones, use the evtest command + deadzone_start: 28000 + deadzone_end: 30000 + inverted: false + axis: ABS_X + output: + device: main + axis: ABS_X + + # Straightforward button mapping + - type: button + input: + device: flightstick + button: BTN_BASE2 + inverted: false + output: + device: main + button: BTN_BASE2 + + # A combo rule - BTN_TRIGGER will be active while BTN_THUMB and BTN_THUMB2 are pressed. + - type: button-combo + inputs: + - device: flightstick + button: BTN_THUMB + - device: flightstick + button: BTN_THUMB2 + output: + device: main + button: BTN_TRIGGER + + # A latched rule - the virtual BTN_BASE3 will toggle each time the physical BTN_BASE3 is pressed. + # This way you can "hold down" the button without having to actually hold it. + - type: button-latched + input: + device: flightstick + button: BTN_BASE3 + output: + device: main + button: BTN_BASE3 + + - type: axis-to-button + # 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, + # and a button press every 10 milliseconds at the axis' maximum value. + repeat_rate_min: 1000 + repeat_rate_max: 10 + input: + device: flightstick + axis: ABS_RY # This axis commonly represents thumbsticks + deadzone_start: 0 + deadzone_end: 30000 + output: + device: main + button: BTN_BASE4 + + - type: axis-to-relaxis + repeat_rate_min: 100 + repeat_rate_max: 10 + # This is the value to write for the axis for 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 + # "overlapping" deadzones to scroll a mousewheel in both directions. + increment: 1 + input: + device: flightstick + axis: ABS_Z + deadzone_start: 0 + deadzone_end: 500 + output: + device: mouse + button: REL_WHEEL \ No newline at end of file diff --git a/examples/all_types.yml b/examples/all_types.yml deleted file mode 100644 index a7b0373..0000000 --- a/examples/all_types.yml +++ /dev/null @@ -1,45 +0,0 @@ -# -devices: - - name: flightstick - type: physical - device_name: Flightstick Name From evlist - - name: main - type: virtual - axes: 8 - buttons: 80 -rules: - # Currently axes can only be simple mappings - - type: simple - input: - device: flightstick - axis: ABS_X - output: - device: main - axis: ABS_X - # Simple mappings also work for buttons - - type: simple - input: - device: flightstick - button: BTN_BASE2 - inverted: false - output: - device: main - button: BTN_BASE2 - # A combo rule - BTN_TRIGGER will be active while BTN_THUMB and BTN_THUMB2 are pressed. - - type: combo - inputs: - - device: flightstick - button: BTN_THUMB - - device: flightstick - button: BTN_THUMB2 - output: - device: main - button: BTN_TRIGGER - # A latched rule - the virtual BTN_BASE3 will toggle each time the physical BTN_BASE3 is pressed. - - type: latched - input: - device: flightstick - button: BTN_BASE3 - output: - device: main - button: BTN_BASE3 \ No newline at end of file diff --git a/readme.md b/readme.md index 9bc6b3f..4ff591d 100644 --- a/readme.md +++ b/readme.md @@ -1,17 +1,10 @@ -# Joyful - virtual joystick remapper for Linux +# Joyful - joystick remapper for Linux -Joyful is a Linux tool for creating virtual joysticks and mapping inputs from various -real devices to them. This is useful when playing games that don't support multiple joysticks, -or for games that don't handle devices changing order (like Star Citizen). +Joyful is a Linux tool for mapping inputs from various joystick-like devices to "virtual" output devices. This is useful when playing games that don't support multiple joysticks, or for games that don't gracefully handle devices changing order (e.g., Star Citizen). -Perhaps more significantly, Joyful allows you to map combinations of physical inputs to a single output, -as well as creating other complex scenarios. Want a single button press to simultaneously produce multiple outputs? -Joyful can do that! +Joyful also allows you to map combinations of physical inputs to a single output, as well as creating other complex scenarios. -Are you a Linux gamer who misses the features of Joystick Gremlin? Wish you could map combo inputs, -or combine your input devices into one virtual device? Are you ok with writing a bunch of YAML? - -Joyful might be the tool for you. +Joyful is ideal for Linux gamers who enjoy space and flight sims and miss the features of Joystick Gremlin. ## Features @@ -20,73 +13,27 @@ Joyful might be the tool for you. * Create virtual devices with up to 8 axes and 56 buttons. * Make simple 1:1 mappings of buttons and axes: Button1 -> VirtualButtonA * Make combination mappings: Button1 + Button2 -> VirtualButtonA -* Multiple modes with per-mode behavior. +* Define multiple modes with per-mode behavior. +* "Split" axis mapping: map sections of an axis to different outputs. +* Configure per-mapping configurable deadzones for axes. +* Axis -> button mapping with optional "proportional" repeat speed (i.e. repeat faster as the axis is engaged further) +* Axis -> Relative Axis mapping, for converting a joystick axis to mouse movement and scrollwheel events. ### Future Features - try them at an unspecified point in the future! -* Partial axis mapping: map sections of an axis to different outputs. -* Highly configurable deadzones * Macros - have a single input produce a sequence of button presses with configurable pauses. * Sequence combos - Button1, Button2, Button3 -> VirtualButtonA -* Proportional axis to button mapping; repeatedly trigger a button with an axis, with frequency controlled by the axis value * More ways to specify keycodes +* Output keyboard button presses +* Input and output from gamepad-like devices. ## Configuration -Configuration is currently done via hand-written YAML files in `~/.config/joyful/`. Joyful will read every -yaml file in this directory and combine them, so you can split your configuration up however you like. +Configuration is handled via YAML files in `~/.config/joyful/`. Joyful will read every yaml file in this directory and combine them, so you can split your configuration up however you like. -Configuration is divided into three sections: `devices`, `modes`, and `rules`. See the `examples/` directory for concrete examples. -Select options are explained in detail below. - -### Device configuration - -Each entry in `devices` must have a couple of fields: - -* `name` - This is an identifier that your rules will use to refer to the device. It is recommended to avoid spaces or special characters. -* `type` - Should be `physical` for an input device, and `virtual` for an output device. - -`physical` devices must additionally define these fields: - -* `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 fields: - -* `buttons` - a number between 0 and 80. Linux may not recognize buttons greater than 56. -* `axes` - a number between 0 and 8. - -### Rules configuration - -All `rules` must have a `type` field. Valid values for this field are: - -* `simple` - a single input mapped to a single output -* `combo` - multiple inputs mapped to a single output. The output event will trigger when all the input conditions are met. -* `latched` - a single input mapped to a single output, but each time the input is pressed, the output will toggle. - -Configuration options for each type vary. See for an example of each type with all options specified. - -### Keycodes - -Currently, there is only one way to specify a button or axis: using evdev's Keycodes. These look like `ABS_X` for axes and `BTN_TRIGGER` -for buttons. See for a full list of these codes, but note that Joyful's virtual devices currently only uses a subset. Specifically, the axes from `ABS_X` to `ABS_RUDDER`, and the buttons from `BTN_JOYSTICK` to `BTN_DEAD`, as well as all of the `BTN_TRIGGER_HAPPY*` codes. - -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: - -``` -evtest | grep -``` - -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. - -We don't have the cycles to develop tool-assisted configuration, but pull requests (or separate projects that produce compatible YAML) are very welcome! - -### Modes - -The top-level `modes` field is a simple list of strings, defining the different modes available to rules. The initial mode is always -the first one in the list. (TODO) - -All rules can have a `modes` field that is a list of strings. If no `modes` field is present, the rule will be active in all modes. +A configuration guide and examples can be found in the `docs/` directory. +Configuration can be fairly complicated and repetitive. If anyone wants to create a graphical interface to configure Joyful, we would love to link to it here. ## Technical details