diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index c0d30b53..91760b70 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -180,6 +180,9 @@
/modules/programs/senpai.nix @malte-v
+/modules/programs/sm64ex.nix @ivarwithoutbones
+/tests/modules/programs/sm64ex @ivarwithoutbones
+
/modules/programs/ssh.nix @rycee
/modules/programs/starship.nix @marsam
diff --git a/modules/misc/news.nix b/modules/misc/news.nix
index 6e88b624..b4eec3bb 100644
--- a/modules/misc/news.nix
+++ b/modules/misc/news.nix
@@ -2118,6 +2118,13 @@ in
A new module is available: 'programs.himalaya'.
'';
}
+
+ {
+ time = "2021-07-11T17:45:56+00:00";
+ message = ''
+ A new module is available: 'programs.sm64ex'.
+ '';
+ }
];
};
}
diff --git a/modules/modules.nix b/modules/modules.nix
index 3609f8fe..13e94ecc 100644
--- a/modules/modules.nix
+++ b/modules/modules.nix
@@ -132,6 +132,7 @@ let
(loadModule ./programs/scmpuff.nix { })
(loadModule ./programs/senpai.nix { })
(loadModule ./programs/skim.nix { })
+ (loadModule ./programs/sm64ex.nix { })
(loadModule ./programs/starship.nix { })
(loadModule ./programs/sbt.nix { })
(loadModule ./programs/ssh.nix { })
diff --git a/modules/programs/sm64ex.nix b/modules/programs/sm64ex.nix
new file mode 100644
index 00000000..332dd21f
--- /dev/null
+++ b/modules/programs/sm64ex.nix
@@ -0,0 +1,128 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.programs.sm64ex;
+
+ # This is required for tests, we cannot overwrite the dummy package.
+ package = if cfg.region == null && cfg.baserom == null
+ && cfg.extraCompileFlags == null then
+ cfg.package
+
+ else
+ cfg.package.override (attrs:
+ { } // optionalAttrs (cfg.region != null) { region = cfg.region; }
+ // optionalAttrs (cfg.baserom != null) { baseRom = cfg.baserom; }
+ // optionalAttrs (cfg.extraCompileFlags != null) {
+ compileFlags = cfg.extraCompileFlags;
+ });
+
+ mkConfig = key: value:
+ let
+ generatedValue = if isBool value then
+ (if value then "true" else "false")
+ else if isList value then
+ concatStringsSep " " value
+ else
+ toString value;
+ in "${key} ${generatedValue}";
+
+in {
+ meta.maintainers = [ maintainers.ivar ];
+
+ options.programs.sm64ex = {
+ enable = mkEnableOption "sm64ex";
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.sm64ex;
+ description = "The sm64ex package to use.";
+ };
+
+ region = mkOption {
+ type = types.nullOr (types.enum [ "us" "eu" "jp" ]);
+ default = null;
+ defaultText =
+ literalExample "us"; # This is set both in nixpkgs and upstream
+ description = ''
+ Your baserom's region. Note that only "us", "eu", and "jp" are supported.
+ '';
+ example = literalExample "jp";
+ };
+
+ baserom = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ description =
+ "The path to the Super Mario 64 baserom to extract assets from.";
+ example = literalExample "/home/foo/baserom.us.z64";
+ };
+
+ extraCompileFlags = mkOption {
+ type = with types; nullOr (listOf str);
+ default = null;
+ description = ''
+ Extra flags to pass to the compiler. See
+
+ for more information.
+ '';
+ example = literalExample ''
+ [
+ "BETTERCAMERA=1"
+ "NODRAWINGDISTANCE=1"
+ ];
+ '';
+ };
+
+ settings = mkOption {
+ type = with types;
+ nullOr (attrsOf (either str (either int (either bool (listOf str)))));
+ default = null;
+ description =
+ "Settings for sm64ex's ~/.local/share/sm64pc/sm64config.txt file.";
+ example = literalExample ''
+ {
+ fullscreen = false;
+ window_x = 0;
+ window_y = 0;
+ window_w = 1920;
+ window_h = 1080;
+ vsync = 1;
+ texture_filtering = 1;
+ master_volume = 127;
+ music_volume = 127;
+ sfx_volume = 127;
+ env_volume = 127;
+ key_a = [ "0026" "1000" "1103" ];
+ key_b = [ "0033" "1002" "1101" ];
+ key_start = [ "0039" "1006" "ffff" ];
+ key_l = [ "0034" "1007" "1104" ];
+ key_r = [ "0036" "100a" "1105" ];
+ key_z = [ "0025" "1009" "1102" ];
+ key_cup = [ "100b" "ffff" "ffff" ];
+ key_cdown = [ "100c" "ffff" "ffff" ];
+ key_cleft = [ "100d" "ffff" "ffff" ];
+ key_cright = [ "100e" "ffff" "ffff" ];
+ key_stickup = [ "0011" "ffff" "ffff" ];
+ key_stickdown = [ "001f" "ffff" "ffff" ];
+ key_stickleft = [ "001e" "ffff" "ffff" ];
+ key_stickright = [ "0020" "ffff" "ffff" ];
+ stick_deadzone = 16;
+ rumble_strength = 10;
+ skip_intro = 1;
+ };
+ '';
+ };
+ };
+
+ config = let
+ configFile = optionals (cfg.settings != null)
+ (concatStringsSep "\n" ((mapAttrsToList mkConfig cfg.settings)));
+ in mkIf cfg.enable {
+ home.packages = [ package ];
+
+ xdg.dataFile."sm64pc/sm64config.txt" =
+ mkIf (cfg.settings != null) { text = configFile; };
+ };
+}
diff --git a/tests/default.nix b/tests/default.nix
index b5f69723..670c45a2 100644
--- a/tests/default.nix
+++ b/tests/default.nix
@@ -76,6 +76,7 @@ import nmt {
./modules/programs/readline
./modules/programs/sbt
./modules/programs/scmpuff
+ ./modules/programs/sm64ex
./modules/programs/ssh
./modules/programs/starship
./modules/programs/texlive
diff --git a/tests/modules/programs/sm64ex/default.nix b/tests/modules/programs/sm64ex/default.nix
new file mode 100644
index 00000000..699c23f5
--- /dev/null
+++ b/tests/modules/programs/sm64ex/default.nix
@@ -0,0 +1 @@
+{ sm64ex = import ./settings.nix; }
diff --git a/tests/modules/programs/sm64ex/settings.nix b/tests/modules/programs/sm64ex/settings.nix
new file mode 100644
index 00000000..9ccf3953
--- /dev/null
+++ b/tests/modules/programs/sm64ex/settings.nix
@@ -0,0 +1,81 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+ config = {
+ programs.sm64ex = {
+ enable = true;
+
+ settings = {
+ fullscreen = true;
+ window_x = 0;
+ window_y = 0;
+ window_w = 1920;
+ window_h = 1080;
+ vsync = 1;
+ texture_filtering = 1;
+ master_volume = 127;
+ music_volume = 127;
+ sfx_volume = 127;
+ env_volume = 127;
+ key_a = [ "0026" "1000" "1103" ];
+ key_b = [ "0033" "1002" "1101" ];
+ key_start = [ "0039" "1006" "ffff" ];
+ key_l = [ "0034" "1007" "1104" ];
+ key_r = [ "0036" "100a" "1105" ];
+ key_z = [ "0025" "1009" "1102" ];
+ key_cup = [ "100b" "ffff" "ffff" ];
+ key_cdown = [ "100c" "ffff" "ffff" ];
+ key_cleft = [ "100d" "ffff" "ffff" ];
+ key_cright = [ "100e" "ffff" "ffff" ];
+ key_stickup = [ "0011" "ffff" "ffff" ];
+ key_stickdown = [ "001f" "ffff" "ffff" ];
+ key_stickleft = [ "001e" "ffff" "ffff" ];
+ key_stickright = [ "0020" "ffff" "ffff" ];
+ stick_deadzone = 16;
+ rumble_strength = 10;
+ skip_intro = 1;
+ };
+ };
+
+ nixpkgs.overlays =
+ [ (self: super: { sm64ex = pkgs.writeScriptBin "dummy-sm64ex" ""; }) ];
+
+ nmt.script = ''
+ assertFileContent \
+ home-files/.local/share/sm64pc/sm64config.txt \
+ ${
+ pkgs.writeText "sm64ex-expected-settings" ''
+ env_volume 127
+ fullscreen true
+ key_a 0026 1000 1103
+ key_b 0033 1002 1101
+ key_cdown 100c ffff ffff
+ key_cleft 100d ffff ffff
+ key_cright 100e ffff ffff
+ key_cup 100b ffff ffff
+ key_l 0034 1007 1104
+ key_r 0036 100a 1105
+ key_start 0039 1006 ffff
+ key_stickdown 001f ffff ffff
+ key_stickleft 001e ffff ffff
+ key_stickright 0020 ffff ffff
+ key_stickup 0011 ffff ffff
+ key_z 0025 1009 1102
+ master_volume 127
+ music_volume 127
+ rumble_strength 10
+ sfx_volume 127
+ skip_intro 1
+ stick_deadzone 16
+ texture_filtering 1
+ vsync 1
+ window_h 1080
+ window_w 1920
+ window_x 0
+ window_y 0''
+ }
+ '';
+ };
+}