diff --git a/content/nixosEmulation/content.md b/content/nixosEmulation/content.md
new file mode 100644
index 0000000..5a95cb3
--- /dev/null
+++ b/content/nixosEmulation/content.md
@@ -0,0 +1,158 @@
+
+

+
+
+
+
+It's been a long while. I just haven't had motivation to write, but I thought
+I'd at least try. This is something I've been obsessing over for the past few
+days and I thought writing about my experiences might help someone. Modern
+games are pretty cool (Deltarune), but I've been really enjoying some classics
+that I've been meaning to play.
+
+
+
+# [sm64coopdx](https://sm64coopdx.com/)
+This isn't emulation, but I still think its valuable info. [sm64coopdx](https://sm64coopdx.com/)
+is a fork of the [Super Mario 64 PC Port](https://github.com/n64decomp/sm64)
+with a ton of QOL, multiplayer, and [great mod support](https://youtu.be/Db-PKxZ9gbw?si=rxuFzwFv3s-Uf8Ho).
+The *intended* way to use the package is to legally obtain your own ROM and manually
+add it to the Nix store--I didn't do that. I hacked up a derivation which downloads
+a ROM in the format expected by the package:
+```nix
+{
+ stdenv,
+ fetchurl,
+ unzip,
+ region ? "us",
+ showRegionMessage ? true,
+}: let
+ rom = stdenv.mkDerivation {
+ pname = "baserom-us";
+ version = "1.0";
+
+ src = fetchurl {
+ url = "https://archive.org/download/nointro-merged/no-intro-merged/Nintendo%20-%20Nintendo%2064%20%28BigEndian%29%20%28Parent-Clone%29%20%2820210924-131351%29.zip/Super%20Mario%2064%20%28USA%29.zip";
+ sha256 = "sha256-SUWwae27Xo6od8aDzJa9FRXJ11hngRDBg+Lvy2aei00=";
+ };
+
+ nativeBuildInputs = [unzip];
+
+ dontConfigure = true;
+ dontBuild = true;
+ dontUnpack = true;
+
+ installPhase = ''
+ unzip "$src"
+ install -Dm644 "Super Mario 64 (USA).z64" "$out/baserom.us.z64"
+ '';
+ };
+in
+ rom
+ // {
+ romPath = "${rom}/baserom.${region}.z64";
+ }
+```
+
+Then I feed it to the package
+none the wiser:
+```nix
+pkgs.sm64coopdx.override {
+ sm64baserom = pkgs.callPackage ./sm64baserom.nix {};
+};
+```
+
+
+
+# [Dusklight](https://twilitrealm.dev/)
+Similarly, [Dusklight](https://twilitrealm.dev/) is a port of
+[The Legend of Zelda: Twilight Princess](https://en.wikipedia.org/wiki/The_Legend_of_Zelda:_Twilight_Princess)
+available for all platforms. Instead of declaratively setting the ROM, I set
+the path to it (`/home/poacher/Games/Roms`) since I don't want a 1 gigabyte game
+in my store.
+
+
+
+# [ES-DE](https://es-de.org/)
+[ES-DE](https://es-de.org/) is by far the best emulation frontend which
+unfortunately isn't packaged anymore. I hacked together my own package
+based on the AppImage:
+```nix
+{
+ appimageTools,
+ fetchurl,
+ makeDesktopItem,
+ symlinkJoin,
+ lib,
+}: let
+ es-de = appimageTools.wrapType2 {
+ pname = "es-de";
+ version = "3.4.1";
+ src = fetchurl {
+ url = "https://gitlab.com/es-de/emulationstation-de/-/package_files/288156961/download";
+ sha256 = "sha256-PGGkTXONVRY9qljt5wcgtCWg32JGDATcI908pYZyNYE=";
+ };
+ };
+ desktopItem = makeDesktopItem {
+ name = "es-de";
+ desktopName = "ES-DE";
+ exec = "${lib.getExe es-de}";
+ categories = ["Game"];
+ comment = "A frontend for browsing and launching games.";
+ icon = fetchurl {
+ name = "icon.png";
+ url = "https://impro.usercontent.one/appid/oneComWsb/domain/es-de.org/media/es-de.org/onewebmedia/ES-DE_logo.png?etag=%226071-6041244a%22&sourceContentType=image%2Fpng&ignoreAspectRatio&resize=240%2B168";
+ hash = "sha256-2Q9Iy6zk6L3tITtqYSVwky6KjLTvovDjP+DBJGyUWK8=";
+ };
+ };
+in
+ symlinkJoin {
+ name = "es-de";
+ paths = [
+ es-de
+ desktopItem
+ ];
+ }
+```
+
+I then configure ES-DE with [hjem](https://github.com/feel-co/hjem). Notably,
+you can even declaratively install themes by sourcing it with [`fetchGit`](https://noogle.dev/f/builtins/fetchGit/)--
+I do this with [Art Book Next](https://github.com/anthonycaccese/art-book-next-es-de).
+
+P.S if you have a fix for the weird horizontal scrolling in that code box then
+please let me know.
+
+
+
+# [RetroArch](https://www.retroarch.com/)
+[RetroArch](https://www.retroarch.com/) is the premiere emulator frontend for
+older systems. I currently use it for SNES (snes9x), PS1 (Swanstation),
+N64 (ParaLLEl), and PS2 (PCSX2). You can easily install these cores
+using the `pkgs.retroarch.withCores` function, or install all cores with
+`pkgs.retroarch.full`. I then also configure this with hjem. Something to note
+is that RetroArch, for whatever reason, doesn't let you use shaders that are
+symlinks. I tried to declaratively setup [crt-royale](https://emulation.gametechwiki.com/index.php/CRT-Royale),
+but it just wouldn't budge.
+
+
+
+# [Dolphin](https://dolphin-emu.org/)
+[Dolphin](https://dolphin-emu.org/) is the best Gamecube and Wii emulator
+available. It's trivial to setup, and can even be configured fully via
+cli arguments for all you wrapper fans. I personally still choose to
+use hjem for convenience.
+
+
+
+# [ShadPS4](https://shadps4.net/)
+What a pain in the ass. Not to say the software is bad, but it can't
+extract PKGs because of legal issues. So, I had to setup a distrobox
+container with an older version which could. After that though, it
+plays games just fine.
+
+
+
+# The Steam Controller
+Not really a NixOS thing (at least I think?), but a lot of this software
+doesn't like using the Steam controller if it isn't run through Steam. ES-DE
+especially hates it and refuses to map to it in Gamepad mode.
diff --git a/content/nixosEmulation/default.nix b/content/nixosEmulation/default.nix
new file mode 100644
index 0000000..80a6223
--- /dev/null
+++ b/content/nixosEmulation/default.nix
@@ -0,0 +1,11 @@
+{templates, ...}: {
+ title = "Game Emulation on NixOS";
+ description = "Just talking about my current setup and the struggles I went through to make it.";
+ content = ./content.md;
+ template = templates.post;
+ date = {
+ day = 25;
+ month = 07;
+ year = 2026;
+ };
+}
diff --git a/flake.nix b/flake.nix
index a166284..ddd26c4 100644
--- a/flake.nix
+++ b/flake.nix
@@ -49,7 +49,8 @@
nixd
alejandra
pandoc
- harper
+ harper
+ nodejs
];
};
};
diff --git a/static/assets/sorry_to_keep_you_waiting.webp b/static/assets/sorry_to_keep_you_waiting.webp
new file mode 100644
index 0000000000000000000000000000000000000000..5519f81c7bc4b2a1551620326314c2cc93236aa4
GIT binary patch
literal 8366
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 |