diff options
author | aszlig <aszlig@redmoonstudios.org> | 2016-01-26 04:09:46 +0100 |
---|---|---|
committer | aszlig <aszlig@redmoonstudios.org> | 2016-01-26 04:09:46 +0100 |
commit | 1515bae55bfd6c21d6277883826a88cc12cce7d7 (patch) | |
tree | 99a5bc0ad94a58c57a0afa2043f3813ed54bd4c7 /modules/hardware/gamecontroller.nix | |
parent | 0353b8b3ffcbaa102d36fa7e8f2bb218a1374820 (diff) |
modules: Add a new gamecontroller module
This module is for declaratively specifying SDL_GAMECONTROLLERCONFIG, an environment variable used by SDL 2 to map arbitrary controllers to that of an XBox reference controller. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Diffstat (limited to 'modules/hardware/gamecontroller.nix')
-rw-r--r-- | modules/hardware/gamecontroller.nix | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/modules/hardware/gamecontroller.nix b/modules/hardware/gamecontroller.nix new file mode 100644 index 00000000..5cfe9d16 --- /dev/null +++ b/modules/hardware/gamecontroller.nix @@ -0,0 +1,109 @@ +{ config, lib, ... }: + +with lib; + +let + mappingType = (types.addCheck types.str (val: let + pattern = "[ab][0-9]+|h[0-9]+\.[0-9]+"; + in builtins.match pattern val == [])) // { + name = "aI (axis), bI (button) or hI.M (hat) where I=index, M=mask"; + }; + + mkAssignmentOption = example: name: description: mkOption { + type = types.nullOr mappingType; + default = null; + inherit example; + description = "Assignment for ${description}."; + }; + + mkAxisOption = mkAssignmentOption "a0"; + mkButtonOption = mkAssignmentOption "b0"; + + axes = { + leftx = "left stick X axis"; + lefty = "left stick Y axis"; + rightx = "right stick X axis"; + righty = "right stick Y axis"; + lefttrigger = "left trigger"; + righttrigger = "right trigger"; + }; + + buttons = { + a = "A button (down)"; + b = "B button (right)"; + x = "X button (left)"; + y = "Y button (up)"; + back = "XBox <literal>back</literal> button"; + guide = "XBox <literal>guide</literal> button"; + start = "<literal>start</literal> button"; + leftstick = "pressing the left stick"; + rightstick = "pressing the right stick"; + leftshoulder = "left shoulder/bumper button"; + rightshoulder = "right shoulder/bumper button"; + dpup = "directional pad up"; + dpdown = "directional pad down"; + dpleft = "directional pad left"; + dpright = "directional pad right"; + }; + + gcSubModule = { name, ... }: { + options = { + name = mkOption { + type = types.str; + default = name; + description = '' + The name of this controller, doesn't have special meaning and is only + there to make it easier to dinguish various mappings. + ''; + }; + + guid = mkOption { + type = types.uniq types.str; + default = name; + description = '' + The SDL2 GUID to uniquely identify this controller. + + Use <literal>vuizvui.list-gamecontrollers</literal> to list them. + ''; + }; + + mapping = mapAttrs mkAxisOption axes // mapAttrs mkButtonOption buttons; + }; + }; + + mkGCLine = const (cfg: let + validMappings = attrNames axes ++ attrNames buttons; + mkMappingVal = name: let + val = cfg.mapping.${name} or null; + in if val == null then null else "${name}:${val}"; + attrs = [ cfg.guid cfg.name "platform:Linux" ] + ++ remove null (map mkMappingVal validMappings); + in concatStringsSep "," attrs); + + controllers = mapAttrsToList mkGCLine config.vuizvui.hardware.gameController; + controllerConfig = concatStringsSep "\n" controllers; + +in { + options.vuizvui.hardware.gameController = mkOption { + type = types.attrsOf (types.submodule gcSubModule); + default = {}; + description = let + url = + "https://upload.wikimedia.org/wikipedia/commons/2/2c/360_controller.svg"; + in '' + A mapping of the game controllers to use with SDL2 games. + + The mapping is always based on the XBox reference controller, so even if + you don't use an XBox controller, you still have to map your keys + according to this layout: + + <link xlink:href="${ + "https://upload.wikimedia.org/wikipedia/commons/2/2c/360_controller.svg" + }"/> + ''; + }; + + config = mkIf (config.vuizvui.hardware.gameController != {}) { + environment.sessionVariables.SDL_GAMECONTROLLERCONFIG = controllerConfig; + }; +} |