summary refs log tree commit diff
path: root/pkgs/applications
diff options
context:
space:
mode:
authorAndersonTorres <torres.anderson.85@protonmail.com>2022-02-15 23:28:16 -0300
committerAndersonTorres <torres.anderson.85@protonmail.com>2022-02-16 01:38:20 -0300
commit8d65e832f0a18f60e2040940c80d96373ac8b88c (patch)
tree3d6ade66b2a81403e3852b80b9e7c660699b6ed6 /pkgs/applications
parent19574af0af3ffaf7c9e359744ed32556f34536bd (diff)
downloadnixpkgs-8d65e832f0a18f60e2040940c80d96373ac8b88c.tar
nixpkgs-8d65e832f0a18f60e2040940c80d96373ac8b88c.tar.gz
nixpkgs-8d65e832f0a18f60e2040940c80d96373ac8b88c.tar.bz2
nixpkgs-8d65e832f0a18f60e2040940c80d96373ac8b88c.tar.lz
nixpkgs-8d65e832f0a18f60e2040940c80d96373ac8b88c.tar.xz
nixpkgs-8d65e832f0a18f60e2040940c80d96373ac8b88c.tar.zst
nixpkgs-8d65e832f0a18f60e2040940c80d96373ac8b88c.zip
Move misc/emulators to applications/emulators - part 1
Emulators form a class by themselves. So, they should be moved to applications/.
Diffstat (limited to 'pkgs/applications')
-rw-r--r--pkgs/applications/emulators/ares/default.nix84
-rw-r--r--pkgs/applications/emulators/ares/fix-ruby.patch27
-rw-r--r--pkgs/applications/emulators/atari++/default.nix32
-rw-r--r--pkgs/applications/emulators/atari800/default.nix43
-rw-r--r--pkgs/applications/emulators/attract-mode/default.nix33
-rw-r--r--pkgs/applications/emulators/bsnes-hd/default.nix55
-rw-r--r--pkgs/applications/emulators/bsnes-hd/macos-copy-app-to-prefix.patch18
-rw-r--r--pkgs/applications/emulators/bsnes-hd/macos-replace-sips-with-png2icns.patch13
-rw-r--r--pkgs/applications/emulators/caprice32/default.nix52
-rw-r--r--pkgs/applications/emulators/caprice32/string.patch12
-rw-r--r--pkgs/applications/emulators/ccemux/default.nix67
-rw-r--r--pkgs/applications/emulators/cdemu/analyzer.nix21
-rw-r--r--pkgs/applications/emulators/cdemu/base.nix36
-rw-r--r--pkgs/applications/emulators/cdemu/client.nix16
-rw-r--r--pkgs/applications/emulators/cdemu/daemon.nix9
-rw-r--r--pkgs/applications/emulators/cdemu/gui.nix23
-rw-r--r--pkgs/applications/emulators/cdemu/libmirage.nix18
-rw-r--r--pkgs/applications/emulators/cdemu/vhba.nix22
-rw-r--r--pkgs/applications/emulators/cen64/default.nix30
-rw-r--r--pkgs/applications/emulators/citra/default.nix91
-rw-r--r--pkgs/applications/emulators/commanderx16/emulator.nix42
-rw-r--r--pkgs/applications/emulators/commanderx16/rom.nix46
-rw-r--r--pkgs/applications/emulators/commanderx16/run.nix37
-rw-r--r--pkgs/applications/emulators/craftos-pc/default.nix43
-rw-r--r--pkgs/applications/emulators/darcnes/default.nix24
-rw-r--r--pkgs/applications/emulators/darcnes/label.patch13
-rw-r--r--pkgs/applications/emulators/desmume/default.nix87
-rw-r--r--pkgs/applications/emulators/dgen-sdl/default.nix69
-rw-r--r--pkgs/applications/emulators/dlx/default.nix29
-rw-r--r--pkgs/applications/emulators/dolphin-emu/default.nix122
-rw-r--r--pkgs/applications/emulators/dolphin-emu/master.nix89
-rw-r--r--pkgs/applications/emulators/dolphin-emu/primehack.nix151
-rw-r--r--pkgs/applications/emulators/dosbox-staging/default.nix112
-rw-r--r--pkgs/applications/emulators/dosbox/default.nix75
-rw-r--r--pkgs/applications/emulators/duckstation/default.nix106
-rw-r--r--pkgs/applications/emulators/emu2/default.nix26
-rw-r--r--pkgs/applications/emulators/emulationstation/default.nix37
-rw-r--r--pkgs/applications/emulators/epsxe/default.nix52
-rw-r--r--pkgs/applications/emulators/fakenes/build.patch84
-rw-r--r--pkgs/applications/emulators/fakenes/default.nix34
-rw-r--r--pkgs/applications/emulators/fceux/default.nix24
-rw-r--r--pkgs/applications/emulators/firebird-emu/default.nix36
-rw-r--r--pkgs/applications/emulators/fs-uae/default.nix65
-rw-r--r--pkgs/applications/emulators/fs-uae/launcher.nix43
-rw-r--r--pkgs/applications/emulators/fuse-emulator/default.nix29
-rw-r--r--pkgs/applications/emulators/gens-gs/default.nix26
-rw-r--r--pkgs/applications/emulators/gxemul/0001-fix-attributes.patch26
-rw-r--r--pkgs/applications/emulators/gxemul/default.nix47
-rw-r--r--pkgs/applications/emulators/hatari/default.nix25
-rw-r--r--pkgs/applications/emulators/higan/001-include-cmath.patch8
-rw-r--r--pkgs/applications/emulators/higan/002-sips-to-png2icns.patch24
-rw-r--r--pkgs/applications/emulators/higan/default.nix155
-rw-r--r--pkgs/applications/emulators/kega-fusion/default.nix78
-rw-r--r--pkgs/applications/emulators/lambda-delta/default.nix26
-rw-r--r--pkgs/applications/emulators/libdsk/default.nix19
-rw-r--r--pkgs/applications/emulators/maiko/default.nix26
-rw-r--r--pkgs/applications/emulators/mame/default.nix105
-rw-r--r--pkgs/applications/emulators/mame/emuopts.patch29
-rw-r--r--pkgs/applications/emulators/mednafen/default.nix74
-rw-r--r--pkgs/applications/emulators/mednafen/server.nix21
-rw-r--r--pkgs/applications/emulators/mednaffe/default.nix37
-rw-r--r--pkgs/applications/emulators/melonDS/default.nix43
-rw-r--r--pkgs/applications/emulators/mgba/default.nix87
-rw-r--r--pkgs/applications/emulators/mupen64plus/default.nix29
-rw-r--r--pkgs/applications/emulators/nestopia/build-fix.patch18
-rw-r--r--pkgs/applications/emulators/nestopia/default.nix72
-rw-r--r--pkgs/applications/emulators/nestopia/gcc6.patch92
-rw-r--r--pkgs/applications/emulators/np2kai/default.nix196
-rw-r--r--pkgs/applications/emulators/oberon-risc-emu/default.nix27
-rw-r--r--pkgs/applications/emulators/openmsx/custom-nix.mk9
-rw-r--r--pkgs/applications/emulators/openmsx/default.nix75
-rw-r--r--pkgs/applications/emulators/pcem/default.nix29
-rw-r--r--pkgs/applications/emulators/pcsx2/default.nix93
-rw-r--r--pkgs/applications/emulators/pcsxr/0001-libpcsxcore-fix-build-with-ffmpeg-4.patch76
-rw-r--r--pkgs/applications/emulators/pcsxr/default.nix89
-rw-r--r--pkgs/applications/emulators/pcsxr/uncompress2.patch20
-rw-r--r--pkgs/applications/emulators/ppsspp/default.nix72
-rw-r--r--pkgs/applications/emulators/proton-caller/default.nix23
-rw-r--r--pkgs/applications/emulators/punes/default.nix74
-rw-r--r--pkgs/applications/emulators/py65/default.nix25
-rw-r--r--pkgs/applications/emulators/qmc2/default.nix41
-rw-r--r--pkgs/applications/emulators/reicast/default.nix52
-rw-r--r--pkgs/applications/emulators/resim/default.nix21
-rw-r--r--pkgs/applications/emulators/retroarch/0001-Disable-menu_show_core_updater.patch25
-rw-r--r--pkgs/applications/emulators/retroarch/0002-Use-fixed-paths-on-libretro_info_path.patch80
-rw-r--r--pkgs/applications/emulators/retroarch/cores.nix919
-rw-r--r--pkgs/applications/emulators/retroarch/default.nix122
-rw-r--r--pkgs/applications/emulators/retroarch/disable-menu-show-core-updater.patch13
-rw-r--r--pkgs/applications/emulators/retroarch/fix-config.patch26
-rw-r--r--pkgs/applications/emulators/retroarch/fix-libretro-paths.patch28
-rw-r--r--pkgs/applications/emulators/retroarch/hashes.json499
-rw-r--r--pkgs/applications/emulators/retroarch/kodi-advanced-launchers.nix36
-rwxr-xr-xpkgs/applications/emulators/retroarch/update.py179
-rw-r--r--pkgs/applications/emulators/retroarch/wrapper.nix37
-rw-r--r--pkgs/applications/emulators/retrofe/default.nix78
-rw-r--r--pkgs/applications/emulators/retrofe/include-paths.patch11
-rw-r--r--pkgs/applications/emulators/rpcs3/0001-llvm-ExecutionEngine-IntelJITEvents-only-use-ITTAPI_.patch62
-rw-r--r--pkgs/applications/emulators/rpcs3/default.nix80
-rwxr-xr-xpkgs/applications/emulators/rpcs3/update.sh59
-rw-r--r--pkgs/applications/emulators/ruffle/default.nix60
-rw-r--r--pkgs/applications/emulators/ryujinx/default.nix90
-rw-r--r--pkgs/applications/emulators/ryujinx/deps.nix227
-rw-r--r--pkgs/applications/emulators/ryujinx/log.patch21
-rwxr-xr-xpkgs/applications/emulators/ryujinx/updater.sh40
-rw-r--r--pkgs/applications/emulators/sameboy/default.nix48
-rw-r--r--pkgs/applications/emulators/simh/default.nix62
-rw-r--r--pkgs/applications/emulators/simplenes/default.nix33
-rw-r--r--pkgs/applications/emulators/snes9x-gtk/default.nix36
-rw-r--r--pkgs/applications/emulators/stella/default.nix45
-rw-r--r--pkgs/applications/emulators/termtekst/default.nix36
-rw-r--r--pkgs/applications/emulators/tilem/default.nix30
-rw-r--r--pkgs/applications/emulators/uae/default.nix27
-rw-r--r--pkgs/applications/emulators/uxn/default.nix54
-rw-r--r--pkgs/applications/emulators/vbam/default.nix67
-rw-r--r--pkgs/applications/emulators/vice/default.nix91
-rw-r--r--pkgs/applications/emulators/wine/base.nix167
-rw-r--r--pkgs/applications/emulators/wine/builder-wow.sh31
-rw-r--r--pkgs/applications/emulators/wine/cert-path.patch15
-rw-r--r--pkgs/applications/emulators/wine/default.nix63
-rw-r--r--pkgs/applications/emulators/wine/fonts.nix22
-rw-r--r--pkgs/applications/emulators/wine/packages.nix44
-rw-r--r--pkgs/applications/emulators/wine/sources.nix93
-rw-r--r--pkgs/applications/emulators/wine/staging.nix28
-rw-r--r--pkgs/applications/emulators/wine/util.nix9
-rw-r--r--pkgs/applications/emulators/wine/vkd3d.nix26
-rw-r--r--pkgs/applications/emulators/wine/winetricks.nix33
-rw-r--r--pkgs/applications/emulators/xcpc/default.nix29
-rw-r--r--pkgs/applications/emulators/yabause/0001-Fixes-for-Qt-5.11-upgrade.patch67
-rw-r--r--pkgs/applications/emulators/yabause/default.nix36
-rw-r--r--pkgs/applications/emulators/yabause/linkage-rwx-linux-elf.patch20
-rw-r--r--pkgs/applications/emulators/yapesdl/default.nix43
-rw-r--r--pkgs/applications/emulators/yuzu/base.nix86
-rw-r--r--pkgs/applications/emulators/yuzu/default.nix28
-rw-r--r--pkgs/applications/emulators/zesarux/default.nix89
-rw-r--r--pkgs/applications/emulators/zsnes/default.nix64
135 files changed, 8380 insertions, 0 deletions
diff --git a/pkgs/applications/emulators/ares/default.nix b/pkgs/applications/emulators/ares/default.nix
new file mode 100644
index 00000000000..33a7858455d
--- /dev/null
+++ b/pkgs/applications/emulators/ares/default.nix
@@ -0,0 +1,84 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, pkg-config
+, alsa-lib
+, gtksourceview3
+, libXv
+, openal
+, libpulseaudio
+, libao
+, udev
+, SDL2
+}:
+
+stdenv.mkDerivation rec {
+  pname = "ares";
+  version = "126";
+
+  src = fetchFromGitHub {
+    owner = "ares-emulator";
+    repo = "ares";
+    rev = "v${version}";
+    sha256 = "1rj4vmz8lvpmfc6wni7222kagnw9f6jda9rcb6qky2kpizlp2d24";
+  };
+
+  parallel-rdp = fetchFromGitHub {
+    owner = "Themaister";
+    repo = "parallel-rdp-standalone";
+    rev = "0dcebe11ee79288441e40e145c8f340d81f52316";
+    sha256 = "1avp4wyfkhk5yfjqx5w3jbqghn2mq5la7k9248kjmnp9n9lip6w9";
+  };
+
+  patches = [
+    ./fix-ruby.patch
+  ];
+
+  enableParallelBuilding = true;
+  dontConfigure = true;
+
+  nativeBuildInputs = [
+    pkg-config
+  ];
+
+  buildInputs = [
+    alsa-lib
+    gtksourceview3
+    libXv
+    openal
+    libpulseaudio
+    libao
+    udev
+    SDL2
+  ];
+
+  buildPhase = ''
+    runHook preBuild
+
+    rm -rf ares/n64/vulkan/parallel-rdp
+    ln -sf ${parallel-rdp} ares/n64/vulkan/parallel-rdp
+    make -C desktop-ui -j $NIX_BUILD_CORES openmp=true vulkan=true local=false hiro=gtk3
+
+    runHook postBuild
+  '';
+
+  installPhase = ''
+    runHook preInstall
+
+    mkdir -p $out/{bin,share/{applications,ares,pixmaps}}
+    cp desktop-ui/out/ares $out/bin
+    cp desktop-ui/resource/ares.desktop $out/share/applications
+    cp desktop-ui/resource/{ares{.ico,.png},font.png} $out/share/pixmaps
+    cp -r ares/{Shaders,System} $out/share/ares
+
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    homepage = "https://ares.dev";
+    description = "Open-source multi-system emulator with a focus on accuracy and preservation";
+    license = licenses.isc;
+    maintainers = with maintainers; [ Madouura ];
+    platforms = platforms.all;
+  };
+}
diff --git a/pkgs/applications/emulators/ares/fix-ruby.patch b/pkgs/applications/emulators/ares/fix-ruby.patch
new file mode 100644
index 00000000000..01bd57ebaad
--- /dev/null
+++ b/pkgs/applications/emulators/ares/fix-ruby.patch
@@ -0,0 +1,27 @@
+diff --git a/ruby/GNUmakefile b/ruby/GNUmakefile
+index e85a51701..7fca89e0f 100644
+--- a/ruby/GNUmakefile
++++ b/ruby/GNUmakefile
+@@ -8,19 +8,9 @@ ifeq ($(ruby),)
+     ruby += audio.openal
+     ruby += input.quartz #input.carbon
+   else ifeq ($(platform),linux)
+-    pkg_check1 = $(if $(shell test -e /usr/lib/lib$1.so && echo 1),$2)
+-    pkg_check2 = $(if $(shell test -e /usr/lib/$(shell uname -m)-linux-gnu/lib$1.so && echo 1),$2)
+-    pkg_check = $(call pkg_check1,$1,$2) $(call pkg_check2,$1,$2)
+-    ruby += video.glx video.glx2 video.xshm
+-    ruby += $(call pkg_check,Xv,video.xvideo)
+-    ruby += audio.oss audio.alsa
+-    ruby += $(call pkg_check,openal,audio.openal)
+-    ruby += $(call pkg_check,pulse,audio.pulseaudio)
+-    ruby += $(call pkg_check,pulse-simple,audio.pulseaudiosimple)
+-    ruby += $(call pkg_check,ao,audio.ao)
+-    ruby += input.xlib
+-    ruby += $(call pkg_check,udev,input.udev)
+-    ruby += $(call pkg_check,SDL2,input.sdl)
++    ruby += video.glx video.glx2 video.xshm video.xvideo
++    ruby += audio.oss audio.alsa audio.openal audio.pulseaudio audio.pulseaudiosimple audio.ao
++    ruby += input.xlib input.udev input.sdl
+   else ifeq ($(platform),bsd)
+     pkg_check = $(if $(shell test -e /usr/local/lib/lib$1.so && echo 1),$2)
+     ruby += video.glx video.glx2 video.xshm
diff --git a/pkgs/applications/emulators/atari++/default.nix b/pkgs/applications/emulators/atari++/default.nix
new file mode 100644
index 00000000000..5e35dcaebd0
--- /dev/null
+++ b/pkgs/applications/emulators/atari++/default.nix
@@ -0,0 +1,32 @@
+{ lib, stdenv, fetchurl, libSM, libX11, libICE, SDL, alsa-lib, gcc-unwrapped, libXext }:
+
+stdenv.mkDerivation rec {
+  pname = "atari++";
+  version = "1.83";
+
+  src = fetchurl {
+    url = "http://www.xl-project.com/download/${pname}_${version}.tar.gz";
+    sha256 = "04fm2ic2qi4a52mi72wcaxyrpll4k8vvchx3qrik8rhg3jrxgm47";
+  };
+
+  buildInputs = [ libSM libX11 SDL libICE alsa-lib gcc-unwrapped libXext ];
+
+  postFixup = ''
+    patchelf --set-rpath ${lib.makeLibraryPath buildInputs} "$out/bin/atari++"
+  '';
+
+  meta = with lib; {
+    homepage = "http://www.xl-project.com/";
+    description = "An enhanced, cycle-accurated Atari emulator";
+    longDescription = ''
+      The Atari++ Emulator is a Unix based emulator of the Atari eight
+      bit computers, namely the Atari 400 and 800, the Atari 400XL,
+      800XL and 130XE, and the Atari 5200 game console. The emulator
+      is auto-configurable and will compile on a variety of systems
+      (Linux, Solaris, Irix).
+    '';
+    maintainers = [ maintainers.AndersonTorres ];
+    license = licenses.gpl2Plus;
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/atari800/default.nix b/pkgs/applications/emulators/atari800/default.nix
new file mode 100644
index 00000000000..37e0d83f140
--- /dev/null
+++ b/pkgs/applications/emulators/atari800/default.nix
@@ -0,0 +1,43 @@
+{ lib, stdenv, fetchFromGitHub, autoreconfHook
+, zlib, SDL, readline, libGLU, libGL, libX11 }:
+
+with lib;
+stdenv.mkDerivation rec {
+  pname = "atari800";
+  version = "4.2.0";
+
+  src = fetchFromGitHub {
+    owner = "atari800";
+    repo = "atari800";
+    rev = "ATARI800_${replaceChars ["."] ["_"] version}";
+    sha256 = "15l08clqqayi9izrgsz9achan6gl4x57wqsc8mad3yn0xayzz3qy";
+  };
+
+  nativeBuildInputs = [ autoreconfHook ];
+
+  buildInputs = [ zlib SDL readline libGLU libGL libX11 ];
+
+  configureFlags = [
+    "--target=default"
+    "--with-video=sdl"
+    "--with-sound=sdl"
+    "--with-readline"
+    "--with-opengl"
+    "--with-x"
+    "--enable-riodevice"
+  ];
+
+  meta = {
+    homepage = "https://atari800.github.io/";
+    description = "An Atari 8-bit emulator";
+    longDescription = ''
+      Atari800 is the emulator of Atari 8-bit computer systems and
+      5200 game console for Unix, Linux, Amiga, MS-DOS, Atari
+      TT/Falcon, MS-Windows, MS WinCE, Sega Dreamcast, Android and
+      other systems supported by the SDL library.
+    '';
+    maintainers = [ maintainers.AndersonTorres ];
+    license = licenses.gpl2Plus;
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/attract-mode/default.nix b/pkgs/applications/emulators/attract-mode/default.nix
new file mode 100644
index 00000000000..7a3f61fd8dc
--- /dev/null
+++ b/pkgs/applications/emulators/attract-mode/default.nix
@@ -0,0 +1,33 @@
+{ expat, fetchFromGitHub, ffmpeg, fontconfig, freetype, libarchive, libjpeg
+, libGLU, libGL, openal, pkg-config, sfml, lib, stdenv, zlib
+}:
+
+stdenv.mkDerivation rec {
+  pname = "attract-mode";
+  version = "2.6.1";
+
+  src = fetchFromGitHub {
+    owner = "mickelson";
+    repo = "attract";
+    rev = "v${version}";
+    sha256 = "16p369j0hanm0l2fiy6h9d9pn0f3qblcy9l39all6h7rfxnhp9ii";
+  };
+
+  nativeBuildInputs = [ pkg-config ];
+
+  patchPhase = ''
+    sed -i "s|prefix=/usr/local|prefix=$out|" Makefile
+  '';
+
+  buildInputs = [
+    expat ffmpeg fontconfig freetype libarchive libjpeg libGLU libGL openal sfml zlib
+  ];
+
+  meta = with lib; {
+    description = "A frontend for arcade cabinets and media PCs";
+    homepage = "http://attractmode.org";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ hrdinka ];
+    platforms = with platforms; linux;
+  };
+}
diff --git a/pkgs/applications/emulators/bsnes-hd/default.nix b/pkgs/applications/emulators/bsnes-hd/default.nix
new file mode 100644
index 00000000000..6494185958c
--- /dev/null
+++ b/pkgs/applications/emulators/bsnes-hd/default.nix
@@ -0,0 +1,55 @@
+{ lib, stdenv, fetchFromGitHub
+, pkg-config
+, libX11, libXv
+, udev
+, SDL2
+, gtk2, gtksourceview
+, alsa-lib, libao, openal, libpulseaudio
+, libicns, Cocoa, OpenAL
+}:
+
+stdenv.mkDerivation {
+  pname = "bsnes-hd";
+  version = "10.6-beta";
+
+  src = fetchFromGitHub {
+    owner = "DerKoun";
+    repo = "bsnes-hd";
+    rev = "beta_10_6";
+    sha256 = "0f3cd89fd0lqskzj98cc1pzmdbscq0psdjckp86w94rbchx7iw4h";
+  };
+
+  patches = [
+    # Replace invocation of `sips` with an equivalent invocation of `png2icns`
+    # while assembling the .app directory hierarchy in the macos build. The
+    # `sips` executable isn't in our environment during the build, but
+    # `png2icns` is available by way of the dependency on libicns.
+    ./macos-replace-sips-with-png2icns.patch
+
+    # During `make install` on macos the Makefile wants to move the .app into
+    # the current user's home directory. This patches the Makefile such that
+    # the .app ends up in $(prefix)/Applications. The $(prefix) variable will
+    # be set to $out, so this will result in the .app ending up in the
+    # Applications directory in the current nix profile.
+    ./macos-copy-app-to-prefix.patch
+  ];
+
+  nativeBuildInputs = [ pkg-config ]
+    ++ lib.optionals stdenv.isDarwin [ libicns ];
+
+  buildInputs = [ SDL2 libao ]
+    ++ lib.optionals stdenv.isLinux [ libX11 libXv udev gtk2 gtksourceview alsa-lib openal libpulseaudio ]
+    ++ lib.optionals stdenv.isDarwin [ Cocoa OpenAL ];
+
+  enableParallelBuilding = true;
+
+  makeFlags = [ "-C" "bsnes" "prefix=$(out)" ];
+
+  meta = with lib; {
+    description = "A fork of bsnes that adds HD video features";
+    homepage = "https://github.com/DerKoun/bsnes-hd";
+    license = licenses.gpl3Only;
+    maintainers = with maintainers; [ stevebob ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/applications/emulators/bsnes-hd/macos-copy-app-to-prefix.patch b/pkgs/applications/emulators/bsnes-hd/macos-copy-app-to-prefix.patch
new file mode 100644
index 00000000000..d38efbc99bc
--- /dev/null
+++ b/pkgs/applications/emulators/bsnes-hd/macos-copy-app-to-prefix.patch
@@ -0,0 +1,18 @@
+diff --git a/bsnes/target-bsnes/GNUmakefile b/bsnes/target-bsnes/GNUmakefile
+index 7a3ab9f..ec8a1a4 100644
+--- a/bsnes/target-bsnes/GNUmakefile
++++ b/bsnes/target-bsnes/GNUmakefile
+@@ -43,11 +43,8 @@ ifeq ($(platform),windows)
+ else ifeq ($(shell id -un),root)
+ 	$(error "make install should not be run as root")
+ else ifeq ($(platform),macos)
+-	mkdir -p ~/Library/Application\ Support/$(name)/
+-	mkdir -p ~/Library/Application\ Support/$(name)/Database/
+-	mkdir -p ~/Library/Application\ Support/$(name)/Firmware/
+-	mkdir -p ~/Library/Application\ Support/$(name)/Shaders/
+-	cp -R out/$(name).app /Applications/$(name).app
++	mkdir -p $(prefix)/Applications
++	cp -R out/$(name).app $(prefix)/Applications
+ else ifneq ($(filter $(platform),linux bsd),)
+ 	mkdir -p $(prefix)/bin/
+ 	mkdir -p $(prefix)/share/applications/
diff --git a/pkgs/applications/emulators/bsnes-hd/macos-replace-sips-with-png2icns.patch b/pkgs/applications/emulators/bsnes-hd/macos-replace-sips-with-png2icns.patch
new file mode 100644
index 00000000000..85adb33e3ab
--- /dev/null
+++ b/pkgs/applications/emulators/bsnes-hd/macos-replace-sips-with-png2icns.patch
@@ -0,0 +1,13 @@
+diff --git a/bsnes/target-bsnes/GNUmakefile b/bsnes/target-bsnes/GNUmakefile
+index 4c67bde..7a3ab9f 100644
+--- a/bsnes/target-bsnes/GNUmakefile
++++ b/bsnes/target-bsnes/GNUmakefile
+@@ -33,7 +33,7 @@ ifeq ($(platform),macos)
+ 	cp Database/* out/$(name).app/Contents/MacOS/Database/
+ 	cp -r ../shaders/* out/$(name).app/Contents/macOS/Shaders/
+ 	cp $(ui)/resource/$(name).plist out/$(name).app/Contents/Info.plist
+-	sips -s format icns $(ui)/resource/$(name).png --out out/$(name).app/Contents/Resources/$(name).icns
++	png2icns out/$(name).app/Contents/Resources/$(name).icns $(ui)/resource/$(name).png
+ endif
+ 
+ verbose: hiro.verbose ruby.verbose nall.verbose all;
diff --git a/pkgs/applications/emulators/caprice32/default.nix b/pkgs/applications/emulators/caprice32/default.nix
new file mode 100644
index 00000000000..6c2932f7e10
--- /dev/null
+++ b/pkgs/applications/emulators/caprice32/default.nix
@@ -0,0 +1,52 @@
+{ lib, stdenv, fetchFromGitHub, desktop-file-utils, libpng
+, pkg-config, SDL, freetype, zlib }:
+
+stdenv.mkDerivation rec {
+
+  pname = "caprice32";
+  version = "4.6.0";
+  # NOTE: When bumping version beyond 4.6.0, you likely need to remove
+  #       string.patch below. The fix of this patch has already been
+  #       done upstream but is not yet part of a release
+
+  src = fetchFromGitHub {
+    repo = "caprice32";
+    rev = "v${version}";
+    owner = "ColinPitrat";
+    sha256 = "0hng5krwgc1h9bz1xlkp2hwnvas965nd7sb3z9mb2m6x9ghxlacz";
+  };
+
+  nativeBuildInputs = [ desktop-file-utils pkg-config ];
+  buildInputs = [ libpng SDL freetype zlib ];
+
+  patches = [ ./string.patch ];
+
+  makeFlags = [
+    "APP_PATH=${placeholder "out"}/share/caprice32"
+    "RELEASE=1"
+    "DESTDIR=${placeholder "out"}"
+    "prefix=/"
+  ];
+
+  postInstall = ''
+    mkdir -p $out/share/icons/
+    mv $out/share/caprice32/resources/freedesktop/caprice32.png $out/share/icons/
+    mv $out/share/caprice32/resources/freedesktop/emulators.png $out/share/icons/
+
+    desktop-file-install --dir $out/share/applications \
+      $out/share/caprice32/resources/freedesktop/caprice32.desktop
+
+    desktop-file-install --dir $out/share/desktop-directories \
+      $out/share/caprice32/resources/freedesktop/Emulators.directory
+
+    install -Dm644 $out/share/caprice32/resources/freedesktop/caprice32.menu -t $out/etc/xdg/menus/applications-merged/
+  '';
+
+  meta = with lib; {
+    description = "A complete emulation of CPC464, CPC664 and CPC6128";
+    homepage = "https://github.com/ColinPitrat/caprice32";
+    license = licenses.gpl2;
+    maintainers = [ ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/caprice32/string.patch b/pkgs/applications/emulators/caprice32/string.patch
new file mode 100644
index 00000000000..fabbbd80d5d
--- /dev/null
+++ b/pkgs/applications/emulators/caprice32/string.patch
@@ -0,0 +1,12 @@
+diff --git a/src/configuration.h b/src/configuration.h
+index 34fd690..97fb0e5 100644
+--- a/src/configuration.h
++++ b/src/configuration.h
+@@ -2,6 +2,7 @@
+ #define CONFIGURATION_H
+ 
+ #include <map>
++#include <string>
+ 
+ namespace config
+ {
diff --git a/pkgs/applications/emulators/ccemux/default.nix b/pkgs/applications/emulators/ccemux/default.nix
new file mode 100644
index 00000000000..11f24d59e5c
--- /dev/null
+++ b/pkgs/applications/emulators/ccemux/default.nix
@@ -0,0 +1,67 @@
+{ lib, stdenv, fetchurl, makeDesktopItem, makeWrapper, jre
+, useCCTweaked ? true
+}:
+
+let
+  version = "1.1.1";
+  rev = "af12e2e4da586275ba931eae8f40a2201251bf59";
+
+  baseUrl = "https://emux.cc/versions/${lib.substring 0 8 rev}/CCEmuX";
+  jar =
+    if useCCTweaked
+    then fetchurl {
+      url = "${baseUrl}-cct.jar";
+      sha256 = "0d9gzi1h5vz32fp4lfn7dam189jcm7bwbqwmlpj0c47p8l0d4lsv";
+    }
+    else fetchurl {
+      url = "${baseUrl}-cc.jar";
+      sha256 = "0ky5vxh8m1v98zllifxif8xxd25j2xdp19hjnj4xlkck71lbnb34";
+    };
+
+  desktopIcon = fetchurl {
+    url = "https://github.com/CCEmuX/CCEmuX/raw/${rev}/src/main/resources/img/icon.png";
+    sha256 = "1vmb6rg9k2y99j8xqfgbsvfgfi3g985rmqwrd7w3y54ffr2r99c2";
+  };
+  desktopItem =  makeDesktopItem {
+    name = "CCEmuX";
+    exec = "ccemux";
+    icon = desktopIcon;
+    comment = "A modular ComputerCraft emulator";
+    desktopName = "CCEmuX";
+    genericName = "ComputerCraft Emulator";
+    categories = "Emulator;";
+  };
+in
+
+stdenv.mkDerivation rec {
+  pname = "ccemux";
+  inherit version;
+
+  src = jar;
+  dontUnpack = true;
+
+  nativeBuildInputs = [ makeWrapper ];
+  buildInputs = [ jre ];
+
+  installPhase = ''
+    runHook preInstall
+
+    mkdir -p $out/{bin,share/ccemux}
+    cp -r ${desktopItem}/share/applications $out/share/applications
+
+    install -D ${src} $out/share/ccemux/ccemux.jar
+    install -D ${desktopIcon} $out/share/pixmaps/ccemux.png
+
+    makeWrapper ${jre}/bin/java $out/bin/ccemux \
+      --add-flags "-jar $out/share/ccemux/ccemux.jar"
+
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    description = "A modular ComputerCraft emulator";
+    homepage = "https://github.com/CCEmuX/CCEmuX";
+    license = licenses.mit;
+    maintainers = with maintainers; [ CrazedProgrammer ];
+  };
+}
diff --git a/pkgs/applications/emulators/cdemu/analyzer.nix b/pkgs/applications/emulators/cdemu/analyzer.nix
new file mode 100644
index 00000000000..338c64a24b8
--- /dev/null
+++ b/pkgs/applications/emulators/cdemu/analyzer.nix
@@ -0,0 +1,21 @@
+{ callPackage, makeWrapper, gobject-introspection, cmake
+, python3Packages, gtk3, glib, libxml2, gnuplot, gnome, gdk-pixbuf, librsvg, intltool, libmirage }:
+let pkg = import ./base.nix {
+  version = "3.2.5";
+  pname = "image-analyzer";
+  pkgSha256 = "00906lky0z1m0bdqnjmzxgcb19dzvljhddhh42lixyr53sjp94cc";
+};
+in callPackage pkg {
+  buildInputs = [ glib gtk3 libxml2 gnuplot libmirage makeWrapper
+                  gnome.adwaita-icon-theme gdk-pixbuf librsvg intltool
+                  python3Packages.python python3Packages.pygobject3 python3Packages.matplotlib ];
+  drvParams = {
+    nativeBuildInputs = [ gobject-introspection cmake ];
+    postFixup = ''
+      wrapProgram $out/bin/image-analyzer \
+        --set PYTHONPATH "$PYTHONPATH" \
+        --set GI_TYPELIB_PATH "$GI_TYPELIB_PATH" \
+        --prefix XDG_DATA_DIRS : "$out/share:$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH"
+    '';
+  };
+}
diff --git a/pkgs/applications/emulators/cdemu/base.nix b/pkgs/applications/emulators/cdemu/base.nix
new file mode 100644
index 00000000000..9464bde70bf
--- /dev/null
+++ b/pkgs/applications/emulators/cdemu/base.nix
@@ -0,0 +1,36 @@
+{ pname, version, pkgSha256 }:
+{ lib, stdenv, fetchurl, cmake, pkg-config, buildInputs, drvParams ? {} }:
+stdenv.mkDerivation ( rec {
+  inherit pname version buildInputs;
+  src = fetchurl {
+    url = "mirror://sourceforge/cdemu/${pname}-${version}.tar.xz";
+    sha256 = pkgSha256;
+  };
+  nativeBuildInputs = [ pkg-config cmake ];
+  setSourceRoot = ''
+    mkdir build
+    cd build
+    sourceRoot="`pwd`"
+  '';
+  configurePhase = ''
+    cmake ../${pname}-${version} -DCMAKE_INSTALL_PREFIX=$out -DCMAKE_BUILD_TYPE=Release -DCMAKE_SKIP_RPATH=ON
+  '';
+  meta = with lib; {
+    description = "A suite of tools for emulating optical drives and discs";
+    longDescription = ''
+      CDEmu consists of:
+
+      - a kernel module implementing a virtual drive-controller
+      - libmirage which is a software library for interpreting optical disc images
+      - a daemon which emulates the functionality of an optical drive+disc
+      - textmode and GTK clients for controlling the emulator
+      - an image analyzer to view the structure of image files
+
+      Optical media emulated by CDemu can be mounted within Linux. Automounting is also allowed.
+    '';
+    homepage = "https://cdemu.sourceforge.io/";
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+    maintainers = with lib.maintainers; [ bendlas ];
+  };
+} // drvParams)
diff --git a/pkgs/applications/emulators/cdemu/client.nix b/pkgs/applications/emulators/cdemu/client.nix
new file mode 100644
index 00000000000..06604e3eae9
--- /dev/null
+++ b/pkgs/applications/emulators/cdemu/client.nix
@@ -0,0 +1,16 @@
+{ callPackage, python3Packages, intltool, makeWrapper }:
+let pkg = import ./base.nix {
+  version = "3.2.5";
+  pname = "cdemu-client";
+  pkgSha256 = "1prrdhv0ia0axc6b73crszqzh802wlkihz6d100yvg7wbgmqabd7";
+};
+in callPackage pkg {
+  buildInputs = [ python3Packages.python python3Packages.dbus-python python3Packages.pygobject3
+                  intltool makeWrapper ];
+  drvParams = {
+    postFixup = ''
+      wrapProgram $out/bin/cdemu \
+        --set PYTHONPATH "$PYTHONPATH"
+    '';
+  };
+}
diff --git a/pkgs/applications/emulators/cdemu/daemon.nix b/pkgs/applications/emulators/cdemu/daemon.nix
new file mode 100644
index 00000000000..3df9e4ad543
--- /dev/null
+++ b/pkgs/applications/emulators/cdemu/daemon.nix
@@ -0,0 +1,9 @@
+{ callPackage, glib, libao, intltool, libmirage }:
+let pkg = import ./base.nix {
+  version = "3.2.5";
+  pname = "cdemu-daemon";
+  pkgSha256 = "16g6fv1lxkdmbsy6zh5sj54dvgwvm900fd18aq609yg8jnqm644d";
+};
+in callPackage pkg {
+  buildInputs = [ glib libao libmirage intltool ];
+}
diff --git a/pkgs/applications/emulators/cdemu/gui.nix b/pkgs/applications/emulators/cdemu/gui.nix
new file mode 100644
index 00000000000..15e595a6172
--- /dev/null
+++ b/pkgs/applications/emulators/cdemu/gui.nix
@@ -0,0 +1,23 @@
+{ callPackage, makeWrapper, gobject-introspection, cmake
+, python3Packages, gtk3, glib, libnotify, intltool, gnome, gdk-pixbuf, librsvg }:
+let
+  pkg = import ./base.nix {
+    version = "3.2.5";
+    pname = "gcdemu";
+    pkgSha256 = "1nvpbq4mz8caw91q5ny9gf206g9bypavxws9nxyfcanfkc4zfkl4";
+  };
+  inherit (python3Packages) python pygobject3;
+in callPackage pkg {
+  buildInputs = [ python pygobject3 gtk3 glib libnotify intltool makeWrapper
+                  gnome.adwaita-icon-theme gdk-pixbuf librsvg ];
+  drvParams = {
+    nativeBuildInputs = [ gobject-introspection cmake ];
+    postFixup = ''
+      wrapProgram $out/bin/gcdemu \
+        --set PYTHONPATH "$PYTHONPATH" \
+        --set GI_TYPELIB_PATH "$GI_TYPELIB_PATH" \
+        --prefix XDG_DATA_DIRS : "$out/share:$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH"
+    '';
+    # TODO AppIndicator
+  };
+}
diff --git a/pkgs/applications/emulators/cdemu/libmirage.nix b/pkgs/applications/emulators/cdemu/libmirage.nix
new file mode 100644
index 00000000000..7016a42d247
--- /dev/null
+++ b/pkgs/applications/emulators/cdemu/libmirage.nix
@@ -0,0 +1,18 @@
+{ callPackage, gobject-introspection, cmake, pkg-config
+, glib, libsndfile, zlib, bzip2, xz, libsamplerate, intltool
+, pcre, util-linux, libselinux, libsepol }:
+
+let pkg = import ./base.nix {
+  version = "3.2.5";
+  pname = "libmirage";
+  pkgSha256 = "0f8i2ha44rykkk3ac2q8zsw3y1zckw6qnf6zvkyrj3qqbzhrf3fm";
+};
+in callPackage pkg {
+  buildInputs = [ glib libsndfile zlib bzip2 xz libsamplerate intltool ];
+  drvParams = {
+    PKG_CONFIG_GOBJECT_INTROSPECTION_1_0_GIRDIR = "${placeholder "out"}/share/gir-1.0";
+    PKG_CONFIG_GOBJECT_INTROSPECTION_1_0_TYPELIBDIR = "${placeholder "out"}/lib/girepository-1.0";
+    nativeBuildInputs = [ cmake gobject-introspection pkg-config ];
+    propagatedBuildInputs = [ pcre util-linux libselinux libsepol ];
+  };
+}
diff --git a/pkgs/applications/emulators/cdemu/vhba.nix b/pkgs/applications/emulators/cdemu/vhba.nix
new file mode 100644
index 00000000000..aeadcf5c1c1
--- /dev/null
+++ b/pkgs/applications/emulators/cdemu/vhba.nix
@@ -0,0 +1,22 @@
+{ lib, stdenv, fetchurl, kernel }:
+
+stdenv.mkDerivation rec {
+  pname = "vhba";
+  version = "20211218";
+
+  src  = fetchurl {
+    url = "mirror://sourceforge/cdemu/vhba-module-${version}.tar.xz";
+    sha256 = "sha256-csWowcRSgF5M74yv787MLSXOGXrkxnODCCgC5a3Nd7Y=";
+  };
+
+  makeFlags = [ "KDIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" "INSTALL_MOD_PATH=$(out)" ];
+  nativeBuildInputs = kernel.moduleBuildDependencies;
+
+  meta = with lib; {
+    description = "Provides a Virtual (SCSI) HBA";
+    homepage = "https://cdemu.sourceforge.io/about/vhba/";
+    platforms = platforms.linux;
+    license = licenses.gpl2Plus;
+    maintainers = with lib.maintainers; [ bendlas ];
+  };
+}
diff --git a/pkgs/applications/emulators/cen64/default.nix b/pkgs/applications/emulators/cen64/default.nix
new file mode 100644
index 00000000000..ddf45547337
--- /dev/null
+++ b/pkgs/applications/emulators/cen64/default.nix
@@ -0,0 +1,30 @@
+{ lib, cmake, fetchFromGitHub, libGL, libiconv, libX11, openal, stdenv }:
+
+stdenv.mkDerivation rec {
+  pname = "cen64";
+  version = "unstable-2021-03-12";
+
+  src = fetchFromGitHub {
+    owner = "n64dev";
+    repo = "cen64";
+    rev = "1b31ca9b3c3bb783391ab9773bd26c50db2056a8";
+    sha256 = "0x1fz3z4ffl5xssiyxnmbhpjlf0k0fxsqn4f2ikrn17742dx4c0z";
+  };
+
+  nativeBuildInputs = [ cmake ];
+  buildInputs = [ libGL libiconv openal libX11 ];
+
+  installPhase = ''
+    runHook preInstall
+    install -D {,$out/bin/}${pname}
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    description = "A Cycle-Accurate Nintendo 64 Emulator";
+    license = licenses.bsd3;
+    homepage = "https://github.com/n64dev/cen64";
+    maintainers = [ maintainers._414owen ];
+    platforms = [ "x86_64-linux" ];
+  };
+}
diff --git a/pkgs/applications/emulators/citra/default.nix b/pkgs/applications/emulators/citra/default.nix
new file mode 100644
index 00000000000..92d0f5b1d36
--- /dev/null
+++ b/pkgs/applications/emulators/citra/default.nix
@@ -0,0 +1,91 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, cmake
+, wrapQtAppsHook
+, boost17x
+, pkg-config
+, libusb1
+, zstd
+, libressl
+, enableSdl2 ? true, SDL2
+, enableQt ? true, qtbase, qtmultimedia
+, enableQtTranslation ? enableQt, qttools
+, enableWebService ? true
+, enableCubeb ? true, libpulseaudio
+, enableFfmpegAudioDecoder ? true
+, enableFfmpegVideoDumper ? true
+, ffmpeg
+, useDiscordRichPresence ? true, rapidjson
+, enableFdk ? false, fdk_aac
+}:
+assert lib.assertMsg (!enableFfmpegAudioDecoder || !enableFdk) "Can't enable both enableFfmpegAudioDecoder and enableFdk";
+
+stdenv.mkDerivation {
+  pname = "citra";
+  version = "2021-11-01";
+
+  src = fetchFromGitHub {
+    owner = "citra-emu";
+    repo = "citra";
+    rev = "5a7d80172dd115ad9bc6e8e85cee6ed9511c48d0";
+    sha256 = "sha256-vy2JMizBsnRK9NBEZ1dxT7fP/HFhOZSsC+5P+Dzi27s=";
+    fetchSubmodules = true;
+  };
+
+  nativeBuildInputs = [
+    cmake
+    pkg-config
+  ]
+  ++ lib.optionals enableQt [ wrapQtAppsHook ];
+
+  buildInputs = [
+    boost17x
+    libusb1
+  ]
+  ++ lib.optionals enableSdl2 [ SDL2 ]
+  ++ lib.optionals enableQt [ qtbase qtmultimedia ]
+  ++ lib.optionals enableQtTranslation [ qttools ]
+  ++ lib.optionals enableCubeb [ libpulseaudio ]
+  ++ lib.optionals (enableFfmpegAudioDecoder || enableFfmpegVideoDumper) [ ffmpeg ]
+  ++ lib.optionals useDiscordRichPresence [ rapidjson ]
+  ++ lib.optionals enableFdk [ fdk_aac ];
+
+  cmakeFlags = [
+    "-DUSE_SYSTEM_BOOST=ON"
+  ]
+  ++ lib.optionals (!enableSdl2) [ "-DENABLE_SDL2=OFF" ]
+  ++ lib.optionals (!enableQt) [ "-DENABLE_QT=OFF" ]
+  ++ lib.optionals enableQtTranslation [ "-DENABLE_QT_TRANSLATION=ON" ]
+  ++ lib.optionals (!enableWebService) [ "-DENABLE_WEB_SERVICE=OFF" ]
+  ++ lib.optionals (!enableCubeb) [ "-DENABLE_CUBEB=OFF" ]
+  ++ lib.optionals enableFfmpegAudioDecoder [ "-DENABLE_FFMPEG_AUDIO_DECODER=ON"]
+  ++ lib.optionals enableFfmpegVideoDumper [ "-DENABLE_FFMPEG_VIDEO_DUMPER=ON" ]
+  ++ lib.optionals useDiscordRichPresence [ "-DUSE_DISCORD_PRESENCE=ON" ]
+  ++ lib.optionals enableFdk [ "-DENABLE_FDK=ON" ];
+
+  postPatch = ''
+    # We already know the submodules are present
+    substituteInPlace CMakeLists.txt \
+      --replace "check_submodules_present()" ""
+
+    # Devendoring
+    rm -rf externals/zstd externals/libressl
+    cp -r ${zstd.src} externals/zstd
+    tar xf ${libressl.src} -C externals/
+    mv externals/${libressl.name} externals/libressl
+    chmod -R a+w externals/zstd
+  '';
+
+  # Todo: cubeb audio backend (the default one) doesn't work on the SDL interface.
+  # This seems to be a problem with libpulseaudio, other applications have similar problems (e.g Duckstation).
+  # Note that the two interfaces have two separate configuration files.
+
+  meta = with lib; {
+    homepage = "https://citra-emu.org";
+    description = "An open-source emulator for the Nintendo 3DS";
+    license = licenses.gpl2;
+    maintainers = with maintainers; [ abbradar ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/commanderx16/emulator.nix b/pkgs/applications/emulators/commanderx16/emulator.nix
new file mode 100644
index 00000000000..73442215ff1
--- /dev/null
+++ b/pkgs/applications/emulators/commanderx16/emulator.nix
@@ -0,0 +1,42 @@
+{ stdenv
+, lib
+, fetchFromGitHub
+, SDL2
+}:
+
+stdenv.mkDerivation rec {
+  pname = "x16-emulator";
+  version = "38";
+
+  src = fetchFromGitHub {
+    owner = "commanderx16";
+    repo = pname;
+    rev = "r${version}";
+    sha256 = "WNRq/m97NpOBWIk6mtxBAKmkxCGWacWjXeOvIhBrkYE=";
+  };
+
+  dontConfigure = true;
+
+  buildInputs = [ SDL2 ];
+
+  installPhase = ''
+    runHook preInstall
+    install -D --mode 755 --target-directory $out/bin/ x16emu
+    install -D --mode 444 --target-directory $out/share/doc/${pname} README.md
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    homepage = "https://www.commanderx16.com/forum/index.php?/home/";
+    description = "The official emulator of CommanderX16 8-bit computer";
+    license = licenses.bsd2;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = SDL2.meta.platforms;
+  };
+
+  passthru = {
+    # upstream project recommends emulator and rom synchronized;
+    # passing through the version is useful to ensure this
+    inherit version;
+  };
+}
diff --git a/pkgs/applications/emulators/commanderx16/rom.nix b/pkgs/applications/emulators/commanderx16/rom.nix
new file mode 100644
index 00000000000..5da77ebceef
--- /dev/null
+++ b/pkgs/applications/emulators/commanderx16/rom.nix
@@ -0,0 +1,46 @@
+{ stdenv
+, lib
+, fetchFromGitHub
+, cc65
+}:
+
+stdenv.mkDerivation rec {
+  pname = "x16-rom";
+  version = "38";
+
+  src = fetchFromGitHub {
+    owner = "commanderx16";
+    repo = pname;
+    rev = "r${version}";
+    sha256 = "xaqF0ppB7I7ST8Uh3jPbC14uRAb/WH21tHlNeTvYpoI=";
+  };
+
+  nativeBuildInputs = [ cc65 ];
+
+  postPatch = ''
+    patchShebangs scripts/
+  '';
+
+  dontConfigure = true;
+
+  installPhase = ''
+    runHook preInstall
+    install -D --mode 444 --target-directory $out/share/${pname} build/x16/rom.bin
+    install -D --mode 444 --target-directory $out/share/doc/${pname} README.md
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    homepage = "https://www.commanderx16.com/forum/index.php?/home/";
+    description = "ROM file for CommanderX16 8-bit computer";
+    license = licenses.bsd2;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = cc65.meta.platforms;
+  };
+
+  passthru = {
+    # upstream project recommends emulator and rom synchronized;
+    # passing through the version is useful to ensure this
+    inherit version;
+  };
+}
diff --git a/pkgs/applications/emulators/commanderx16/run.nix b/pkgs/applications/emulators/commanderx16/run.nix
new file mode 100644
index 00000000000..1f14fdb223c
--- /dev/null
+++ b/pkgs/applications/emulators/commanderx16/run.nix
@@ -0,0 +1,37 @@
+{ runtimeShell
+, symlinkJoin
+, writeTextFile
+}:
+
+{ emulator, rom }:
+
+assert emulator.version == rom.version;
+
+let
+  runScript = writeTextFile {
+    name = "run-x16";
+    text = ''
+      #!${runtimeShell}
+
+      defaultRom="${rom}/share/x16-rom/rom.bin"
+
+      exec "${emulator}/bin/x16emu" -rom $defaultRom "$@"
+    '';
+    executable = true;
+    destination = "/bin/run-x16";
+  };
+in
+symlinkJoin {
+  name = "run-x16-${emulator.version}";
+
+  paths = [
+    emulator
+    rom
+    runScript
+  ];
+}
+# TODO [ AndersonTorres ]:
+
+# 1. Parse the command line in order to allow the user to set an optional
+# rom-file
+# 2. generate runScript based on symlinkJoin (maybe a postBuild?)
diff --git a/pkgs/applications/emulators/craftos-pc/default.nix b/pkgs/applications/emulators/craftos-pc/default.nix
new file mode 100644
index 00000000000..3bc9e0b81cc
--- /dev/null
+++ b/pkgs/applications/emulators/craftos-pc/default.nix
@@ -0,0 +1,43 @@
+{ lib, stdenv, fetchFromGitHub, poco, openssl, SDL2, SDL2_mixer }:
+
+let
+  craftos2-lua = fetchFromGitHub {
+    owner = "MCJack123";
+    repo = "craftos2-lua";
+    rev = "v2.4.4";
+    sha256 = "1q63ki4sxx8bxaa6ag3xj153p7a8a12ivm0k33k935p41k6y2k64";
+  };
+in
+
+stdenv.mkDerivation rec {
+  pname = "craftos-pc";
+  version = "2.4.5";
+
+  src = fetchFromGitHub {
+    owner = "MCJack123";
+    repo = "craftos2";
+    rev = "v${version}";
+    sha256 = "00a4p365krbdprlv4979d13mm3alhxgzzj3vqz2g67795plf64j4";
+  };
+
+  buildInputs = [ poco openssl SDL2 SDL2_mixer ];
+
+  preBuild = ''
+    cp -R ${craftos2-lua}/* ./craftos2-lua/
+    chmod -R u+w ./craftos2-lua
+    make -C craftos2-lua linux
+  '';
+
+  installPhase = ''
+    mkdir -p $out/bin
+    DESTDIR=$out/bin make install
+  '';
+
+  meta = with lib; {
+    description = "An implementation of the CraftOS-PC API written in C++ using SDL";
+    homepage = "https://www.craftos-pc.cc";
+    license = licenses.mit;
+    platforms = platforms.linux;
+    maintainers = [ maintainers.siraben ];
+  };
+}
diff --git a/pkgs/applications/emulators/darcnes/default.nix b/pkgs/applications/emulators/darcnes/default.nix
new file mode 100644
index 00000000000..7919e0a9009
--- /dev/null
+++ b/pkgs/applications/emulators/darcnes/default.nix
@@ -0,0 +1,24 @@
+{ lib, stdenv, fetchurl, libX11, libXt, libXext, libXaw }:
+
+stdenv.mkDerivation rec {
+  pname = "darcnes";
+  version = "9b0401";
+
+  src = fetchurl {
+    url = "https://web.archive.org/web/20130511081532/http://www.dridus.com/~nyef/darcnes/download/dn${version}.tgz";
+    sha256 = "05a7mh51rg7ydb414m3p5mm05p4nz2bgvspqzwm3bhbj7zz543k3";
+  };
+
+  patches = [ ./label.patch ];
+
+  buildInputs = [ libX11 libXt libXext libXaw ];
+  installPhase = "install -Dt $out/bin darcnes";
+
+  meta = {
+    homepage = "https://web.archive.org/web/20130502171725/http://www.dridus.com/~nyef/darcnes/";
+    description = "Sega Master System, Game Gear, SG-1000, NES, ColecoVision and Apple II emulator";
+    # Prohibited commercial use, credit required.
+    license = lib.licenses.free;
+    platforms = [ "i686-linux" ];
+  };
+}
diff --git a/pkgs/applications/emulators/darcnes/label.patch b/pkgs/applications/emulators/darcnes/label.patch
new file mode 100644
index 00000000000..612aa1e3911
--- /dev/null
+++ b/pkgs/applications/emulators/darcnes/label.patch
@@ -0,0 +1,13 @@
+http://gentoo-overlays.zugaina.org/funtoo/portage/games-emulation/darcnes/files/darcnes-0401-exec-stack.patch
+
+diff -Naur old/video_x.c new/video_x.c
+--- old/video_x.c	2004-09-04 01:26:41.102187277 +0200
++++ new/video_x.c	2004-09-04 01:27:51.586427427 +0200
+@@ -366,6 +366,7 @@
+ 	}
+ 	
+     default:
++    	break;
+     }
+ }
+ 
diff --git a/pkgs/applications/emulators/desmume/default.nix b/pkgs/applications/emulators/desmume/default.nix
new file mode 100644
index 00000000000..49cb2498e64
--- /dev/null
+++ b/pkgs/applications/emulators/desmume/default.nix
@@ -0,0 +1,87 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, SDL2
+, agg
+, alsa-lib
+, desktop-file-utils
+, gtk3
+, intltool
+, libGLU
+, libXmu
+, libpcap
+, libtool
+, lua
+, meson
+, ninja
+, openal
+, pkg-config
+, soundtouch
+, tinyxml
+, zlib
+}:
+
+stdenv.mkDerivation rec {
+  pname = "desmume";
+  version = "0.9.11+unstable=2021-09-22";
+
+  src = fetchFromGitHub {
+    owner = "TASVideos";
+    repo = pname;
+    rev = "7fc2e4b6b6a58420de65a4089d4df3934d7a46b1";
+    hash = "sha256-sTCyjQ31w1Lp+aa3VQ7/rdLbhjnqthce54mjKJZQIDM=";
+  };
+
+  nativeBuildInputs = [
+    desktop-file-utils
+    intltool
+    libtool
+    lua
+    meson
+    ninja
+    pkg-config
+  ];
+
+  buildInputs = [
+    SDL2
+    agg
+    alsa-lib
+    gtk3
+    libGLU
+    libXmu
+    libpcap
+    openal
+    soundtouch
+    tinyxml
+    zlib
+  ];
+
+  hardeningDisable = [ "format" ];
+
+  preConfigure = ''
+    cd desmume/src/frontend/posix
+  '';
+
+  mesonFlags = [
+    "-Db_pie=true"
+    "-Dopenal=true"
+    "-Dwifi=true"
+  ];
+
+  meta = with lib; {
+    homepage = "https://www.github.com/TASVideos/desmume/";
+    description = "An open-source Nintendo DS emulator";
+    longDescription = ''
+      DeSmuME is a freeware emulator for the NDS roms & Nintendo DS Lite games
+      created by YopYop156 and now maintained by the TASvideos team. It supports
+      many homebrew nds rom demoes as well as a handful of Wireless Multiboot
+      demo nds roms. DeSmuME is also able to emulate nearly all of the
+      commercial nds rom titles which other DS Emulators aren't.
+    '';
+    license = licenses.gpl2Plus;
+    maintainers = [ maintainers.AndersonTorres ];
+    platforms = platforms.unix;
+  };
+}
+# TODO: investigate the patches
+# TODO: investigate other platforms
diff --git a/pkgs/applications/emulators/dgen-sdl/default.nix b/pkgs/applications/emulators/dgen-sdl/default.nix
new file mode 100644
index 00000000000..e56ca12a4e9
--- /dev/null
+++ b/pkgs/applications/emulators/dgen-sdl/default.nix
@@ -0,0 +1,69 @@
+{ lib, stdenv
+, fetchurl
+, libarchive
+, SDL
+}:
+
+let
+  pname = "dgen-sdl";
+  version = "1.33";
+in stdenv.mkDerivation {
+  inherit pname version;
+
+  src = fetchurl {
+    url = "https://sourceforge.net/projects/dgen/files/dgen/${version}/${pname}-${version}.tar.gz";
+    hash = "sha256-meLAYBfCKHPHf4gYbrzAmGckTrbgQsdjuwlLArje9h4=";
+  };
+
+  buildInputs = [ SDL libarchive ];
+
+  configureFlags = [
+    "--enable-joystick"
+    "--enable-debugger"
+    "--enable-debug-vdp"
+    "--enable-pico" # experimental
+    "--enable-vgmdump"
+    "--with-star=no" # Needs ASM support
+    "--with-musa"
+    "--with-cyclone=no" # Needs ASM support
+    "--with-mz80"
+    "--with-cz80"
+    "--with-drz80=no" # Needs ASM support
+    "--with-dz80"
+  ];
+
+  meta = with lib; {
+    homepage = "https://dgen.sourceforge.net/";
+    description = "Sega Genesis/Mega Drive emulator";
+    longDescription = ''
+      DGen/SDL is a free, open source emulator for Sega Genesis/Mega Drive
+      systems. DGen was originally written by Dave, then ported to SDL by Joe
+      Groff and Phil K. Hornung in 1998.
+
+      It features:
+
+      - Game Genie/Hex codes support
+      - PAL/NTSC, fullscreen modes
+      - Joypad/joystick support
+      - Mouse support
+      - Highly configurable controls
+      - OpenGL textured video output
+      - Portable (64‐bit, endian safe), runs in Windows using MinGW
+      - Screenshots, demos recording and playback
+      - Musashi (generic) and StarScream (x86‐only) CPU cores
+      - Cyclone 68000 and DrZ80 (both ARM‐only) CPU cores
+      - CZ80 (generic) and MZ80 (generic and x86‐only versions)
+      - 16‐bit, 8000 to 48000Hz sound output
+      - Support for 8, 15, 16, 24 and 32 bpp modes
+      - Archived/compressed ROMs support
+      - M68K debugger (contributed by Edd Barrett)
+      - Z80 debugger
+      - hqx and scale2x upscaling filters
+      - VGM dumping
+    '';
+    license = licenses.mit;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = with platforms; unix;
+  };
+}
+# TODO: implement configure options
diff --git a/pkgs/applications/emulators/dlx/default.nix b/pkgs/applications/emulators/dlx/default.nix
new file mode 100644
index 00000000000..9573dd6d48d
--- /dev/null
+++ b/pkgs/applications/emulators/dlx/default.nix
@@ -0,0 +1,29 @@
+{ lib, stdenv, fetchzip }:
+
+stdenv.mkDerivation rec {
+  pname = "dlx";
+  version = "2012-07-08";
+
+  src = fetchzip {
+    url = "https://www.davidviner.com/zip/dlx/dlx.zip";
+    sha256 = "0508linnar9ivy3xr99gzrb2l027ngx12dlxaxs7w67cnwqnb0dg";
+  };
+
+  makeFlags = [ "CC=${stdenv.cc.targetPrefix}cc" "LINK=${stdenv.cc.targetPrefix}cc" "CFLAGS=-O2" ];
+  hardeningDisable = [ "format" ];
+
+  installPhase = ''
+    mkdir -p $out/include/dlx $out/share/dlx/{examples,doc} $out/bin
+    mv masm mon dasm $out/bin/
+    mv *.i auto.a $out/include/dlx/
+    mv *.a *.m $out/share/dlx/examples/
+    mv README.txt MANUAL.TXT $out/share/dlx/doc/
+  '';
+
+  meta = with lib; {
+    homepage = "https://www.davidviner.com/dlx.html?name=DLX+Simulator";
+    description = "An DLX simulator written in C";
+    license = licenses.gpl2Only;
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/dolphin-emu/default.nix b/pkgs/applications/emulators/dolphin-emu/default.nix
new file mode 100644
index 00000000000..c2d73d3e7ff
--- /dev/null
+++ b/pkgs/applications/emulators/dolphin-emu/default.nix
@@ -0,0 +1,122 @@
+{ stdenv
+, lib
+, fetchpatch
+, pkg-config
+, cmake
+, bluez
+, ffmpeg
+, libao
+, gtk2
+, glib
+, libGLU
+, libGL
+, gettext
+, libpthreadstubs
+, libXrandr
+, libXext
+, readline
+, openal
+, libXdmcp
+, portaudio
+, fetchFromGitHub
+, libusb1
+, libevdev
+, wxGTK30
+, soundtouch
+, miniupnpc
+, mbedtls
+, curl
+, lzo
+, sfml
+, libpulseaudio ? null
+}:
+
+stdenv.mkDerivation rec {
+  pname = "dolphin-emu";
+  version = "5.0";
+
+  src = fetchFromGitHub {
+    owner = "dolphin-emu";
+    repo = "dolphin";
+    rev = version;
+    sha256 = "07mlfnh0hwvk6xarcg315x7z2j0qbg9g7cm040df9c8psiahc3g6";
+  };
+
+  patches = [
+    # Fix build with soundtouch 2.1.2
+    (fetchpatch {
+      url = "https://src.fedoraproject.org/rpms/dolphin-emu/raw/a1b91fdf94981e12c8889a02cba0ec2267d0f303/f/dolphin-emu-5.0-soundtouch-exception-fix.patch";
+      name = "dolphin-emu-5.0-soundtouch-exception-fix.patch";
+      sha256 = "0yd3l46nja5qiknnl30ryad98f3v8911jwnr67hn61dzx2kwbbaw";
+    })
+    # Fix build with gcc 8
+    (fetchpatch {
+      url = "https://salsa.debian.org/games-team/dolphin-emu/raw/9b7b4aeac1b60dcf28bdcafbed6bc498b2aeb0ad/debian/patches/03_gcc8.patch";
+      name = "03_gcc8.patch";
+      sha256 = "1da95gb8c95kd5cjhdvg19cv2z863lj3va5gx3bqc7g8r36glqxr";
+    })
+  ];
+
+  postPatch = ''
+    substituteInPlace Source/Core/VideoBackends/OGL/RasterFont.cpp \
+      --replace " CHAR_WIDTH " " CHARWIDTH "
+  '';
+
+  cmakeFlags = [
+    "-DGTK2_GLIBCONFIG_INCLUDE_DIR=${glib.out}/lib/glib-2.0/include"
+    "-DGTK2_GDKCONFIG_INCLUDE_DIR=${gtk2.out}/lib/gtk-2.0/include"
+    "-DGTK2_INCLUDE_DIRS=${gtk2.dev}/include/gtk-2.0"
+    "-DENABLE_LTO=True"
+  ];
+
+  nativeBuildInputs = [
+    pkg-config
+    cmake
+  ];
+
+  buildInputs = [
+    bluez
+    ffmpeg
+    libao
+    libGLU
+    libGL
+    gtk2
+    glib
+    gettext
+    libpthreadstubs
+    libXrandr
+    libXext
+    readline
+    openal
+    libevdev
+    libXdmcp
+    portaudio
+    libpulseaudio
+    libevdev
+    libXdmcp
+    portaudio
+    libusb1
+    libpulseaudio
+    wxGTK30
+    soundtouch
+    miniupnpc
+    mbedtls
+    curl
+    lzo
+    sfml
+  ];
+
+  postInstall = lib.optionalString stdenv.hostPlatform.isLinux ''
+    install -D $src/Data/51-usb-device.rules $out/etc/udev/rules.d/51-usb-device.rules
+  '';
+
+  meta = with lib; {
+    homepage = "https://dolphin-emu.org/";
+    description = "Gamecube/Wii/Triforce emulator for x86_64 and ARMv8";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ MP2E ashkitten ];
+    # x86_32 is an unsupported platform.
+    # Enable generic build if you really want a JIT-less binary.
+    platforms = [ "x86_64-linux" ];
+  };
+}
diff --git a/pkgs/applications/emulators/dolphin-emu/master.nix b/pkgs/applications/emulators/dolphin-emu/master.nix
new file mode 100644
index 00000000000..56e107300b5
--- /dev/null
+++ b/pkgs/applications/emulators/dolphin-emu/master.nix
@@ -0,0 +1,89 @@
+{ lib, stdenv, fetchFromGitHub, pkg-config, cmake
+, wrapQtAppsHook, qtbase, bluez, ffmpeg, libao, libGLU, libGL, pcre, gettext
+, libXrandr, libusb1, lzo, libpthreadstubs, libXext, libXxf86vm, libXinerama
+, libSM, libXdmcp, readline, openal, udev, libevdev, portaudio, curl, alsa-lib
+, miniupnpc, enet, mbedtls, soundtouch, sfml, writeScript
+, vulkan-loader ? null, libpulseaudio ? null
+
+# - Inputs used for Darwin
+, CoreBluetooth, ForceFeedback, IOKit, OpenGL, libpng, hidapi }:
+
+stdenv.mkDerivation rec {
+  pname = "dolphin-emu";
+  version = "5.0-15993";
+
+  src = fetchFromGitHub {
+    owner = "dolphin-emu";
+    repo = "dolphin";
+    rev = "5e595616379a694789fe749e40a27ef069f0090e";
+    sha256 = "1kid8qjn8r7dxh2yc1y6yal6qkfxij0ymi3zryxsnym3rjh1jds9";
+    fetchSubmodules = true;
+  };
+
+  nativeBuildInputs = [ cmake pkg-config ]
+  ++ lib.optional stdenv.isLinux wrapQtAppsHook;
+
+  buildInputs = [
+    curl ffmpeg libao libGLU libGL pcre gettext libpthreadstubs libpulseaudio
+    libXrandr libXext libXxf86vm libXinerama libSM readline openal libXdmcp lzo
+    portaudio libusb1 libpng hidapi miniupnpc enet mbedtls soundtouch sfml
+    qtbase
+  ] ++ lib.optionals stdenv.isLinux [
+    bluez udev libevdev alsa-lib vulkan-loader
+  ] ++ lib.optionals stdenv.isDarwin [
+    CoreBluetooth OpenGL ForceFeedback IOKit
+  ];
+
+  cmakeFlags = [
+    "-DUSE_SHARED_ENET=ON"
+    "-DENABLE_LTO=ON"
+    "-DDOLPHIN_WC_REVISION=${src.rev}"
+    "-DDOLPHIN_WC_DESCRIBE=${version}"
+    "-DDOLPHIN_WC_BRANCH=master"
+  ] ++ lib.optionals stdenv.isDarwin [
+    "-DOSX_USE_DEFAULT_SEARCH_PATH=True"
+  ];
+
+  qtWrapperArgs = lib.optionals stdenv.isLinux [
+    "--prefix LD_LIBRARY_PATH : ${vulkan-loader}/lib"
+    # https://bugs.dolphin-emu.org/issues/11807
+    # The .desktop file should already set this, but Dolphin may be launched in other ways
+    "--set QT_QPA_PLATFORM xcb"
+  ];
+
+  # - Allow Dolphin to use nix-provided libraries instead of building them
+  postPatch = ''
+    sed -i -e 's,DISTRIBUTOR "None",DISTRIBUTOR "NixOS",g' CMakeLists.txt
+  '' + lib.optionalString stdenv.isDarwin ''
+    sed -i -e 's,if(NOT APPLE),if(true),g' CMakeLists.txt
+    sed -i -e 's,if(LIBUSB_FOUND AND NOT APPLE),if(LIBUSB_FOUND),g' \
+      CMakeLists.txt
+  '';
+
+  postInstall = lib.optionalString stdenv.hostPlatform.isLinux ''
+    install -D $src/Data/51-usb-device.rules $out/etc/udev/rules.d/51-usb-device.rules
+  '';
+
+
+  passthru.updateScript = writeScript "dolphin-update-script" ''
+    #!/usr/bin/env nix-shell
+    #!nix-shell -i bash -p curl jq common-updater-scripts
+    set -eou pipefail
+    json="$(curl -s https://dolphin-emu.org/update/latest/beta)"
+    version="$(jq -r '.shortrev' <<< "$json")"
+    rev="$(jq -r '.hash' <<< "$json")"
+    update-source-version dolphin-emu-beta "$version" --rev="$rev"
+  '';
+
+  meta = with lib; {
+    homepage = "https://dolphin-emu.org";
+    description = "Gamecube/Wii/Triforce emulator for x86_64 and ARMv8";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ MP2E ashkitten xfix ];
+    branch = "master";
+    # x86_32 is an unsupported platform.
+    # Enable generic build if you really want a JIT-less binary.
+    broken = stdenv.isDarwin;
+    platforms = [ "x86_64-linux" "x86_64-darwin" ];
+  };
+}
diff --git a/pkgs/applications/emulators/dolphin-emu/primehack.nix b/pkgs/applications/emulators/dolphin-emu/primehack.nix
new file mode 100644
index 00000000000..90510d64522
--- /dev/null
+++ b/pkgs/applications/emulators/dolphin-emu/primehack.nix
@@ -0,0 +1,151 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, pkg-config
+, cmake
+, wrapQtAppsHook
+, qtbase
+, bluez
+, ffmpeg
+, libao
+, libGLU
+, libGL
+, pcre
+, gettext
+, libXrandr
+, libusb1
+, lzo
+, libpthreadstubs
+, libXext
+, libXxf86vm
+, libXinerama
+, libSM
+, libXdmcp
+, readline
+, openal
+, udev
+, libevdev
+, portaudio
+, curl
+, alsa-lib
+, miniupnpc
+, enet
+, mbedtls
+, soundtouch
+, sfml
+, fmt
+, vulkan-loader
+, libpulseaudio
+
+# - Inputs used for Darwin
+, CoreBluetooth
+, ForceFeedback
+, IOKit
+, OpenGL
+, libpng
+, hidapi
+}:
+
+stdenv.mkDerivation rec {
+  pname = "dolphin-emu-primehack";
+  version = "1.0.5";
+
+  src = fetchFromGitHub {
+    owner = "shiiion";
+    repo = "dolphin";
+    rev = version;
+    sha256 = "011qghswgh9l7k993lfn1hrwhgyrv9m33smgspsjq50jww6r27fl";
+    fetchSubmodules = true;
+  };
+
+  nativeBuildInputs = [
+    pkg-config
+    cmake
+  ] ++ lib.optional stdenv.isLinux wrapQtAppsHook;
+
+  buildInputs = [
+    curl
+    ffmpeg
+    libao
+    libGLU
+    libGL
+    pcre
+    gettext
+    libpthreadstubs
+    libpulseaudio
+    libXrandr
+    libXext
+    libXxf86vm
+    libXinerama
+    libSM
+    readline
+    openal
+    libXdmcp
+    lzo
+    portaudio
+    libusb1
+    libpng
+    hidapi
+    miniupnpc
+    enet
+    mbedtls
+    soundtouch
+    sfml
+    fmt
+    qtbase
+  ] ++ lib.optionals stdenv.isLinux [
+    bluez
+    udev
+    libevdev
+    alsa-lib
+    vulkan-loader
+  ] ++ lib.optionals stdenv.isDarwin [
+    CoreBluetooth
+    OpenGL
+    ForceFeedback
+    IOKit
+  ];
+
+  cmakeFlags = [
+    "-DUSE_SHARED_ENET=ON"
+    "-DENABLE_LTO=ON"
+  ] ++ lib.optionals stdenv.isDarwin [
+    "-DOSX_USE_DEFAULT_SEARCH_PATH=True"
+  ];
+
+  qtWrapperArgs = lib.optionals stdenv.isLinux [
+    "--prefix LD_LIBRARY_PATH : ${vulkan-loader}/lib"
+    # https://bugs.dolphin-emu.org/issues/11807
+    # The .desktop file should already set this, but Dolphin may be launched in other ways
+    "--set QT_QPA_PLATFORM xcb"
+  ];
+
+  # - Allow Dolphin to use nix-provided libraries instead of building them
+  postPatch = ''
+    substituteInPlace CMakeLists.txt --replace 'DISTRIBUTOR "None"' 'DISTRIBUTOR "NixOS"'
+  '' + lib.optionalString stdenv.isDarwin ''
+    substituteInPlace CMakeLists.txt --replace 'if(NOT APPLE)' 'if(true)'
+    substituteInPlace CMakeLists.txt --replace 'if(LIBUSB_FOUND AND NOT APPLE)' 'if(LIBUSB_FOUND)'
+  '';
+
+  postInstall = ''
+    mv $out/bin/dolphin-emu $out/bin/dolphin-emu-primehack
+    mv $out/bin/dolphin-emu-nogui $out/bin/dolphin-emu-primehack-nogui
+    mv $out/share/applications/dolphin-emu.desktop $out/share/applications/dolphin-emu-primehack.desktop
+    mv $out/share/icons/hicolor/256x256/apps/dolphin-emu.png $out/share/icons/hicolor/256x256/apps/dolphin-emu-primehack.png
+    substituteInPlace $out/share/applications/dolphin-emu-primehack.desktop --replace 'dolphin-emu' 'dolphin-emu-primehack'
+  '' + lib.optionalString stdenv.hostPlatform.isLinux ''
+    install -D $src/Data/51-usb-device.rules $out/etc/udev/rules.d/51-usb-device.rules
+  '';
+
+  meta = with lib; {
+    homepage = "https://github.com/shiiion/dolphin";
+    description = "Gamecube/Wii/Triforce emulator for x86_64 and ARMv8";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ MP2E ashkitten Madouura ];
+    # x86_32 is an unsupported platform.
+    # Enable generic build if you really want a JIT-less binary.
+    broken = stdenv.isDarwin;
+    platforms = [ "x86_64-linux" "x86_64-darwin" ];
+  };
+}
diff --git a/pkgs/applications/emulators/dosbox-staging/default.nix b/pkgs/applications/emulators/dosbox-staging/default.nix
new file mode 100644
index 00000000000..438849e7fd8
--- /dev/null
+++ b/pkgs/applications/emulators/dosbox-staging/default.nix
@@ -0,0 +1,112 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, SDL2
+, SDL2_net
+, alsa-lib
+, copyDesktopItems
+, fluidsynth
+, gtest
+, libGL
+, libGLU
+, libogg
+, libpng
+, libslirp
+, makeDesktopItem
+, makeWrapper
+, meson
+, libmt32emu
+, ninja
+, opusfile
+, pkg-config
+, libpulseaudio
+, glib
+, libjack2
+, libsndfile
+}:
+
+stdenv.mkDerivation rec {
+  pname = "dosbox-staging";
+  version = "0.78.1";
+
+  src = fetchFromGitHub {
+    owner = pname;
+    repo = pname;
+    rev = "v${version}";
+    hash = "sha256-gozFZcJorZtbEK0joksig6qWmAMy03hmBHiyJMONfpk=";
+  };
+
+  nativeBuildInputs = [
+    copyDesktopItems
+    gtest
+    makeWrapper
+    meson
+    ninja
+    pkg-config
+  ];
+
+  buildInputs = [
+    SDL2
+    SDL2_net
+    alsa-lib
+    fluidsynth
+    glib
+    libGL
+    libGLU
+    libjack2
+    libmt32emu
+    libogg
+    libpng
+    libpulseaudio
+    libslirp
+    libsndfile
+    opusfile
+  ];
+
+   NIX_CFLAGS_COMPILE = [
+     "-I${SDL2_net}/include/SDL2"
+   ];
+
+  desktopItems = [
+    (makeDesktopItem {
+      name = "dosbox-staging";
+      exec = "dosbox-staging";
+      icon = "dosbox-staging";
+      comment = "x86 dos emulator enhanced";
+      desktopName = "DosBox-Staging";
+      genericName = "DOS emulator";
+      categories = "Emulator;Game;";
+    })
+  ];
+
+  postFixup = ''
+    # Rename binary, add a wrapper, and copy manual to avoid conflict with
+    # original dosbox. Doing it this way allows us to work with frontends and
+    # launchers that expect the binary to be named dosbox, but get out of the
+    # way of vanilla dosbox if the user desires to install that as well.
+    mv $out/bin/dosbox $out/bin/${pname}
+    makeWrapper $out/bin/dosbox-staging $out/bin/dosbox
+
+    # Create a symlink to dosbox manual instead of merely copying it
+    pushd $out/share/man/man1/
+    mv dosbox.1.gz ${pname}.1.gz
+    ln -s ${pname}.1.gz dosbox.1.gz
+    popd
+  '';
+
+  meta = with lib; {
+    homepage = "https://dosbox-staging.github.io/";
+    description = "A modernized DOS emulator";
+    longDescription = ''
+      DOSBox Staging is an attempt to revitalize DOSBox's development
+      process. It's not a rewrite, but a continuation and improvement on the
+      existing DOSBox codebase while leveraging modern development tools and
+      practices.
+    '';
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ joshuafern AndersonTorres ];
+    platforms = platforms.unix;
+    priority = 101;
+  };
+}
+# TODO: report upstream about not finding SDL2_net
diff --git a/pkgs/applications/emulators/dosbox/default.nix b/pkgs/applications/emulators/dosbox/default.nix
new file mode 100644
index 00000000000..383e943ff24
--- /dev/null
+++ b/pkgs/applications/emulators/dosbox/default.nix
@@ -0,0 +1,75 @@
+{ lib
+, stdenv
+, fetchurl
+, SDL
+, SDL_net
+, SDL_sound
+, copyDesktopItems
+, graphicsmagick
+, libGL
+, libGLU
+, libpng
+, makeDesktopItem
+}:
+
+stdenv.mkDerivation rec {
+  pname = "dosbox";
+  version = "0.74-3";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/dosbox/dosbox-${version}.tar.gz";
+    hash = "sha256-wNE91+0u02O2jeYVR1eB6JHNWC6BYrXDZpE3UCIiJgo=";
+  };
+
+  nativeBuildInputs = [
+    copyDesktopItems
+    graphicsmagick
+  ];
+
+  buildInputs = [
+    SDL
+    SDL_net
+    SDL_sound
+    libGL
+    libGLU
+    libpng
+  ];
+
+  hardeningDisable = [ "format" ];
+
+  configureFlags = lib.optional stdenv.isDarwin "--disable-sdltest";
+
+  desktopItems = [
+    (makeDesktopItem {
+      name = "dosbox";
+      exec = "dosbox";
+      icon = "dosbox";
+      comment = "x86 dos emulator";
+      desktopName = "DOSBox";
+      genericName = "DOS emulator";
+      categories = "Emulator;Game;";
+    })
+  ];
+
+  postInstall = ''
+     mkdir -p $out/share/icons/hicolor/256x256/apps
+     gm convert src/dosbox.ico $out/share/icons/hicolor/256x256/apps/dosbox.png
+  '';
+
+  enableParallelBuilding = true;
+
+  meta = with lib; {
+    homepage = "http://www.dosbox.com/";
+    description = "A DOS emulator";
+    longDescription = ''
+      DOSBox is an emulator that recreates a MS-DOS compatible environment
+      (complete with Sound, Input, Graphics and even basic networking). This
+      environment is complete enough to run many classic MS-DOS games completely
+      unmodified. In order to utilize all of DOSBox's features you need to first
+      understand some basic concepts about the MS-DOS environment.
+    '';
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ matthewbauer ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/applications/emulators/duckstation/default.nix b/pkgs/applications/emulators/duckstation/default.nix
new file mode 100644
index 00000000000..8e4d909a724
--- /dev/null
+++ b/pkgs/applications/emulators/duckstation/default.nix
@@ -0,0 +1,106 @@
+{ lib
+, mkDerivation
+, fetchFromGitHub
+, SDL2
+, cmake
+, curl
+, extra-cmake-modules
+, gtk3
+, libevdev
+, libpulseaudio
+, mesa
+, ninja
+, pkg-config
+, qtbase
+, qttools
+, sndio
+, vulkan-loader
+, wayland
+, wrapQtAppsHook
+}:
+
+mkDerivation rec {
+  pname = "duckstation";
+  version = "0.pre+date=2022-01-18";
+
+  src = fetchFromGitHub {
+    owner = "stenzek";
+    repo = pname;
+    rev = "51041e47f70123eda41d999701f5651830a0a95e";
+    sha256 = "sha256-nlF6ctDU8KCK7MN2pniPLLqUbPUygX9rl0hjzVQ+mPo=";
+  };
+
+  nativeBuildInputs = [
+    cmake
+    extra-cmake-modules
+    ninja
+    pkg-config
+    qttools
+    wrapQtAppsHook
+  ];
+
+  buildInputs = [
+    SDL2
+    curl
+    gtk3
+    libevdev
+    libpulseaudio
+    mesa
+    qtbase
+    sndio
+    vulkan-loader
+    wayland
+  ];
+
+  cmakeFlags = [
+    "-DUSE_DRMKMS=ON"
+    "-DUSE_WAYLAND=ON"
+  ];
+
+  postPatch = ''
+    substituteInPlace extras/linux-desktop-files/duckstation-qt.desktop \
+      --replace "duckstation-qt" "duckstation" \
+      --replace "TryExec=duckstation" "tryExec=duckstation-qt" \
+      --replace "Exec=duckstation" "Exec=duckstation-qt"
+    substituteInPlace extras/linux-desktop-files/duckstation-nogui.desktop \
+      --replace "duckstation-nogui" "duckstation" \
+      --replace "TryExec=duckstation" "tryExec=duckstation-nogui" \
+      --replace "Exec=duckstation" "Exec=duckstation-nogui"
+  '';
+
+  installPhase = ''
+    runHook preInstall
+
+    mkdir -p $out/bin $out/share $out/share/pixmaps $out/share/applications
+    rm bin/common-tests
+
+    cp -r bin $out/share/duckstation
+    ln -s $out/share/duckstation/duckstation-{qt,nogui} $out/bin/
+
+    cp ../extras/icons/icon-256px.png $out/share/pixmaps/duckstation.png
+    cp ../extras/linux-desktop-files/* $out/share/applications/
+
+    runHook postInstall
+  '';
+
+  doCheck = true;
+  checkPhase = ''
+    runHook preCheck
+    ./bin/common-tests
+    runHook postCheck
+  '';
+
+  qtWrapperArgs = [
+    "--prefix LD_LIBRARY_PATH : ${vulkan-loader}/lib"
+  ];
+
+  meta = with lib; {
+    homepage = "https://github.com/stenzek/duckstation";
+    description = "Fast PlayStation 1 emulator for x86-64/AArch32/AArch64";
+    license = licenses.gpl3Only;
+    maintainers = with maintainers; [ guibou AndersonTorres ];
+    platforms = platforms.linux;
+  };
+}
+# TODO: default sound backend (cubeb) does not work, but SDL does. Strangely,
+# switching to cubeb while a game is running makes it work.
diff --git a/pkgs/applications/emulators/emu2/default.nix b/pkgs/applications/emulators/emu2/default.nix
new file mode 100644
index 00000000000..7949a3f2b05
--- /dev/null
+++ b/pkgs/applications/emulators/emu2/default.nix
@@ -0,0 +1,26 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+}:
+
+stdenv.mkDerivation rec {
+  pname = "emu2";
+  version = "0.pre+unstable=2021-09-22";
+
+  src = fetchFromGitHub {
+    owner = "dmsc";
+    repo = "emu2";
+    rev = "8d01b53f154d6bfc9561a44b9c281b46e00a4e87";
+    hash = "sha256-Jafl0Pw2k5RCF9GgpdAWcQ+HBTsiX7dOKSMCWPHQ+2E=";
+  };
+
+  makeFlags = [ "PREFIX=$(out)" ];
+
+  meta = with lib; {
+    homepage = "https://github.com/dmsc/emu2/";
+    description = "A simple text-mode x86 + DOS emulator";
+    platforms = platforms.linux;
+    maintainers = with maintainers; [ AndersonTorres ];
+    license = licenses.gpl2Plus;
+  };
+}
diff --git a/pkgs/applications/emulators/emulationstation/default.nix b/pkgs/applications/emulators/emulationstation/default.nix
new file mode 100644
index 00000000000..4cb5ca9ec2e
--- /dev/null
+++ b/pkgs/applications/emulators/emulationstation/default.nix
@@ -0,0 +1,37 @@
+{ lib, stdenv, fetchFromGitHub, pkg-config, cmake, curl, boost, eigen
+, freeimage, freetype, libGLU, libGL, SDL2, alsa-lib, libarchive
+, fetchpatch }:
+
+stdenv.mkDerivation {
+  pname = "emulationstation";
+  version = "2.0.1a";
+
+  src = fetchFromGitHub {
+    owner = "Aloshi";
+    repo = "EmulationStation";
+    rev = "646bede3d9ec0acf0ae378415edac136774a66c5";
+    sha256 = "0cm0sq2wri2l9cvab1l0g02za59q7klj0h3p028vr96n6njj4w9v";
+  };
+
+  patches = [
+    (fetchpatch {
+      url = "https://github.com/Aloshi/EmulationStation/commit/49ccd8fc7a7b1dfd974fc57eb13317c42842f22c.patch";
+      sha256 = "1v5d81l7bav0k5z4vybrc3rjcysph6lkm5pcfr6m42wlz7jmjw0p";
+    })
+  ];
+
+  nativeBuildInputs = [ pkg-config cmake ];
+  buildInputs = [ alsa-lib boost curl eigen freeimage freetype libarchive libGLU libGL SDL2 ];
+
+  installPhase = ''
+    install -D ../emulationstation $out/bin/emulationstation
+  '';
+
+  meta = {
+    description = "A flexible emulator front-end supporting keyboardless navigation and custom system themes";
+    homepage = "https://emulationstation.org";
+    maintainers = [ lib.maintainers.edwtjo ];
+    license = lib.licenses.mit;
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/epsxe/default.nix b/pkgs/applications/emulators/epsxe/default.nix
new file mode 100644
index 00000000000..f39c2ae74ac
--- /dev/null
+++ b/pkgs/applications/emulators/epsxe/default.nix
@@ -0,0 +1,52 @@
+{ lib, stdenv, fetchurl, alsa-lib, curl, gdk-pixbuf, glib, gtk3, libGLU, libGL,
+  libX11, openssl_1_0_2, ncurses5, SDL, SDL_ttf, unzip, zlib, wrapGAppsHook, autoPatchelfHook }:
+
+with lib;
+
+stdenv.mkDerivation rec {
+  pname = "epsxe";
+  version = "2.0.5";
+
+  src = let
+    version2 = replaceStrings ["."] [""] version;
+    platform = "linux" + (optionalString stdenv.is64bit "_x64");
+  in fetchurl {
+    url = "https://www.epsxe.com/files/ePSXe${version2}${platform}.zip";
+    sha256 = if stdenv.is64bit
+             then "16fa9qc2xhaz1f6294m0b56s5l86cbmclwm9w3mqnch0yjsrvab0"
+             else "1677lclam557kp8jwvchdrk27zfj50fqx2q9i3bcx26d9k61q3kl";
+  };
+
+  nativeBuildInputs = [ unzip wrapGAppsHook autoPatchelfHook ];
+  sourceRoot = ".";
+
+  buildInputs = [
+    alsa-lib
+    curl
+    gdk-pixbuf
+    glib
+    gtk3
+    libX11
+    libGLU libGL
+    openssl_1_0_2
+    ncurses5
+    SDL
+    SDL_ttf
+    stdenv.cc.cc.lib
+    zlib
+  ];
+
+  dontStrip = true;
+
+  installPhase = ''
+    install -D ${if stdenv.is64bit then "epsxe_x64" else "ePSXe"} $out/bin/epsxe
+  '';
+
+  meta = {
+    homepage = "http://epsxe.com/";
+    description = "Enhanced PSX (PlayStation 1) emulator";
+    license = licenses.unfree;
+    maintainers = with maintainers; [ yana ];
+    platforms = [ "i686-linux" "x86_64-linux" ];
+  };
+}
diff --git a/pkgs/applications/emulators/fakenes/build.patch b/pkgs/applications/emulators/fakenes/build.patch
new file mode 100644
index 00000000000..90799d977a1
--- /dev/null
+++ b/pkgs/applications/emulators/fakenes/build.patch
@@ -0,0 +1,84 @@
+diff --git a/build/openal.cbd b/build/openal.cbd
+index d18e62d..74af061 100644
+--- a/build/openal.cbd
++++ b/build/openal.cbd
+@@ -23,7 +23,7 @@ CFLAGS += ' -DUSE_OPENAL'
+ # --
+ 
+ do ifplat unix
+-   LDFLAGS += ' `openal-config --libs`'
++   LDFLAGS += ' -lopenal'
+ else
+    LDFLAGS += ' -lOpenAL32'
+ done
+diff --git a/build/alleggl.cbd b/build/alleggl.cbd
+index e2708ff..e826371 100644
+--- a/build/alleggl.cbd
++++ b/build/alleggl.cbd
+@@ -22,7 +22,7 @@ CFLAGS += ' -DUSE_ALLEGROGL'
+ 
+ # --
+ 
+-LIBAGL = agl
++LIBAGL = alleggl
+ 
+ ifopt debug LIBAGL = 'agld'
+
+diff --git a/src/apu.cpp b/src/apu.cpp
+index af59f1c..893a798 100644
+--- a/src/apu.cpp
++++ b/src/apu.cpp
+@@ -1930,7 +1930,7 @@ static void amplify(real& sample)
+          gain -= releaseRate;
+       }
+ 
+-      real output = (1.0 / max(gain, EPSILON));
++      real output = (1.0 / MAX(gain, EPSILON));
+       output = fixf(output, apu_agc_gain_floor, apu_agc_gain_ceiling);
+       sample *= output;
+    }
+diff --git a/src/audio.cpp b/src/audio.cpp
+index b9650dc..c21c05e 100644
+--- a/src/audio.cpp
++++ b/src/audio.cpp
+@@ -7,6 +7,7 @@
+    You must read and accept the license prior to use. */
+ 
+ #include <allegro.h>
++#include <cstdio>
+ #include <cstdlib>
+ #include <cstring>
+ #include <vector>
+@@ -234,7 +235,7 @@ void audio_update(void)
+          const unsigned queuedFrames = (audioQueue.size() / audio_channels);
+          if(queuedFrames > 0) {
+             // Determine how many frames we want to make room for.
+-            const unsigned framesToAdd = min(queuedFrames, audio_buffer_size_frames);
++            const unsigned framesToAdd = MIN(queuedFrames, audio_buffer_size_frames);
+             // Make room for the frames in the buffer.
+             const unsigned framesToMove = (audioBufferedFrames - framesToAdd);
+             if(framesToMove > 0) {
+@@ -258,7 +259,7 @@ void audio_update(void)
+          // Determine how many frames are available in the buffer.
+          const unsigned bufferableFrames = (audio_buffer_size_frames - audioBufferedFrames);
+          // Determine the number of frames to copy to the buffer.
+-         const unsigned framesToCopy = min(queuedFrames, bufferableFrames);
++         const unsigned framesToCopy = MIN(queuedFrames, bufferableFrames);
+ 
+          // Copy frames to the buffer.
+          for(unsigned frame = 0; frame < framesToCopy; frame++) {
+diff --git a/src/include/common.h b/src/include/common.h
+index be28795..e2d21d1 100644
+--- a/src/include/common.h
++++ b/src/include/common.h
+@@ -41,8 +41,10 @@ extern "C" {
+ #define true   TRUE
+ #define false  FALSE
+ 
++/*
+ #define min(x,y)   MIN((x),(y))
+ #define max(x,y)   MAX((x),(y))
++*/
+ 
+ #define true_or_false(x)   ((x) ? true : false)
+ 
diff --git a/pkgs/applications/emulators/fakenes/default.nix b/pkgs/applications/emulators/fakenes/default.nix
new file mode 100644
index 00000000000..6bc4b1480ff
--- /dev/null
+++ b/pkgs/applications/emulators/fakenes/default.nix
@@ -0,0 +1,34 @@
+{lib, stdenv, fetchurl, allegro, openal, libGLU, libGL, zlib, hawknl, freeglut, libX11,
+  libXxf86vm, libXcursor, libXpm }:
+
+stdenv.mkDerivation rec {
+  pname = "fakenes";
+  version = "0.5.9-beta3";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/fakenes/fakenes-${version}.tar.gz";
+    sha256 = "026h67s4pzc1vma59pmzk02iy379255qbai2q74wln9bxqcpniy4";
+  };
+
+  buildInputs = [ allegro openal libGLU libGL zlib hawknl freeglut libX11
+    libXxf86vm libXcursor libXpm ];
+
+  hardeningDisable = [ "format" ];
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp fakenes $out/bin
+  '';
+
+  NIX_LDFLAGS = "-lX11 -lXxf86vm -lXcursor -lXpm";
+
+  patches = [ ./build.patch ];
+
+  meta = {
+    homepage = "http://fakenes.sourceforge.net/";
+    license = lib.licenses.gpl2Plus;
+    description = "Portable Open Source NES Emulator";
+    platforms = lib.platforms.linux;
+    broken = true;
+  };
+}
diff --git a/pkgs/applications/emulators/fceux/default.nix b/pkgs/applications/emulators/fceux/default.nix
new file mode 100644
index 00000000000..9289fb081f0
--- /dev/null
+++ b/pkgs/applications/emulators/fceux/default.nix
@@ -0,0 +1,24 @@
+{ lib, stdenv, fetchFromGitHub, cmake, pkg-config, wrapQtAppsHook, SDL2, lua5_1, minizip, x264 }:
+
+stdenv.mkDerivation rec {
+  pname = "fceux";
+  version = "2.6.2";
+
+  src = fetchFromGitHub {
+    owner = "TASEmulators";
+    repo = pname;
+    rev = "${pname}-${version}";
+    sha256 = "sha256-yQX58m/sMW/8Jr5cm2SrVXTiF7qyZOgOZg1v0qEyiLw=";
+  };
+
+  nativeBuildInputs = [ cmake pkg-config wrapQtAppsHook ];
+  buildInputs = [ SDL2 lua5_1 minizip x264 ];
+
+  meta = with lib; {
+    description = "A Nintendo Entertainment System (NES) Emulator";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ sbruder scubed2 ];
+    homepage = "http://www.fceux.com/";
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/firebird-emu/default.nix b/pkgs/applications/emulators/firebird-emu/default.nix
new file mode 100644
index 00000000000..8a759d00582
--- /dev/null
+++ b/pkgs/applications/emulators/firebird-emu/default.nix
@@ -0,0 +1,36 @@
+{ mkDerivation, lib, fetchFromGitHub, qmake, qtbase, qtdeclarative }:
+
+mkDerivation rec {
+  pname = "firebird-emu";
+  version = "1.5";
+
+  src = fetchFromGitHub {
+    owner = "nspire-emus";
+    repo = "firebird";
+    rev = "v${version}";
+    sha256 = "sha256-T62WB6msdB6/wIulqd/468JrCEiPGUrvtpjkZyo4wiA=";
+    fetchSubmodules = true;
+  };
+
+  nativeBuildInputs = [ qmake ];
+
+  buildInputs = [ qtbase qtdeclarative ];
+
+  makeFlags = [ "INSTALL_ROOT=$(out)" ];
+
+  # Attempts to install to /usr/bin and /usr/share/applications, which Nix does
+  # not use.
+  prePatch = ''
+    substituteInPlace firebird.pro \
+      --replace '/usr/' '/'
+  '';
+
+  meta = {
+    homepage = "https://github.com/nspire-emus/firebird";
+    description = "Third-party multi-platform emulator of the ARM-based TI-Nspire™ calculators";
+    license = lib.licenses.gpl3;
+    maintainers = with lib.maintainers; [ pneumaticat ];
+    # Only tested on Linux, but likely possible to build on, e.g. macOS
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/fs-uae/default.nix b/pkgs/applications/emulators/fs-uae/default.nix
new file mode 100644
index 00000000000..4bd67908a78
--- /dev/null
+++ b/pkgs/applications/emulators/fs-uae/default.nix
@@ -0,0 +1,65 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, SDL2
+, autoreconfHook
+, freetype
+, gettext
+, glib
+, gtk2
+, libGL
+, libGLU
+, libmpeg2
+, lua
+, openal
+, pkg-config
+, zip
+, zlib
+}:
+
+
+stdenv.mkDerivation rec {
+  pname = "fs-uae";
+  version = "3.1.66";
+
+  src = fetchFromGitHub {
+    owner = "FrodeSolheim";
+    repo = pname;
+    rev = "v${version}";
+    hash = "sha256-zPVRPazelmNaxcoCStB0j9b9qwQDTgv3O7Bg3VlW9ys=";
+  };
+
+  nativeBuildInputs = [
+    autoreconfHook
+    pkg-config
+  ];
+
+  buildInputs = [
+    SDL2
+    freetype
+    gettext
+    glib
+    gtk2
+    libGL
+    libGLU
+    libmpeg2
+    lua
+    openal
+    zip
+    zlib
+  ];
+
+  meta = with lib; {
+    homepage = "https://fs-uae.net";
+    description = "An accurate, customizable Amiga Emulator";
+    longDescription = ''
+      FS-UAE integrates the most accurate Amiga emulation code available
+      from WinUAE. FS-UAE emulates A500, A500+, A600, A1200, A1000, A3000
+      and A4000 models, but you can tweak the hardware configuration and
+      create customized Amigas.
+    '';
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = [ "i686-linux" "x86_64-linux" ];
+  };
+}
diff --git a/pkgs/applications/emulators/fs-uae/launcher.nix b/pkgs/applications/emulators/fs-uae/launcher.nix
new file mode 100644
index 00000000000..afe12aab0c8
--- /dev/null
+++ b/pkgs/applications/emulators/fs-uae/launcher.nix
@@ -0,0 +1,43 @@
+{ lib
+, stdenv
+, fetchurl
+, gettext
+, makeWrapper
+, python3
+}:
+
+stdenv.mkDerivation rec {
+  pname = "fs-uae-launcher";
+  version = "3.0.5";
+
+  src = fetchurl {
+    url = "https://fs-uae.net/stable/${version}/${pname}-${version}.tar.gz";
+    sha256 = "1dknra4ngz7bpppwqghmza1q68pn1yaw54p9ba0f42zwp427ly97";
+  };
+
+  nativeBuildInputs = [
+    gettext
+    makeWrapper
+    python3
+  ];
+
+  buildInputs = with python3.pkgs; [
+    pyqt5
+    requests
+    setuptools
+  ];
+
+  makeFlags = [ "prefix=$(out)" ];
+
+  postInstall = ''
+    wrapProgram $out/bin/fs-uae-launcher --set PYTHONPATH "$PYTHONPATH"
+  '';
+
+  meta = with lib; {
+    homepage = "https://fs-uae.net";
+    description = "Graphical front-end for the FS-UAE emulator";
+    license = lib.licenses.gpl2Plus;
+    maintainers = with  maintainers; [ sander AndersonTorres ];
+    platforms = [ "i686-linux" "x86_64-linux" ];
+  };
+}
diff --git a/pkgs/applications/emulators/fuse-emulator/default.nix b/pkgs/applications/emulators/fuse-emulator/default.nix
new file mode 100644
index 00000000000..35e28ba55f6
--- /dev/null
+++ b/pkgs/applications/emulators/fuse-emulator/default.nix
@@ -0,0 +1,29 @@
+{ lib, stdenv, fetchurl, perl, pkg-config, wrapGAppsHook
+, SDL, bzip2, glib, gtk3, libgcrypt, libpng, libspectrum, libxml2, zlib
+}:
+
+stdenv.mkDerivation rec {
+  pname = "fuse-emulator";
+  version = "1.6.0";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/${pname}/fuse-${version}.tar.gz";
+    sha256 = "sha256-Oo/t8v/pR8VxVhusVaWa2tTFkzj3TkSbfnpn2coEcJY=";
+  };
+
+  nativeBuildInputs = [ perl pkg-config wrapGAppsHook ];
+
+  buildInputs = [ SDL bzip2 glib gtk3 libgcrypt libpng libspectrum libxml2 zlib ];
+
+  configureFlags = [ "--enable-desktop-integration" ];
+
+  enableParallelBuilding = true;
+
+  meta = with lib; {
+    homepage = "http://fuse-emulator.sourceforge.net/";
+    description = "ZX Spectrum emulator";
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+    maintainers = with maintainers; [ orivej ];
+  };
+}
diff --git a/pkgs/applications/emulators/gens-gs/default.nix b/pkgs/applications/emulators/gens-gs/default.nix
new file mode 100644
index 00000000000..0fbd12fc365
--- /dev/null
+++ b/pkgs/applications/emulators/gens-gs/default.nix
@@ -0,0 +1,26 @@
+{ lib, stdenv, fetchurl, pkg-config, gtk2, SDL, nasm, zlib, libpng, libGLU, libGL }:
+
+stdenv.mkDerivation rec {
+  pname = "gens-gs";
+  version = "7";
+
+  src = fetchurl {
+    url = "http://retrocdn.net/images/6/6d/Gens-gs-r${version}.tar.gz";
+    sha256 = "1ha5s6d3y7s9aq9f4zmn9p88109c3mrj36z2w68jhiw5xrxws833";
+  };
+
+  nativeBuildInputs = [ pkg-config ];
+  buildInputs = [ gtk2 SDL nasm zlib libpng libGLU libGL ];
+
+  # Work around build failures on recent GTK.
+  # See http://ubuntuforums.org/showthread.php?p=10535837
+  NIX_CFLAGS_COMPILE = "-UGTK_DISABLE_DEPRECATED -UGSEAL_ENABLE";
+
+  meta = with lib; {
+    homepage = "https://segaretro.org/Gens/GS";
+    description = "A Genesis/Mega Drive emulator";
+    platforms = [ "i686-linux" ];
+    license = licenses.gpl2Plus;
+    maintainers = [ maintainers.eelco ];
+  };
+}
diff --git a/pkgs/applications/emulators/gxemul/0001-fix-attributes.patch b/pkgs/applications/emulators/gxemul/0001-fix-attributes.patch
new file mode 100644
index 00000000000..3ed9cabc7ad
--- /dev/null
+++ b/pkgs/applications/emulators/gxemul/0001-fix-attributes.patch
@@ -0,0 +1,26 @@
+diff -Naur gxemul-0.7.0-old/src/include/thirdparty/pcireg.h gxemul-0.7.0/src/include/thirdparty/pcireg.h
+--- gxemul-0.7.0-old/src/include/thirdparty/pcireg.h	2021-04-22 15:04:14.000000000 -0300
++++ gxemul-0.7.0-new/src/include/thirdparty/pcireg.h	2021-06-28 18:41:13.063065322 -0300
+@@ -12,9 +12,6 @@
+ #undef __noreturn__
+ #endif
+ 
+-#define __attribute__(x)  /*  */
+-#define __noreturn__  /*  */
+-
+ /*
+  * Copyright (c) 1995, 1996, 1999, 2000
+  *     Christopher G. Demetriou.  All rights reserved.
+diff -Naur gxemul-0.7.0-old/src/include/thirdparty/sgi_arcbios.h gxemul-0.7.0/src/include/thirdparty/sgi_arcbios.h
+--- gxemul-0.7.0-old/src/include/thirdparty/sgi_arcbios.h	2021-04-22 15:04:14.000000000 -0300
++++ gxemul-0.7.0-new/src/include/thirdparty/sgi_arcbios.h	2021-06-28 18:41:33.549981505 -0300
+@@ -14,9 +14,6 @@
+ #undef __noreturn__
+ #endif
+ 
+-#define	__attribute__(x)  /*  */
+-#define	__noreturn__  /*  */
+-
+ /*	$NetBSD: arcbios.h,v 1.3 2001/12/06 14:59:02 rafal Exp $	*/
+ 
+ /*-
diff --git a/pkgs/applications/emulators/gxemul/default.nix b/pkgs/applications/emulators/gxemul/default.nix
new file mode 100644
index 00000000000..cacb521c2fb
--- /dev/null
+++ b/pkgs/applications/emulators/gxemul/default.nix
@@ -0,0 +1,47 @@
+{ lib
+, stdenv
+, fetchurl
+, libX11
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gxemul";
+  version = "0.7.0";
+
+  src = fetchurl {
+    url = "http://gavare.se/gxemul/src/${pname}-${version}.tar.gz";
+    sha256 = "sha256-ecRDfG+MqQT0bTOsNgYqZf3PSpKiSEeOQIqxEpXPjoM=";
+  };
+
+  buildInputs = [
+    libX11
+  ];
+
+  patches = [
+    # Fix compilation; remove when next release arrives
+    ./0001-fix-attributes.patch
+  ];
+
+  dontAddPrefix = true;
+
+  preConfigure = ''
+    export PREFIX=${placeholder "out"}
+  '';
+
+  meta = with lib; {
+    homepage = "http://gavare.se/gxemul/";
+    description = "Gavare's experimental emulator";
+    longDescription = ''
+      GXemul is a framework for full-system computer architecture
+      emulation. Several real machines have been implemented within the
+      framework, consisting of processors (ARM, MIPS, Motorola 88K, PowerPC, and
+      SuperH) and surrounding hardware components such as framebuffers,
+      interrupt controllers, busses, disk controllers, and serial
+      controllers. The emulation is working well enough to allow several
+      unmodified "guest" operating systems to run.
+    '';
+    license = licenses.bsd3;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/applications/emulators/hatari/default.nix b/pkgs/applications/emulators/hatari/default.nix
new file mode 100644
index 00000000000..de98278b832
--- /dev/null
+++ b/pkgs/applications/emulators/hatari/default.nix
@@ -0,0 +1,25 @@
+{ lib, stdenv, fetchurl, zlib, SDL, cmake }:
+
+stdenv.mkDerivation rec {
+  pname = "hatari";
+  version = "2.3.1";
+
+  src = fetchurl {
+    url = "https://download.tuxfamily.org/hatari/${version}/${pname}-${version}.tar.bz2";
+    sha256 = "sha256-RKL2LKmV442eCHSAaVbwucPMhOqJ4BaaY4SbY807ZL0=";
+  };
+
+  # For pthread_cancel
+  cmakeFlags = [ "-DCMAKE_EXE_LINKER_FLAGS=-lgcc_s" ];
+
+  nativeBuildInputs = [ cmake ];
+  buildInputs = [ zlib SDL ];
+
+  meta = {
+    homepage = "http://hatari.tuxfamily.org/";
+    description = "Atari ST/STE/TT/Falcon emulator";
+    license = lib.licenses.gpl2Plus;
+    platforms = lib.platforms.linux;
+    maintainers = with lib.maintainers; [ ];
+  };
+}
diff --git a/pkgs/applications/emulators/higan/001-include-cmath.patch b/pkgs/applications/emulators/higan/001-include-cmath.patch
new file mode 100644
index 00000000000..67644e656aa
--- /dev/null
+++ b/pkgs/applications/emulators/higan/001-include-cmath.patch
@@ -0,0 +1,8 @@
+diff -Naur source-old/higan/fc/ppu/ppu.cpp source-new/higan/fc/ppu/ppu.cpp
+--- source-old/higan/fc/ppu/ppu.cpp	1969-12-31 21:00:01.000000000 -0300
++++ source-new/higan/fc/ppu/ppu.cpp	2021-09-29 22:23:19.107527772 -0300
+@@ -1,3 +1,4 @@
++#include <cmath>
+ #include <fc/fc.hpp>
+ 
+ namespace higan::Famicom {
diff --git a/pkgs/applications/emulators/higan/002-sips-to-png2icns.patch b/pkgs/applications/emulators/higan/002-sips-to-png2icns.patch
new file mode 100644
index 00000000000..0585c8a38c7
--- /dev/null
+++ b/pkgs/applications/emulators/higan/002-sips-to-png2icns.patch
@@ -0,0 +1,24 @@
+diff -Naur source-old/higan-ui/GNUmakefile source-new/higan-ui/GNUmakefile
+--- source-old/higan-ui/GNUmakefile	1969-12-31 21:00:01.000000000 -0300
++++ source-new/higan-ui/GNUmakefile	2021-09-29 22:35:35.744721052 -0300
+@@ -61,7 +61,7 @@
+ 	mkdir -p $(output.path)/$(name).app/Contents/Resources/
+ 	mv $(output.path)/$(name) $(output.path)/$(name).app/Contents/MacOS/$(name)
+ 	cp resource/$(name).plist $(output.path)/$(name).app/Contents/Info.plist
+-	sips -s format icns resource/$(name).png --out $(output.path)/$(name).app/Contents/Resources/$(name).icns
++	png2icns $(output.path)/$(name).app/Contents/Resources/$(name).icns resource/$(name).png
+ endif
+ 
+ verbose: nall.verbose ruby.verbose hiro.verbose all;
+diff -Naur source-old/icarus/GNUmakefile source-new/icarus/GNUmakefile
+--- source-old/icarus/GNUmakefile	1969-12-31 21:00:01.000000000 -0300
++++ source-new/icarus/GNUmakefile	2021-09-29 22:35:53.639846113 -0300
+@@ -26,7 +26,7 @@
+ 	mkdir -p $(output.path)/$(name).app/Contents/Resources/
+ 	mv $(output.path)/$(name) $(output.path)/$(name).app/Contents/MacOS/$(name)
+ 	cp resource/$(name).plist $(output.path)/$(name).app/Contents/Info.plist
+-	sips -s format icns resource/$(name).png --out $(output.path)/$(name).app/Contents/Resources/$(name).icns
++	png2icns $(output.path)/$(name).app/Contents/Resources/$(name).icns resource/$(name).png
+ endif
+ 
+ verbose: hiro.verbose nall.verbose all;
diff --git a/pkgs/applications/emulators/higan/default.nix b/pkgs/applications/emulators/higan/default.nix
new file mode 100644
index 00000000000..c5f38a040c1
--- /dev/null
+++ b/pkgs/applications/emulators/higan/default.nix
@@ -0,0 +1,155 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, SDL2
+, alsa-lib
+, gtk3
+, gtksourceview3
+, libGL
+, libGLU
+, libX11
+, libXv
+, libao
+, libpulseaudio
+, openal
+, pkg-config
+, runtimeShell
+, udev
+# Darwin dependencies
+, libicns
+, darwin
+}:
+
+stdenv.mkDerivation rec {
+  pname = "higan";
+  version = "115+unstable=2021-08-18";
+
+  src = fetchFromGitHub {
+    owner = "higan-emu";
+    repo = "higan";
+    rev = "9bf1b3314b2bcc73cbc11d344b369c31562aff10";
+    hash = "sha256-HZItJ97x20OjFKv2OVbMja7g+c1ZXcgcaC/XDe3vMZM=";
+  };
+
+  nativeBuildInputs = [
+    pkg-config
+  ] ++ lib.optionals stdenv.isDarwin [
+    libicns
+  ];
+
+  buildInputs = [
+    SDL2
+    libao
+  ] ++ lib.optionals stdenv.isLinux [
+    alsa-lib
+    gtk3
+    gtksourceview3
+    libGL
+    libGLU
+    libX11
+    libXv
+    libpulseaudio
+    openal
+    udev
+  ]
+  ++ lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [
+    Carbon
+    Cocoa
+    OpenAL
+    OpenGL
+  ]);
+
+  patches = [
+    # Includes cmath header
+    ./001-include-cmath.patch
+    # Uses png2icns instead of sips
+    ./002-sips-to-png2icns.patch
+  ];
+
+  dontConfigure = true;
+
+  enableParallelBuilding = true;
+
+  buildPhase = ''
+    runHook preBuild
+
+    make -j $NIX_BUILD_CORES compiler=${stdenv.cc.targetPrefix}c++ \
+         platform=linux openmp=true hiro=gtk3 build=accuracy local=false \
+         cores="cv fc gb gba md ms msx ngp pce sfc sg ws" -C higan-ui
+    make -j $NIX_BUILD_CORES compiler=${stdenv.cc.targetPrefix}c++ \
+         platform=linux openmp=true hiro=gtk3 -C icarus
+
+    runHook postBuild
+  '';
+
+  installPhase = ''
+    runHook preInstall
+
+  '' + (if stdenv.isDarwin then ''
+    mkdir ${placeholder "out"}
+    mv higan/out/higan.app ${placeholder "out"}/
+    mv icarus/out/icarus.app ${placeholder "out"}/
+  '' else ''
+    install -d ${placeholder "out"}/bin
+    install higan-ui/out/higan -t ${placeholder "out"}/bin/
+    install icarus/out/icarus -t ${placeholder "out"}/bin/
+
+    install -d ${placeholder "out"}/share/applications
+    install higan-ui/resource/higan.desktop -t ${placeholder "out"}/share/applications/
+    install icarus/resource/icarus.desktop -t ${placeholder "out"}/share/applications/
+
+    install -d ${placeholder "out"}/share/pixmaps
+    install higan/higan/resource/higan.svg ${placeholder "out"}/share/pixmaps/higan-icon.svg
+    install higan/higan/resource/logo.png ${placeholder "out"}/share/pixmaps/higan-icon.png
+    install icarus/resource/icarus.svg ${placeholder "out"}/share/pixmaps/icarus-icon.svg
+    install icarus/resource/icarus.png ${placeholder "out"}/share/pixmaps/icarus-icon.png
+  '') + ''
+    install -d ${placeholder "out"}/share/higan
+    cp -rd extras/ higan/System/ ${placeholder "out"}/share/higan/
+
+    install -d ${placeholder "out"}/share/icarus
+    cp -rd icarus/Database icarus/Firmware ${placeholder "out"}/share/icarus/
+  '' + (
+    # A dirty workaround, suggested by @cpages:
+    # we create a first-run script to populate
+    # $HOME with all the stuff needed at runtime
+    let
+      dest = if stdenv.isDarwin
+           then "\\$HOME/Library/Application Support/higan"
+           else "\\$HOME/higan";
+    in ''
+    mkdir -p ${placeholder "out"}/bin
+    cat <<EOF > ${placeholder "out"}/bin/higan-init.sh
+    #!${runtimeShell}
+
+    cp --recursive --update ${placeholder "out"}/share/higan/System/ "${dest}"/
+
+    EOF
+
+    chmod +x ${placeholder "out"}/bin/higan-init.sh
+  '') + ''
+
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    homepage = "https://github.com/higan-emu/higan";
+    description = "An open-source, cycle-accurate multi-system emulator";
+    longDescription = ''
+      higan is a multi-system emulator, originally developed by Near, with an
+      uncompromising focus on accuracy and code readability.
+
+      It currently emulates the following systems: Famicom, Famicom Disk System,
+      Super Famicom, Super Game Boy, Game Boy, Game Boy Color, Game Boy Advance,
+      Game Boy Player, SG-1000, SC-3000, Master System, Game Gear, Mega Drive,
+      Mega CD, PC Engine, SuperGrafx, MSX, MSX2, ColecoVision, Neo Geo Pocket,
+      Neo Geo Pocket Color, WonderSwan, WonderSwan Color, SwanCrystal, Pocket
+      Challenge V2.
+    '';
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = platforms.unix;
+    broken = stdenv.isDarwin;
+  };
+}
+# TODO: select between Qt, GTK2 and GTK3
diff --git a/pkgs/applications/emulators/kega-fusion/default.nix b/pkgs/applications/emulators/kega-fusion/default.nix
new file mode 100644
index 00000000000..e8feb1ea7ed
--- /dev/null
+++ b/pkgs/applications/emulators/kega-fusion/default.nix
@@ -0,0 +1,78 @@
+{ stdenv, lib, writeText, fetchurl, upx, libGLU, glib, gtk2, alsa-lib, libSM, libX11, gdk-pixbuf, pango, libXinerama, mpg123, runtimeShell }:
+
+let
+  libPath = lib.makeLibraryPath [ stdenv.cc.cc libGLU glib gtk2 alsa-lib libSM libX11 gdk-pixbuf pango libXinerama ];
+
+in stdenv.mkDerivation {
+  pname = "kega-fusion";
+  version = "3.63x";
+
+  src = fetchurl {
+    url = "http://www.carpeludum.com/download/Fusion363x.tar.gz";
+    sha256 = "14s6czy20h5khyy7q95hd7k77v17ssafv9l6lafkiysvj2nmw94g";
+  };
+
+  plugins = fetchurl {
+    url = "http://www.carpeludum.com/download/PluginsLinux.tar.gz";
+    sha256 = "0d623cvh6n5ijj3wb64g93mxx2xbichsn7hj7brbb0ndw5cs70qj";
+  };
+
+  runner = writeText "kega-fusion" ''
+    #!${runtimeShell} -ex
+
+    kega_libdir="@out@/lib/kega-fusion"
+    kega_localdir="$HOME/.Kega Fusion"
+
+    # create local plugins directory if not present
+    mkdir -p "$kega_localdir/Plugins"
+
+    # create links for every included plugin
+    if [ $(ls -1A $kega_libdir/plugins | wc -l) -gt 0 ]; then
+      for i in $kega_libdir/plugins/*; do
+        if [ ! -e "$kega_localdir/Plugins/$(basename "$i")" ]; then
+          ln -sf "$i" "$kega_localdir/Plugins/"
+        fi
+      done
+    fi
+
+    # copy configuration file if not present
+    if ! [ -f "$kega_localdir/Fusion.ini" ]; then
+      cat > "$kega_localdir/Fusion.ini" <<EOF
+    ALSADeviceName=default
+    libmpg123path=${lib.getLib mpg123}/lib/libmpg123.so.0
+    EOF
+    else
+      sed -i 's,^\(libmpg123path=\).*,\1${lib.getLib mpg123}/lib/libmpg123.so.0,' "$kega_localdir/Fusion.ini"
+    fi
+
+    # here we go!
+    exec "$kega_libdir/Fusion" "$@"
+  '';
+
+  dontStrip = true;
+  dontPatchELF = true;
+
+  nativeBuildInputs = [ upx ];
+
+  installPhase = ''
+    upx -d Fusion
+    install -Dm755 Fusion "$out/lib/kega-fusion/Fusion"
+    patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" --set-rpath "${libPath}" "$out/lib/kega-fusion/Fusion"
+
+    tar -xaf $plugins
+    mkdir -p "$out/lib/kega-fusion/plugins"
+    cp -r Plugins/*.rpi "$out/lib/kega-fusion/plugins"
+
+    mkdir -p "$out/bin"
+    substitute "$runner" "$out/bin/kega-fusion" --subst-var out
+    chmod +x "$out/bin/kega-fusion"
+  '';
+
+  meta = with lib; {
+    description = "Sega SG1000, SC3000, SF7000, Master System, Game Gear, Genesis/Megadrive, SVP, Pico, SegaCD/MegaCD and 32X emulator";
+    homepage = "https://www.carpeludum.com/kega-fusion/";
+    maintainers = with maintainers; [ abbradar ];
+    license = licenses.unfreeRedistributable;
+    platforms = [ "i686-linux" ];
+  };
+}
diff --git a/pkgs/applications/emulators/lambda-delta/default.nix b/pkgs/applications/emulators/lambda-delta/default.nix
new file mode 100644
index 00000000000..a17a0eadfd5
--- /dev/null
+++ b/pkgs/applications/emulators/lambda-delta/default.nix
@@ -0,0 +1,26 @@
+{ lib, stdenv, fetchFromGitHub, autoreconfHook, pkg-config, SDL2 }:
+
+stdenv.mkDerivation rec {
+  pname = "lambda-delta";
+  version = "0.98.3";
+
+  src = fetchFromGitHub {
+    owner = "dseagrav";
+    repo = "ld";
+    rev = version;
+    sha256 = "02m43fj9dzc1i1jl01qwnhjiq1rh03jw1xq59sx2h3bhn7dk941x";
+  };
+
+  nativeBuildInputs = [ autoreconfHook pkg-config ];
+  buildInputs = [ SDL2 ];
+
+  configureFlags = [ "--without-SDL1" ];
+
+  meta = with lib; {
+    description = "LMI (Lambda Lisp Machine) emulator";
+    homepage = "https://github.com/dseagrav/ld";
+    license = licenses.gpl2;
+    maintainers = with maintainers; [ siraben ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/applications/emulators/libdsk/default.nix b/pkgs/applications/emulators/libdsk/default.nix
new file mode 100644
index 00000000000..247aef118e8
--- /dev/null
+++ b/pkgs/applications/emulators/libdsk/default.nix
@@ -0,0 +1,19 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "libdsk";
+  version = "1.5.18";
+
+  src = fetchurl {
+    url = "https://www.seasip.info/Unix/LibDsk/${pname}-${version}.tar.gz";
+    sha256 = "sha256-43HUMQ35nwOwaQP8F1vO7zFccxHrQqJhZ6D5zzYhB5A=";
+  };
+
+  meta = with lib; {
+    description = "A library for accessing discs and disc image files";
+    homepage = "http://www.seasip.info/Unix/LibDsk/";
+    license = licenses.gpl2Plus;
+    maintainers = [ ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/applications/emulators/maiko/default.nix b/pkgs/applications/emulators/maiko/default.nix
new file mode 100644
index 00000000000..e78b680d617
--- /dev/null
+++ b/pkgs/applications/emulators/maiko/default.nix
@@ -0,0 +1,26 @@
+{ lib, stdenv, fetchFromGitHub, cmake, libX11 }:
+
+stdenv.mkDerivation rec {
+  pname = "maiko";
+  version = "2021-04-14";
+  src = fetchFromGitHub {
+    owner = "Interlisp";
+    repo = "maiko";
+    rev = "91fe7d51f9d607bcedde0e78e435ee188a8c84c0";
+    hash = "sha256-Y+ngep/xHw6RCU8XVRYSWH6S+9hJ74z50pGpIqS2CjM=";
+  };
+  nativeBuildInputs = [ cmake ];
+  buildInputs = [ libX11 ];
+  installPhase = ''
+    runHook preInstall
+    find . -maxdepth 1 -executable -type f -exec install -Dt $out/bin '{}' \;
+    runHook postInstall
+  '';
+  meta = with lib; {
+    description = "Medley Interlisp virtual machine";
+    homepage = "https://interlisp.org/";
+    license = licenses.mit;
+    maintainers = with maintainers; [ ehmry ];
+    inherit (libX11.meta) platforms;
+  };
+}
diff --git a/pkgs/applications/emulators/mame/default.nix b/pkgs/applications/emulators/mame/default.nix
new file mode 100644
index 00000000000..e0915703003
--- /dev/null
+++ b/pkgs/applications/emulators/mame/default.nix
@@ -0,0 +1,105 @@
+{ lib
+, stdenv
+, alsa-lib
+, CoreAudioKit
+, fetchFromGitHub
+, fontconfig
+, ForceFeedback
+, installShellFiles
+, libpcap
+, libpulseaudio
+, libXi
+, libXinerama
+, makeDesktopItem
+, makeWrapper
+, pkg-config
+, python3
+, qtbase
+, SDL2
+, SDL2_ttf
+, which
+}:
+
+let
+  desktopItem = makeDesktopItem {
+    name = "MAME";
+    exec = "mame${lib.optionalString stdenv.is64bit "64"}";
+    desktopName = "MAME";
+    genericName = "MAME is a multi-purpose emulation framework";
+    categories = "System;Emulator;";
+  };
+
+  dest = "$out/opt/mame";
+in
+stdenv.mkDerivation rec {
+  pname = "mame";
+  version = "0.239";
+
+  src = fetchFromGitHub {
+    owner = "mamedev";
+    repo = "mame";
+    rev = "mame${builtins.replaceStrings [ "." ] [ "" ] version}";
+    sha256 = "sha256-svclBaFkp4d6db+zWZNvZP8vWIFz/7M5N1M6WseOFEk=";
+  };
+
+  hardeningDisable = [ "fortify" ];
+  NIX_CFLAGS_COMPILE = [ "-Wno-error=maybe-uninitialized" "-Wno-error=missing-braces" ];
+
+  makeFlags = [
+    "TOOLS=1"
+    "USE_LIBSDL=1"
+    "CC=${stdenv.cc.targetPrefix}cc"
+    "CXX=${stdenv.cc.targetPrefix}c++"
+  ];
+
+  dontWrapQtApps = true;
+
+  # https://docs.mamedev.org/initialsetup/compilingmame.html
+  buildInputs =
+    [ SDL2 SDL2_ttf qtbase ]
+    ++ lib.optionals stdenv.isLinux [ alsa-lib libpulseaudio libXinerama libXi fontconfig ]
+    ++ lib.optionals stdenv.isDarwin [ libpcap CoreAudioKit ForceFeedback ];
+
+  nativeBuildInputs = [ python3 pkg-config which makeWrapper installShellFiles ];
+
+  # by default MAME assumes that paths with stock resources
+  # are relative and that you run MAME changing to
+  # install directory, so we add absolute paths here
+  patches = [
+    ./emuopts.patch
+  ];
+
+  postPatch = ''
+    substituteInPlace src/emu/emuopts.cpp \
+      --subst-var-by mame ${dest}
+  '';
+
+  installPhase = ''
+    make -f dist.mak PTR64=${lib.optionalString stdenv.is64bit "1"}
+    mkdir -p ${dest}
+    mv build/release/*/Release/mame/* ${dest}
+
+    mkdir -p $out/bin
+    find ${dest} -maxdepth 1 -executable -type f -exec mv -t $out/bin {} \;
+    install -Dm755 src/osd/sdl/taputil.sh $out/bin/taputil.sh
+
+    installManPage ${dest}/docs/man/*.1 ${dest}/docs/man/*.6
+
+    mv artwork plugins samples ${dest}
+  '' + lib.optionalString stdenv.isLinux ''
+    mkdir -p $out/share
+    ln -s ${desktopItem}/share/applications $out/share
+  '';
+
+  enableParallelBuilding = true;
+
+  meta = with lib; {
+    description = "Is a multi-purpose emulation framework";
+    homepage = "https://www.mamedev.org/";
+    license = with licenses; [ bsd3 gpl2Plus ];
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ thiagokokada ];
+    # macOS needs more time to build
+    timeout = 24 * 3600;
+  };
+}
diff --git a/pkgs/applications/emulators/mame/emuopts.patch b/pkgs/applications/emulators/mame/emuopts.patch
new file mode 100644
index 00000000000..b85291f52f7
--- /dev/null
+++ b/pkgs/applications/emulators/mame/emuopts.patch
@@ -0,0 +1,29 @@
+diff --git a/src/emu/emuopts.cpp b/src/emu/emuopts.cpp
+index c42fcef848..d1bddae060 100644
+--- a/src/emu/emuopts.cpp
++++ b/src/emu/emuopts.cpp
+@@ -36,16 +36,16 @@ const options_entry emu_options::s_option_entries[] =
+ 	{ nullptr,                                           nullptr,     OPTION_HEADER,     "CORE SEARCH PATH OPTIONS" },
+ 	{ OPTION_HOMEPATH,                                   ".",         OPTION_STRING,     "path to base folder for plugin data (read/write)" },
+ 	{ OPTION_MEDIAPATH ";rp;biospath;bp",                "roms",      OPTION_STRING,     "path to ROM sets and hard disk images" },
+-	{ OPTION_HASHPATH ";hash_directory;hash",            "hash",      OPTION_STRING,     "path to software definition files" },
+-	{ OPTION_SAMPLEPATH ";sp",                           "samples",   OPTION_STRING,     "path to audio sample sets" },
+-	{ OPTION_ARTPATH,                                    "artwork",   OPTION_STRING,     "path to artwork files" },
+-	{ OPTION_CTRLRPATH,                                  "ctrlr",     OPTION_STRING,     "path to controller definitions" },
+-	{ OPTION_INIPATH,                                    ".;ini;ini/presets",     OPTION_STRING,     "path to ini files" },
+-	{ OPTION_FONTPATH,                                   ".",         OPTION_STRING,     "path to font files" },
++	{ OPTION_HASHPATH ";hash_directory;hash",            "hash;@mame@/hash",      OPTION_STRING,     "path to software definition files" },
++	{ OPTION_SAMPLEPATH ";sp",                           "samples;@mame@/samples",   OPTION_STRING,     "path to audio sample sets" },
++	{ OPTION_ARTPATH,                                    "artwork;@mame@/artwork",   OPTION_STRING,     "path to artwork files" },
++	{ OPTION_CTRLRPATH,                                  "ctrlr;@mame@/ctrlr",     OPTION_STRING,     "path to controller definitions" },
++	{ OPTION_INIPATH,                                    ".;ini;ini/presets;@mame@/ini/presets",     OPTION_STRING,     "path to ini files" },
++	{ OPTION_FONTPATH,                                   ".;@mame@",         OPTION_STRING,     "path to font files" },
+ 	{ OPTION_CHEATPATH,                                  "cheat",     OPTION_STRING,     "path to cheat files" },
+ 	{ OPTION_CROSSHAIRPATH,                              "crosshair", OPTION_STRING,     "path to crosshair files" },
+-	{ OPTION_PLUGINSPATH,                                "plugins",   OPTION_STRING,     "path to plugin files" },
+-	{ OPTION_LANGUAGEPATH,                               "language",  OPTION_STRING,     "path to UI translation files" },
++	{ OPTION_PLUGINSPATH,                                "plugins;@mame@/plugins",   OPTION_STRING,     "path to plugin files" },
++	{ OPTION_LANGUAGEPATH,                               "language;@mame@/language",  OPTION_STRING,     "path to UI translation files" },
+ 	{ OPTION_SWPATH,                                     "software",  OPTION_STRING,     "path to loose software" },
+ 
+ 	// output directory options
diff --git a/pkgs/applications/emulators/mednafen/default.nix b/pkgs/applications/emulators/mednafen/default.nix
new file mode 100644
index 00000000000..f76ddb78bd5
--- /dev/null
+++ b/pkgs/applications/emulators/mednafen/default.nix
@@ -0,0 +1,74 @@
+{ lib, stdenv, fetchurl, pkg-config, freeglut, libGLU, libGL, libcdio, libjack2
+, libsamplerate, libsndfile, libX11, SDL2, SDL2_net, zlib, alsa-lib }:
+
+stdenv.mkDerivation rec {
+  pname = "mednafen";
+  version = "1.26.1";
+
+  src = fetchurl {
+    url = "https://mednafen.github.io/releases/files/${pname}-${version}.tar.xz";
+    sha256 = "1x7xhxjhwsdbak8l0iyb497f043xkhibk73w96xck4j2bk10fac4";
+  };
+
+  nativeBuildInputs = [ pkg-config ];
+
+  buildInputs = [
+    freeglut
+    libGLU libGL
+    libcdio
+    libjack2
+    alsa-lib
+    libsamplerate
+    libsndfile
+    libX11
+    SDL2
+    SDL2_net
+    zlib
+  ];
+
+  hardeningDisable = [ "pic" ];
+
+  postInstall = ''
+    mkdir -p $out/share/doc
+    mv Documentation $out/share/doc/mednafen
+  '';
+
+  meta = with lib; {
+    description = "A portable, CLI-driven, SDL+OpenGL-based, multi-system emulator";
+    longDescription = ''
+      Mednafen is a portable, utilizing OpenGL and SDL,
+      argument(command-line)-driven multi-system emulator. Mednafen has the
+      ability to remap hotkey functions and virtual system inputs to a keyboard,
+      a joystick, or both simultaneously. Save states are supported, as is
+      real-time game rewinding. Screen snapshots may be taken, in the PNG file
+      format, at the press of a button. Mednafen can record audiovisual movies
+      in the QuickTime file format, with several different lossless codecs
+      supported.
+
+      The following systems are supported (refer to the emulation module
+      documentation for more details):
+
+      - Apple II/II+
+      - Atari Lynx
+      - Neo Geo Pocket (Color)
+      - WonderSwan
+      - GameBoy (Color)
+      - GameBoy Advance
+      - Nintendo Entertainment System
+      - Super Nintendo Entertainment System/Super Famicom
+      - Virtual Boy
+      - PC Engine/TurboGrafx 16 (CD)
+      - SuperGrafx
+      - PC-FX
+      - Sega Game Gear
+      - Sega Genesis/Megadrive
+      - Sega Master System
+      - Sega Saturn (experimental, x86_64 only)
+      - Sony PlayStation
+    '';
+    homepage = "https://mednafen.github.io/";
+    license = licenses.gpl2;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/mednafen/server.nix b/pkgs/applications/emulators/mednafen/server.nix
new file mode 100644
index 00000000000..24c13bf0228
--- /dev/null
+++ b/pkgs/applications/emulators/mednafen/server.nix
@@ -0,0 +1,21 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "mednafen-server";
+  version = "0.5.2";
+
+  src = fetchurl {
+    url = "https://mednafen.github.io/releases/files/mednafen-server-${version}.tar.xz";
+    sha256 = "0xm7dj5nwnrsv69r72rcnlw03jm0l8rmrg3s05gjfvxyqmlb36dq";
+  };
+
+  postInstall = "install -m 644 -Dt $out/share/mednafen-server standard.conf";
+
+  meta = with lib; {
+    description = "Netplay server for Mednafen";
+    homepage = "https://mednafen.github.io/";
+    license = licenses.gpl2;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/applications/emulators/mednaffe/default.nix b/pkgs/applications/emulators/mednaffe/default.nix
new file mode 100644
index 00000000000..4874d5efee7
--- /dev/null
+++ b/pkgs/applications/emulators/mednaffe/default.nix
@@ -0,0 +1,37 @@
+{ stdenv
+, lib
+, fetchFromGitHub
+, autoreconfHook
+, pkg-config
+, mednafen
+, gtk3
+, wrapGAppsHook
+}:
+
+stdenv.mkDerivation rec {
+  pname = "mednaffe";
+  version = "0.9.2";
+
+  src = fetchFromGitHub {
+    owner = "AmatCoder";
+    repo = "mednaffe";
+    rev = version;
+    sha256 = "sha256-zvSAt6CMcgdoPpTTA5sPlQaWUw9LUMsR2Xg9jM2UaWY=";
+  };
+
+  nativeBuildInputs = [ autoreconfHook pkg-config wrapGAppsHook ];
+  buildInputs = [ gtk3 mednafen ];
+
+  postInstall = ''
+    wrapProgram $out/bin/mednaffe \
+      --prefix PATH ':' "${mednafen}/bin"
+   '';
+
+  meta = with lib; {
+    description = "GTK-based frontend for mednafen emulator";
+    homepage = "https://github.com/AmatCoder/mednaffe";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ sheenobu yana AndersonTorres ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/melonDS/default.nix b/pkgs/applications/emulators/melonDS/default.nix
new file mode 100644
index 00000000000..3e30be8c2a3
--- /dev/null
+++ b/pkgs/applications/emulators/melonDS/default.nix
@@ -0,0 +1,43 @@
+{ lib
+, fetchFromGitHub
+, mkDerivation
+, cmake
+, libepoxy
+, libarchive
+, libpcap
+, libslirp
+, pkg-config
+, qtbase
+, SDL2
+}:
+
+mkDerivation rec {
+  pname = "melonDS";
+  version = "0.9.3";
+
+  src = fetchFromGitHub {
+    owner = "Arisotura";
+    repo = pname;
+    rev = version;
+    sha256 = "1v8a060gbpx7rdkk2w4hym361l2wip7yjjn8wny1gfsa273k3zy5";
+  };
+
+  nativeBuildInputs = [ cmake pkg-config ];
+  buildInputs = [
+    libepoxy
+    libarchive
+    libslirp
+    qtbase
+    SDL2
+  ];
+
+  qtWrapperArgs = [ "--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ libpcap ]}" ];
+
+  meta = with lib; {
+    homepage = "http://melonds.kuribo64.net/";
+    description = "Work in progress Nintendo DS emulator";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ artemist benley shamilton xfix ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/mgba/default.nix b/pkgs/applications/emulators/mgba/default.nix
new file mode 100644
index 00000000000..d8defe6f2e9
--- /dev/null
+++ b/pkgs/applications/emulators/mgba/default.nix
@@ -0,0 +1,87 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, SDL2
+, cmake
+, libepoxy
+, ffmpeg_4
+, imagemagick
+, libedit
+, libelf
+, libzip
+, makeDesktopItem
+, minizip
+, pkg-config
+, qtbase
+, qtmultimedia
+, qttools
+, wrapQtAppsHook
+}:
+
+stdenv.mkDerivation rec {
+  pname = "mgba";
+  version = "0.9.3";
+
+  src = fetchFromGitHub {
+    owner = "mgba-emu";
+    repo = "mgba";
+    rev = version;
+    hash = "sha256-0ZtoyyoD+YjplJlPFpZgIg5119j/6X8ZaSZP+UpX5K0=";
+  };
+
+  nativeBuildInputs = [
+    cmake
+    pkg-config
+    wrapQtAppsHook
+  ];
+
+  buildInputs = [
+    SDL2
+    libepoxy
+    ffmpeg_4
+    imagemagick
+    libedit
+    libelf
+    libzip
+    minizip
+    qtbase
+    qtmultimedia
+    qttools
+  ];
+
+  desktopItems = [
+    (makeDesktopItem {
+      name = "mgba";
+      exec = "mgba-qt";
+      icon = "mgba";
+      comment = "A Game Boy Advance Emulator";
+      desktopName = "mgba";
+      genericName = "Game Boy Advance Emulator";
+      categories = "Game;Emulator;";
+      startupNotify = "false";
+    })
+  ];
+
+  meta = with lib; {
+    homepage = "https://mgba.io";
+    description = "A modern GBA emulator with a focus on accuracy";
+    longDescription = ''
+      mGBA is a new Game Boy Advance emulator written in C.
+
+      The project started in April 2013 with the goal of being fast enough to
+      run on lower end hardware than other emulators support, without
+      sacrificing accuracy or portability. Even in the initial version, games
+      generally play without problems. It is loosely based on the previous
+      GBA.js emulator, although very little of GBA.js can still be seen in mGBA.
+
+      Other goals include accurate enough emulation to provide a development
+      environment for homebrew software, a good workflow for tool-assist
+      runners, and a modern feature set for emulators that older emulators may
+      not support.
+    '';
+    license = licenses.mpl20;
+    maintainers = with maintainers; [ MP2E AndersonTorres ];
+    platforms = platforms.linux;
+  };
+}
+# TODO: use desktopItem functions
diff --git a/pkgs/applications/emulators/mupen64plus/default.nix b/pkgs/applications/emulators/mupen64plus/default.nix
new file mode 100644
index 00000000000..f5d17d9d395
--- /dev/null
+++ b/pkgs/applications/emulators/mupen64plus/default.nix
@@ -0,0 +1,29 @@
+{lib, stdenv, fetchurl, boost, dash, freetype, libpng, pkg-config, SDL, which, zlib, nasm }:
+
+stdenv.mkDerivation rec {
+  pname = "mupen64plus";
+  version = "2.5.9";
+
+  src = fetchurl {
+    url = "https://github.com/mupen64plus/mupen64plus-core/releases/download/${version}/mupen64plus-bundle-src-${version}.tar.gz";
+    sha256 = "1a21n4gqdvag6krwcjm5bnyw5phrlxw6m0mk73jy53iq03f3s96m";
+  };
+
+  nativeBuildInputs = [ pkg-config nasm ];
+  buildInputs = [ boost dash freetype libpng SDL which zlib ];
+
+  buildPhase = ''
+    dash m64p_build.sh PREFIX="$out" COREDIR="$out/lib/" PLUGINDIR="$out/lib/mupen64plus" SHAREDIR="$out/share/mupen64plus"
+  '';
+  installPhase = ''
+    dash m64p_install.sh DESTDIR="$out" PREFIX=""
+  '';
+
+  meta = with lib; {
+    description = "A Nintendo 64 Emulator";
+    license = licenses.gpl2Plus;
+    homepage = "http://www.mupen64plus.org/";
+    maintainers = [ maintainers.sander ];
+    platforms = [ "x86_64-linux" ];
+  };
+}
diff --git a/pkgs/applications/emulators/nestopia/build-fix.patch b/pkgs/applications/emulators/nestopia/build-fix.patch
new file mode 100644
index 00000000000..a7d82ead15c
--- /dev/null
+++ b/pkgs/applications/emulators/nestopia/build-fix.patch
@@ -0,0 +1,18 @@
+diff -wbBur rdanbrook-nestopia-f1dde9b/Makefile rdanbrook-nestopia-f1dde9b.my/Makefile
+--- rdanbrook-nestopia-f1dde9b/Makefile	2013-01-20 20:10:25.000000000 +0400
++++ rdanbrook-nestopia-f1dde9b.my/Makefile	2013-01-21 15:18:54.727577673 +0400
+@@ -197,11 +197,11 @@
+ 	install -m 0644 NstDatabase.xml $(DATADIR)
+ 	install -m 0644 source/unix/icons/*.png $(DATADIR)/icons
+ 	install -m 0644 source/unix/icons/*.svg $(DATADIR)/icons
+-	install -m 0644 source/unix/icons/nestopia.svg $(PREFIX)/share/pixmaps
+-	xdg-desktop-menu install --novendor $(DATADIR)/nestopia.desktop
++	install -m 0644 source/unix/icons/nestopia.svg $(PREFIX)/share/pixmaps/nestopia.svg
++	install -Dm0644 $(DATADIR)/nestopia.desktop $(PREFIX)/share/applications/nestopia.desktop
+ 
+ uninstall:
+-	xdg-desktop-menu uninstall $(DATADIR)/nestopia.desktop
++	rm $(PREFIX)/share/applications/nestopia.desktop
+ 	rm $(PREFIX)/share/pixmaps/nestopia.svg
+ 	rm $(BINDIR)/$(BIN)
+ 	rm -rf $(DATADIR)
diff --git a/pkgs/applications/emulators/nestopia/default.nix b/pkgs/applications/emulators/nestopia/default.nix
new file mode 100644
index 00000000000..fa55c2e9635
--- /dev/null
+++ b/pkgs/applications/emulators/nestopia/default.nix
@@ -0,0 +1,72 @@
+{ lib, stdenv, fetchFromGitHub, pkg-config, SDL2, alsa-lib, gtk3
+, makeWrapper, libGLU, libGL, libarchive, libao, unzip, xdg-utils
+, libepoxy, gdk-pixbuf, gnome, wrapGAppsHook
+}:
+
+stdenv.mkDerivation rec {
+  version = "1.47";
+  pname = "nestopia";
+
+  src = fetchFromGitHub {
+    owner = "rdanbrook";
+    repo = "nestopia";
+    rev = version;
+    sha256 = "0frr0gvjh5mxzdhj0ii3sh671slgnzlm8naqlc4h87rx4p4sz2y2";
+  };
+
+  # nondeterministic failures when creating directories
+  enableParallelBuilding = false;
+
+  hardeningDisable = [ "format" ];
+
+  buildInputs = [
+    SDL2
+    alsa-lib
+    libepoxy
+    gtk3
+    gdk-pixbuf
+    libGLU libGL
+    libarchive
+    libao
+    xdg-utils
+    gnome.adwaita-icon-theme
+  ];
+
+  nativeBuildInputs = [
+    pkg-config
+    makeWrapper
+    wrapGAppsHook
+    unzip
+  ];
+
+  installPhase = ''
+    mkdir -p $out/{bin,share/nestopia}
+    make install PREFIX=$out
+  '';
+
+  preFixup = ''
+     for f in $out/bin/*; do
+       wrapProgram $f \
+         --prefix XDG_DATA_DIRS : "$GSETTINGS_SCHEMAS_PATH:$out/share"
+     done
+  '';
+
+  patches = [
+    #(fetchpatch {
+    #  url = "https://github.com/rdanbrook/nestopia/commit/f4bc74ac4954328b25e961e7afb7337377084079.patch";
+    #  name = "gcc6.patch";
+    #  sha256 = "1jy0c85xsfk9hrv5a6v0kk48d94864qb62yyni9fp93kyl33y2p4";
+    #})
+    ./gcc6.patch
+    ./build-fix.patch
+  ];
+
+  meta = {
+    homepage = "http://0ldsk00l.ca/nestopia/";
+    description = "NES emulator with a focus on accuracy";
+    license = lib.licenses.gpl2;
+    platforms = lib.platforms.linux;
+    maintainers = with lib.maintainers; [ MP2E ];
+  };
+}
+
diff --git a/pkgs/applications/emulators/nestopia/gcc6.patch b/pkgs/applications/emulators/nestopia/gcc6.patch
new file mode 100644
index 00000000000..65dcc72c0c2
--- /dev/null
+++ b/pkgs/applications/emulators/nestopia/gcc6.patch
@@ -0,0 +1,92 @@
+From f4bc74ac4954328b25e961e7afb7337377084079 Mon Sep 17 00:00:00 2001
+From: David Seifert <soap@gentoo.org>
+Date: Sat, 31 Dec 2016 18:21:18 +0200
+Subject: [PATCH] Fix compiling in C++14 mode
+
+* Left shifting a negative signed is undefined behaviour
+* Fix incorrect printf() specifiers found with -Wformat
+---
+ source/core/NstCore.hpp            | 4 ++--
+ source/unix/gtkui/gtkui.cpp        | 2 +-
+ source/unix/gtkui/gtkui.h          | 1 -
+ source/unix/gtkui/gtkui_cheats.cpp | 8 ++++----
+ source/unix/video.cpp              | 2 +-
+ 5 files changed, 8 insertions(+), 9 deletions(-)
+
+diff --git a/source/core/NstCore.hpp b/source/core/NstCore.hpp
+index 50e20f6..420cc4a 100644
+--- a/source/core/NstCore.hpp
++++ b/source/core/NstCore.hpp
+@@ -279,14 +279,14 @@ namespace Nes
+ 		template<typename T>

+ 		inline long signed_shl(T v,uint c)

+ 		{

+-			enum {NATIVE = T(-7) << 1 == -14};

++			enum {NATIVE = -(T(7) << 1) == -14};

+ 			return Helper::ShiftSigned<T,NATIVE>::Left( v, c );

+ 		}

+ 

+ 		template<typename T>

+ 		inline long signed_shr(T v,uint c)

+ 		{

+-			enum {NATIVE = T(-7) >> 1 == -4 || T(-7) >> 1 == -3};

++			enum {NATIVE = -(T(7) >> 1) == -4 || -(T(7) >> 1) == -3};

+ 			return Helper::ShiftSigned<T,NATIVE>::Right( v, c );

+ 		}

+ 

+diff --git a/source/unix/gtkui/gtkui.cpp b/source/unix/gtkui/gtkui.cpp
+index 3cfeeab..d4a5e2d 100644
+--- a/source/unix/gtkui/gtkui.cpp
++++ b/source/unix/gtkui/gtkui.cpp
+@@ -438,7 +438,7 @@ void gtkui_message(const char* message) {
+ 				GTK_DIALOG_DESTROY_WITH_PARENT,
+ 				GTK_MESSAGE_INFO,
+ 				GTK_BUTTONS_OK,
+-				message);
++				"%s", message);
+ 	gtk_dialog_run(GTK_DIALOG(messagewindow));
+ 	gtk_widget_destroy(messagewindow);
+ }
+diff --git a/source/unix/gtkui/gtkui_cheats.cpp b/source/unix/gtkui/gtkui_cheats.cpp
+index afc01b0..e7b691a 100644
+--- a/source/unix/gtkui/gtkui_cheats.cpp
++++ b/source/unix/gtkui/gtkui_cheats.cpp
+@@ -373,7 +373,7 @@ void gtkui_cheats_fill_tree(char *filename) {
+ 				else if (node.GetChild(L"address")) { // Raw
+ 					char rawbuf[11];
+ 					snprintf(rawbuf, sizeof(rawbuf),
+-								"%04x %02x %02x",
++								"%04lu %02lu %02lu",
+ 								node.GetChild(L"address").GetUnsignedValue(),
+ 								node.GetChild(L"value").GetUnsignedValue(),
+ 								node.GetChild(L"compare").GetUnsignedValue());
+@@ -545,13 +545,13 @@ gboolean gtkui_cheats_scan_list(GtkTreeModel *model, GtkTreePath *path, GtkTreeI
+ 			int addr, value, compare;
+ 			char buf[5];
+ 			
+-			snprintf(buf, sizeof(buf), "%c%c%c%c\0", rawcode[0], rawcode[1], rawcode[2], rawcode[3]);
++			snprintf(buf, sizeof(buf), "%c%c%c%c", rawcode[0], rawcode[1], rawcode[2], rawcode[3]);
+ 			sscanf(buf, "%x", &addr);
+ 			
+-			snprintf(buf, sizeof(buf), "%c%c\0", rawcode[5], rawcode[6]);
++			snprintf(buf, sizeof(buf), "%c%c", rawcode[5], rawcode[6]);
+ 			sscanf(buf, "%x", &value);
+ 			
+-			snprintf(buf, sizeof(buf), "%c%c\0", rawcode[8], rawcode[9]);
++			snprintf(buf, sizeof(buf), "%c%c", rawcode[8], rawcode[9]);
+ 			sscanf(buf, "%x", &compare);
+ 			
+ 			code.address = addr;
+diff --git a/source/unix/video.cpp b/source/unix/video.cpp
+index 3eff19d..c34bb22 100644
+--- a/source/unix/video.cpp
++++ b/source/unix/video.cpp
+@@ -757,7 +757,7 @@ void video_screenshot(const char* filename) {
+ 	if (filename == NULL) {
+ 		// Set the filename
+ 		char sshotpath[512];
+-		snprintf(sshotpath, sizeof(sshotpath), "%sscreenshots/%s-%d-%d.png", nstpaths.nstdir, nstpaths.gamename, time(NULL), rand() % 899 + 100);
++		snprintf(sshotpath, sizeof(sshotpath), "%sscreenshots/%s-%ld-%d.png", nstpaths.nstdir, nstpaths.gamename, time(NULL), rand() % 899 + 100);
+ 		
+ 		// Save the file
+ 		lodepng_encode32_file(sshotpath, (const unsigned char*)pixels, rendersize.w, rendersize.h);
diff --git a/pkgs/applications/emulators/np2kai/default.nix b/pkgs/applications/emulators/np2kai/default.nix
new file mode 100644
index 00000000000..0ed47af8f5b
--- /dev/null
+++ b/pkgs/applications/emulators/np2kai/default.nix
@@ -0,0 +1,196 @@
+{ stdenv
+, lib
+, fetchFromGitHub
+, enable16Bit ? true
+, enable32Bit ? true
+
+, enableSDL ? true
+, withSDLVersion ? "2"
+, SDL
+, SDL_ttf
+, SDL_mixer
+, SDL2
+, SDL2_ttf
+, SDL2_mixer
+
+, enableX11 ? stdenv.hostPlatform.isLinux
+, automake
+, autoconf
+, autoconf-archive
+, libtool
+, pkg-config
+, unzip
+, gtk2
+, libusb1
+, libXxf86vm
+, nasm
+, libICE
+, libSM
+
+  # HAXM build succeeds but the binary segfaults, seemingly due to the missing HAXM kernel module
+  # Enable once there is a HAXM kernel module option in NixOS? Or somehow bind it to the system kernel having HAXM?
+  # Or leave it disabled by default?
+  # https://github.com/intel/haxm/blob/master/docs/manual-linux.md
+, enableHAXM ? false
+}:
+
+assert lib.assertMsg (enable16Bit || enable32Bit)
+  "Must enable 16-Bit and/or 32-Bit system variant.";
+assert lib.assertMsg (enableSDL || enableX11)
+  "Must enable SDL and/or X11 graphics interfaces.";
+assert lib.assertOneOf "withSDLVersion" withSDLVersion [ "1" "2" ];
+assert enableHAXM -> (lib.assertMsg enableX11
+  "Must enable X11 graphics interface for HAXM build.");
+let
+  inherit (lib) optional optionals optionalString;
+  inherit (lib.strings) concatStringsSep concatMapStringsSep;
+  isSDL2 = (withSDLVersion == "2");
+  sdlInfix = optionalString isSDL2 "2";
+  sdlDeps1 = [
+    SDL
+    SDL_ttf
+    SDL_mixer
+  ];
+  sdlDeps2 = [
+    SDL2
+    SDL2_ttf
+    SDL2_mixer
+  ];
+  sdlDepsBuildonly = if isSDL2 then sdlDeps1 else sdlDeps2;
+  sdlDepsTarget = if isSDL2 then sdlDeps2 else sdlDeps1;
+  sdlMakefileSuffix =
+    if stdenv.hostPlatform.isWindows then "win"
+    else if stdenv.hostPlatform.isDarwin then "mac"
+    else "unix";
+  sdlMakefiles = concatMapStringsSep " " (x: x + "." + sdlMakefileSuffix)
+    (optionals enable16Bit [
+      "Makefile"
+    ] ++ optionals enable32Bit [
+      "Makefile21"
+    ]);
+  sdlBuildFlags = concatStringsSep " "
+    (optionals enableSDL [
+      "SDL_VERSION=${withSDLVersion}"
+    ]);
+  sdlBins = concatStringsSep " "
+    (optionals enable16Bit [
+      "np2kai"
+    ] ++ optionals enable32Bit [
+      "np21kai"
+    ]);
+  x11ConfigureFlags = concatStringsSep " "
+    ((
+      if ((enableHAXM && (enable16Bit || enable32Bit)) || (enable16Bit && enable32Bit)) then [
+        "--enable-build-all"
+      ] else if enableHAXM then [
+        "--enable-haxm"
+      ] else if enable32Bit then [
+        "--enable-ia32"
+      ] else [ ]
+    ) ++ optionals (!isSDL2) [
+      "--enable-sdl"
+      "--enable-sdlmixer"
+      "--enable-sdlttf"
+
+      "--enable-sdl2=no"
+      "--enable-sdl2mixer=no"
+      "--enable-sdl2ttf=no"
+    ]);
+  x11BuildFlags = concatStringsSep " " [
+    "SDL2_CONFIG=sdl2-config"
+    "SDL_CONFIG=sdl-config"
+    "SDL_CFLAGS=\"$(sdl${sdlInfix}-config --cflags)\""
+    "SDL_LIBS=\"$(sdl${sdlInfix}-config --libs) -lSDL${sdlInfix}_mixer -lSDL${sdlInfix}_ttf\""
+  ];
+  x11Bins = concatStringsSep " "
+    (optionals enable16Bit [
+      "xnp2kai"
+    ] ++ optionals enable32Bit [
+      "xnp21kai"
+    ] ++ optionals enableHAXM [
+      "xnp21kai_haxm"
+    ]);
+in
+stdenv.mkDerivation rec {
+  pname = "np2kai";
+  version = "0.86rev22"; #update src.rev to commit rev accordingly
+
+  src = fetchFromGitHub rec {
+    owner = "AZO234";
+    repo = "NP2kai";
+    rev = "4a317747724669343e4c33ebdd34783fb7043221";
+    sha256 = "0kxysxhx6jyk82mx30ni0ydzmwdcbnlxlnarrlq018rsnwb4md72";
+  };
+
+  configurePhase = ''
+    export GIT_VERSION=${builtins.substring 0 7 src.rev}
+    buildFlags="$buildFlags ''${enableParallelBuilding:+-j$NIX_BUILD_CORES -l$NIX_BUILD_CORES}"
+  '' + optionalString enableX11 ''
+    cd x11
+    substituteInPlace Makefile.am \
+      --replace 'GIT_VERSION :=' 'GIT_VERSION ?='
+    ./autogen.sh ${x11ConfigureFlags}
+    ./configure ${x11ConfigureFlags}
+    cd ..
+  '';
+
+  nativeBuildInputs = sdlDepsBuildonly
+    ++ optionals enableX11 [
+    automake
+    autoconf
+    autoconf-archive
+    libtool
+    pkg-config
+    unzip
+    nasm
+  ];
+
+  buildInputs = sdlDepsTarget
+    ++ optionals enableX11 [
+    gtk2
+    libICE
+    libSM
+    libusb1
+    libXxf86vm
+  ];
+
+  enableParallelBuilding = true;
+
+  buildPhase = optionalString enableSDL ''
+    cd sdl2
+    for mkfile in ${sdlMakefiles}; do
+      substituteInPlace $mkfile \
+        --replace 'GIT_VERSION :=' 'GIT_VERSION ?='
+      echo make -f $mkfile $buildFlags ${sdlBuildFlags} clean
+      make -f $mkfile $buildFlags ${sdlBuildFlags} clean
+      make -f $mkfile $buildFlags ${sdlBuildFlags}
+    done
+    cd ..
+  '' + optionalString enableX11 ''
+    cd x11
+    make $buildFlags ${x11BuildFlags}
+    cd ..
+  '';
+
+  installPhase = optionalString enableSDL ''
+    cd sdl2
+    for emu in ${sdlBins}; do
+      install -D -m 755 $emu $out/bin/$emu
+    done
+    cd ..
+  '' + optionalString enableX11 ''
+    cd x11
+    for emu in ${x11Bins}; do
+      install -D -m 755 $emu $out/bin/$emu
+    done
+    cd ..
+  '';
+
+  meta = with lib; {
+    description = "A PC-9801 series emulator";
+    homepage = "https://github.com/AZO234/NP2kai";
+    license = licenses.mit;
+    maintainers = with maintainers; [ OPNA2608 ];
+    platforms = platforms.x86;
+  };
+}
diff --git a/pkgs/applications/emulators/oberon-risc-emu/default.nix b/pkgs/applications/emulators/oberon-risc-emu/default.nix
new file mode 100644
index 00000000000..749e3549bf8
--- /dev/null
+++ b/pkgs/applications/emulators/oberon-risc-emu/default.nix
@@ -0,0 +1,27 @@
+{ lib, stdenv, fetchFromGitHub, SDL2 }:
+
+stdenv.mkDerivation {
+  pname = "oberon-risc-emu";
+  version = "unstable-2020-08-18";
+
+  src = fetchFromGitHub {
+    owner = "pdewacht";
+    repo = "oberon-risc-emu";
+    rev = "26c8ac5737c71811803c87ad51f1f0d6e62e71fe";
+    sha256 = "1iriix3cfcpbkjb5xjb4ysh592xppgprwzp3b6qhwcx44g7kdvxq";
+  };
+
+  buildInputs = [ SDL2 ];
+
+  installPhase = ''
+    mkdir -p $out/bin
+    mv risc $out/bin
+  '';
+
+  meta = with lib; {
+    homepage    = "https://github.com/pdewacht/oberon-risc-emu/";
+    description = "Emulator for the Oberon RISC machine";
+    license     = licenses.isc;
+    maintainers = with maintainers; [ siraben ];
+  };
+}
diff --git a/pkgs/applications/emulators/openmsx/custom-nix.mk b/pkgs/applications/emulators/openmsx/custom-nix.mk
new file mode 100644
index 00000000000..9098762e40d
--- /dev/null
+++ b/pkgs/applications/emulators/openmsx/custom-nix.mk
@@ -0,0 +1,9 @@
+# This file substitutes $sourceRoot/build/custom.mk
+
+VERSION_EXEC:=false
+SYMLINK_FOR_BINARY:=false
+INSTALL_CONTRIB:=true
+INSTALL_BASE:=${out}
+INSTALL_DOC_DIR:=${INSTALL_BASE}/share/doc/openmsx
+INSTALL_SHARE_DIR:=${INSTALL_BASE}/share/openmsx
+INSTALL_BINARY_DIR:=${INSTALL_BASE}/bin
diff --git a/pkgs/applications/emulators/openmsx/default.nix b/pkgs/applications/emulators/openmsx/default.nix
new file mode 100644
index 00000000000..f054b954b59
--- /dev/null
+++ b/pkgs/applications/emulators/openmsx/default.nix
@@ -0,0 +1,75 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, pkg-config
+, SDL2
+, SDL2_image
+, SDL2_ttf
+, alsa-lib
+, freetype
+, glew
+, libGL
+, libogg
+, libpng
+, libtheora
+, libvorbis
+, python
+, tcl
+, zlib
+}:
+
+stdenv.mkDerivation rec {
+  pname = "openmsx";
+  version = "17.0";
+
+  src = fetchFromGitHub {
+    owner = "openMSX";
+    repo = "openMSX";
+    rev = "RELEASE_${builtins.replaceStrings ["."] ["_"] version}";
+    sha256 = "sha256-9PdUNahJZ2O6ASkzLW/uudP3hiIzTDpxzFy6Pjb8JiU=";
+    fetchSubmodules = true;
+  };
+
+  nativeBuildInputs = [
+    pkg-config
+    python
+  ];
+
+  buildInputs = [
+    SDL2
+    SDL2_image
+    SDL2_ttf
+    alsa-lib
+    freetype
+    glew
+    libGL
+    libogg
+    libpng
+    libtheora
+    libvorbis
+    tcl
+    zlib
+  ];
+
+  postPatch = ''
+    cp ${./custom-nix.mk} build/custom.mk
+  '';
+
+  dontAddPrefix = true;
+
+  # Many thanks @mthuurne from OpenMSX project for providing support to
+  # Nixpkgs! :)
+  TCL_CONFIG="${tcl}/lib/";
+
+  meta = with lib; {
+    homepage = "https://openmsx.org";
+    description = "The MSX emulator that aims for perfection";
+    longDescription = ''
+      OpenMSX is an emulator for the MSX home computer system. Its goal is
+      to emulate all aspects of the MSX with 100% accuracy.
+    '';
+    license = with licenses; [ bsd2 boost gpl2Plus ];
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/applications/emulators/pcem/default.nix b/pkgs/applications/emulators/pcem/default.nix
new file mode 100644
index 00000000000..2e6aa683e4d
--- /dev/null
+++ b/pkgs/applications/emulators/pcem/default.nix
@@ -0,0 +1,29 @@
+{ stdenv, lib, fetchzip, wxGTK31, coreutils, SDL2, openal, alsa-lib, pkg-config
+, autoreconfHook, withNetworking ? true, withALSA ? true }:
+
+stdenv.mkDerivation rec {
+  pname = "pcem";
+  version = "17";
+
+  src = fetchzip {
+    url = "https://pcem-emulator.co.uk/files/PCemV${version}Linux.tar.gz";
+    stripRoot = false;
+    sha256 = "067pbnc15h6a4pnnym82klr1w8qwfm6p0pkx93gx06wvwqsxvbdv";
+  };
+
+  nativeBuildInputs = [ autoreconfHook pkg-config ];
+  buildInputs = [ wxGTK31 coreutils SDL2 openal ]
+    ++ lib.optional withALSA alsa-lib;
+
+  configureFlags = [ "--enable-release-build" ]
+    ++ lib.optional withNetworking "--enable-networking"
+    ++ lib.optional withALSA "--enable-alsa";
+
+  meta = with lib; {
+    description = "Emulator for IBM PC computers and clones";
+    homepage = "https://pcem-emulator.co.uk/";
+    license = licenses.gpl2Only;
+    maintainers = [ maintainers.terin ];
+    platforms = platforms.linux ++ platforms.windows;
+  };
+}
diff --git a/pkgs/applications/emulators/pcsx2/default.nix b/pkgs/applications/emulators/pcsx2/default.nix
new file mode 100644
index 00000000000..2e22e7d9053
--- /dev/null
+++ b/pkgs/applications/emulators/pcsx2/default.nix
@@ -0,0 +1,93 @@
+{ alsa-lib
+, cmake
+, fetchFromGitHub
+, fmt
+, gettext
+, glib
+, gtk3
+, harfbuzz
+, lib
+, libaio
+, libpcap
+, libpng
+, libpulseaudio
+, libsamplerate
+, libxml2
+, perl
+, pkg-config
+, portaudio
+, SDL2
+, soundtouch
+, stdenv
+, udev
+, wrapGAppsHook
+, wxGTK
+, zlib
+, wayland
+}:
+
+stdenv.mkDerivation rec {
+  pname = "pcsx2";
+  version = "1.7.2105";
+
+  src = fetchFromGitHub {
+    owner = "PCSX2";
+    repo = "pcsx2";
+    fetchSubmodules = true;
+    rev = "v${version}";
+    hash = "sha256-/A8u7oDIVs0Zmne0ebaXxOeIQbM9pr62KEH6FJR2umk=";
+  };
+
+  cmakeFlags = [
+    "-DDISABLE_ADVANCE_SIMD=TRUE"
+    "-DDISABLE_PCSX2_WRAPPER=TRUE"
+    "-DPACKAGE_MODE=TRUE"
+    "-DWAYLAND_API=TRUE"
+    "-DXDG_STD=TRUE"
+  ];
+
+  nativeBuildInputs = [ cmake perl pkg-config wrapGAppsHook ];
+
+  buildInputs = [
+    alsa-lib
+    fmt
+    gettext
+    glib
+    gtk3
+    harfbuzz
+    libaio
+    libpcap
+    libpng
+    libpulseaudio
+    libsamplerate
+    libxml2
+    portaudio
+    SDL2
+    soundtouch
+    udev
+    wayland
+    wxGTK
+    zlib
+  ];
+
+  meta = with lib; {
+    description = "Playstation 2 emulator";
+    longDescription = ''
+      PCSX2 is an open-source PlayStation 2 (AKA PS2) emulator. Its purpose
+      is to emulate the PS2 hardware, using a combination of MIPS CPU
+      Interpreters, Recompilers and a Virtual Machine which manages hardware
+      states and PS2 system memory. This allows you to play PS2 games on your
+      PC, with many additional features and benefits.
+    '';
+    homepage = "https://pcsx2.net";
+    maintainers = with maintainers; [ hrdinka govanify ];
+    mainProgram = "PCSX2";
+
+    # PCSX2's source code is released under LGPLv3+. It However ships
+    # additional data files and code that are licensed differently.
+    # This might be solved in future, for now we should stick with
+    # license.free
+    license = licenses.free;
+    platforms = platforms.x86;
+  };
+}
diff --git a/pkgs/applications/emulators/pcsxr/0001-libpcsxcore-fix-build-with-ffmpeg-4.patch b/pkgs/applications/emulators/pcsxr/0001-libpcsxcore-fix-build-with-ffmpeg-4.patch
new file mode 100644
index 00000000000..0edc6281a7e
--- /dev/null
+++ b/pkgs/applications/emulators/pcsxr/0001-libpcsxcore-fix-build-with-ffmpeg-4.patch
@@ -0,0 +1,76 @@
+From 351be6b3f2ad10d86ec4ae711db5a1067acc592a Mon Sep 17 00:00:00 2001
+From: Zane van Iperen <zane@zanevaniperen.com>
+Date: Sun, 7 Nov 2021 15:17:07 +1000
+Subject: [PATCH] libpcsxcore: fix build with ffmpeg 4
+
+---
+ libpcsxcore/cdriso.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c
+index f89678e..6314482 100644
+--- a/libpcsxcore/cdriso.c
++++ b/libpcsxcore/cdriso.c
+@@ -266,14 +266,14 @@ static int decode_compressed_cdda_track(FILE* outfile, const char* infilepath, s
+ 		}
+ 
+ 		if (!decoded_frame) {
+-			if (!(decoded_frame = avcodec_alloc_frame())) {
++			if (!(decoded_frame = av_frame_alloc())) {
+ 				SysMessage(_(" -> Error allocating audio frame buffer. This track will not be available."));
+ 				avformat_close_input(&inAudioFormat);
+-				avcodec_free_frame(&decoded_frame);
++				av_frame_free(&decoded_frame);
+ 				return 1; // error decoding frame
+ 			}
+ 		} else {
+-			avcodec_get_frame_defaults(decoded_frame);
++			av_frame_unref(decoded_frame);
+ 		}
+ 		len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
+ 		if (len > 0 && got_frame) {
+@@ -285,7 +285,7 @@ static int decode_compressed_cdda_track(FILE* outfile, const char* infilepath, s
+ 			fwrite(decoded_frame->data[0], 1, data_size, outfile);
+ 		}
+ 		av_free_packet(&avpkt);
+-		//avcodec_free_frame(&decoded_frame);
++		//av_frame_free(&decoded_frame);
+ 	} while (moreFrames >= 0); // TODO: check for possible leaks
+ 
+ 	// file will be closed later on, now just flush it
+@@ -294,7 +294,7 @@ static int decode_compressed_cdda_track(FILE* outfile, const char* infilepath, s
+ 	avformat_close_input(&inAudioFormat);
+ 	//avcodec_close(c);
+ 	//av_free(c);
+-	avcodec_free_frame(&decoded_frame);
++	av_frame_free(&decoded_frame);
+ 	return 0;
+ }
+ #endif
+@@ -340,12 +340,12 @@ static int decode_compressed_cdda_track(FILE* outfile, FILE* infile, enum AVCode
+ 	while (avpkt.size > 0) {
+ 		int got_frame = 0;
+ 		if (!decoded_frame) {
+-			if (!(decoded_frame = avcodec_alloc_frame())) {
++			if (!(decoded_frame = av_frame_alloc())) {
+ 				SysPrintf(" -> Error allocating audio frame buffer. Track will not be available.");
+ 				return 1; // error decoding frame
+ 			}
+ 		} else {
+-			avcodec_get_frame_defaults(decoded_frame);
++			av_frame_unref(decoded_frame);
+ 		}
+ 
+ 		len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
+@@ -383,7 +383,7 @@ static int decode_compressed_cdda_track(FILE* outfile, FILE* infile, enum AVCode
+ 
+ 	avcodec_close(c);
+ 	av_free(c);
+-	avcodec_free_frame(&decoded_frame);
++	av_frame_free(&decoded_frame);
+ 	return 0;
+ }
+ #endif
+-- 
+2.31.1
+
diff --git a/pkgs/applications/emulators/pcsxr/default.nix b/pkgs/applications/emulators/pcsxr/default.nix
new file mode 100644
index 00000000000..e3126efe82d
--- /dev/null
+++ b/pkgs/applications/emulators/pcsxr/default.nix
@@ -0,0 +1,89 @@
+{ lib, stdenv, fetchurl, autoreconfHook, intltool, pkg-config, gtk3, SDL2, xorg
+, wrapGAppsHook, libcdio, nasm, ffmpeg, file
+, fetchpatch }:
+
+stdenv.mkDerivation rec {
+  pname = "pcsxr";
+  version = "1.9.94";
+
+  # codeplex does not support direct downloading
+  src = fetchurl {
+    url = "mirror://debian/pool/main/p/pcsxr/pcsxr_${version}.orig.tar.xz";
+    sha256 = "0q7nj0z687lmss7sgr93ij6my4dmhkm2nhjvlwx48dn2lxl6ndla";
+  };
+
+  patches = [
+    ( fetchpatch {
+      url = "https://salsa.debian.org/games-team/pcsxr/raw/315e56d16e36ef3011f72d0fe86190728d2ba596/debian/patches/01_fix-i386-exec-stack.patch";
+      sha256 = "17497wjxd6b92bj458s2769d9bpp68ydbvmfs9gp51yhnq4zl81x";
+    })
+    ( fetchpatch {
+      url = "https://salsa.debian.org/games-team/pcsxr/raw/315e56d16e36ef3011f72d0fe86190728d2ba596/debian/patches/02_disable-ppc-auto-dynarec.patch";
+      sha256 = "0v8n79z034w6cqdrzhgd9fkdpri42mzvkdjm19x4asz94gg2i2kf";
+    })
+    ( fetchpatch {
+      url = "https://salsa.debian.org/games-team/pcsxr/raw/315e56d16e36ef3011f72d0fe86190728d2ba596/debian/patches/03_fix-plugin-dir.patch";
+      sha256 = "0vkl0mv6whqaz79kvvvlmlmjpynyq4lh352j3bbxcr0vjqffxvsy";
+    })
+    ( fetchpatch {
+      url = "https://salsa.debian.org/games-team/pcsxr/raw/315e56d16e36ef3011f72d0fe86190728d2ba596/debian/patches/04_update-homedir-symlinks.patch";
+      sha256 = "18r6n025ybr8fljfsaqm4ap31wp8838j73lrsffi49fkis60dp4j";
+    })
+    ( fetchpatch {
+      url = "https://salsa.debian.org/games-team/pcsxr/raw/315e56d16e36ef3011f72d0fe86190728d2ba596/debian/patches/05_format-security.patch";
+      sha256 = "03m4kfc9bk5669hf7ji1anild08diliapx634f9cigyxh72jcvni";
+    })
+    ( fetchpatch {
+      url = "https://salsa.debian.org/games-team/pcsxr/raw/315e56d16e36ef3011f72d0fe86190728d2ba596/debian/patches/06_warnings.patch";
+      sha256 = "0iz3g9ihnhisfgrzma9l74y4lhh57na9h41bmiam1millb796g71";
+    })
+    ( fetchpatch {
+      url = "https://salsa.debian.org/games-team/pcsxr/raw/315e56d16e36ef3011f72d0fe86190728d2ba596/debian/patches/07_non-linux-ip-addr.patch";
+      sha256 = "14vb9l0l4nzxcymhjjs4q57nmsncmby9qpdr7c19rly5wavm4k77";
+    })
+    ( fetchpatch {
+      url = "https://salsa.debian.org/games-team/pcsxr/raw/315e56d16e36ef3011f72d0fe86190728d2ba596/debian/patches/08_reproducible.patch";
+      sha256 = "1cx9q59drsk9h6l31097lg4aanaj93ysdz5p88pg9c7wvxk1qz06";
+    })
+
+    ./uncompress2.patch
+    ./0001-libpcsxcore-fix-build-with-ffmpeg-4.patch
+  ];
+
+  nativeBuildInputs = [ autoreconfHook intltool pkg-config wrapGAppsHook ];
+  buildInputs = [
+    gtk3 SDL2 xorg.libXv xorg.libXtst libcdio nasm ffmpeg file
+    xorg.libXxf86vm
+  ];
+
+  dynarecTarget =
+   if stdenv.isx86_64 then "x86_64"
+   else if stdenv.isi686 then "x86"
+   else "no"; #debian patch 2 says ppc doesn't work
+
+  configureFlags = [
+    "--enable-opengl"
+    "--enable-ccdda"
+    "--enable-libcdio"
+    "--enable-dynarec=${dynarecTarget}"
+  ];
+
+  postInstall = ''
+    mkdir -p "$out/share/doc/${pname}-${version}"
+    cp README \
+       AUTHORS \
+       doc/keys.txt \
+       doc/tweaks.txt \
+       ChangeLog.df \
+       ChangeLog \
+       "$out/share/doc/${pname}-${version}"
+  '';
+
+  meta = with lib; {
+    description = "Playstation 1 emulator";
+    homepage = "https://pcsxr.codeplex.com/";
+    maintainers = with maintainers; [ rardiol ];
+    license = licenses.gpl2Plus;
+    platforms = platforms.all;
+  };
+}
diff --git a/pkgs/applications/emulators/pcsxr/uncompress2.patch b/pkgs/applications/emulators/pcsxr/uncompress2.patch
new file mode 100644
index 00000000000..356868ce7a8
--- /dev/null
+++ b/pkgs/applications/emulators/pcsxr/uncompress2.patch
@@ -0,0 +1,20 @@
+--- a/libpcsxcore/cdriso.c
++++ b/libpcsxcore/cdriso.c
+@@ -1219,7 +1219,7 @@
+ 	return ret;
+ }
+ 
+-static int uncompress2(void *out, unsigned long *out_size, void *in, unsigned long in_size)
++static int uncompress3(void *out, unsigned long *out_size, void *in, unsigned long in_size)
+ {
+ 	static z_stream z;
+ 	int ret = 0;
+@@ -1298,7 +1298,7 @@
+ 	if (is_compressed) {
+ 		cdbuffer_size_expect = sizeof(compr_img->buff_raw[0]) << compr_img->block_shift;
+ 		cdbuffer_size = cdbuffer_size_expect;
+-		ret = uncompress2(compr_img->buff_raw[0], &cdbuffer_size, compr_img->buff_compressed, size);
++		ret = uncompress3(compr_img->buff_raw[0], &cdbuffer_size, compr_img->buff_compressed, size);
+ 		if (ret != 0) {
+ 			SysPrintf("uncompress failed with %d for block %d, sector %d\n",
+ 					ret, block, sector);
diff --git a/pkgs/applications/emulators/ppsspp/default.nix b/pkgs/applications/emulators/ppsspp/default.nix
new file mode 100644
index 00000000000..b84d18a4e7a
--- /dev/null
+++ b/pkgs/applications/emulators/ppsspp/default.nix
@@ -0,0 +1,72 @@
+{ mkDerivation
+, fetchFromGitHub
+, SDL2
+, cmake
+, ffmpeg
+, glew
+, lib
+, libzip
+, pkg-config
+, python3
+, qtbase
+, qtmultimedia
+, snappy
+, zlib
+}:
+
+mkDerivation rec {
+  pname = "ppsspp";
+  version = "1.12.3";
+
+  src = fetchFromGitHub {
+    owner = "hrydgard";
+    repo = pname;
+    rev = "v${version}";
+    fetchSubmodules = true;
+    sha256 = "sha256-S16rTB0svksW5MwrPV/+qpTK4uKZ7mFcmbOyEmMmzhY=";
+  };
+
+  postPatch = ''
+    substituteInPlace git-version.cmake --replace unknown ${src.rev}
+    substituteInPlace UI/NativeApp.cpp --replace /usr/share $out/share
+  '';
+
+  nativeBuildInputs = [ cmake pkg-config python3 ];
+
+  buildInputs = [
+    SDL2
+    ffmpeg
+    glew
+    libzip
+    qtbase
+    qtmultimedia
+    snappy
+    zlib
+  ];
+
+  cmakeFlags = [
+    "-DHEADLESS=OFF"
+    "-DOpenGL_GL_PREFERENCE=GLVND"
+    "-DUSE_SYSTEM_FFMPEG=ON"
+    "-DUSE_SYSTEM_LIBZIP=ON"
+    "-DUSE_SYSTEM_SNAPPY=ON"
+    "-DUSING_QT_UI=ON"
+  ];
+
+  installPhase = ''
+    runHook preInstall
+    mkdir -p $out/share/ppsspp
+    install -Dm555 PPSSPPQt $out/bin/ppsspp
+    mv assets $out/share/ppsspp
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    homepage = "https://www.ppsspp.org/";
+    description = "A HLE Playstation Portable emulator, written in C++";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = platforms.linux;
+  };
+}
+# TODO: add SDL headless port
diff --git a/pkgs/applications/emulators/proton-caller/default.nix b/pkgs/applications/emulators/proton-caller/default.nix
new file mode 100644
index 00000000000..d10c4364232
--- /dev/null
+++ b/pkgs/applications/emulators/proton-caller/default.nix
@@ -0,0 +1,23 @@
+{ lib, fetchFromGitHub, rustPlatform }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "proton-caller";
+  version = "2.3.2";
+
+  src = fetchFromGitHub {
+    owner = "caverym";
+    repo = pname;
+    rev = version;
+    sha256 = "sha256-k+cH86atuVoLCQ+I1zu08f4T+y0u8vnjo3VA+Otg+a4=";
+  };
+
+  cargoSha256 = "sha256-rkgg96IdIhVXZ5y/ECUxNPyPV9Nv5XGAtlxAkILry2s=";
+
+  meta = with lib; {
+    description = "Run Windows programs with Proton";
+    changelog = "https://github.com/caverym/proton-caller/releases/tag/${version}";
+    homepage = "https://github.com/caverym/proton-caller";
+    license = licenses.mit;
+    maintainers = with maintainers; [ kho-dialga ];
+  };
+}
diff --git a/pkgs/applications/emulators/punes/default.nix b/pkgs/applications/emulators/punes/default.nix
new file mode 100644
index 00000000000..9b147de4fa9
--- /dev/null
+++ b/pkgs/applications/emulators/punes/default.nix
@@ -0,0 +1,74 @@
+{ mkDerivation
+, stdenv
+, lib
+, fetchFromGitHub
+, fetchpatch
+, nix-update-script
+, qtbase
+, qtsvg
+, qttools
+, autoreconfHook
+, cmake
+, pkg-config
+, ffmpeg
+, libGLU
+, alsa-lib
+, libX11
+, libXrandr
+, sndio
+}:
+
+mkDerivation rec {
+  pname = "punes";
+  version = "0.108";
+
+  src = fetchFromGitHub {
+    owner = "punesemu";
+    repo = "puNES";
+    rev = "v${version}";
+    sha256 = "0inkwmvbr2w4addmgk9r4f13yismang9ylfgflhh9352lf0lirv8";
+  };
+
+  patches = [
+    # Drop when version > 0.108
+    # https://github.com/punesemu/puNES/issues/185
+    (fetchpatch {
+      name = "0001-punes-Fixed-make-install.patch";
+      url = "https://github.com/punesemu/puNES/commit/902434f50398ebcda0786ade4b28a0496084810e.patch";
+      sha256 = "1a3052n3n1qipi4bd7f7gq4zl5jjjzzzpbijdisis2vxvhnfvcim";
+    })
+  ];
+
+  postPatch = ''
+    substituteInPlace configure.ac \
+      --replace '`$PKG_CONFIG --variable=host_bins Qt5Core`/lrelease' '${qttools.dev}/bin/lrelease'
+  '';
+
+  nativeBuildInputs = [ autoreconfHook cmake pkg-config qttools ];
+
+  buildInputs = [ ffmpeg qtbase qtsvg libGLU ]
+    ++ lib.optionals stdenv.hostPlatform.isLinux [ alsa-lib libX11 libXrandr ]
+    ++ lib.optionals stdenv.hostPlatform.isBSD [ sndio ];
+
+  dontUseCmakeConfigure = true;
+
+  enableParallelBuilding = true;
+
+  configureFlags = [
+    "--prefix=${placeholder "out"}"
+    "--without-opengl-nvidia-cg"
+    "--with-ffmpeg"
+  ];
+
+  passthru.updateScript = nix-update-script {
+    attrPath = pname;
+  };
+
+  meta = with lib; {
+    description = "Qt-based Nintendo Entertainment System emulator and NSF/NSFe Music Player";
+    homepage = "https://github.com/punesemu/puNES";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ OPNA2608 ];
+    platforms = with platforms; linux ++ freebsd ++ openbsd ++ windows;
+  };
+}
diff --git a/pkgs/applications/emulators/py65/default.nix b/pkgs/applications/emulators/py65/default.nix
new file mode 100644
index 00000000000..66ba3cdf4b4
--- /dev/null
+++ b/pkgs/applications/emulators/py65/default.nix
@@ -0,0 +1,25 @@
+{ lib, fetchPypi, buildPythonApplication }:
+
+buildPythonApplication rec {
+  pname = "py65";
+  version = "1.1.0";
+  format = "wheel";
+
+  src = fetchPypi {
+    inherit pname version format;
+    sha256 = "Q7rjiHJ/Ew985vut/8fVAf/wWYW5aBPSvNPm8A6g1zg=";
+  };
+
+  meta = with lib; {
+    homepage = "https://py65.readthedocs.io/";
+    description = "Emulate 6502-based microcomputer systems in Python";
+    longDescription = ''
+      Py65 includes a program called Py65Mon that functions as a machine
+      language monitor. This kind of program is sometimes also called a
+      debugger. Py65Mon provides a command line with many convenient commands
+      for interacting with the simulated 6502-based system.
+    '';
+    license = licenses.bsd3;
+    maintainers = with maintainers; [ AndersonTorres ];
+  };
+}
diff --git a/pkgs/applications/emulators/qmc2/default.nix b/pkgs/applications/emulators/qmc2/default.nix
new file mode 100644
index 00000000000..6c6a52fc65c
--- /dev/null
+++ b/pkgs/applications/emulators/qmc2/default.nix
@@ -0,0 +1,41 @@
+{ lib, stdenv
+, fetchurl, qttools, pkg-config
+, minizip, zlib
+, qtbase, qtsvg, qtmultimedia, qtwebkit, qttranslations, qtxmlpatterns
+, rsync, SDL2, xwininfo
+, util-linux
+, xorg
+}:
+
+stdenv.mkDerivation rec {
+  pname = "qmc2";
+  version = "0.195";
+
+  src = fetchurl {
+      url = "mirror://sourceforge/project/qmc2/qmc2/${version}/${pname}-${version}.tar.gz";
+      sha256 = "1dzmjlfk8pdspns6zg1jmd5fqzg8igd4q38cz4a1vf39lx74svns";
+  };
+
+  preBuild = ''
+    patchShebangs scripts
+  '';
+
+  nativeBuildInputs = [ qttools pkg-config ];
+  buildInputs = [ minizip qtbase qtsvg qtmultimedia qtwebkit
+                  qttranslations qtxmlpatterns rsync SDL2
+                  xwininfo zlib util-linux xorg.libxcb ];
+
+  makeFlags = [ "DESTDIR=$(out)"
+                "PREFIX=/"
+                "DATADIR=/share/"
+                "SYSCONFDIR=/etc" ];
+
+  meta = with lib; {
+    description = "A Qt frontend for MAME/MESS";
+    homepage = "https://qmc2.batcom-it.net";
+    license = licenses.gpl2;
+    maintainers = [ ];
+    platforms = platforms.linux;
+    broken = true;
+  };
+}
diff --git a/pkgs/applications/emulators/reicast/default.nix b/pkgs/applications/emulators/reicast/default.nix
new file mode 100644
index 00000000000..f9e8e4d6937
--- /dev/null
+++ b/pkgs/applications/emulators/reicast/default.nix
@@ -0,0 +1,52 @@
+{ lib, stdenv
+, fetchFromGitHub
+, cmake
+, pkg-config
+, curl
+, alsa-lib
+, libGLU
+, libX11
+, libevdev
+, udev
+, libpulseaudio
+}:
+
+stdenv.mkDerivation rec {
+  pname = "reicast";
+  version = "20.04";
+
+  src = fetchFromGitHub {
+    owner = "reicast";
+    repo = "reicast-emulator";
+    rev = "r${version}";
+    sha256 = "0vz3b1hg1qj6nycnqq5zcpzqpcbxw1c2ffamia5z3x7rapjx5d71";
+  };
+
+  nativeBuildInputs = [ cmake pkg-config ];
+  buildInputs = [
+    curl
+    alsa-lib
+    libGLU
+    libX11
+    libevdev
+    udev
+    libpulseaudio
+  ];
+
+  # No rule to make target 'install'
+  installPhase = ''
+    runHook preInstall
+
+    install -D ./reicast $out/bin/reicast
+
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    homepage = "https://reicast.com/";
+    description = "A multi-platform Sega Dreamcast emulator";
+    license = with licenses; [ bsd3 gpl2Only lgpl2Only ];
+    platforms = ["x86_64-linux" ];
+    maintainers = [ maintainers.ivar ];
+  };
+}
diff --git a/pkgs/applications/emulators/resim/default.nix b/pkgs/applications/emulators/resim/default.nix
new file mode 100644
index 00000000000..49d7721174f
--- /dev/null
+++ b/pkgs/applications/emulators/resim/default.nix
@@ -0,0 +1,21 @@
+{ fetchFromGitHub, lib, stdenv, cmake, qt4 }:
+
+stdenv.mkDerivation {
+  pname = "resim";
+  version = "unstable-2016-11-11";
+  src = fetchFromGitHub {
+    owner = "itszor";
+    repo = "resim";
+    rev = "cdc7808ceb7ba4ac00d0d08ca646b58615059150";
+    sha256 = "1743lngqxd7ai4k6cd4d1cf9h60z2pnvr2iynfs1zlpcj3w1hx0c";
+  };
+  nativeBuildInputs = [ cmake ];
+  buildInputs = [ qt4 ];
+  installPhase = ''
+    mkdir -pv $out/{lib,bin}
+    cp -v libresim/libarmsim.so $out/lib/libarmsim.so
+    cp -v vc4emul/vc4emul $out/bin/vc4emul
+  '';
+
+  meta.license = lib.licenses.mit;
+}
diff --git a/pkgs/applications/emulators/retroarch/0001-Disable-menu_show_core_updater.patch b/pkgs/applications/emulators/retroarch/0001-Disable-menu_show_core_updater.patch
new file mode 100644
index 00000000000..75018dc8c4d
--- /dev/null
+++ b/pkgs/applications/emulators/retroarch/0001-Disable-menu_show_core_updater.patch
@@ -0,0 +1,25 @@
+From 546b343294209abbb193883ab76b679b7f99c6d3 Mon Sep 17 00:00:00 2001
+From: Thiago Kenji Okada <thiagokokada@gmail.com>
+Date: Sat, 20 Nov 2021 16:03:50 -0300
+Subject: [PATCH 1/2] Disable "menu_show_core_updater"
+
+---
+ retroarch.cfg | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/retroarch.cfg b/retroarch.cfg
+index cdcb199c9f..ab72f3920f 100644
+--- a/retroarch.cfg
++++ b/retroarch.cfg
+@@ -681,7 +681,7 @@
+ # menu_show_online_updater = true
+ 
+ # If disabled, will hide the ability to update cores (and core info files) inside the menu.
+-# menu_show_core_updater = true
++menu_show_core_updater = false
+ 
+ # If disabled, the libretro core will keep running in the background when we
+ # are in the menu.
+-- 
+2.31.1
+
diff --git a/pkgs/applications/emulators/retroarch/0002-Use-fixed-paths-on-libretro_info_path.patch b/pkgs/applications/emulators/retroarch/0002-Use-fixed-paths-on-libretro_info_path.patch
new file mode 100644
index 00000000000..9aa8db6ab04
--- /dev/null
+++ b/pkgs/applications/emulators/retroarch/0002-Use-fixed-paths-on-libretro_info_path.patch
@@ -0,0 +1,80 @@
+From 6788718299e1aba3ff8b31cd6ef012e8d3643bd3 Mon Sep 17 00:00:00 2001
+From: Thiago Kenji Okada <thiagokokada@gmail.com>
+Date: Sat, 20 Nov 2021 15:59:23 -0300
+Subject: [PATCH 2/2] Use fixed paths on "libretro_info_path"
+
+This patch sets "libretro_info_path" to `handle = false`, so instead of
+using the values from `retroarch.cfg`, it will always use the default.
+
+Also, it patches the default "libretro_info_path" to the
+`@libretro_info_path` string, so we can substitute it with the full path
+to it during build.
+---
+ configuration.c                    | 2 +-
+ frontend/drivers/platform_darwin.m | 9 ++-------
+ frontend/drivers/platform_unix.c   | 8 ++++----
+ 3 files changed, 7 insertions(+), 12 deletions(-)
+
+diff --git a/configuration.c b/configuration.c
+index e6a3841324..afb1d6e2ce 100644
+--- a/configuration.c
++++ b/configuration.c
+@@ -1456,7 +1456,7 @@ static struct config_path_setting *populate_settings_path(
+    SETTING_PATH("core_options_path",
+          settings->paths.path_core_options, false, NULL, true);
+    SETTING_PATH("libretro_info_path",
+-         settings->paths.path_libretro_info, false, NULL, true);
++         settings->paths.path_libretro_info, false, NULL, false);
+    SETTING_PATH("content_database_path",
+          settings->paths.path_content_database, false, NULL, true);
+    SETTING_PATH("cheat_database_path",
+diff --git a/frontend/drivers/platform_darwin.m b/frontend/drivers/platform_darwin.m
+index f922e50c55..52732f65ae 100644
+--- a/frontend/drivers/platform_darwin.m
++++ b/frontend/drivers/platform_darwin.m
+@@ -383,14 +383,9 @@ static void frontend_darwin_get_env(int *argc, char *argv[],
+          home_dir_buf, "shaders_glsl",
+          sizeof(g_defaults.dirs[DEFAULT_DIR_SHADER]));
+ #endif
+-#ifdef HAVE_UPDATE_CORES
+     fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE],
+-		    home_dir_buf, "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
+-#else
+-    fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE],
+-		    bundle_path_buf, "modules", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
+-#endif
+-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], home_dir_buf, "info", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));
++		    "@libretro_directory@", "", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
++   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], "@libretro_info_path@", "", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));
+    fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OVERLAY], home_dir_buf, "overlays", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY]));
+ #ifdef HAVE_VIDEO_LAYOUT
+    fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT], home_dir_buf, "layouts", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT]));
+diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c
+index 722e1c595c..d87e01cf12 100644
+--- a/frontend/drivers/platform_unix.c
++++ b/frontend/drivers/platform_unix.c
+@@ -1815,8 +1815,8 @@ static void frontend_unix_get_env(int *argc,
+       strcpy_literal(base_path, "retroarch");
+ #endif
+ 
+-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], base_path,
+-         "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
++   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], "@libretro_directory@",
++         "", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
+ #if defined(DINGUX)
+    /* On platforms that require manual core installation/
+     * removal, placing core info files in the same directory
+@@ -1825,8 +1825,8 @@ static void frontend_unix_get_env(int *argc,
+    fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], base_path,
+          "core_info", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));
+ #else
+-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], base_path,
+-         "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));
++   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], "@libretro_info_path@",
++         "", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));
+ #endif
+    fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG], base_path,
+          "autoconfig", sizeof(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG]));
+-- 
+2.31.1
+
diff --git a/pkgs/applications/emulators/retroarch/cores.nix b/pkgs/applications/emulators/retroarch/cores.nix
new file mode 100644
index 00000000000..e0045a3827d
--- /dev/null
+++ b/pkgs/applications/emulators/retroarch/cores.nix
@@ -0,0 +1,919 @@
+{ lib
+, stdenv
+, SDL
+, alsa-lib
+, boost
+, buildPackages
+, bzip2
+, cmake
+, curl
+, fetchFromGitHub
+, ffmpeg
+, fluidsynth
+, gettext
+, hexdump
+, hidapi
+, icu
+, libaio
+, libGL
+, libGLU
+, libevdev
+, libjpeg
+, libpcap
+, libpng
+, libvorbis
+, libxml2
+, libzip
+, makeWrapper
+, nasm
+, openssl
+, pcre
+, pkg-config
+, portaudio
+, python3
+, retroarch
+, sfml
+, snappy
+, udev
+, which
+, xorg
+, xxd
+, xz
+, zlib
+}:
+
+let
+  hashesFile = builtins.fromJSON (builtins.readFile ./hashes.json);
+
+  getCoreSrc = core:
+    fetchFromGitHub (builtins.getAttr core hashesFile);
+
+  mkLibRetroCore =
+    { core
+    , description
+      # Check https://github.com/libretro/libretro-core-info for license information
+    , license
+    , src ? (getCoreSrc core)
+    , broken ? false
+    , version ? "unstable-2022-01-21"
+    , platforms ? retroarch.meta.platforms
+      # The resulting core file is based on core name
+      # Setting `normalizeCore` to `true` will convert `-` to `_` on the core filename
+    , normalizeCore ? true
+    , ...
+    }@args:
+    stdenv.mkDerivation (
+      let
+        d2u = if normalizeCore then (lib.replaceChars [ "-" ] [ "_" ]) else (x: x);
+      in
+      (rec {
+        pname = "libretro-${core}";
+        inherit version src;
+
+        buildInputs = [ zlib ] ++ args.extraBuildInputs or [ ];
+        nativeBuildInputs = [ makeWrapper ] ++ args.extraNativeBuildInputs or [ ];
+
+        makefile = "Makefile.libretro";
+        makeFlags = [
+          "platform=${{
+            linux = "unix";
+            darwin = "osx";
+            windows = "win";
+          }.${stdenv.hostPlatform.parsed.kernel.name} or stdenv.hostPlatform.parsed.kernel.name}"
+          "ARCH=${{
+            armv7l = "arm";
+            armv6l = "arm";
+            i686 = "x86";
+          }.${stdenv.hostPlatform.parsed.cpu.name} or stdenv.hostPlatform.parsed.cpu.name}"
+        ] ++ (args.makeFlags or [ ]);
+
+        coreDir = "${placeholder "out"}/lib/retroarch/cores";
+
+        installPhase = ''
+          runHook preInstall
+
+          mkdir -p $out/bin
+          mkdir -p $coreDir
+          mv ${d2u args.core}_libretro${stdenv.hostPlatform.extensions.sharedLibrary} $coreDir
+          makeWrapper ${retroarch}/bin/retroarch $out/bin/retroarch-${core} \
+            --add-flags "-L $coreDir/${d2u core}_libretro${stdenv.hostPlatform.extensions.sharedLibrary} $@"
+
+          runHook postInstall
+        '';
+
+        enableParallelBuilding = true;
+
+        passthru = {
+          inherit core;
+          libretroCore = "/lib/retroarch/cores";
+        };
+
+        meta = with lib; {
+          inherit broken description license platforms;
+          homepage = "https://www.libretro.com/";
+          maintainers = with maintainers; [ edwtjo hrdinka MP2E thiagokokada ];
+        };
+      }) // builtins.removeAttrs args [ "core" "src" "description" "license" "makeFlags" ]
+    );
+in
+{
+  inherit mkLibRetroCore;
+
+  atari800 = mkLibRetroCore {
+    core = "atari800";
+    description = "Port of Atari800 to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+    makeFlags = [ "GIT_VERSION=" ];
+  };
+
+  beetle-gba = mkLibRetroCore {
+    core = "mednafen-gba";
+    src = getCoreSrc "beetle-gba";
+    description = "Port of Mednafen's GameBoy Advance core to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  beetle-lynx = mkLibRetroCore {
+    core = "mednafen-lynx";
+    src = getCoreSrc "beetle-lynx";
+    description = "Port of Mednafen's Lynx core to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  beetle-ngp = mkLibRetroCore {
+    core = "mednafen-ngp";
+    src = getCoreSrc "beetle-ngp";
+    description = "Port of Mednafen's NeoGeo Pocket core to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  beetle-pce-fast = mkLibRetroCore {
+    core = "mednafen-pce-fast";
+    src = getCoreSrc "beetle-pce-fast";
+    description = "Port of Mednafen's PC Engine core to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  beetle-pcfx = mkLibRetroCore {
+    core = "mednafen-pcfx";
+    src = getCoreSrc "beetle-pcfx";
+    description = "Port of Mednafen's PCFX core to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  beetle-psx = mkLibRetroCore {
+    core = "mednafen-psx";
+    src = getCoreSrc "beetle-psx";
+    description = "Port of Mednafen's PSX Engine core to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+    makeFlags = [ "HAVE_HW=0" "HAVE_LIGHTREC=1" ];
+  };
+
+  beetle-psx-hw = mkLibRetroCore {
+    core = "mednafen-psx-hw";
+    src = getCoreSrc "beetle-psx";
+    description = "Port of Mednafen's PSX Engine (with HW accel) core to libretro";
+    license = lib.licenses.gpl2Only;
+    extraBuildInputs = [ libGL libGLU ];
+    makefile = "Makefile";
+    makeFlags = [ "HAVE_VULKAN=1" "HAVE_OPENGL=1" "HAVE_HW=1" "HAVE_LIGHTREC=1" ];
+  };
+
+  beetle-saturn = mkLibRetroCore {
+    core = "mednafen-saturn";
+    src = getCoreSrc "beetle-saturn";
+    description = "Port of Mednafen's Saturn core to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+    platforms = [ "x86_64-linux" "aarch64-linux" ];
+  };
+
+  beetle-snes = mkLibRetroCore {
+    core = "mednafen-snes";
+    src = getCoreSrc "beetle-snes";
+    description = "Port of Mednafen's SNES core to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  beetle-supergrafx = mkLibRetroCore {
+    core = "mednafen-supergrafx";
+    src = getCoreSrc "beetle-supergrafx";
+    description = "Port of Mednafen's SuperGrafx core to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  beetle-vb = mkLibRetroCore {
+    core = "mednafen-vb";
+    src = getCoreSrc "beetle-vb";
+    description = "Port of Mednafen's VirtualBoy core to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  beetle-wswan = mkLibRetroCore {
+    core = "mednafen-wswan";
+    src = getCoreSrc "beetle-wswan";
+    description = "Port of Mednafen's WonderSwan core to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  blastem = mkLibRetroCore {
+    core = "blastem";
+    description = "Port of BlastEm to libretro";
+    license = lib.licenses.gpl3Only;
+  };
+
+  bluemsx = mkLibRetroCore {
+    core = "bluemsx";
+    description = "Port of BlueMSX to libretro";
+    license = lib.licenses.gpl2Only;
+  };
+
+  bsnes = mkLibRetroCore {
+    core = "bsnes";
+    description = "Port of bsnes to libretro";
+    license = lib.licenses.gpl3Only;
+    makefile = "Makefile";
+  };
+
+  bsnes-hd =
+    let
+      # linux = bsd
+      # https://github.com/DerKoun/bsnes-hd/blob/f0b6cf34e9780d53516977ed2de64137a8bcc3c5/bsnes/GNUmakefile#L37
+      platform = if stdenv.isDarwin then "macos" else "linux";
+    in
+    mkLibRetroCore {
+      core = "bsnes-hd-beta";
+      src = getCoreSrc "bsnes-hd";
+      description = "Port of bsnes-hd to libretro";
+      license = lib.licenses.gpl3Only;
+      makefile = "GNUmakefile";
+      makeFlags = [
+        "-C"
+        "bsnes"
+        "target=libretro"
+        "platform=${platform}"
+      ];
+      extraBuildInputs = [ xorg.libX11 xorg.libXext ];
+      postBuild = "cd bsnes/out";
+    };
+
+  bsnes-mercury = mkLibRetroCore {
+    core = "bsnes-mercury-accuracy";
+    src = getCoreSrc "bsnes-mercury";
+    description = "Fork of bsnes with HLE DSP emulation restored";
+    license = lib.licenses.gpl3Only;
+    makefile = "Makefile";
+    makeFlags = [ "PROFILE=accuracy" ];
+  };
+
+  bsnes-mercury-balanced = mkLibRetroCore {
+    core = "bsnes-mercury-balanced";
+    src = getCoreSrc "bsnes-mercury";
+    description = "Fork of bsnes with HLE DSP emulation restored";
+    license = lib.licenses.gpl3Only;
+    makefile = "Makefile";
+    makeFlags = [ "PROFILE=balanced" ];
+  };
+
+  bsnes-mercury-performance = mkLibRetroCore {
+    core = "bsnes-mercury-performance";
+    src = getCoreSrc "bsnes-mercury";
+    description = "Fork of bsnes with HLE DSP emulation restored";
+    license = lib.licenses.gpl3Only;
+    makefile = "Makefile";
+    makeFlags = [ "PROFILE=performance" ];
+  };
+
+  citra = mkLibRetroCore {
+    core = "citra";
+    description = "Port of Citra to libretro";
+    license = lib.licenses.gpl2Plus;
+    extraNativeBuildInputs = [ cmake pkg-config ];
+    extraBuildInputs = [ libGLU libGL boost ];
+    makefile = "Makefile";
+    cmakeFlags = [
+      "-DENABLE_LIBRETRO=ON"
+      "-DENABLE_QT=OFF"
+      "-DENABLE_SDL2=OFF"
+      "-DENABLE_WEB_SERVICE=OFF"
+      "-DENABLE_DISCORD_PRESENCE=OFF"
+    ];
+    preConfigure = "sed -e '77d' -i externals/cmake-modules/GetGitRevisionDescription.cmake";
+    postBuild = "cd src/citra_libretro";
+  };
+
+  citra-canary = mkLibRetroCore {
+    core = "citra-canary";
+    description = "Port of Citra Canary/Experimental to libretro";
+    license = lib.licenses.gpl2Plus;
+    extraNativeBuildInputs = [ cmake pkg-config ];
+    extraBuildInputs = [ libGLU libGL boost ];
+    makefile = "Makefile";
+    cmakeFlags = [
+      "-DENABLE_LIBRETRO=ON"
+      "-DENABLE_QT=OFF"
+      "-DENABLE_SDL2=OFF"
+      "-DENABLE_WEB_SERVICE=OFF"
+      "-DENABLE_DISCORD_PRESENCE=OFF"
+    ];
+    preConfigure = "sed -e '77d' -i externals/cmake-modules/GetGitRevisionDescription.cmake";
+    postBuild = "cd src/citra_libretro";
+  };
+
+  desmume = mkLibRetroCore {
+    core = "desmume";
+    description = "libretro wrapper for desmume NDS emulator";
+    license = lib.licenses.gpl2Plus;
+    extraBuildInputs = [ libpcap libGLU libGL xorg.libX11 ];
+    preBuild = "cd desmume/src/frontend/libretro";
+    makeFlags = lib.optional stdenv.hostPlatform.isAarch32 "platform=armv-unix"
+      ++ lib.optional (!stdenv.hostPlatform.isx86) "DESMUME_JIT=0";
+  };
+
+  desmume2015 = mkLibRetroCore {
+    core = "desmume2015";
+    description = "libretro wrapper for desmume NDS emulator from 2015";
+    license = lib.licenses.gpl2Plus;
+    extraBuildInputs = [ libpcap libGLU libGL xorg.libX11 ];
+    makeFlags = lib.optional stdenv.hostPlatform.isAarch32 "platform=armv-unix"
+      ++ lib.optional (!stdenv.hostPlatform.isx86) "DESMUME_JIT=0";
+    preBuild = "cd desmume";
+  };
+
+  dolphin = mkLibRetroCore {
+    core = "dolphin";
+    description = "Port of Dolphin to libretro";
+    license = lib.licenses.gpl2Plus;
+
+    extraNativeBuildInputs = [ cmake curl pkg-config ];
+    extraBuildInputs = [
+      libGLU
+      libGL
+      pcre
+      sfml
+      gettext
+      hidapi
+      libevdev
+      udev
+    ] ++ (with xorg; [ libSM libX11 libXi libpthreadstubs libxcb xcbutil libXext libXrandr libXinerama libXxf86vm ]);
+    makefile = "Makefile";
+    cmakeFlags = [
+      "-DLIBRETRO=ON"
+      "-DLIBRETRO_STATIC=1"
+      "-DENABLE_QT=OFF"
+      "-DENABLE_LTO=OFF"
+      "-DUSE_UPNP=OFF"
+      "-DUSE_DISCORD_PRESENCE=OFF"
+    ];
+    dontUseCmakeBuildDir = true;
+  };
+
+  dosbox = mkLibRetroCore {
+    core = "dosbox";
+    description = "Port of DOSBox to libretro";
+    license = lib.licenses.gpl2Only;
+  };
+
+  eightyone = mkLibRetroCore {
+    core = "81";
+    src = getCoreSrc "eightyone";
+    description = "Port of EightyOne to libretro";
+    license = lib.licenses.gpl3Only;
+  };
+
+  fbalpha2012 = mkLibRetroCore {
+    core = "fbalpha2012";
+    description = "Port of Final Burn Alpha ~2012 to libretro";
+    license = "Non-commercial";
+    makefile = "makefile.libretro";
+    preBuild = "cd svn-current/trunk";
+  };
+
+  fbneo = mkLibRetroCore {
+    core = "fbneo";
+    description = "Port of FBNeo to libretro";
+    license = "Non-commercial";
+    makefile = "Makefile";
+    preBuild = "cd src/burner/libretro";
+  };
+
+  fceumm = mkLibRetroCore {
+    core = "fceumm";
+    description = "FCEUmm libretro port";
+    license = lib.licenses.gpl2Only;
+  };
+
+  flycast = mkLibRetroCore {
+    core = "flycast";
+    description = "Flycast libretro port";
+    license = lib.licenses.gpl2Only;
+    extraBuildInputs = [ libGL libGLU ];
+    makefile = "Makefile";
+    makeFlags = lib.optional stdenv.hostPlatform.isAarch64 [ "platform=arm64" ];
+    platforms = [ "aarch64-linux" "x86_64-linux" ];
+  };
+
+  fmsx = mkLibRetroCore {
+    core = "fmsx";
+    description = "FMSX libretro port";
+    license = "Non-commercial";
+    makefile = "Makefile";
+  };
+
+  freeintv = mkLibRetroCore {
+    core = "freeintv";
+    description = "FreeIntv libretro port";
+    license = lib.licenses.gpl3Only;
+    makefile = "Makefile";
+  };
+
+  gambatte = mkLibRetroCore {
+    core = "gambatte";
+    description = "Gambatte libretro port";
+    license = lib.licenses.gpl2Only;
+  };
+
+  genesis-plus-gx = mkLibRetroCore {
+    core = "genesis-plus-gx";
+    description = "Enhanced Genesis Plus libretro port";
+    license = "Non-commercial";
+  };
+
+  gpsp = mkLibRetroCore {
+    core = "gpsp";
+    description = "Port of gpSP to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  gw = mkLibRetroCore {
+    core = "gw";
+    description = "Port of Game and Watch to libretro";
+    license = lib.licenses.zlib;
+    makefile = "Makefile";
+  };
+
+  handy = mkLibRetroCore {
+    core = "handy";
+    description = "Port of Handy to libretro";
+    license = lib.licenses.zlib;
+    makefile = "Makefile";
+  };
+
+  hatari = mkLibRetroCore {
+    core = "hatari";
+    description = "Port of Hatari to libretro";
+    license = lib.licenses.gpl2Only;
+    extraBuildInputs = [ SDL zlib ];
+    extraNativeBuildInputs = [ cmake which ];
+    dontUseCmakeConfigure = true;
+    dontConfigure = true;
+    makeFlags = [ "EXTERNAL_ZLIB=1" ];
+    depsBuildBuild = [ buildPackages.stdenv.cc ];
+  };
+
+  mame = mkLibRetroCore {
+    core = "mame";
+    description = "Port of MAME to libretro";
+    license = with lib.licenses; [ bsd3 gpl2Plus ];
+    extraBuildInputs = [ alsa-lib libGLU libGL portaudio python3 xorg.libX11 ];
+    makefile = "Makefile.libretro";
+  };
+
+  mame2000 = mkLibRetroCore {
+    core = "mame2000";
+    description = "Port of MAME ~2000 to libretro";
+    license = "MAME";
+    makefile = "Makefile";
+    makeFlags = lib.optional (!stdenv.hostPlatform.isx86) "IS_X86=0";
+    enableParallelBuilding = false;
+  };
+
+  mame2003 = mkLibRetroCore {
+    core = "mame2003";
+    description = "Port of MAME ~2003 to libretro";
+    license = "MAME";
+    makefile = "Makefile";
+    enableParallelBuilding = false;
+  };
+
+  mame2003-plus = mkLibRetroCore {
+    core = "mame2003-plus";
+    description = "Port of MAME ~2003+ to libretro";
+    license = "MAME";
+    makefile = "Makefile";
+    enableParallelBuilding = false;
+  };
+
+  mame2010 = mkLibRetroCore {
+    core = "mame2010";
+    description = "Port of MAME ~2010 to libretro";
+    license = "MAME";
+    makefile = "Makefile";
+    makeFlags = lib.optionals stdenv.hostPlatform.isAarch64 [ "PTR64=1" "ARM_ENABLED=1" "X86_SH2DRC=0" "FORCE_DRC_C_BACKEND=1" ];
+    enableParallelBuilding = false;
+  };
+
+  mame2015 = mkLibRetroCore {
+    core = "mame2015";
+    description = "Port of MAME ~2015 to libretro";
+    license = "MAME";
+    makeFlags = [ "PYTHON=python3" ];
+    extraNativeBuildInputs = [ python3 ];
+    extraBuildInputs = [ alsa-lib ];
+    makefile = "Makefile";
+    enableParallelBuilding = false;
+  };
+
+  mame2016 = mkLibRetroCore {
+    core = "mame2016";
+    description = "Port of MAME ~2016 to libretro";
+    license = with lib.licenses; [ bsd3 gpl2Plus ];
+    extraNativeBuildInputs = [ python3 ];
+    extraBuildInputs = [ alsa-lib ];
+    makeFlags = [ "PYTHON_EXECUTABLE=python3" ];
+    postPatch = ''
+      # Prevent the failure during the parallel building of:
+      # make -C 3rdparty/genie/build/gmake.linux -f genie.make obj/Release/src/host/lua-5.3.0/src/lgc.o
+      mkdir -p 3rdparty/genie/build/gmake.linux/obj/Release/src/host/lua-5.3.0/src
+    '';
+    enableParallelBuilding = false;
+  };
+
+  melonds = mkLibRetroCore {
+    core = "melonds";
+    description = "Port of MelonDS to libretro";
+    license = lib.licenses.gpl3Only;
+    extraBuildInputs = [ libGL libGLU ];
+    makefile = "Makefile";
+  };
+
+  mesen = mkLibRetroCore {
+    core = "mesen";
+    description = "Port of Mesen to libretro";
+    license = lib.licenses.gpl3Only;
+    makefile = "Makefile";
+    preBuild = "cd Libretro";
+  };
+
+  mesen-s = mkLibRetroCore {
+    core = "mesen-s";
+    description = "Port of Mesen-S to libretro";
+    license = lib.licenses.gpl3Only;
+    makefile = "Makefile";
+    preBuild = "cd Libretro";
+    normalizeCore = false;
+  };
+
+  meteor = mkLibRetroCore {
+    core = "meteor";
+    description = "Port of Meteor to libretro";
+    license = lib.licenses.gpl3Only;
+    makefile = "Makefile";
+    preBuild = "cd libretro";
+  };
+
+  mgba = mkLibRetroCore {
+    core = "mgba";
+    description = "Port of mGBA to libretro";
+    license = lib.licenses.mpl20;
+  };
+
+  mupen64plus = mkLibRetroCore {
+    core = "mupen64plus-next";
+    src = getCoreSrc "mupen64plus";
+    description = "Libretro port of Mupen64 Plus, GL only";
+    license = lib.licenses.gpl3Only;
+    extraBuildInputs = [ libGLU libGL libpng nasm xorg.libX11 ];
+    makefile = "Makefile";
+  };
+
+  neocd = mkLibRetroCore {
+    core = "neocd";
+    description = "NeoCD libretro port";
+    license = lib.licenses.lgpl3Only;
+    makefile = "Makefile";
+  };
+
+  nestopia = mkLibRetroCore {
+    core = "nestopia";
+    description = "Nestopia libretro port";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+    preBuild = "cd libretro";
+  };
+
+  np2kai = mkLibRetroCore rec {
+    core = "np2kai";
+    src = getCoreSrc core;
+    description = "Neko Project II kai libretro port";
+    license = lib.licenses.mit;
+    makefile = "Makefile.libretro";
+    makeFlags = [
+      # See https://github.com/AZO234/NP2kai/tags
+      "NP2KAI_VERSION=rev.22"
+      "NP2KAI_HASH=${src.rev}"
+    ];
+    preBuild = "cd sdl";
+  };
+
+  o2em = mkLibRetroCore {
+    core = "o2em";
+    description = "Port of O2EM to libretro";
+    license = lib.licenses.artistic1;
+    makefile = "Makefile";
+  };
+
+  opera = mkLibRetroCore {
+    core = "opera";
+    description = "Opera is a port of 4DO/libfreedo to libretro";
+    license = "Non-commercial";
+    makefile = "Makefile";
+    makeFlags = [ "CC_PREFIX=${stdenv.cc.targetPrefix}" ];
+  };
+
+  parallel-n64 = mkLibRetroCore {
+    core = "parallel-n64";
+    description = "Parallel Mupen64plus rewrite for libretro.";
+    license = lib.licenses.gpl3Only;
+    extraBuildInputs = [ libGLU libGL libpng ];
+    makefile = "Makefile";
+    postPatch = lib.optionalString stdenv.hostPlatform.isAarch64 ''
+      sed -i -e '1 i\CPUFLAGS += -DARM_FIX -DNO_ASM -DARM_ASM -DDONT_WANT_ARM_OPTIMIZATIONS -DARM64' Makefile \
+      && sed -i -e 's,CPUFLAGS  :=,,g' Makefile
+    '';
+  };
+
+  pcsx2 = mkLibRetroCore {
+    core = "pcsx2";
+    description = "Port of PCSX2 to libretro";
+    license = lib.licenses.gpl3Plus;
+    extraNativeBuildInputs = [
+      cmake
+      gettext
+      pkg-config
+    ];
+    extraBuildInputs = [
+      libaio
+      libGL
+      libGLU
+      libpcap
+      libpng
+      libxml2
+      xz
+      xxd
+    ];
+    makefile = "Makefile";
+    cmakeFlags = [
+      "-DLIBRETRO=ON"
+    ];
+    postPatch = ''
+      # remove ccache
+      substituteInPlace CMakeLists.txt --replace "ccache" ""
+    '';
+    postBuild = "cd /build/source/build/pcsx2";
+    platforms = lib.platforms.x86;
+  };
+
+  pcsx_rearmed = mkLibRetroCore {
+    core = "pcsx_rearmed";
+    description = "Port of PCSX ReARMed with GNU lightning to libretro";
+    license = lib.licenses.gpl2Only;
+    dontConfigure = true;
+  };
+
+  picodrive = mkLibRetroCore {
+    core = "picodrive";
+    description = "Fast MegaDrive/MegaCD/32X emulator";
+    license = "MAME";
+
+    extraBuildInputs = [ libpng SDL ];
+    SDL_CONFIG = "${SDL.dev}/bin/sdl-config";
+    dontAddPrefix = true;
+    configurePlatforms = [ ];
+    makeFlags = lib.optional stdenv.hostPlatform.isAarch64 [ "platform=aarch64" ];
+  };
+
+  play = mkLibRetroCore {
+    core = "play";
+    description = "Port of Play! to libretro";
+    license = lib.licenses.bsd2;
+    extraBuildInputs = [ boost bzip2 curl openssl icu libGL libGLU xorg.libX11 ];
+    extraNativeBuildInputs = [ cmake ];
+    makefile = "Makefile";
+    cmakeFlags = [ "-DBUILD_PLAY=OFF" "-DBUILD_LIBRETRO_CORE=ON" ];
+    postBuild = "cd Source/ui_libretro";
+  };
+
+  ppsspp = mkLibRetroCore {
+    core = "ppsspp";
+    description = "ppsspp libretro port";
+    license = lib.licenses.gpl2Plus;
+    extraNativeBuildInputs = [ cmake pkg-config python3 ];
+    extraBuildInputs = [ libGLU libGL libzip ffmpeg snappy xorg.libX11 ];
+    makefile = "Makefile";
+    cmakeFlags = [
+      "-DLIBRETRO=ON"
+      "-DUSE_SYSTEM_FFMPEG=ON"
+      "-DUSE_SYSTEM_SNAPPY=ON"
+      "-DUSE_SYSTEM_LIBZIP=ON"
+      "-DOpenGL_GL_PREFERENCE=GLVND"
+    ];
+    postBuild = "cd lib";
+  };
+
+  prboom = mkLibRetroCore {
+    core = "prboom";
+    description = "Prboom libretro port";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  prosystem = mkLibRetroCore {
+    core = "prosystem";
+    description = "Port of ProSystem to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  quicknes = mkLibRetroCore {
+    core = "quicknes";
+    description = "QuickNES libretro port";
+    license = lib.licenses.lgpl21Plus;
+    makefile = "Makefile";
+  };
+
+  sameboy = mkLibRetroCore {
+    core = "sameboy";
+    description = "SameBoy libretro port";
+    license = lib.licenses.mit;
+    extraNativeBuildInputs = [ which hexdump ];
+    preBuild = "cd libretro";
+    makefile = "Makefile";
+  };
+
+  scummvm = mkLibRetroCore {
+    core = "scummvm";
+    description = "Libretro port of ScummVM";
+    license = lib.licenses.gpl2Only;
+    extraBuildInputs = [ fluidsynth libjpeg libvorbis libGLU libGL SDL ];
+    makefile = "Makefile";
+    preConfigure = "cd backends/platform/libretro/build";
+  };
+
+  smsplus-gx = mkLibRetroCore {
+    core = "smsplus";
+    src = getCoreSrc "smsplus-gx";
+    description = "SMS Plus GX libretro port";
+    license = lib.licenses.gpl2Plus;
+  };
+
+  snes9x = mkLibRetroCore {
+    core = "snes9x";
+    description = "Port of SNES9x git to libretro";
+    license = "Non-commercial";
+    makefile = "Makefile";
+    preBuild = "cd libretro";
+  };
+
+  snes9x2002 = mkLibRetroCore {
+    core = "snes9x2002";
+    description = "Optimized port/rewrite of SNES9x 1.39 to Libretro";
+    license = "Non-commercial";
+    makefile = "Makefile";
+  };
+
+  snes9x2005 = mkLibRetroCore {
+    core = "snes9x2005";
+    description = "Optimized port/rewrite of SNES9x 1.43 to Libretro";
+    license = "Non-commercial";
+    makefile = "Makefile";
+  };
+
+  snes9x2005-plus = mkLibRetroCore {
+    core = "snes9x2005-plus";
+    src = getCoreSrc "snes9x2005";
+    description = "Optimized port/rewrite of SNES9x 1.43 to Libretro, with Blargg's APU";
+    license = "Non-commercial";
+    makefile = "Makefile";
+    makeFlags = [ "USE_BLARGG_APU=1" ];
+  };
+
+  snes9x2010 = mkLibRetroCore {
+    core = "snes9x2010";
+    description = "Optimized port/rewrite of SNES9x 1.52+ to Libretro";
+    license = "Non-commercial";
+  };
+
+  stella = mkLibRetroCore {
+    core = "stella";
+    description = "Port of Stella to libretro";
+    license = lib.licenses.gpl2Only;
+    extraBuildInputs = [ libpng pkg-config SDL ];
+    makefile = "Makefile";
+    preBuild = "cd src/libretro";
+    dontConfigure = true;
+  };
+
+  stella2014 = mkLibRetroCore {
+    core = "stella2014";
+    description = "Port of Stella to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  swanstation = mkLibRetroCore {
+    core = "swanstation";
+    description = "Port of SwanStation (a fork of DuckStation) to libretro";
+    license = lib.licenses.gpl3Only;
+    extraNativeBuildInputs = [ cmake ];
+    makefile = "Makefile";
+    cmakeFlags = [
+      "-DBUILD_LIBRETRO_CORE=ON"
+    ];
+  };
+
+  tgbdual = mkLibRetroCore {
+    core = "tgbdual";
+    description = "Port of TGBDual to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+  };
+
+  thepowdertoy = mkLibRetroCore {
+    core = "thepowdertoy";
+    description = "Port of The Powder Toy to libretro";
+    license = lib.licenses.gpl3Only;
+    extraNativeBuildInputs = [ cmake ];
+    makefile = "Makefile";
+    postBuild = "cd src";
+  };
+
+  tic80 = mkLibRetroCore {
+    core = "tic80";
+    description = "Port of TIC-80 to libretro";
+    license = lib.licenses.mit;
+    extraNativeBuildInputs = [ cmake pkg-config libGL libGLU ];
+    makefile = "Makefile";
+    cmakeFlags = [
+      "-DBUILD_LIBRETRO=ON"
+      "-DBUILD_DEMO_CARTS=OFF"
+      "-DBUILD_PRO=OFF"
+      "-DBUILD_PLAYER=OFF"
+      "-DBUILD_SDL=OFF"
+      "-DBUILD_SOKOL=OFF"
+    ];
+    preConfigure = "cd core";
+    postBuild = "cd lib";
+  };
+
+  vba-m = mkLibRetroCore {
+    core = "vbam";
+    src = getCoreSrc "vba-m";
+    description = "vanilla VBA-M libretro port";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+    preBuild = "cd src/libretro";
+  };
+
+  vba-next = mkLibRetroCore {
+    core = "vba-next";
+    description = "VBA-M libretro port with modifications for speed";
+    license = lib.licenses.gpl2Only;
+  };
+
+  vecx = mkLibRetroCore {
+    core = "vecx";
+    description = "Port of Vecx to libretro";
+    license = lib.licenses.gpl3Only;
+    extraBuildInputs = [ libGL libGLU ];
+  };
+
+  virtualjaguar = mkLibRetroCore {
+    core = "virtualjaguar";
+    description = "Port of VirtualJaguar to libretro";
+    license = lib.licenses.gpl3Only;
+    makefile = "Makefile";
+  };
+
+  yabause = mkLibRetroCore {
+    core = "yabause";
+    description = "Port of Yabause to libretro";
+    license = lib.licenses.gpl2Only;
+    makefile = "Makefile";
+    # Disable SSE for non-x86. DYNAREC doesn't build on aarch64.
+    makeFlags = lib.optional (!stdenv.hostPlatform.isx86) "HAVE_SSE=0";
+    preBuild = "cd yabause/src/libretro";
+  };
+}
diff --git a/pkgs/applications/emulators/retroarch/default.nix b/pkgs/applications/emulators/retroarch/default.nix
new file mode 100644
index 00000000000..2c49874e544
--- /dev/null
+++ b/pkgs/applications/emulators/retroarch/default.nix
@@ -0,0 +1,122 @@
+{ lib
+, stdenv
+, enableNvidiaCgToolkit ? false
+, withGamemode ? stdenv.isLinux
+, withVulkan ? stdenv.isLinux
+, alsa-lib
+, AppKit
+, fetchFromGitHub
+, ffmpeg_4
+, Foundation
+, freetype
+, gamemode
+, libdrm
+, libGL
+, libGLU
+, libobjc
+, libpulseaudio
+, libv4l
+, libX11
+, libXdmcp
+, libXext
+, libxkbcommon
+, libxml2
+, libXxf86vm
+, makeWrapper
+, mesa
+, nvidia_cg_toolkit
+, pkg-config
+, python3
+, SDL2
+, udev
+, vulkan-loader
+, wayland
+, which
+}:
+
+let
+  version = "1.10.0";
+  libretroCoreInfo = fetchFromGitHub {
+    owner = "libretro";
+    repo = "libretro-core-info";
+    sha256 = "sha256-3j7fvcfbgyk71MmbUUKYi+/0cpQFNbYXO+DMDUjDqkQ=";
+    rev = "v${version}";
+  };
+  runtimeLibs = lib.optional withVulkan vulkan-loader
+    ++ lib.optional withGamemode gamemode.lib;
+in
+stdenv.mkDerivation rec {
+  pname = "retroarch-bare";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "libretro";
+    repo = "RetroArch";
+    sha256 = "sha256-bpTSzODVRKRs1OW6JafjbU3e/AqdQeGzWcg1lb9SIyo=";
+    rev = "v${version}";
+  };
+
+  patches = [
+    ./0001-Disable-menu_show_core_updater.patch
+    ./0002-Use-fixed-paths-on-libretro_info_path.patch
+  ];
+
+  postPatch = ''
+    substituteInPlace "frontend/drivers/platform_unix.c" \
+      --replace "@libretro_directory@" "$out/lib" \
+      --replace "@libretro_info_path@" "$out/share/libretro/info"
+    substituteInPlace "frontend/drivers/platform_darwin.m" \
+      --replace "@libretro_directory@" "$out/lib" \
+      --replace "@libretro_info_path@" "$out/share/libretro/info"
+  '';
+
+  nativeBuildInputs = [ pkg-config ] ++
+    lib.optional stdenv.isLinux wayland ++
+    lib.optional (runtimeLibs != [ ]) makeWrapper;
+
+  buildInputs = [ ffmpeg_4 freetype libxml2 libGLU libGL python3 SDL2 which ] ++
+    lib.optional enableNvidiaCgToolkit nvidia_cg_toolkit ++
+    lib.optional withVulkan vulkan-loader ++
+    lib.optionals stdenv.isDarwin [ libobjc AppKit Foundation ] ++
+    lib.optionals stdenv.isLinux [
+      alsa-lib
+      libX11
+      libXdmcp
+      libXext
+      libXxf86vm
+      libdrm
+      libpulseaudio
+      libv4l
+      libxkbcommon
+      mesa
+      udev
+      wayland
+    ];
+
+  enableParallelBuilding = true;
+
+  configureFlags = lib.optionals stdenv.isLinux [ "--enable-kms" "--enable-egl" ];
+
+  postInstall = ''
+    mkdir -p $out/share/libretro/info
+    # TODO: ideally each core should have its own core information
+    cp -r ${libretroCoreInfo}/* $out/share/libretro/info
+  '' + lib.optionalString (runtimeLibs != [ ]) ''
+    wrapProgram $out/bin/retroarch \
+      --prefix LD_LIBRARY_PATH ':' ${lib.makeLibraryPath runtimeLibs}
+  '';
+
+  preFixup = "rm $out/bin/retroarch-cg2glsl";
+
+  meta = with lib; {
+    homepage = "https://libretro.com";
+    description = "Multi-platform emulator frontend for libretro cores";
+    license = licenses.gpl3Plus;
+    platforms = platforms.unix;
+    changelog = "https://github.com/libretro/RetroArch/blob/v${version}/CHANGES.md";
+    maintainers = with maintainers; [ MP2E edwtjo matthewbauer kolbycrouch thiagokokada ];
+    # FIXME: exits with error on macOS:
+    # No Info.plist file in application bundle or no NSPrincipalClass in the Info.plist file, exiting
+    broken = stdenv.isDarwin;
+  };
+}
diff --git a/pkgs/applications/emulators/retroarch/disable-menu-show-core-updater.patch b/pkgs/applications/emulators/retroarch/disable-menu-show-core-updater.patch
new file mode 100644
index 00000000000..34fea554ef7
--- /dev/null
+++ b/pkgs/applications/emulators/retroarch/disable-menu-show-core-updater.patch
@@ -0,0 +1,13 @@
+diff --git a/retroarch.cfg b/retroarch.cfg
+index cdcb199c9f..ab72f3920f 100644
+--- a/retroarch.cfg
++++ b/retroarch.cfg
+@@ -681,7 +681,7 @@
+ # menu_show_online_updater = true
+ 
+ # If disabled, will hide the ability to update cores (and core info files) inside the menu.
+-# menu_show_core_updater = true
++menu_show_core_updater = false
+ 
+ # If disabled, the libretro core will keep running in the background when we
+ # are in the menu.
diff --git a/pkgs/applications/emulators/retroarch/fix-config.patch b/pkgs/applications/emulators/retroarch/fix-config.patch
new file mode 100644
index 00000000000..1a71bf43cb1
--- /dev/null
+++ b/pkgs/applications/emulators/retroarch/fix-config.patch
@@ -0,0 +1,26 @@
+diff --git a/retroarch.cfg b/retroarch.cfg
+index cdcb199c9f..08b9b1cf10 100644
+--- a/retroarch.cfg
++++ b/retroarch.cfg
+@@ -681,7 +681,7 @@
+ # menu_show_online_updater = true
+ 
+ # If disabled, will hide the ability to update cores (and core info files) inside the menu.
+-# menu_show_core_updater = true
++menu_show_core_updater = false
+ 
+ # If disabled, the libretro core will keep running in the background when we
+ # are in the menu.
+@@ -823,10 +823,10 @@
+ # rgui_browser_directory =
+ 
+ # Core directory for libretro core implementations.
+-# libretro_directory =
++libretro_directory = @libretro_directory@
+ 
+ # Core info directory for libretro core information.
+-# libretro_info_path =
++libretro_info_path = @libretro_info_path@
+ 
+ # Path to content database directory.
+ # content_database_path =
diff --git a/pkgs/applications/emulators/retroarch/fix-libretro-paths.patch b/pkgs/applications/emulators/retroarch/fix-libretro-paths.patch
new file mode 100644
index 00000000000..203ce836533
--- /dev/null
+++ b/pkgs/applications/emulators/retroarch/fix-libretro-paths.patch
@@ -0,0 +1,28 @@
+diff --git a/configuration.c b/configuration.c
+index e6a3841324..afb1d6e2ce 100644
+--- a/configuration.c
++++ b/configuration.c
+@@ -1456,7 +1456,7 @@ static struct config_path_setting *populate_settings_path(
+    SETTING_PATH("core_options_path",
+          settings->paths.path_core_options, false, NULL, true);
+    SETTING_PATH("libretro_info_path",
+-         settings->paths.path_libretro_info, false, NULL, true);
++         settings->paths.path_libretro_info, false, NULL, false);
+    SETTING_PATH("content_database_path",
+          settings->paths.path_content_database, false, NULL, true);
+    SETTING_PATH("cheat_database_path",
+diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c
+index 722e1c595c..e7313ee038 100644
+--- a/frontend/drivers/platform_unix.c
++++ b/frontend/drivers/platform_unix.c
+@@ -1825,8 +1825,8 @@ static void frontend_unix_get_env(int *argc,
+    fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], base_path,
+          "core_info", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));
+ #else
+-   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], base_path,
+-         "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));
++   fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], "@libretro_info_path@",
++         "", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));
+ #endif
+    fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG], base_path,
+          "autoconfig", sizeof(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG]));
diff --git a/pkgs/applications/emulators/retroarch/hashes.json b/pkgs/applications/emulators/retroarch/hashes.json
new file mode 100644
index 00000000000..1280f25047d
--- /dev/null
+++ b/pkgs/applications/emulators/retroarch/hashes.json
@@ -0,0 +1,499 @@
+{
+    "atari800": {
+        "owner": "libretro",
+        "repo": "libretro-atari800",
+        "rev": "478a8ec99a7f8436a39d5ac193c5fe313233ee7b",
+        "sha256": "LJpRegJVR2+sS1UmTTpVest0rMrNDBMXmj/jRFVglWI="
+    },
+    "beetle-gba": {
+        "owner": "libretro",
+        "repo": "beetle-gba-libretro",
+        "rev": "38182572571a48cb58057cde64b915237c4e2d58",
+        "sha256": "4xnXWswozlcXBNI1lbGSNW/gAdIeLLO9Bf1SxOFLhSo="
+    },
+    "beetle-lynx": {
+        "owner": "libretro",
+        "repo": "beetle-lynx-libretro",
+        "rev": "8930e88a4342945c023cbf713031a65de11a8e75",
+        "sha256": "bg/a+9ZJNTUIuEHKrFIss8sia3JWMWXIXbxha5qKVeI="
+    },
+    "beetle-ngp": {
+        "owner": "libretro",
+        "repo": "beetle-ngp-libretro",
+        "rev": "f7c393184e5228c3d3807ee74c951c4c549107d8",
+        "sha256": "7vki8VkwOzxwMZcUxekg1DFSskV7VNQ1SRaU3M1xHZ0="
+    },
+    "beetle-pce-fast": {
+        "owner": "libretro",
+        "repo": "beetle-pce-fast-libretro",
+        "rev": "0f43fd4dc406e7da6bbdc13b6eb1c105d6072f8a",
+        "sha256": "u1lOgXEYuGAF4sOLdsBzcA4/A5Yz1b82TjFBiM57yE4="
+    },
+    "beetle-pcfx": {
+        "owner": "libretro",
+        "repo": "beetle-pcfx-libretro",
+        "rev": "6d2b11e17ad5a95907c983e7c8a70e75508c2d41",
+        "sha256": "WG2YpCYdL/MxW5EbiP2+1VtAjbX7yYDIcLXhb+YySI4="
+    },
+    "beetle-psx": {
+        "owner": "libretro",
+        "repo": "beetle-psx-libretro",
+        "rev": "297970e4ff080ea80a5670209aeea4fde8059020",
+        "sha256": "6kZher3/+5ywXyC3n9R9JVA4IVLZBaSfAcWEKp2SsDE="
+    },
+    "beetle-saturn": {
+        "owner": "libretro",
+        "repo": "beetle-saturn-libretro",
+        "rev": "e6ba71f8bcc647b646d94dec812b24d00c41cf3f",
+        "sha256": "tDbV+CsDr4bowBbJ/C8J9scfCryTAXxz58pGaUHU5yU="
+    },
+    "beetle-snes": {
+        "owner": "libretro",
+        "repo": "beetle-bsnes-libretro",
+        "rev": "bc867656d7438aaffc6818b3b92350587bc78a47",
+        "sha256": "TyUCRGK+uyXowDjXW9/4m+zL8Vh/3GGsX1eznrTCbAg="
+    },
+    "beetle-supergrafx": {
+        "owner": "libretro",
+        "repo": "beetle-supergrafx-libretro",
+        "rev": "7bae6fb1a238f1e66b129c7c70c7cb6dbdc09fa1",
+        "sha256": "OAJ86XrwjDrgCjrk0RHMn8sHYaJFhJhLaQnhaEVXN38="
+    },
+    "beetle-vb": {
+        "owner": "libretro",
+        "repo": "beetle-vb-libretro",
+        "rev": "aa77198c6c60b935503b5ea2149b8ff7598344da",
+        "sha256": "ShsMYc2vjDoiN1yCCoSl91P5ecYJDj/V+VWUYuYVxas="
+    },
+    "beetle-wswan": {
+        "owner": "libretro",
+        "repo": "beetle-wswan-libretro",
+        "rev": "5717c101b314f64d4c384c23b1934d09fcbf82bb",
+        "sha256": "Nfezb6hja1qHv1fMGU9HMbbb56GHAfe/zIgRqrzz334="
+    },
+    "blastem": {
+        "owner": "libretro",
+        "repo": "blastem",
+        "rev": "0786858437ed71996f43b7af0fbe627eb88152fc",
+        "sha256": "uEP5hSgLAle1cLv/EM7D11TJMAggu7pqWxfrUt3rhEg="
+    },
+    "bluemsx": {
+        "owner": "libretro",
+        "repo": "bluemsx-libretro",
+        "rev": "5dfdb75106e10ef8bc21b8bcea1432ecbd590b2a",
+        "sha256": "0D0xufIt3qmQ+/UjyWynoLyLDSza8cTrFp3UwGWBXko="
+    },
+    "bsnes": {
+        "owner": "libretro",
+        "repo": "bsnes-libretro",
+        "rev": "1b2987ab1e9caf5c8d7550da01ffa08edff2f128",
+        "sha256": "l6Jvn0ZgFaKSWjiV2bN9aemxLyfnNEQFc+HS1/MuiaY="
+    },
+    "bsnes-hd": {
+        "owner": "DerKoun",
+        "repo": "bsnes-hd",
+        "rev": "65f24e56c37f46bb752190024bd4058e64ad77d1",
+        "sha256": "1dk2i71NOLeTTOZjVll8wrkr5dIH5bGSGUeeHqWjZHE="
+    },
+    "bsnes-mercury": {
+        "owner": "libretro",
+        "repo": "bsnes-mercury",
+        "rev": "d232c6ea90552f5921fec33a06626f08d3e18b24",
+        "sha256": "fpl7hmqz+Ca+9ZeM6E1JSikbiu+NJUU8xXtyl6Dd9Gg="
+    },
+    "citra": {
+        "owner": "libretro",
+        "repo": "citra",
+        "rev": "b1959d07a340bfd9af65ad464fd19eb6799a96ef",
+        "sha256": "bwnYkMvbtRF5bGZRYVtMWxnCu9P45qeX4+ntOj9eRds=",
+        "fetchSubmodules": true,
+        "leaveDotGit": true,
+        "deepClone": true
+    },
+    "citra-canary": {
+        "owner": "libretro",
+        "repo": "citra",
+        "rev": "5401990a9be46e4497abc92db3d5f2042674303d",
+        "sha256": "JKKJBa840i7ESwMrB5tKamCBmrYvvoEUdibqxkWg5Gc=",
+        "fetchSubmodules": true,
+        "leaveDotGit": true,
+        "deepClone": true
+    },
+    "desmume": {
+        "owner": "libretro",
+        "repo": "desmume",
+        "rev": "7ea0fc96804fcd9c8d33e8f76cf64b1be50cc5ea",
+        "sha256": "4S/CirRVOBN6PVbato5X5fu0tBn3Fu5FEAbdf3TBqng="
+    },
+    "desmume2015": {
+        "owner": "libretro",
+        "repo": "desmume2015",
+        "rev": "cd89fb7c48c735cb321311fbce7e6e9889dda1ce",
+        "sha256": "9Ou/n6pxRjJOp/Ybpyg4+Simosj2X26kLZCMEqeVL6U="
+    },
+    "dolphin": {
+        "owner": "libretro",
+        "repo": "dolphin",
+        "rev": "3b19e6d1781584f3e1fd2922b48b8ae6b3bcb686",
+        "sha256": "EcgJhkMzdZfYRwSpU1OcsJqQyq4V8dq5PndVufZFy7k="
+    },
+    "dosbox": {
+        "owner": "libretro",
+        "repo": "dosbox-libretro",
+        "rev": "aa71b67d54eaaf9e41cdd3cb5153d9cff0ad116e",
+        "sha256": "L0Y67UROjldnXUlLQ+Xbd7RHLb96jDxlB/k+LR9Kbas="
+    },
+    "eightyone": {
+        "owner": "libretro",
+        "repo": "81-libretro",
+        "rev": "86d7d5afe98f16006d4b1fdb99d281f1d7ea6b2f",
+        "sha256": "QN7anzqv1z8SgY8dlkjr8Ns7reGWc7hTneiRmorXZSk="
+    },
+    "fbalpha2012": {
+        "owner": "libretro",
+        "repo": "fbalpha2012",
+        "rev": "23f98fc7cf4f2f216149c263cf5913d2e28be8d4",
+        "sha256": "dAInW6tTV7oXcPhKMnHWcmQaWQCTqRrYHD2yuaI1I1w="
+    },
+    "fbneo": {
+        "owner": "libretro",
+        "repo": "fbneo",
+        "rev": "4ecf2782a4eee042d1e126d1671e5231b6437b6e",
+        "sha256": "15MYI03r45mmRsXCwzWnjfBdtzSaHLp7DfmcACQFTvU="
+    },
+    "fceumm": {
+        "owner": "libretro",
+        "repo": "libretro-fceumm",
+        "rev": "eb06d17e7912780a3ee117ae73bc50c3948c761c",
+        "sha256": "aBqskJtK1bFBjwaoo9hilr33fyAWsdj5+hFC3WY3sKk="
+    },
+    "flycast": {
+        "owner": "libretro",
+        "repo": "flycast",
+        "rev": "0d8c6a2e717c002bc76ce26a152353b004fb15e7",
+        "sha256": "t2RGHAyYXeHVqTqqhayOUWx/msFN9q/Z9P2wXJUtQTI="
+    },
+    "fmsx": {
+        "owner": "libretro",
+        "repo": "fmsx-libretro",
+        "rev": "dfcda056896576c6a1c75c002a82d0e6c1160ccc",
+        "sha256": "9ANZ1suAQcYOhqSchQ20Yuqvgw06j5Sd3Z1fjrp2UFc="
+    },
+    "freeintv": {
+        "owner": "libretro",
+        "repo": "freeintv",
+        "rev": "d58caf23ed1438a1db58f8d6ac24ca521b411d3b",
+        "sha256": "nUV+A3Zh66M1K5NDK0ksNF5H1HS3AQdeYLaGfaA34n4="
+    },
+    "gambatte": {
+        "owner": "libretro",
+        "repo": "gambatte-libretro",
+        "rev": "79bb2e56d034c30d8dcac02b6c34a59ec8fe91bc",
+        "sha256": "H+Hkeep18whaSYbyG8DcaJqsVVu7DEX9T28pkfXfyCg="
+    },
+    "genesis-plus-gx": {
+        "owner": "libretro",
+        "repo": "Genesis-Plus-GX",
+        "rev": "88c9ad000ba553b9c819d9eb259f741fabd877bb",
+        "sha256": "8ZCMq8/sk5TqwTNWMfDevZHRPSOM1PJ57kiZZ7qfQxA="
+    },
+    "gpsp": {
+        "owner": "libretro",
+        "repo": "gpsp",
+        "rev": "e554360dd3ed283696fc607877024a219248b735",
+        "sha256": "ImsqB89XmjF8nvs7j8IZVvFltgZRYvF2L7LTcJG/xCU="
+    },
+    "gw": {
+        "owner": "libretro",
+        "repo": "gw-libretro",
+        "rev": "0f1ccca156388880bf4507ad44741f80945dfc6f",
+        "sha256": "BVpx8pL224J2u9W6UDrxzfEv4qIsh6wrf3bDdd1R850="
+    },
+    "handy": {
+        "owner": "libretro",
+        "repo": "libretro-handy",
+        "rev": "3b02159ba32aa37c1b93d7f7eac56b28e3715645",
+        "sha256": "mBKK+pdWgkxYkV4OOiBrlWbLAMugDX0fd6QRh0D7JYU="
+    },
+    "hatari": {
+        "owner": "libretro",
+        "repo": "hatari",
+        "rev": "79d128888ca3efdd27d639a35edf72a9bc81a798",
+        "sha256": "du2xORgAXTSQArqNuFa5gjticgZ+weqySFHVz2Y2qzI="
+    },
+    "mame": {
+        "owner": "libretro",
+        "repo": "mame",
+        "rev": "2f9c793a77222ae46266c71f64d491cf7870dc1e",
+        "sha256": "WAhm6QMMVbnuSIK4PW7Ek+AAkMs7s95gGb6ERzlon0w="
+    },
+    "mame2000": {
+        "owner": "libretro",
+        "repo": "mame2000-libretro",
+        "rev": "4793742b457945afb74053c8a895e6ff0b36b033",
+        "sha256": "DA9fZTic/jlYzSAIiOjfhohyEyQZiBNdIa8YCZoKZNs="
+    },
+    "mame2003": {
+        "owner": "libretro",
+        "repo": "mame2003-libretro",
+        "rev": "dbda6ddacdd8962cfea25000421dba398e551aef",
+        "sha256": "RSL3iZZEJCxOtsJqjnM5ZiT0yM2nAgg/Ujq6FBLMHkk="
+    },
+    "mame2003-plus": {
+        "owner": "libretro",
+        "repo": "mame2003-plus-libretro",
+        "rev": "9c0c954f0f88730f44abdd4d414691fef6b1cd7c",
+        "sha256": "NLdHc0VuZhqQhAzv+8kipc0mhqT2BNaJeLYZUx7DwRU="
+    },
+    "mame2010": {
+        "owner": "libretro",
+        "repo": "mame2010-libretro",
+        "rev": "932e6f2c4f13b67b29ab33428a4037dee9a236a8",
+        "sha256": "HSZRSnc+0300UE9fPcUOMrXABlxHhTewkFPTqQ4Srxs="
+    },
+    "mame2015": {
+        "owner": "libretro",
+        "repo": "mame2015-libretro",
+        "rev": "e6a7aa4d53726e61498f68d6b8e2c092a2169fa2",
+        "sha256": "IgiLxYYuUIn3YE+kQCXzgshES2VNpUHn0Qjsorw0w/s="
+    },
+    "mame2016": {
+        "owner": "libretro",
+        "repo": "mame2016-libretro",
+        "rev": "bcff8046328da388d100b1634718515e1b15415d",
+        "sha256": "XxnX39+0VUbG9TF8+wFEFVxHCm2rzrJsIQryyNsF6zU="
+    },
+    "melonds": {
+        "owner": "libretro",
+        "repo": "melonds",
+        "rev": "0053daa700018657bf2e47562b3b4eb86f9b9d03",
+        "sha256": "K6ZYuk7cE+ioq1rLRyAKNQxddCYIOXLU5SXT7sYgGnc="
+    },
+    "mesen": {
+        "owner": "libretro",
+        "repo": "mesen",
+        "rev": "094d82bf724448426acbaad45e83bc38994e32f6",
+        "sha256": "9+AqZRv8lugNNa+ZZzIPJNO87J1aBUEiOggL8aYno1M="
+    },
+    "mesen-s": {
+        "owner": "libretro",
+        "repo": "mesen-s",
+        "rev": "42eb0e8ad346608dae86feb8a04833d16ad21541",
+        "sha256": "q6zeoNiZtFy8ZYls9/E+O7o9BYTcVcmYjbJA48qiraU="
+    },
+    "meteor": {
+        "owner": "libretro",
+        "repo": "meteor-libretro",
+        "rev": "e533d300d0561564451bde55a2b73119c768453c",
+        "sha256": "zMkgzUz2rk0SD5ojY4AqaDlNM4k4QxuUxVBRBcn6TqQ="
+    },
+    "mgba": {
+        "owner": "libretro",
+        "repo": "mgba",
+        "rev": "43da6e1d54ad0395f474346db88fe59a4c0aa451",
+        "sha256": "JxiWIBQi1fZoBV2lvx2r7iIvlQm0BYuJFz0TsxngUT8="
+    },
+    "mupen64plus": {
+        "owner": "libretro",
+        "repo": "mupen64plus-libretro-nx",
+        "rev": "350f90a73cf0f5d65357ce982ccbaa3b22fc3569",
+        "sha256": "9Hq93+dvO60LBbcXLIHsTq243QThicI0rVJW3tou/5Y="
+    },
+    "neocd": {
+        "owner": "libretro",
+        "repo": "neocd_libretro",
+        "rev": "83d10f3be10fff2f28aa56fc674c687528cb7f5c",
+        "sha256": "yYZGoMsUfE8cpU9i826UWQGi1l0zPJPcBDb2CINxGeQ="
+    },
+    "nestopia": {
+        "owner": "libretro",
+        "repo": "nestopia",
+        "rev": "8af07b7ab49e45495cbc4ba73cd2f879d9908b55",
+        "sha256": "Z447flP1L/7gWEovWhbBearPKzsZNnGE2cz7jH7kEnY="
+    },
+    "np2kai": {
+        "owner": "AZO234",
+        "repo": "NP2kai",
+        "rev": "30d4b6959c48db039207a37e278c868c7737ed69",
+        "sha256": "uIcgbpcEz6yUKrBe0r84Yq2ihWfT0+TdUTIF5kMT5mI=",
+        "fetchSubmodules": true
+    },
+    "o2em": {
+        "owner": "libretro",
+        "repo": "libretro-o2em",
+        "rev": "f1050243e0d5285e7769e94a882b0cf39d2b7370",
+        "sha256": "wD+iJ8cKC8jYFZ6OVvX71uO7sSh5b/LLoc5+g7f3Yyg="
+    },
+    "opera": {
+        "owner": "libretro",
+        "repo": "opera-libretro",
+        "rev": "3849c969c64b82e622a7655b327fa94bc5a4c7cc",
+        "sha256": "McSrvjrYTemqAAnfHELf9qXC6n6Dg4kNsUDA7e2DvkE="
+    },
+    "parallel-n64": {
+        "owner": "libretro",
+        "repo": "parallel-n64",
+        "rev": "28c4572c9a09447b3bf5ed5fbd3594a558bc210d",
+        "sha256": "by8NvKjVT9OrgVhNtv5E4Fqmdva42lWV8UQi0SKfBL8="
+    },
+    "pcsx2": {
+        "owner": "libretro",
+        "repo": "pcsx2",
+        "rev": "3ef2a36b0608e9dcae808c7ef01c7a760d628735",
+        "sha256": "ezqVntonhGfejiGx9cxQEnjsXEHqT++M1fO0Jz1t/Us="
+    },
+    "pcsx_rearmed": {
+        "owner": "libretro",
+        "repo": "pcsx_rearmed",
+        "rev": "12fc12797064599dfca2d44043d5c02a949711ef",
+        "sha256": "SXmNfHGyk+KChiwkKlA+d/oezzp/7p1DJY+w2bES6kg="
+    },
+    "picodrive": {
+        "owner": "libretro",
+        "repo": "picodrive",
+        "rev": "50b8b47838fea8096535d543caaacdcc56aa7df2",
+        "sha256": "C1Htwel5PHZcjkKmjiiN/QgRofMhqlArxktOSqoTxTc=",
+        "fetchSubmodules": true
+    },
+    "play": {
+        "owner": "jpd002",
+        "repo": "Play-",
+        "rev": "fd6a5161030215090d48a8036680f57914c71bb0",
+        "sha256": "g6UBRV7biLjPBXdlejjXUSk3v1wrsYWA3quZlpPj23U=",
+        "fetchSubmodules": true
+    },
+    "ppsspp": {
+        "owner": "hrydgard",
+        "repo": "ppsspp",
+        "rev": "54d63cc1daf2a0cdc812e9af85854bb4ae5ef399",
+        "sha256": "iB/8zf4FYdsbiKZVq/YISTEQSoo1kme1uZsyuhbOcoc=",
+        "fetchSubmodules": true
+    },
+    "prboom": {
+        "owner": "libretro",
+        "repo": "libretro-prboom",
+        "rev": "af1b5bf89d01095326ee27e178f9257f9e728873",
+        "sha256": "pvTUv4E+wBOYfjz8Ph11CK4E7rIm1T+u90TWDNXEBIU="
+    },
+    "prosystem": {
+        "owner": "libretro",
+        "repo": "prosystem-libretro",
+        "rev": "89e6df7b60d151310fedbe118fb472959a9dcd61",
+        "sha256": "uxgKddS53X7ntPClE8MGezBAG+7OAFvMXTnyKpOOau0="
+    },
+    "quicknes": {
+        "owner": "libretro",
+        "repo": "QuickNES_Core",
+        "rev": "743e6e06db246c5edab27c738c7a573d83140485",
+        "sha256": "NYmP+HFeZGUeIRaT3bzdpWw9cmEAaBkA3EGnw/zpDXA="
+    },
+    "sameboy": {
+        "owner": "libretro",
+        "repo": "sameboy",
+        "rev": "b154b7d3d885a3cf31203f0b8f50d3b37c8b742b",
+        "sha256": "tavGHiNpRiPkibi66orMf93cnCqQCD8XhSl/36nl/9M="
+    },
+    "scummvm": {
+        "owner": "libretro",
+        "repo": "scummvm",
+        "rev": "80cb7269a33b233dcea27d8d01df084b0d35c80a",
+        "sha256": "5kMWM8d5aBbT7TseNyaYxw7VDkrLL0G+KUvJcUboQgA="
+    },
+    "smsplus-gx": {
+        "owner": "libretro",
+        "repo": "smsplus-gx",
+        "rev": "3f1ffede55bcfe0168caa484a00bf041ab591abf",
+        "sha256": "fD+grzMPk4uXvmzGf+f9Mor0eefBLHIumCydsSHUsck="
+    },
+    "snes9x": {
+        "owner": "snes9xgit",
+        "repo": "snes9x",
+        "rev": "34b6160805c4995a8edf5f9b3328f5e492ae4c44",
+        "sha256": "YRRqtd5iu2evRk+7SyQpqpxqTaEFOkDZ/XQHEjpSBcM="
+    },
+    "snes9x2002": {
+        "owner": "libretro",
+        "repo": "snes9x2002",
+        "rev": "e16cb16efa00765b1bc3b8fee195680efb1542c7",
+        "sha256": "0dhLpNy+NUE3mE/ejEwbq3G28/a2HONS5NPslI5LOEc="
+    },
+    "snes9x2005": {
+        "owner": "libretro",
+        "repo": "snes9x2005",
+        "rev": "77e9cd293c791b47f4397da0a47242b329243cb5",
+        "sha256": "iHGfZIGzE4n3EHrVRxTULuYKsOse5NcJftmasoJFwFo="
+    },
+    "snes9x2010": {
+        "owner": "libretro",
+        "repo": "snes9x2010",
+        "rev": "714b1c8e08c7580430190119b07e793405773ac2",
+        "sha256": "yKSQEE+lT4V2V1XqemfziHuIt79TcvC0ranU9ounTXo="
+    },
+    "stella": {
+        "owner": "stella-emu",
+        "repo": "stella",
+        "rev": "1db9de390a331a7d55c35591c93d9e89184cce5f",
+        "sha256": "vICKxx+UBYvMzZ3a3F86yzJRKfdo0jMxa27wsUX0KZw="
+    },
+    "stella2014": {
+        "owner": "libretro",
+        "repo": "stella2014-libretro",
+        "rev": "934c7a2a44ef038af529b68950ddba4f7ea3478e",
+        "sha256": "s7LQ47sAPTyk4COONk4qnebxCq78zGLIjh3Y2+1fIak="
+    },
+    "swanstation": {
+        "owner": "libretro",
+        "repo": "swanstation",
+        "rev": "61c5debe60192b0fecd8c15310b2e4c4473f9438",
+        "sha256": "DZJApJnGDMsUhjO35TBc7tMldCGKDPPtrwxPLe0Ey1s="
+    },
+    "tgbdual": {
+        "owner": "libretro",
+        "repo": "tgbdual-libretro",
+        "rev": "1e0c4f931d8c5e859e6d3255d67247d7a2987434",
+        "sha256": "0wHv9DpKuzJ/q5vERqCo4GBLre2ggClBIWSjGnMLQq8="
+    },
+    "thepowdertoy": {
+        "owner": "libretro",
+        "repo": "ThePowderToy",
+        "rev": "ac620c0a89a18774c3ad176a8a1bc596df23ff57",
+        "sha256": "C/X1DbmnucRddemEYml2zN3qr5yoXY3b+nvqfpboS0M="
+    },
+    "tic80": {
+        "owner": "libretro",
+        "repo": "tic-80",
+        "rev": "967eb78c3610385a0e6cba8bb5c60ebc3b886d3e",
+        "sha256": "N0QFNTYFVbhWwt2yx5fLM7Dl6pJZPYrt9o3+6rjnWa8=",
+        "fetchSubmodules": true
+    },
+    "vba-m": {
+        "owner": "libretro",
+        "repo": "vbam-libretro",
+        "rev": "254f6effebe882b7d3d29d9e417c6aeeabc08026",
+        "sha256": "vJWjdqJ913NLGL4G15sRPqO/wp9xPsuhUMLUuAbDRKk="
+    },
+    "vba-next": {
+        "owner": "libretro",
+        "repo": "vba-next",
+        "rev": "b218f48bb27b5d3885fa4076ff325922b5acd817",
+        "sha256": "idqGMbMA9mZlIh0QAba3BxpPDi/bFJJkUbnxV3xMOCo="
+    },
+    "vecx": {
+        "owner": "libretro",
+        "repo": "libretro-vecx",
+        "rev": "28d6efc8972313903d0802a736ff8c3bc115e78f",
+        "sha256": "VYa8s+HB8IYF+HS6SA+sO5DzpgCtnMGrh88KTVNGICY="
+    },
+    "virtualjaguar": {
+        "owner": "libretro",
+        "repo": "virtualjaguar-libretro",
+        "rev": "d1b1b28a6ad2518b746e3f7537ec6d66db96ec57",
+        "sha256": "Io25dt80fqIqIxwzF2DK9J5UFz6YCUQoqThcIuxdEBo="
+    },
+    "yabause": {
+        "owner": "libretro",
+        "repo": "yabause",
+        "rev": "f30153ff9e534b96049c6f1ac3075b572642ceb5",
+        "sha256": "AdqCr5X3Bq8ic2jkIestmYi+CBByZ5Fyf0BUYwBkWnA="
+    }
+}
diff --git a/pkgs/applications/emulators/retroarch/kodi-advanced-launchers.nix b/pkgs/applications/emulators/retroarch/kodi-advanced-launchers.nix
new file mode 100644
index 00000000000..9d83c46396c
--- /dev/null
+++ b/pkgs/applications/emulators/retroarch/kodi-advanced-launchers.nix
@@ -0,0 +1,36 @@
+{ stdenv, pkgs, lib, runtimeShell, cores ? [ ] }:
+
+let
+
+  script = exec: ''
+    #!${runtimeShell}
+    nohup sh -c "pkill -SIGTSTP kodi" &
+    # https://forum.kodi.tv/showthread.php?tid=185074&pid=1622750#pid1622750
+    nohup sh -c "sleep 10 && ${exec} '$@' -f;pkill -SIGCONT kodi"
+  '';
+  scriptSh = exec: pkgs.writeScript ("kodi-"+exec.name) (script exec.path);
+  execs = map (core: rec { name = core.core; path = core+"/bin/retroarch-"+name;}) cores;
+
+in
+
+stdenv.mkDerivation {
+  pname = "kodi-retroarch-advanced-launchers";
+  version = "0.2";
+
+  dontBuild = true;
+
+  buildCommand = ''
+    mkdir -p $out/bin
+    ${lib.concatMapStrings (exec: "ln -s ${scriptSh exec} $out/bin/kodi-${exec.name};") execs}
+  '';
+
+  meta = {
+    description = "Kodi retroarch advanced launchers";
+    longDescription = ''
+      These retroarch launchers are intended to be used with
+      advanced (emulation) launcher for Kodi since device input is
+      otherwise caught by both Kodi and the retroarch process.
+    '';
+    license = lib.licenses.gpl3;
+  };
+}
diff --git a/pkgs/applications/emulators/retroarch/update.py b/pkgs/applications/emulators/retroarch/update.py
new file mode 100755
index 00000000000..68f72103168
--- /dev/null
+++ b/pkgs/applications/emulators/retroarch/update.py
@@ -0,0 +1,179 @@
+#!/usr/bin/env nix-shell
+#!nix-shell -I nixpkgs=../../../../ -i python3 -p "python3.withPackages (ps: with ps; [ requests nix-prefetch-github ])" -p "git"
+
+import json
+import sys
+import subprocess
+from pathlib import Path
+
+SCRIPT_PATH = Path(__file__).absolute().parent
+HASHES_PATH = SCRIPT_PATH / "hashes.json"
+CORES = {
+    "atari800": {"repo": "libretro-atari800"},
+    "beetle-gba": {"repo": "beetle-gba-libretro"},
+    "beetle-lynx": {"repo": "beetle-lynx-libretro"},
+    "beetle-ngp": {"repo": "beetle-ngp-libretro"},
+    "beetle-pce-fast": {"repo": "beetle-pce-fast-libretro"},
+    "beetle-pcfx": {"repo": "beetle-pcfx-libretro"},
+    "beetle-psx": {"repo": "beetle-psx-libretro"},
+    "beetle-saturn": {"repo": "beetle-saturn-libretro"},
+    "beetle-snes": {"repo": "beetle-bsnes-libretro"},
+    "beetle-supergrafx": {"repo": "beetle-supergrafx-libretro"},
+    "beetle-vb": {"repo": "beetle-vb-libretro"},
+    "beetle-wswan": {"repo": "beetle-wswan-libretro"},
+    "blastem": {"repo": "blastem"},
+    "bluemsx": {"repo": "bluemsx-libretro"},
+    "bsnes": {"repo": "bsnes-libretro"},
+    "bsnes-hd": {"repo": "bsnes-hd", "owner": "DerKoun"},
+    "bsnes-mercury": {"repo": "bsnes-mercury"},
+    "citra": {
+        "repo": "citra",
+        "fetch_submodules": True,
+        "deep_clone": True,
+        "leave_dot_git": True,
+    },
+    "citra-canary": {
+        "repo": "citra",
+        "fetch_submodules": True,
+        "deep_clone": True,
+        "leave_dot_git": True,
+        "rev": "canary",
+    },
+    "desmume": {"repo": "desmume"},
+    "desmume2015": {"repo": "desmume2015"},
+    "dolphin": {"repo": "dolphin"},
+    "dosbox": {"repo": "dosbox-libretro"},
+    "eightyone": {"repo": "81-libretro"},
+    "fbalpha2012": {"repo": "fbalpha2012"},
+    "fbneo": {"repo": "fbneo"},
+    "fceumm": {"repo": "libretro-fceumm"},
+    "flycast": {"repo": "flycast"},
+    "fmsx": {"repo": "fmsx-libretro"},
+    "freeintv": {"repo": "freeintv"},
+    "gambatte": {"repo": "gambatte-libretro"},
+    "genesis-plus-gx": {"repo": "Genesis-Plus-GX"},
+    "gpsp": {"repo": "gpsp"},
+    "gw": {"repo": "gw-libretro"},
+    "handy": {"repo": "libretro-handy"},
+    "hatari": {"repo": "hatari"},
+    "mame": {"repo": "mame"},
+    "mame2000": {"repo": "mame2000-libretro"},
+    "mame2003": {"repo": "mame2003-libretro"},
+    "mame2003-plus": {"repo": "mame2003-plus-libretro"},
+    "mame2010": {"repo": "mame2010-libretro"},
+    "mame2015": {"repo": "mame2015-libretro"},
+    "mame2016": {"repo": "mame2016-libretro"},
+    "melonds": {"repo": "melonds"},
+    "mesen": {"repo": "mesen"},
+    "mesen-s": {"repo": "mesen-s"},
+    "meteor": {"repo": "meteor-libretro"},
+    "mgba": {"repo": "mgba"},
+    "mupen64plus": {"repo": "mupen64plus-libretro-nx"},
+    "neocd": {"repo": "neocd_libretro"},
+    "nestopia": {"repo": "nestopia"},
+    "np2kai": {"repo": "NP2kai", "owner": "AZO234", "fetch_submodules": True},
+    "o2em": {"repo": "libretro-o2em"},
+    "opera": {"repo": "opera-libretro"},
+    "parallel-n64": {"repo": "parallel-n64"},
+    "pcsx2": {"repo": "pcsx2"},
+    "pcsx_rearmed": {"repo": "pcsx_rearmed"},
+    "picodrive": {"repo": "picodrive", "fetch_submodules": True},
+    "play": {"repo": "Play-", "owner": "jpd002", "fetch_submodules": True},
+    "ppsspp": {"repo": "ppsspp", "owner": "hrydgard", "fetch_submodules": True},
+    "prboom": {"repo": "libretro-prboom"},
+    "prosystem": {"repo": "prosystem-libretro"},
+    "quicknes": {"repo": "QuickNES_Core"},
+    "sameboy": {"repo": "sameboy"},
+    "scummvm": {"repo": "scummvm"},
+    "smsplus-gx": {"repo": "smsplus-gx"},
+    "snes9x": {"repo": "snes9x", "owner": "snes9xgit"},
+    "snes9x2002": {"repo": "snes9x2002"},
+    "snes9x2005": {"repo": "snes9x2005"},
+    "snes9x2010": {"repo": "snes9x2010"},
+    "stella": {"repo": "stella", "owner": "stella-emu"},
+    "stella2014": {"repo": "stella2014-libretro"},
+    "swanstation": {"repo": "swanstation"},
+    "tgbdual": {"repo": "tgbdual-libretro"},
+    "thepowdertoy": {"repo": "ThePowderToy"},
+    "tic80": {"repo": "tic-80", "fetch_submodules": True},
+    "vba-m": {"repo": "vbam-libretro"},
+    "vba-next": {"repo": "vba-next"},
+    "vecx": {"repo": "libretro-vecx"},
+    "virtualjaguar": {"repo": "virtualjaguar-libretro"},
+    "yabause": {"repo": "yabause"},
+}
+
+
+def info(*msg):
+    print(*msg, file=sys.stderr)
+
+
+def get_repo_hash_fetchFromGitHub(
+    repo,
+    owner="libretro",
+    deep_clone=False,
+    fetch_submodules=False,
+    leave_dot_git=False,
+    rev=None,
+):
+    extra_args = []
+    if deep_clone:
+        extra_args.append("--deep-clone")
+    if fetch_submodules:
+        extra_args.append("--fetch-submodules")
+    if leave_dot_git:
+        extra_args.append("--leave-dot-git")
+    if rev:
+        extra_args.append("--rev")
+        extra_args.append(rev)
+    result = subprocess.run(
+        ["nix-prefetch-github", owner, repo, *extra_args],
+        check=True,
+        capture_output=True,
+        text=True,
+    )
+    j = json.loads(result.stdout)
+    # Remove False values
+    return {k: v for k, v in j.items() if v}
+
+
+def get_repo_hash(fetcher="fetchFromGitHub", **kwargs):
+    if fetcher == "fetchFromGitHub":
+        return get_repo_hash_fetchFromGitHub(**kwargs)
+    else:
+        raise ValueError(f"Unsupported fetcher: {fetcher}")
+
+
+def get_repo_hashes(cores_to_update=[]):
+    with open(HASHES_PATH) as f:
+        repo_hashes = json.loads(f.read())
+
+    for core, repo in CORES.items():
+        if core in cores_to_update:
+            info(f"Getting repo hash for '{core}'...")
+            repo_hashes[core] = get_repo_hash(**repo)
+        else:
+            info(f"Skipping '{core}'...")
+
+    return repo_hashes
+
+
+def main():
+    # If you don't want to update all cores, pass the name of the cores you
+    # want to update on the command line. E.g.:
+    # $ ./update.py citra snes9x
+    if len(sys.argv) > 1:
+        cores_to_update = sys.argv[1:]
+    else:
+        cores_to_update = CORES.keys()
+
+    repo_hashes = get_repo_hashes(cores_to_update)
+    info(f"Generating '{HASHES_PATH}'...")
+    with open(HASHES_PATH, "w") as f:
+        f.write(json.dumps(dict(sorted(repo_hashes.items())), indent=4))
+        f.write("\n")
+    info("Finished!")
+
+
+if __name__ == "__main__":
+    main()
diff --git a/pkgs/applications/emulators/retroarch/wrapper.nix b/pkgs/applications/emulators/retroarch/wrapper.nix
new file mode 100644
index 00000000000..e667afdf079
--- /dev/null
+++ b/pkgs/applications/emulators/retroarch/wrapper.nix
@@ -0,0 +1,37 @@
+{ stdenv, lib, makeWrapper, retroarch, cores ? [ ] }:
+
+stdenv.mkDerivation {
+  pname = "retroarch";
+  version = lib.getVersion retroarch;
+
+  nativeBuildInputs = [ makeWrapper ];
+
+  buildCommand = ''
+    mkdir -p $out/lib
+    for coreDir in $cores
+    do
+      ln -s $coreDir/* $out/lib/.
+    done
+
+    ln -s -t $out ${retroarch}/share
+
+    if [ -d ${retroarch}/Applications ]; then
+      ln -s -t $out ${retroarch}/Applications
+    fi
+
+    makeWrapper ${retroarch}/bin/retroarch $out/bin/retroarch \
+      --suffix-each LD_LIBRARY_PATH ':' "$cores" \
+      --add-flags "-L $out/lib/" \
+  '';
+
+  cores = map (x: x + x.libretroCore) cores;
+  preferLocalBuild = true;
+
+  meta = with retroarch.meta; {
+    inherit changelog license homepage platforms maintainers;
+    description = description
+      + " (with cores: "
+      + lib.concatStringsSep ", " (map (x: "${x.name}") cores)
+      + ")";
+  };
+}
diff --git a/pkgs/applications/emulators/retrofe/default.nix b/pkgs/applications/emulators/retrofe/default.nix
new file mode 100644
index 00000000000..dc1a23f33b3
--- /dev/null
+++ b/pkgs/applications/emulators/retrofe/default.nix
@@ -0,0 +1,78 @@
+{ lib, stdenv, fetchhg, cmake, glib, gst_all_1, makeWrapper, pkg-config
+, python2, SDL2, SDL2_image, SDL2_mixer, SDL2_ttf, sqlite, zlib, runtimeShell
+}:
+
+stdenv.mkDerivation {
+  pname = "retrofe";
+  version = "0.6.169";
+
+  src = fetchhg {
+    url = "https://bitbucket.org/teamretro/retrofe";
+    rev = "8793e03";
+    sha256 = "0cvsg07ff0fdqh5zgiv2fs7s6c98hn150kpxmpw5fn6jilaszwkm";
+  };
+
+  nativeBuildInputs = [ cmake makeWrapper pkg-config python2 ];
+
+  buildInputs = [
+    glib gst_all_1.gstreamer SDL2 SDL2_image SDL2_mixer SDL2_ttf sqlite zlib
+  ] ++ (with gst_all_1; [ gst-libav gst-plugins-base gst-plugins-good ]);
+
+  patches = [ ./include-paths.patch ];
+
+  configurePhase = ''
+    cmake RetroFE/Source -BRetroFE/Build -DCMAKE_BUILD_TYPE=Release \
+      -DVERSION_MAJOR=0 -DVERSION_MINOR=0 -DVERSION_BUILD=0 \
+      -DGSTREAMER_BASE_INCLUDE_DIRS='${gst_all_1.gst-plugins-base.dev}/include/gstreamer-1.0'
+  '';
+
+  buildPhase = ''
+    cmake --build RetroFE/Build
+    python Scripts/Package.py --os=linux --build=full
+  '';
+
+  installPhase = ''
+    mkdir -p $out/bin
+    mkdir -p $out/share/retrofe
+    cp -r Artifacts/linux/RetroFE $out/share/retrofe/example
+    mv $out/share/retrofe/example/retrofe $out/bin/
+
+    cat > $out/bin/retrofe-init << EOF
+    #!${runtimeShell}
+
+    echo "This will install retrofe's example files into this directory"
+    echo "Example files location: $out/share/retrofe/example/"
+
+    while true; do
+        read -p "Do you want to proceed? [yn] " yn
+        case \$yn in
+            [Yy]* ) cp -r --no-preserve=all $out/share/retrofe/example/* .; break;;
+            [Nn]* ) exit;;
+            * ) echo "Please answer with yes or no.";;
+        esac
+    done
+    EOF
+
+    chmod +x $out/bin/retrofe-init
+
+    runHook postInstall
+  '';
+
+  # retrofe will look for config files in its install path ($out/bin).
+  # When set it will use $RETROFE_PATH instead. Sadly this behaviour isn't
+  # documented well. To make it behave more like as expected it's set to
+  # $PWD by default here.
+  postInstall = ''
+    wrapProgram "$out/bin/retrofe" \
+      --prefix GST_PLUGIN_PATH : "$GST_PLUGIN_SYSTEM_PATH_1_0" \
+      --run 'export RETROFE_PATH=''${RETROFE_PATH:-$PWD}'
+  '';
+
+  meta = with lib; {
+    description = "A frontend for arcade cabinets and media PCs";
+    homepage = "http://retrofe.com";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ hrdinka ];
+    platforms = with platforms; linux;
+  };
+}
diff --git a/pkgs/applications/emulators/retrofe/include-paths.patch b/pkgs/applications/emulators/retrofe/include-paths.patch
new file mode 100644
index 00000000000..02eef2594ea
--- /dev/null
+++ b/pkgs/applications/emulators/retrofe/include-paths.patch
@@ -0,0 +1,11 @@
+diff -ur RetroFE.1/RetroFE/Source/CMakeLists.txt RetroFE.2/RetroFE/Source/CMakeLists.txt
+--- RetroFE.1/RetroFE/Source/CMakeLists.txt	2016-02-21 14:52:36.726070602 +0100
++++ RetroFE.2/RetroFE/Source/CMakeLists.txt	2016-02-21 14:38:43.036249029 +0100
+@@ -59,6 +59,7 @@
+ set(RETROFE_INCLUDE_DIRS

+ 	"${GLIB2_INCLUDE_DIRS}"

+ 	"${GSTREAMER_INCLUDE_DIRS}"

++	"${GSTREAMER_BASE_INCLUDE_DIRS}"

+ 	"${SDL2_INCLUDE_DIRS}"

+ 	"${SDL2_IMAGE_INCLUDE_DIRS}"

+ 	"${SDL2_MIXER_INCLUDE_DIRS}"

diff --git a/pkgs/applications/emulators/rpcs3/0001-llvm-ExecutionEngine-IntelJITEvents-only-use-ITTAPI_.patch b/pkgs/applications/emulators/rpcs3/0001-llvm-ExecutionEngine-IntelJITEvents-only-use-ITTAPI_.patch
new file mode 100644
index 00000000000..dccf06fc078
--- /dev/null
+++ b/pkgs/applications/emulators/rpcs3/0001-llvm-ExecutionEngine-IntelJITEvents-only-use-ITTAPI_.patch
@@ -0,0 +1,62 @@
+From 9866ce8f538e1ab1f0902408b7575013b768f365 Mon Sep 17 00:00:00 2001
+From: Zane van Iperen <zane@zanevaniperen.com>
+Date: Wed, 2 Feb 2022 23:41:59 +1000
+Subject: [PATCH] llvm/ExecutionEngine/IntelJITEvents: only use
+ ITTAPI_SOURCE_DIR
+
+---
+ .../IntelJITEvents/CMakeLists.txt             | 32 ++-----------------
+ 1 file changed, 2 insertions(+), 30 deletions(-)
+
+diff --git a/llvm/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt b/llvm/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt
+index 0c5017c3..d20c35f3 100644
+--- a/llvm/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt
++++ b/llvm/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt
+@@ -1,34 +1,6 @@
+ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
+ 
+-if(NOT DEFINED ITTAPI_GIT_REPOSITORY)
+-    set(ITTAPI_GIT_REPOSITORY https://github.com/intel/ittapi.git)
+-endif()
+-
+-if(NOT DEFINED ITTAPI_GIT_TAG)
+-    set(ITTAPI_GIT_TAG v3.18.12)
+-endif()
+-
+-if(NOT DEFINED ITTAPI_SOURCE_DIR)
+-    set(ITTAPI_SOURCE_DIR ${PROJECT_BINARY_DIR})
+-endif()
+-
+-if(NOT EXISTS ${ITTAPI_SOURCE_DIR}/ittapi)
+-    execute_process(COMMAND ${GIT_EXECUTABLE} clone ${ITTAPI_GIT_REPOSITORY}
+-                    WORKING_DIRECTORY ${ITTAPI_SOURCE_DIR}
+-                    RESULT_VARIABLE GIT_CLONE_RESULT)
+-    if(NOT GIT_CLONE_RESULT EQUAL "0")
+-        message(FATAL_ERROR "git clone ${ITTAPI_GIT_REPOSITORY} failed with ${GIT_CLONE_RESULT}, please clone ${ITTAPI_GIT_REPOSITORY}")
+-    endif()
+-endif()
+-
+-execute_process(COMMAND ${GIT_EXECUTABLE} checkout ${ITTAPI_GIT_TAG}
+-                WORKING_DIRECTORY ${ITTAPI_SOURCE_DIR}/ittapi
+-                RESULT_VARIABLE GIT_CHECKOUT_RESULT)
+-if(NOT GIT_CHECKOUT_RESULT EQUAL "0")
+-    message(FATAL_ERROR "git checkout ${ITTAPI_GIT_TAG} failed with ${GIT_CHECKOUT_RESULT}, please checkout ${ITTAPI_GIT_TAG} at ${ITTAPI_SOURCE_DIR}/ittapi")
+-endif()
+-
+-include_directories( ${ITTAPI_SOURCE_DIR}/ittapi/include/ )
++include_directories( ${ITTAPI_SOURCE_DIR}/include/ )
+ 
+ if( HAVE_LIBDL )
+     set(LLVM_INTEL_JIT_LIBS ${CMAKE_DL_LIBS})
+@@ -40,7 +12,7 @@ set(LLVM_INTEL_JIT_LIBS ${LLVM_PTHREAD_LIB} ${LLVM_INTEL_JIT_LIBS})
+ add_llvm_component_library(LLVMIntelJITEvents
+   IntelJITEventListener.cpp
+   jitprofiling.c
+-  ${ITTAPI_SOURCE_DIR}/ittapi/src/ittnotify/ittnotify_static.c
++  ${ITTAPI_SOURCE_DIR}/src/ittnotify/ittnotify_static.c
+ 
+   LINK_LIBS ${LLVM_INTEL_JIT_LIBS}
+ 
+-- 
+2.34.1
+
diff --git a/pkgs/applications/emulators/rpcs3/default.nix b/pkgs/applications/emulators/rpcs3/default.nix
new file mode 100644
index 00000000000..0ea56d3a72d
--- /dev/null
+++ b/pkgs/applications/emulators/rpcs3/default.nix
@@ -0,0 +1,80 @@
+{ gcc11Stdenv, lib, fetchFromGitHub, wrapQtAppsHook, cmake, pkg-config, git
+, qtbase, qtquickcontrols, qtmultimedia, openal, glew, vulkan-headers, vulkan-loader, libpng
+, ffmpeg, libevdev, libusb1, zlib, curl, wolfssl, python3, pugixml, faudio, flatbuffers
+, sdl2Support ? true, SDL2
+, pulseaudioSupport ? true, libpulseaudio
+, waylandSupport ? true, wayland
+, alsaSupport ? true, alsa-lib
+}:
+
+let
+  # Keep these separate so the update script can regex them
+  rpcs3GitVersion = "13222-8c2fd5095";
+  rpcs3Version = "0.0.20-13222-8c2fd5095";
+  rpcs3Revision = "8c2fd50957be3af05c04a9bb782dce8505fb6400";
+  rpcs3Sha256 = "1cf62vpqdc9i4masgv9zz24h7zdc7gcymx6n1hbh7wp5gg1dw4qi";
+
+  ittapi = fetchFromGitHub {
+    owner = "intel";
+    repo = "ittapi";
+    rev = "v3.18.12";
+    sha256 = "0c3g30rj1y8fbd2q4kwlpg1jdy02z4w5ryhj3yr9051pdnf4kndz";
+  };
+in
+gcc11Stdenv.mkDerivation {
+  pname = "rpcs3";
+  version = rpcs3Version;
+
+  src = fetchFromGitHub {
+    owner = "RPCS3";
+    repo = "rpcs3";
+    rev = rpcs3Revision;
+    fetchSubmodules = true;
+    sha256 = rpcs3Sha256;
+  };
+
+  patches = [ ./0001-llvm-ExecutionEngine-IntelJITEvents-only-use-ITTAPI_.patch ];
+
+  passthru.updateScript = ./update.sh;
+
+  preConfigure = ''
+    cat > ./rpcs3/git-version.h <<EOF
+    #define RPCS3_GIT_VERSION "${rpcs3GitVersion}"
+    #define RPCS3_GIT_FULL_BRANCH "RPCS3/rpcs3/master"
+    #define RPCS3_GIT_BRANCH "HEAD"
+    #define RPCS3_GIT_VERSION_NO_UPDATE 1
+    EOF
+  '';
+
+  cmakeFlags = [
+    "-DUSE_SYSTEM_ZLIB=ON"
+    "-DUSE_SYSTEM_LIBUSB=ON"
+    "-DUSE_SYSTEM_LIBPNG=ON"
+    "-DUSE_SYSTEM_FFMPEG=ON"
+    "-DUSE_SYSTEM_CURL=ON"
+    "-DUSE_SYSTEM_WOLFSSL=ON"
+    "-DUSE_SYSTEM_FAUDIO=ON"
+    "-DUSE_SYSTEM_PUGIXML=ON"
+    "-DUSE_SYSTEM_FLATBUFFERS=ON"
+    "-DUSE_NATIVE_INSTRUCTIONS=OFF"
+    "-DITTAPI_SOURCE_DIR=${ittapi}"
+  ];
+
+  nativeBuildInputs = [ cmake pkg-config git wrapQtAppsHook ];
+
+  buildInputs = [
+    qtbase qtquickcontrols qtmultimedia openal glew vulkan-headers vulkan-loader libpng ffmpeg
+    libevdev zlib libusb1 curl wolfssl python3 pugixml faudio flatbuffers
+  ] ++ lib.optional sdl2Support SDL2
+    ++ lib.optional pulseaudioSupport libpulseaudio
+    ++ lib.optional alsaSupport alsa-lib
+    ++ lib.optional waylandSupport wayland;
+
+  meta = with lib; {
+    description = "PS3 emulator/debugger";
+    homepage = "https://rpcs3.net/";
+    maintainers = with maintainers; [ abbradar neonfuz ilian zane ];
+    license = licenses.gpl2Only;
+    platforms = [ "x86_64-linux" ];
+  };
+}
diff --git a/pkgs/applications/emulators/rpcs3/update.sh b/pkgs/applications/emulators/rpcs3/update.sh
new file mode 100755
index 00000000000..0c8477c5282
--- /dev/null
+++ b/pkgs/applications/emulators/rpcs3/update.sh
@@ -0,0 +1,59 @@
+#!/usr/bin/env nix-shell
+#!nix-shell -i bash --pure --keep GITHUB_TOKEN -p gnused jq nix-prefetch-git curl cacert
+
+set -eou pipefail
+
+ROOT="$(dirname "$(readlink -f "$0")")"
+if [[ ! "$(basename $ROOT)" == "rpcs3" || ! -f "$ROOT/default.nix" ]]; then
+    echo "ERROR: Not in the rpcs3 folder"
+    exit 1
+fi
+
+if [[ ! -v GITHUB_TOKEN ]]; then
+    echo "ERROR: \$GITHUB_TOKEN not set"
+    exit 1
+fi
+
+payload=$(jq -cn --rawfile query /dev/stdin '{"query": $query}' <<EOF | curl -s -H "Authorization: bearer $GITHUB_TOKEN" -d '@-' https://api.github.com/graphql
+{
+  repository(owner: "RPCS3", name: "rpcs3") {
+    branch: ref(qualifiedName: "refs/heads/master") {
+      target {
+        oid
+        ... on Commit {
+          history {
+            totalCount
+          }
+        }
+      }
+    }
+
+    tag: refs(refPrefix: "refs/tags/", first: 1, orderBy: {field: TAG_COMMIT_DATE, direction: DESC}) {
+      nodes {
+        name
+      }
+    }
+  }
+}
+EOF
+)
+
+commit_sha=$(jq -r .data.repository.branch.target.oid <<< "$payload")
+major_ver=$(jq -r .data.repository.tag.nodes[0].name <<< "$payload" | sed 's/^v//g')
+commit_count=$(jq -r .data.repository.branch.target.history.totalCount <<< "$payload")
+git_ver="$commit_count-${commit_sha::9}"
+final_ver="$major_ver-$git_ver"
+
+
+echo "INFO: Latest commit is $commit_sha"
+echo "INFO: Latest version is $final_ver"
+
+nix_sha256=$(nix-prefetch-git --quiet --fetch-submodules https://github.com/RPCS3/rpcs3.git "$commit_sha" | jq -r .sha256)
+echo "INFO: SHA256 is $nix_sha256"
+
+sed -i -E \
+    -e "s/rpcs3GitVersion\s*=\s*\"[\.a-z0-9-]+\";$/rpcs3GitVersion = \"${git_ver}\";/g" \
+    -e "s/rpcs3Version\s*=\s*\"[\.a-z0-9-]+\";$/rpcs3Version = \"${final_ver}\";/g" \
+    -e "s/rpcs3Revision\s*=\s*\"[a-z0-9]+\";$/rpcs3Revision = \"${commit_sha}\";/g" \
+    -e "s/rpcs3Sha256\s*=\s*\"[a-z0-9]+\";$/rpcs3Sha256 = \"${nix_sha256}\";/g" \
+    "$ROOT/default.nix"
diff --git a/pkgs/applications/emulators/ruffle/default.nix b/pkgs/applications/emulators/ruffle/default.nix
new file mode 100644
index 00000000000..784ea69d397
--- /dev/null
+++ b/pkgs/applications/emulators/ruffle/default.nix
@@ -0,0 +1,60 @@
+{ alsa-lib
+, fetchFromGitHub
+, makeWrapper
+, openssl
+, pkg-config
+, python3
+, rustPlatform
+, lib
+, wayland
+, xorg
+, vulkan-loader
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "ruffle";
+  version = "nightly-2022-02-02";
+
+  src = fetchFromGitHub {
+    owner = "ruffle-rs";
+    repo = pname;
+    rev = version;
+    sha256 = "sha256-AV3zGfWacYdkyxHED1nGwTqRHhXpybaCVnudmHqWvqw=";
+  };
+
+  nativeBuildInputs = [
+    makeWrapper
+    pkg-config
+    python3
+  ];
+
+  buildInputs = [
+    alsa-lib
+    openssl
+    wayland
+    xorg.libX11
+    xorg.libXcursor
+    xorg.libXrandr
+    xorg.libXi
+    xorg.libxcb
+    xorg.libXrender
+    vulkan-loader
+  ];
+
+  postInstall = ''
+    # This name is too generic
+    mv $out/bin/exporter $out/bin/ruffle_exporter
+
+    wrapProgram $out/bin/ruffle_desktop --prefix LD_LIBRARY_PATH ':' ${vulkan-loader}/lib
+  '';
+
+  cargoSha256 = "sha256-LP9aHcey+e3fqtWdOkqF5k8dwjdAOKpP+mKGxFhTte0=";
+
+  meta = with lib; {
+    description = "An Adobe Flash Player emulator written in the Rust programming language.";
+    homepage = "https://ruffle.rs/";
+    license = with licenses; [ mit asl20 ];
+    maintainers = with maintainers; [ govanify ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/ryujinx/default.nix b/pkgs/applications/emulators/ryujinx/default.nix
new file mode 100644
index 00000000000..2f684257114
--- /dev/null
+++ b/pkgs/applications/emulators/ryujinx/default.nix
@@ -0,0 +1,90 @@
+{ lib, buildDotnetModule, fetchFromGitHub, makeDesktopItem, copyDesktopItems
+, dotnetCorePackages, libX11, libgdiplus, ffmpeg
+, SDL2_mixer, openal, libsoundio, sndio, pulseaudio
+, gtk3, gdk-pixbuf, wrapGAppsHook
+}:
+
+buildDotnetModule rec {
+  pname = "ryujinx";
+  version = "1.0.7168"; # Versioning is based off of the official appveyor builds: https://ci.appveyor.com/project/gdkchan/ryujinx
+
+  src = fetchFromGitHub {
+    owner = "Ryujinx";
+    repo = "Ryujinx";
+    rev = "6e0799580f0d1b473a79471c5d365c6524d97a86";
+    sha256 = "145sn9xkjxj79292faypcdmpmbxm1w70q0iprg6pfymf9920gvfv";
+  };
+
+  dotnet-sdk = dotnetCorePackages.sdk_6_0;
+  dotnet-runtime = dotnetCorePackages.runtime_6_0;
+
+  projectFile = "Ryujinx.sln";
+  nugetDeps = ./deps.nix;
+
+  dotnetFlags = [ "/p:ExtraDefineConstants=DISABLE_UPDATER" ];
+
+  # TODO: Add the headless frontend. Currently errors on the following:
+  # System.Exception: SDL2 initlaization failed with error "No available video device"
+  executables = [ "Ryujinx" ];
+
+  nativeBuildInputs = [
+    copyDesktopItems
+    wrapGAppsHook
+  ];
+
+  buildInputs = [
+    gtk3
+    gdk-pixbuf
+  ];
+
+  runtimeDeps = [
+    gtk3
+    libX11
+    libgdiplus
+    ffmpeg
+    SDL2_mixer
+    openal
+    libsoundio
+    sndio
+    pulseaudio
+  ];
+
+  patches = [
+    ./log.patch # Without this, Ryujinx attempts to write logs to the nix store. This patch makes it write to "~/.config/Ryujinx/Logs" on Linux.
+  ];
+
+  preInstall = ''
+    # TODO: fix this hack https://github.com/Ryujinx/Ryujinx/issues/2349
+    mkdir -p $out/lib/sndio-6
+    ln -s ${sndio}/lib/libsndio.so $out/lib/sndio-6/libsndio.so.6
+
+    makeWrapperArgs+=(
+      --suffix LD_LIBRARY_PATH : "$out/lib/sndio-6"
+    )
+
+    for i in 16 32 48 64 96 128 256 512 1024; do
+      install -D ${src}/Ryujinx/Ui/Resources/Logo_Ryujinx.png $out/share/icons/hicolor/''${i}x$i/apps/ryujinx.png
+    done
+  '';
+
+  desktopItems = [(makeDesktopItem {
+    desktopName = "Ryujinx";
+    name = "ryujinx";
+    exec = "Ryujinx";
+    icon = "ryujinx";
+    comment = meta.description;
+    type = "Application";
+    categories = "Game;";
+  })];
+
+  meta = with lib; {
+    description = "Experimental Nintendo Switch Emulator written in C#";
+    homepage = "https://ryujinx.org/";
+    license = licenses.mit;
+    changelog = "https://github.com/Ryujinx/Ryujinx/wiki/Changelog";
+    maintainers = [ maintainers.ivar ];
+    platforms = [ "x86_64-linux" ];
+    mainProgram = "Ryujinx";
+  };
+  passthru.updateScript = ./updater.sh;
+}
diff --git a/pkgs/applications/emulators/ryujinx/deps.nix b/pkgs/applications/emulators/ryujinx/deps.nix
new file mode 100644
index 00000000000..991d00a5a4b
--- /dev/null
+++ b/pkgs/applications/emulators/ryujinx/deps.nix
@@ -0,0 +1,227 @@
+{ fetchNuGet }: [
+  (fetchNuGet { pname = "AtkSharp"; version = "3.22.25.128"; sha256 = "0fg01zi7v6127043jzxzihirsdp187pyj83gfa6p79cx763l7z94"; })
+  (fetchNuGet { pname = "CairoSharp"; version = "3.22.25.128"; sha256 = "1rjdxd4fq5z3n51qx8vrcaf4i277ccc62jxk88xzbsxapdmjjdf9"; })
+  (fetchNuGet { pname = "CommandLineParser"; version = "2.8.0"; sha256 = "1m32xyilv2b7k55jy8ddg08c20glbcj2yi545kxs9hj2ahanhrbb"; })
+  (fetchNuGet { pname = "Concentus"; version = "1.1.7"; sha256 = "0y5z444wrbhlmsqpy2sxmajl1fbf74843lvgj3y6vz260dn2q0l0"; })
+  (fetchNuGet { pname = "Crc32.NET"; version = "1.2.0"; sha256 = "0qaj3192k1vfji87zf50rhydn5mrzyzybrs2k4v7ap29k8i0vi5h"; })
+  (fetchNuGet { pname = "DiscordRichPresence"; version = "1.0.175"; sha256 = "180sax976327d70qbinv07f65g3w2zbw80n49hckg8wd4rw209vd"; })
+  (fetchNuGet { pname = "FFmpeg.AutoGen"; version = "4.4.1"; sha256 = "01j989g68arm2d8abq44hp0f22pp6azf2xi7wi7hv7m4sl0l9cwp"; })
+  (fetchNuGet { pname = "GdkSharp"; version = "3.22.25.128"; sha256 = "0bmn0ddaw8797pnhpyl03h2zl8i5ha67yv38gly4ydy50az2xhj7"; })
+  (fetchNuGet { pname = "GioSharp"; version = "3.22.25.128"; sha256 = "0syfa1f2hg7wsxln5lh86n8m1lihhprc51b6km91gkl25l5hw5bv"; })
+  (fetchNuGet { pname = "GLibSharp"; version = "3.22.25.128"; sha256 = "1j8i5izk97ga30z1qpd765zqd2q5w71y8bhnkqq4bj59768fyxp5"; })
+  (fetchNuGet { pname = "GtkSharp"; version = "3.22.25.128"; sha256 = "0z0wx0p3gc02r8d7y88k1rw307sb2vapbr1k1yc5qdc38fxz5jsy"; })
+  (fetchNuGet { pname = "GtkSharp.Dependencies"; version = "1.1.0"; sha256 = "1g1rhcn38ww97638rds6l5bysra43hkhv47fy71fvq89623zgyxn"; })
+  (fetchNuGet { pname = "LibHac"; version = "0.14.3"; sha256 = "13pv5dwffj8c2mfibra3hkd1pgg5cj075sf48kgp82y501l25q5m"; })
+  (fetchNuGet { pname = "Microsoft.AspNetCore.App.Runtime.linux-x64"; version = "6.0.0"; sha256 = "0r6jyxl3h1asj30la78skd5gsxgwjpvkspmkw1gglxfg85hnqc8w"; })
+  (fetchNuGet { pname = "Microsoft.AspNetCore.App.Runtime.osx-x64"; version = "6.0.0"; sha256 = "1hnqhvgjp342nx9s47w5sknmlpkfxbcfi50pa4vary2r7sv8ka2w"; })
+  (fetchNuGet { pname = "Microsoft.AspNetCore.App.Runtime.win-x64"; version = "6.0.0"; sha256 = "1j8cn97swc67ly7ca7m05akczrswbg0gjsk7473vad6770ph79vm"; })
+  (fetchNuGet { pname = "Microsoft.CodeCoverage"; version = "16.8.0"; sha256 = "1y05sjk7wgd29a47v1yhn2s1lrd8wgazkilvmjbvivmrrm3fqjs8"; })
+  (fetchNuGet { pname = "Microsoft.CSharp"; version = "4.0.1"; sha256 = "0zxc0apx1gcx361jlq8smc9pfdgmyjh6hpka8dypc9w23nlsh6yj"; })
+  (fetchNuGet { pname = "Microsoft.CSharp"; version = "4.5.0"; sha256 = "01i28nvzccxbqmiz217fxs6hnjwmd5fafs37rd49a6qp53y6623l"; })
+  (fetchNuGet { pname = "Microsoft.DotNet.InternalAbstractions"; version = "1.0.0"; sha256 = "0mp8ihqlb7fsa789frjzidrfjc1lrhk88qp3xm5qvr7vf4wy4z8x"; })
+  (fetchNuGet { pname = "Microsoft.IdentityModel.JsonWebTokens"; version = "6.15.0"; sha256 = "0dwx7dk8jr10784nriqbi364qbxzfwq0c6xia0ac5rzrp7179r4d"; })
+  (fetchNuGet { pname = "Microsoft.IdentityModel.Logging"; version = "6.15.0"; sha256 = "0jn9a20a2zixnkm3bmpmvmiv7mk0hqdlnpi0qgjkg1nir87czm19"; })
+  (fetchNuGet { pname = "Microsoft.IdentityModel.Tokens"; version = "6.15.0"; sha256 = "1nbgydr45f7lp980xyrkzpyaw2mkkishjwp3slgxk7f0mz6q8i1v"; })
+  (fetchNuGet { pname = "Microsoft.NETCore.App.Host.osx-x64"; version = "6.0.0"; sha256 = "188cbx99ahvksap9w20943p62fmzxa6fl133w4r7c6bjpsrm29a4"; })
+  (fetchNuGet { pname = "Microsoft.NETCore.App.Host.win-x64"; version = "6.0.0"; sha256 = "1016ld3kg4dav2yxxh0i32cy0ixv7s0wl9czydbhkbs2d8669kfx"; })
+  (fetchNuGet { pname = "Microsoft.NETCore.App.Runtime.linux-x64"; version = "6.0.0"; sha256 = "0qaylw18flrfl3vxnbp8wsiz29znidmn6dhv7k4v4jj2za16wmji"; })
+  (fetchNuGet { pname = "Microsoft.NETCore.App.Runtime.osx-x64"; version = "6.0.0"; sha256 = "1njh3iky5wyxdrisz8xfpy7kzbsrvzfhpdl01xbavvz189x4ajqp"; })
+  (fetchNuGet { pname = "Microsoft.NETCore.App.Runtime.win-x64"; version = "6.0.0"; sha256 = "13x1nkigy3nhbr8gxalij7krmzxpciyq4i8k7jdy9278zs1lm5a6"; })
+  (fetchNuGet { pname = "Microsoft.NETCore.Platforms"; version = "1.0.1"; sha256 = "01al6cfxp68dscl15z7rxfw9zvhm64dncsw09a1vmdkacsa2v6lr"; })
+  (fetchNuGet { pname = "Microsoft.NETCore.Platforms"; version = "1.1.0"; sha256 = "08vh1r12g6ykjygq5d3vq09zylgb84l63k49jc4v8faw9g93iqqm"; })
+  (fetchNuGet { pname = "Microsoft.NETCore.Platforms"; version = "2.0.0"; sha256 = "1fk2fk2639i7nzy58m9dvpdnzql4vb8yl8vr19r2fp8lmj9w2jr0"; })
+  (fetchNuGet { pname = "Microsoft.NETCore.Targets"; version = "1.0.1"; sha256 = "0ppdkwy6s9p7x9jix3v4402wb171cdiibq7js7i13nxpdky7074p"; })
+  (fetchNuGet { pname = "Microsoft.NETCore.Targets"; version = "1.1.0"; sha256 = "193xwf33fbm0ni3idxzbr5fdq3i2dlfgihsac9jj7whj0gd902nh"; })
+  (fetchNuGet { pname = "Microsoft.NET.Test.Sdk"; version = "16.8.0"; sha256 = "1ln2mva7j2mpsj9rdhpk8vhm3pgd8wn563xqdcwd38avnhp74rm9"; })
+  (fetchNuGet { pname = "Microsoft.TestPlatform.ObjectModel"; version = "16.8.0"; sha256 = "0ii9d88py6mjsxzj9v3zx4izh6rb9ma6s9kj85xmc0xrw7jc2g3m"; })
+  (fetchNuGet { pname = "Microsoft.TestPlatform.TestHost"; version = "16.8.0"; sha256 = "1rh8cga1km3jfafkwfjr0dwqrxb4306hf7fipwba9h02w7vlhb9a"; })
+  (fetchNuGet { pname = "Microsoft.Win32.Primitives"; version = "4.0.1"; sha256 = "1n8ap0cmljbqskxpf8fjzn7kh1vvlndsa75k01qig26mbw97k2q7"; })
+  (fetchNuGet { pname = "Microsoft.Win32.Primitives"; version = "4.3.0"; sha256 = "0j0c1wj4ndj21zsgivsc24whiya605603kxrbiw6wkfdync464wq"; })
+  (fetchNuGet { pname = "Microsoft.Win32.Registry"; version = "4.3.0"; sha256 = "1gxyzxam8163vk1kb6xzxjj4iwspjsz9zhgn1w9rjzciphaz0ig7"; })
+  (fetchNuGet { pname = "Microsoft.Win32.Registry"; version = "4.5.0"; sha256 = "1zapbz161ji8h82xiajgriq6zgzmb1f3ar517p2h63plhsq5gh2q"; })
+  (fetchNuGet { pname = "Microsoft.Win32.SystemEvents"; version = "6.0.0"; sha256 = "0c6pcj088g1yd1vs529q3ybgsd2vjlk5y1ic6dkmbhvrp5jibl9p"; })
+  (fetchNuGet { pname = "MsgPack.Cli"; version = "1.0.1"; sha256 = "1dk2bs3g16lsxcjjm7gfx6jxa4667wccw94jlh2ql7y7smvh9z8r"; })
+  (fetchNuGet { pname = "NETStandard.Library"; version = "1.6.0"; sha256 = "0nmmv4yw7gw04ik8ialj3ak0j6pxa9spih67hnn1h2c38ba8h58k"; })
+  (fetchNuGet { pname = "NETStandard.Library"; version = "2.0.0"; sha256 = "1bc4ba8ahgk15m8k4nd7x406nhi0kwqzbgjk2dmw52ss553xz7iy"; })
+  (fetchNuGet { pname = "Newtonsoft.Json"; version = "12.0.2"; sha256 = "0w2fbji1smd2y7x25qqibf1qrznmv4s6s0jvrbvr6alb7mfyqvh5"; })
+  (fetchNuGet { pname = "Newtonsoft.Json"; version = "9.0.1"; sha256 = "0mcy0i7pnfpqm4pcaiyzzji4g0c8i3a5gjz28rrr28110np8304r"; })
+  (fetchNuGet { pname = "NuGet.Frameworks"; version = "5.0.0"; sha256 = "18ijvmj13cwjdrrm52c8fpq021531zaz4mj4b4zapxaqzzxf2qjr"; })
+  (fetchNuGet { pname = "NUnit"; version = "3.12.0"; sha256 = "1880j2xwavi8f28vxan3hyvdnph4nlh5sbmh285s4lc9l0b7bdk2"; })
+  (fetchNuGet { pname = "NUnit3TestAdapter"; version = "3.17.0"; sha256 = "0kxc6z3b8ccdrcyqz88jm5yh5ch9nbg303v67q8sp5hhs8rl8nk6"; })
+  (fetchNuGet { pname = "OpenTK.Core"; version = "4.5.0"; sha256 = "06qxczikp0aah20d4skk3g588dgh2vn2xffn0ajyyv0475m61s9m"; })
+  (fetchNuGet { pname = "OpenTK.Graphics"; version = "4.5.0"; sha256 = "180g5c92fhhhpmwl6paihx4h1bil7akaihlz2qy124n28pf4s988"; })
+  (fetchNuGet { pname = "OpenTK.Mathematics"; version = "4.5.0"; sha256 = "1h9dxhq1llxdbgdzsi87ijqgj2ilr3rv0zkxhaa65xrc5x8j8fva"; })
+  (fetchNuGet { pname = "OpenTK.OpenAL"; version = "4.5.0"; sha256 = "0lqxpc3vnxglql42x2frvq5bpkl5cf3dpnf9nx6pr3q6qnhigkfb"; })
+  (fetchNuGet { pname = "PangoSharp"; version = "3.22.25.128"; sha256 = "0dkl9j0yd65s5ds9xj5z6yb7yca7wlycqz25m8dng20d13sqr1zp"; })
+  (fetchNuGet { pname = "runtime.any.System.Collections"; version = "4.3.0"; sha256 = "0bv5qgm6vr47ynxqbnkc7i797fdi8gbjjxii173syrx14nmrkwg0"; })
+  (fetchNuGet { pname = "runtime.any.System.Diagnostics.Tools"; version = "4.3.0"; sha256 = "1wl76vk12zhdh66vmagni66h5xbhgqq7zkdpgw21jhxhvlbcl8pk"; })
+  (fetchNuGet { pname = "runtime.any.System.Diagnostics.Tracing"; version = "4.3.0"; sha256 = "00j6nv2xgmd3bi347k00m7wr542wjlig53rmj28pmw7ddcn97jbn"; })
+  (fetchNuGet { pname = "runtime.any.System.Globalization"; version = "4.3.0"; sha256 = "1daqf33hssad94lamzg01y49xwndy2q97i2lrb7mgn28656qia1x"; })
+  (fetchNuGet { pname = "runtime.any.System.Globalization.Calendars"; version = "4.3.0"; sha256 = "1ghhhk5psqxcg6w88sxkqrc35bxcz27zbqm2y5p5298pv3v7g201"; })
+  (fetchNuGet { pname = "runtime.any.System.IO"; version = "4.3.0"; sha256 = "0l8xz8zn46w4d10bcn3l4yyn4vhb3lrj2zw8llvz7jk14k4zps5x"; })
+  (fetchNuGet { pname = "runtime.any.System.Reflection"; version = "4.3.0"; sha256 = "02c9h3y35pylc0zfq3wcsvc5nqci95nrkq0mszifc0sjx7xrzkly"; })
+  (fetchNuGet { pname = "runtime.any.System.Reflection.Extensions"; version = "4.3.0"; sha256 = "0zyri97dfc5vyaz9ba65hjj1zbcrzaffhsdlpxc9bh09wy22fq33"; })
+  (fetchNuGet { pname = "runtime.any.System.Reflection.Primitives"; version = "4.3.0"; sha256 = "0x1mm8c6iy8rlxm8w9vqw7gb7s1ljadrn049fmf70cyh42vdfhrf"; })
+  (fetchNuGet { pname = "runtime.any.System.Resources.ResourceManager"; version = "4.3.0"; sha256 = "03kickal0iiby82wa5flar18kyv82s9s6d4xhk5h4bi5kfcyfjzl"; })
+  (fetchNuGet { pname = "runtime.any.System.Runtime"; version = "4.3.0"; sha256 = "1cqh1sv3h5j7ixyb7axxbdkqx6cxy00p4np4j91kpm492rf4s25b"; })
+  (fetchNuGet { pname = "runtime.any.System.Runtime.Handles"; version = "4.3.0"; sha256 = "0bh5bi25nk9w9xi8z23ws45q5yia6k7dg3i4axhfqlnj145l011x"; })
+  (fetchNuGet { pname = "runtime.any.System.Runtime.InteropServices"; version = "4.3.0"; sha256 = "0c3g3g3jmhlhw4klrc86ka9fjbl7i59ds1fadsb2l8nqf8z3kb19"; })
+  (fetchNuGet { pname = "runtime.any.System.Text.Encoding"; version = "4.3.0"; sha256 = "0aqqi1v4wx51h51mk956y783wzags13wa7mgqyclacmsmpv02ps3"; })
+  (fetchNuGet { pname = "runtime.any.System.Text.Encoding.Extensions"; version = "4.3.0"; sha256 = "0lqhgqi0i8194ryqq6v2gqx0fb86db2gqknbm0aq31wb378j7ip8"; })
+  (fetchNuGet { pname = "runtime.any.System.Threading.Tasks"; version = "4.3.0"; sha256 = "03mnvkhskbzxddz4hm113zsch1jyzh2cs450dk3rgfjp8crlw1va"; })
+  (fetchNuGet { pname = "runtime.any.System.Threading.Timer"; version = "4.3.0"; sha256 = "0aw4phrhwqz9m61r79vyfl5la64bjxj8l34qnrcwb28v49fg2086"; })
+  (fetchNuGet { pname = "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl"; version = "4.3.0"; sha256 = "16rnxzpk5dpbbl1x354yrlsbvwylrq456xzpsha1n9y3glnhyx9d"; })
+  (fetchNuGet { pname = "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl"; version = "4.3.0"; sha256 = "0hkg03sgm2wyq8nqk6dbm9jh5vcq57ry42lkqdmfklrw89lsmr59"; })
+  (fetchNuGet { pname = "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl"; version = "4.3.0"; sha256 = "0c2p354hjx58xhhz7wv6div8xpi90sc6ibdm40qin21bvi7ymcaa"; })
+  (fetchNuGet { pname = "runtime.native.System"; version = "4.0.0"; sha256 = "1ppk69xk59ggacj9n7g6fyxvzmk1g5p4fkijm0d7xqfkig98qrkf"; })
+  (fetchNuGet { pname = "runtime.native.System"; version = "4.3.0"; sha256 = "15hgf6zaq9b8br2wi1i3x0zvmk410nlmsmva9p0bbg73v6hml5k4"; })
+  (fetchNuGet { pname = "runtime.native.System.IO.Compression"; version = "4.1.0"; sha256 = "0d720z4lzyfcabmmnvh0bnj76ll7djhji2hmfh3h44sdkjnlkknk"; })
+  (fetchNuGet { pname = "runtime.native.System.Net.Http"; version = "4.0.1"; sha256 = "1hgv2bmbaskx77v8glh7waxws973jn4ah35zysnkxmf0196sfxg6"; })
+  (fetchNuGet { pname = "runtime.native.System.Security.Cryptography"; version = "4.0.0"; sha256 = "0k57aa2c3b10wl3hfqbgrl7xq7g8hh3a3ir44b31dn5p61iiw3z9"; })
+  (fetchNuGet { pname = "runtime.native.System.Security.Cryptography.OpenSsl"; version = "4.3.0"; sha256 = "18pzfdlwsg2nb1jjjjzyb5qlgy6xjxzmhnfaijq5s2jw3cm3ab97"; })
+  (fetchNuGet { pname = "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl"; version = "4.3.0"; sha256 = "0qyynf9nz5i7pc26cwhgi8j62ps27sqmf78ijcfgzab50z9g8ay3"; })
+  (fetchNuGet { pname = "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl"; version = "4.3.0"; sha256 = "1klrs545awhayryma6l7g2pvnp9xy4z0r1i40r80zb45q3i9nbyf"; })
+  (fetchNuGet { pname = "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl"; version = "4.3.0"; sha256 = "0zcxjv5pckplvkg0r6mw3asggm7aqzbdjimhvsasb0cgm59x09l3"; })
+  (fetchNuGet { pname = "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl"; version = "4.3.0"; sha256 = "0vhynn79ih7hw7cwjazn87rm9z9fj0rvxgzlab36jybgcpcgphsn"; })
+  (fetchNuGet { pname = "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl"; version = "4.3.0"; sha256 = "160p68l2c7cqmyqjwxydcvgw7lvl1cr0znkw8fp24d1by9mqc8p3"; })
+  (fetchNuGet { pname = "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl"; version = "4.3.0"; sha256 = "15zrc8fgd8zx28hdghcj5f5i34wf3l6bq5177075m2bc2j34jrqy"; })
+  (fetchNuGet { pname = "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl"; version = "4.3.0"; sha256 = "1p4dgxax6p7rlgj4q73k73rslcnz4wdcv8q2flg1s8ygwcm58ld5"; })
+  (fetchNuGet { pname = "runtime.unix.Microsoft.Win32.Primitives"; version = "4.3.0"; sha256 = "0y61k9zbxhdi0glg154v30kkq7f8646nif8lnnxbvkjpakggd5id"; })
+  (fetchNuGet { pname = "runtime.unix.System.Console"; version = "4.3.0"; sha256 = "1pfpkvc6x2if8zbdzg9rnc5fx51yllprl8zkm5npni2k50lisy80"; })
+  (fetchNuGet { pname = "runtime.unix.System.Diagnostics.Debug"; version = "4.3.0"; sha256 = "1lps7fbnw34bnh3lm31gs5c0g0dh7548wfmb8zz62v0zqz71msj5"; })
+  (fetchNuGet { pname = "runtime.unix.System.IO.FileSystem"; version = "4.3.0"; sha256 = "14nbkhvs7sji5r1saj2x8daz82rnf9kx28d3v2qss34qbr32dzix"; })
+  (fetchNuGet { pname = "runtime.unix.System.Net.Primitives"; version = "4.3.0"; sha256 = "0bdnglg59pzx9394sy4ic66kmxhqp8q8bvmykdxcbs5mm0ipwwm4"; })
+  (fetchNuGet { pname = "runtime.unix.System.Net.Sockets"; version = "4.3.0"; sha256 = "03npdxzy8gfv035bv1b9rz7c7hv0rxl5904wjz51if491mw0xy12"; })
+  (fetchNuGet { pname = "runtime.unix.System.Private.Uri"; version = "4.3.0"; sha256 = "1jx02q6kiwlvfksq1q9qr17fj78y5v6mwsszav4qcz9z25d5g6vk"; })
+  (fetchNuGet { pname = "runtime.unix.System.Runtime.Extensions"; version = "4.3.0"; sha256 = "0pnxxmm8whx38dp6yvwgmh22smknxmqs5n513fc7m4wxvs1bvi4p"; })
+  (fetchNuGet { pname = "runtime.win.Microsoft.Win32.Primitives"; version = "4.3.0"; sha256 = "0k1h8nnp1s0p8rjwgjyj1387cc1yycv0k22igxc963lqdzrx2z36"; })
+  (fetchNuGet { pname = "runtime.win.System.Console"; version = "4.3.0"; sha256 = "0x2yajfrbc5zc6g7nmlr44xpjk6p1hxjq47jn3xki5j7i33zw9jc"; })
+  (fetchNuGet { pname = "runtime.win.System.Diagnostics.Debug"; version = "4.3.0"; sha256 = "16fbn4bcynad1ygdq0yk1wmckvs8jvrrf104xa5dc2hlc8y3x58f"; })
+  (fetchNuGet { pname = "runtime.win.System.IO.FileSystem"; version = "4.3.0"; sha256 = "1c01nklbxywszsbfaxc76hsz7gdxac3jkphrywfkdsi3v4bwd6g8"; })
+  (fetchNuGet { pname = "runtime.win.System.Net.Primitives"; version = "4.3.0"; sha256 = "1dixh195bi7473n17hspll6i562gghdz9m4jk8d4kzi1mlzjk9cf"; })
+  (fetchNuGet { pname = "runtime.win.System.Net.Sockets"; version = "4.3.0"; sha256 = "0lr3zki831vs6qhk5wckv2b9qbfk9rcj0ds2926qvj1b9y9m6sck"; })
+  (fetchNuGet { pname = "runtime.win.System.Runtime.Extensions"; version = "4.3.0"; sha256 = "1700famsxndccfbcdz9q14qb20p49lax67mqwpgy4gx3vja1yczr"; })
+  (fetchNuGet { pname = "Ryujinx.Audio.OpenAL.Dependencies"; version = "1.21.0.1"; sha256 = "0z5k42h252nr60d02p2ww9190d7k1kzrb26vil4ydfhxqqqv6w9l"; })
+  (fetchNuGet { pname = "Ryujinx.Graphics.Nvdec.Dependencies"; version = "4.4.0-build7"; sha256 = "0g1l3lgs0ffxp64ka81v6q1cgsdirl1qlf73255v29r3v337074m"; })
+  (fetchNuGet { pname = "Ryujinx.Graphics.Nvdec.Dependencies"; version = "4.4.0-build9"; sha256 = "121zmh0byi22qsc9b25wv58kwcq6pmk7zf4f2rfafmdjvwx8bkxc"; })
+  (fetchNuGet { pname = "Ryujinx.SDL2-CS"; version = "2.0.17-build18"; sha256 = "0j0vs6075c4fniydqxhpp18pg3x679mq463x4gxqgkri3vhpj4vl"; })
+  (fetchNuGet { pname = "SharpZipLib"; version = "1.3.3"; sha256 = "1gij11wfj1mqm10631cjpnhzw882bnzx699jzwhdqakxm1610q8x"; })
+  (fetchNuGet { pname = "SixLabors.Fonts"; version = "1.0.0-beta0013"; sha256 = "0r0aw8xxd32rwcawawcz6asiyggz02hnzg5hvz8gimq8hvwx1wql"; })
+  (fetchNuGet { pname = "SixLabors.ImageSharp"; version = "1.0.4"; sha256 = "0fmgn414my76gjgp89qlc210a0lqvnvkvk2fcwnpwxdhqpfvyilr"; })
+  (fetchNuGet { pname = "SixLabors.ImageSharp.Drawing"; version = "1.0.0-beta11"; sha256 = "0hl0rs3kr1zdnx3gdssxgli6fyvmwzcfp99f4db71s0i8j8b2bp5"; })
+  (fetchNuGet { pname = "SPB"; version = "0.0.4-build17"; sha256 = "0arp7mwdn1w67qx8a0m90xh8waj15154ynswrbsp5w4wmzkcss1i"; })
+  (fetchNuGet { pname = "System.AppContext"; version = "4.1.0"; sha256 = "0fv3cma1jp4vgj7a8hqc9n7hr1f1kjp541s6z0q1r6nazb4iz9mz"; })
+  (fetchNuGet { pname = "System.Buffers"; version = "4.0.0"; sha256 = "13s659bcmg9nwb6z78971z1lr6bmh2wghxi1ayqyzl4jijd351gr"; })
+  (fetchNuGet { pname = "System.Buffers"; version = "4.3.0"; sha256 = "0fgns20ispwrfqll4q1zc1waqcmylb3zc50ys9x8zlwxh9pmd9jy"; })
+  (fetchNuGet { pname = "System.CodeDom"; version = "4.4.0"; sha256 = "1zgbafm5p380r50ap5iddp11kzhr9khrf2pnai6k593wjar74p1g"; })
+  (fetchNuGet { pname = "System.CodeDom"; version = "6.0.0"; sha256 = "1i55cxp8ycc03dmxx4n22qi6jkwfl23cgffb95izq7bjar8avxxq"; })
+  (fetchNuGet { pname = "System.Collections"; version = "4.0.11"; sha256 = "1ga40f5lrwldiyw6vy67d0sg7jd7ww6kgwbksm19wrvq9hr0bsm6"; })
+  (fetchNuGet { pname = "System.Collections"; version = "4.3.0"; sha256 = "19r4y64dqyrq6k4706dnyhhw7fs24kpp3awak7whzss39dakpxk9"; })
+  (fetchNuGet { pname = "System.Collections.Concurrent"; version = "4.0.12"; sha256 = "07y08kvrzpak873pmyxs129g1ch8l27zmg51pcyj2jvq03n0r0fc"; })
+  (fetchNuGet { pname = "System.Collections.NonGeneric"; version = "4.3.0"; sha256 = "07q3k0hf3mrcjzwj8fwk6gv3n51cb513w4mgkfxzm3i37sc9kz7k"; })
+  (fetchNuGet { pname = "System.Collections.Specialized"; version = "4.3.0"; sha256 = "1sdwkma4f6j85m3dpb53v9vcgd0zyc9jb33f8g63byvijcj39n20"; })
+  (fetchNuGet { pname = "System.ComponentModel"; version = "4.3.0"; sha256 = "0986b10ww3nshy30x9sjyzm0jx339dkjxjj3401r3q0f6fx2wkcb"; })
+  (fetchNuGet { pname = "System.ComponentModel.EventBasedAsync"; version = "4.3.0"; sha256 = "1rv9bkb8yyhqqqrx6x95njv6mdxlbvv527b44mrd93g8fmgkifl7"; })
+  (fetchNuGet { pname = "System.ComponentModel.Primitives"; version = "4.3.0"; sha256 = "1svfmcmgs0w0z9xdw2f2ps05rdxmkxxhf0l17xk9l1l8xfahkqr0"; })
+  (fetchNuGet { pname = "System.ComponentModel.TypeConverter"; version = "4.3.0"; sha256 = "17ng0p7v3nbrg3kycz10aqrrlw4lz9hzhws09pfh8gkwicyy481x"; })
+  (fetchNuGet { pname = "System.Console"; version = "4.0.0"; sha256 = "0ynxqbc3z1nwbrc11hkkpw9skw116z4y9wjzn7id49p9yi7mzmlf"; })
+  (fetchNuGet { pname = "System.Diagnostics.Debug"; version = "4.0.11"; sha256 = "0gmjghrqmlgzxivd2xl50ncbglb7ljzb66rlx8ws6dv8jm0d5siz"; })
+  (fetchNuGet { pname = "System.Diagnostics.Debug"; version = "4.3.0"; sha256 = "00yjlf19wjydyr6cfviaph3vsjzg3d5nvnya26i2fvfg53sknh3y"; })
+  (fetchNuGet { pname = "System.Diagnostics.DiagnosticSource"; version = "4.0.0"; sha256 = "1n6c3fbz7v8d3pn77h4v5wvsfrfg7v1c57lg3nff3cjyh597v23m"; })
+  (fetchNuGet { pname = "System.Diagnostics.Process"; version = "4.3.0"; sha256 = "0g4prsbkygq8m21naqmcp70f24a1ksyix3dihb1r1f71lpi3cfj7"; })
+  (fetchNuGet { pname = "System.Diagnostics.Tools"; version = "4.0.1"; sha256 = "19cknvg07yhakcvpxg3cxa0bwadplin6kyxd8mpjjpwnp56nl85x"; })
+  (fetchNuGet { pname = "System.Diagnostics.Tracing"; version = "4.1.0"; sha256 = "1d2r76v1x610x61ahfpigda89gd13qydz6vbwzhpqlyvq8jj6394"; })
+  (fetchNuGet { pname = "System.Diagnostics.Tracing"; version = "4.3.0"; sha256 = "1m3bx6c2s958qligl67q7grkwfz3w53hpy7nc97mh6f7j5k168c4"; })
+  (fetchNuGet { pname = "System.Drawing.Common"; version = "6.0.0"; sha256 = "02n8rzm58dac2np8b3xw8ychbvylja4nh6938l5k2fhyn40imlgz"; })
+  (fetchNuGet { pname = "System.Dynamic.Runtime"; version = "4.0.11"; sha256 = "1pla2dx8gkidf7xkciig6nifdsb494axjvzvann8g2lp3dbqasm9"; })
+  (fetchNuGet { pname = "System.Globalization"; version = "4.0.11"; sha256 = "070c5jbas2v7smm660zaf1gh0489xanjqymkvafcs4f8cdrs1d5d"; })
+  (fetchNuGet { pname = "System.Globalization"; version = "4.3.0"; sha256 = "1cp68vv683n6ic2zqh2s1fn4c2sd87g5hpp6l4d4nj4536jz98ki"; })
+  (fetchNuGet { pname = "System.Globalization.Calendars"; version = "4.0.1"; sha256 = "0bv0alrm2ck2zk3rz25lfyk9h42f3ywq77mx1syl6vvyncnpg4qh"; })
+  (fetchNuGet { pname = "System.Globalization.Extensions"; version = "4.0.1"; sha256 = "0hjhdb5ri8z9l93bw04s7ynwrjrhx2n0p34sf33a9hl9phz69fyc"; })
+  (fetchNuGet { pname = "System.Globalization.Extensions"; version = "4.3.0"; sha256 = "02a5zfxavhv3jd437bsncbhd2fp1zv4gxzakp1an9l6kdq1mcqls"; })
+  (fetchNuGet { pname = "System.IdentityModel.Tokens.Jwt"; version = "6.15.0"; sha256 = "0kzc9rqwn8xgixwm1z5zajf6bapa2rvi9lv8vgz7hlp1lgi964zk"; })
+  (fetchNuGet { pname = "System.IO"; version = "4.1.0"; sha256 = "1g0yb8p11vfd0kbkyzlfsbsp5z44lwsvyc0h3dpw6vqnbi035ajp"; })
+  (fetchNuGet { pname = "System.IO"; version = "4.3.0"; sha256 = "05l9qdrzhm4s5dixmx68kxwif4l99ll5gqmh7rqgw554fx0agv5f"; })
+  (fetchNuGet { pname = "System.IO.Compression"; version = "4.1.0"; sha256 = "0iym7s3jkl8n0vzm3jd6xqg9zjjjqni05x45dwxyjr2dy88hlgji"; })
+  (fetchNuGet { pname = "System.IO.Compression.ZipFile"; version = "4.0.1"; sha256 = "0h72znbagmgvswzr46mihn7xm7chfk2fhrp5krzkjf29pz0i6z82"; })
+  (fetchNuGet { pname = "System.IO.FileSystem"; version = "4.0.1"; sha256 = "0kgfpw6w4djqra3w5crrg8xivbanh1w9dh3qapb28q060wb9flp1"; })
+  (fetchNuGet { pname = "System.IO.FileSystem"; version = "4.3.0"; sha256 = "0z2dfrbra9i6y16mm9v1v6k47f0fm617vlb7s5iybjjsz6g1ilmw"; })
+  (fetchNuGet { pname = "System.IO.FileSystem.Primitives"; version = "4.0.1"; sha256 = "1s0mniajj3lvbyf7vfb5shp4ink5yibsx945k6lvxa96r8la1612"; })
+  (fetchNuGet { pname = "System.IO.FileSystem.Primitives"; version = "4.3.0"; sha256 = "0j6ndgglcf4brg2lz4wzsh1av1gh8xrzdsn9f0yznskhqn1xzj9c"; })
+  (fetchNuGet { pname = "System.Linq"; version = "4.1.0"; sha256 = "1ppg83svb39hj4hpp5k7kcryzrf3sfnm08vxd5sm2drrijsla2k5"; })
+  (fetchNuGet { pname = "System.Linq"; version = "4.3.0"; sha256 = "1w0gmba695rbr80l1k2h4mrwzbzsyfl2z4klmpbsvsg5pm4a56s7"; })
+  (fetchNuGet { pname = "System.Linq.Expressions"; version = "4.1.0"; sha256 = "1gpdxl6ip06cnab7n3zlcg6mqp7kknf73s8wjinzi4p0apw82fpg"; })
+  (fetchNuGet { pname = "System.Management"; version = "6.0.0"; sha256 = "0ra1g75ykapg6i5y0za721kpjd6xcq6dalijkdm6fsxxmz8iz4dr"; })
+  (fetchNuGet { pname = "System.Net.Http"; version = "4.1.0"; sha256 = "1i5rqij1icg05j8rrkw4gd4pgia1978mqhjzhsjg69lvwcdfg8yb"; })
+  (fetchNuGet { pname = "System.Net.NameResolution"; version = "4.3.0"; sha256 = "15r75pwc0rm3vvwsn8rvm2krf929mjfwliv0mpicjnii24470rkq"; })
+  (fetchNuGet { pname = "System.Net.Primitives"; version = "4.0.11"; sha256 = "10xzzaynkzkakp7jai1ik3r805zrqjxiz7vcagchyxs2v26a516r"; })
+  (fetchNuGet { pname = "System.Net.Sockets"; version = "4.1.0"; sha256 = "1385fvh8h29da5hh58jm1v78fzi9fi5vj93vhlm2kvqpfahvpqls"; })
+  (fetchNuGet { pname = "System.Numerics.Vectors"; version = "4.3.0"; sha256 = "05kji1mv4sl75iwmc613p873145nynm02xiajx8pn0h2kx53d23s"; })
+  (fetchNuGet { pname = "System.Numerics.Vectors"; version = "4.5.0"; sha256 = "1kzrj37yzawf1b19jq0253rcs8hsq1l2q8g69d7ipnhzb0h97m59"; })
+  (fetchNuGet { pname = "System.ObjectModel"; version = "4.0.12"; sha256 = "1sybkfi60a4588xn34nd9a58png36i0xr4y4v4kqpg8wlvy5krrj"; })
+  (fetchNuGet { pname = "System.Private.Uri"; version = "4.3.0"; sha256 = "04r1lkdnsznin0fj4ya1zikxiqr0h6r6a1ww2dsm60gqhdrf0mvx"; })
+  (fetchNuGet { pname = "System.Reflection"; version = "4.1.0"; sha256 = "1js89429pfw79mxvbzp8p3q93il6rdff332hddhzi5wqglc4gml9"; })
+  (fetchNuGet { pname = "System.Reflection"; version = "4.3.0"; sha256 = "0xl55k0mw8cd8ra6dxzh974nxif58s3k1rjv1vbd7gjbjr39j11m"; })
+  (fetchNuGet { pname = "System.Reflection.Emit"; version = "4.0.1"; sha256 = "0ydqcsvh6smi41gyaakglnv252625hf29f7kywy2c70nhii2ylqp"; })
+  (fetchNuGet { pname = "System.Reflection.Emit"; version = "4.3.0"; sha256 = "11f8y3qfysfcrscjpjym9msk7lsfxkk4fmz9qq95kn3jd0769f74"; })
+  (fetchNuGet { pname = "System.Reflection.Emit.ILGeneration"; version = "4.0.1"; sha256 = "1pcd2ig6bg144y10w7yxgc9d22r7c7ww7qn1frdfwgxr24j9wvv0"; })
+  (fetchNuGet { pname = "System.Reflection.Emit.ILGeneration"; version = "4.3.0"; sha256 = "0w1n67glpv8241vnpz1kl14sy7zlnw414aqwj4hcx5nd86f6994q"; })
+  (fetchNuGet { pname = "System.Reflection.Emit.Lightweight"; version = "4.0.1"; sha256 = "1s4b043zdbx9k39lfhvsk68msv1nxbidhkq6nbm27q7sf8xcsnxr"; })
+  (fetchNuGet { pname = "System.Reflection.Emit.Lightweight"; version = "4.3.0"; sha256 = "0ql7lcakycrvzgi9kxz1b3lljd990az1x6c4jsiwcacrvimpib5c"; })
+  (fetchNuGet { pname = "System.Reflection.Extensions"; version = "4.0.1"; sha256 = "0m7wqwq0zqq9gbpiqvgk3sr92cbrw7cp3xn53xvw7zj6rz6fdirn"; })
+  (fetchNuGet { pname = "System.Reflection.Extensions"; version = "4.3.0"; sha256 = "02bly8bdc98gs22lqsfx9xicblszr2yan7v2mmw3g7hy6miq5hwq"; })
+  (fetchNuGet { pname = "System.Reflection.Primitives"; version = "4.0.1"; sha256 = "1bangaabhsl4k9fg8khn83wm6yial8ik1sza7401621jc6jrym28"; })
+  (fetchNuGet { pname = "System.Reflection.Primitives"; version = "4.3.0"; sha256 = "04xqa33bld78yv5r93a8n76shvc8wwcdgr1qvvjh959g3rc31276"; })
+  (fetchNuGet { pname = "System.Reflection.TypeExtensions"; version = "4.1.0"; sha256 = "1bjli8a7sc7jlxqgcagl9nh8axzfl11f4ld3rjqsyxc516iijij7"; })
+  (fetchNuGet { pname = "System.Reflection.TypeExtensions"; version = "4.3.0"; sha256 = "0y2ssg08d817p0vdag98vn238gyrrynjdj4181hdg780sif3ykp1"; })
+  (fetchNuGet { pname = "System.Resources.ResourceManager"; version = "4.0.1"; sha256 = "0b4i7mncaf8cnai85jv3wnw6hps140cxz8vylv2bik6wyzgvz7bi"; })
+  (fetchNuGet { pname = "System.Resources.ResourceManager"; version = "4.3.0"; sha256 = "0sjqlzsryb0mg4y4xzf35xi523s4is4hz9q4qgdvlvgivl7qxn49"; })
+  (fetchNuGet { pname = "System.Runtime"; version = "4.1.0"; sha256 = "02hdkgk13rvsd6r9yafbwzss8kr55wnj8d5c7xjnp8gqrwc8sn0m"; })
+  (fetchNuGet { pname = "System.Runtime"; version = "4.3.0"; sha256 = "066ixvgbf2c929kgknshcxqj6539ax7b9m570cp8n179cpfkapz7"; })
+  (fetchNuGet { pname = "System.Runtime.CompilerServices.Unsafe"; version = "4.7.0"; sha256 = "16r6sn4czfjk8qhnz7bnqlyiaaszr0ihinb7mq9zzr1wba257r54"; })
+  (fetchNuGet { pname = "System.Runtime.Extensions"; version = "4.1.0"; sha256 = "0rw4rm4vsm3h3szxp9iijc3ksyviwsv6f63dng3vhqyg4vjdkc2z"; })
+  (fetchNuGet { pname = "System.Runtime.Extensions"; version = "4.3.0"; sha256 = "1ykp3dnhwvm48nap8q23893hagf665k0kn3cbgsqpwzbijdcgc60"; })
+  (fetchNuGet { pname = "System.Runtime.Handles"; version = "4.0.1"; sha256 = "1g0zrdi5508v49pfm3iii2hn6nm00bgvfpjq1zxknfjrxxa20r4g"; })
+  (fetchNuGet { pname = "System.Runtime.Handles"; version = "4.3.0"; sha256 = "0sw2gfj2xr7sw9qjn0j3l9yw07x73lcs97p8xfc9w1x9h5g5m7i8"; })
+  (fetchNuGet { pname = "System.Runtime.InteropServices"; version = "4.1.0"; sha256 = "01kxqppx3dr3b6b286xafqilv4s2n0gqvfgzfd4z943ga9i81is1"; })
+  (fetchNuGet { pname = "System.Runtime.InteropServices"; version = "4.3.0"; sha256 = "00hywrn4g7hva1b2qri2s6rabzwgxnbpw9zfxmz28z09cpwwgh7j"; })
+  (fetchNuGet { pname = "System.Runtime.InteropServices.RuntimeInformation"; version = "4.0.0"; sha256 = "0glmvarf3jz5xh22iy3w9v3wyragcm4hfdr17v90vs7vcrm7fgp6"; })
+  (fetchNuGet { pname = "System.Runtime.InteropServices.RuntimeInformation"; version = "4.3.0"; sha256 = "0q18r1sh4vn7bvqgd6dmqlw5v28flbpj349mkdish2vjyvmnb2ii"; })
+  (fetchNuGet { pname = "System.Runtime.Numerics"; version = "4.0.1"; sha256 = "1y308zfvy0l5nrn46mqqr4wb4z1xk758pkk8svbz8b5ij7jnv4nn"; })
+  (fetchNuGet { pname = "System.Runtime.Serialization.Primitives"; version = "4.1.1"; sha256 = "042rfjixknlr6r10vx2pgf56yming8lkjikamg3g4v29ikk78h7k"; })
+  (fetchNuGet { pname = "System.Security.AccessControl"; version = "4.5.0"; sha256 = "1wvwanz33fzzbnd2jalar0p0z3x0ba53vzx1kazlskp7pwyhlnq0"; })
+  (fetchNuGet { pname = "System.Security.Claims"; version = "4.3.0"; sha256 = "0jvfn7j22l3mm28qjy3rcw287y9h65ha4m940waaxah07jnbzrhn"; })
+  (fetchNuGet { pname = "System.Security.Cryptography.Algorithms"; version = "4.2.0"; sha256 = "148s9g5dgm33ri7dnh19s4lgnlxbpwvrw2jnzllq2kijj4i4vs85"; })
+  (fetchNuGet { pname = "System.Security.Cryptography.Cng"; version = "4.2.0"; sha256 = "118jijz446kix20blxip0f0q8mhsh9bz118mwc2ch1p6g7facpzc"; })
+  (fetchNuGet { pname = "System.Security.Cryptography.Cng"; version = "4.5.0"; sha256 = "1pm4ykbcz48f1hdmwpia432ha6qbb9kbrxrrp7cg3m8q8xn52ngn"; })
+  (fetchNuGet { pname = "System.Security.Cryptography.Csp"; version = "4.0.0"; sha256 = "1cwv8lqj8r15q81d2pz2jwzzbaji0l28xfrpw29kdpsaypm92z2q"; })
+  (fetchNuGet { pname = "System.Security.Cryptography.Encoding"; version = "4.0.0"; sha256 = "0a8y1a5wkmpawc787gfmnrnbzdgxmx1a14ax43jf3rj9gxmy3vk4"; })
+  (fetchNuGet { pname = "System.Security.Cryptography.OpenSsl"; version = "4.0.0"; sha256 = "16sx3cig3d0ilvzl8xxgffmxbiqx87zdi8fc73i3i7zjih1a7f4q"; })
+  (fetchNuGet { pname = "System.Security.Cryptography.Primitives"; version = "4.0.0"; sha256 = "0i7cfnwph9a10bm26m538h5xcr8b36jscp9sy1zhgifksxz4yixh"; })
+  (fetchNuGet { pname = "System.Security.Cryptography.X509Certificates"; version = "4.1.0"; sha256 = "0clg1bv55mfv5dq00m19cp634zx6inm31kf8ppbq1jgyjf2185dh"; })
+  (fetchNuGet { pname = "System.Security.Principal"; version = "4.3.0"; sha256 = "12cm2zws06z4lfc4dn31iqv7072zyi4m910d4r6wm8yx85arsfxf"; })
+  (fetchNuGet { pname = "System.Security.Principal.Windows"; version = "4.3.0"; sha256 = "00a0a7c40i3v4cb20s2cmh9csb5jv2l0frvnlzyfxh848xalpdwr"; })
+  (fetchNuGet { pname = "System.Security.Principal.Windows"; version = "4.5.0"; sha256 = "0rmj89wsl5yzwh0kqjgx45vzf694v9p92r4x4q6yxldk1cv1hi86"; })
+  (fetchNuGet { pname = "System.Text.Encoding"; version = "4.0.11"; sha256 = "1dyqv0hijg265dwxg6l7aiv74102d6xjiwplh2ar1ly6xfaa4iiw"; })
+  (fetchNuGet { pname = "System.Text.Encoding"; version = "4.3.0"; sha256 = "1f04lkir4iladpp51sdgmis9dj4y8v08cka0mbmsy0frc9a4gjqr"; })
+  (fetchNuGet { pname = "System.Text.Encoding.Extensions"; version = "4.0.11"; sha256 = "08nsfrpiwsg9x5ml4xyl3zyvjfdi4mvbqf93kjdh11j4fwkznizs"; })
+  (fetchNuGet { pname = "System.Text.Encoding.Extensions"; version = "4.3.0"; sha256 = "11q1y8hh5hrp5a3kw25cb6l00v5l5dvirkz8jr3sq00h1xgcgrxy"; })
+  (fetchNuGet { pname = "System.Text.RegularExpressions"; version = "4.1.0"; sha256 = "1mw7vfkkyd04yn2fbhm38msk7dz2xwvib14ygjsb8dq2lcvr18y7"; })
+  (fetchNuGet { pname = "System.Text.RegularExpressions"; version = "4.3.0"; sha256 = "1bgq51k7fwld0njylfn7qc5fmwrk2137gdq7djqdsw347paa9c2l"; })
+  (fetchNuGet { pname = "System.Threading"; version = "4.0.11"; sha256 = "19x946h926bzvbsgj28csn46gak2crv2skpwsx80hbgazmkgb1ls"; })
+  (fetchNuGet { pname = "System.Threading"; version = "4.3.0"; sha256 = "0rw9wfamvhayp5zh3j7p1yfmx9b5khbf4q50d8k5rk993rskfd34"; })
+  (fetchNuGet { pname = "System.Threading.Overlapped"; version = "4.3.0"; sha256 = "1nahikhqh9nk756dh8p011j36rlcp1bzz3vwi2b4m1l2s3vz8idm"; })
+  (fetchNuGet { pname = "System.Threading.Tasks"; version = "4.0.11"; sha256 = "0nr1r41rak82qfa5m0lhk9mp0k93bvfd7bbd9sdzwx9mb36g28p5"; })
+  (fetchNuGet { pname = "System.Threading.Tasks"; version = "4.3.0"; sha256 = "134z3v9abw3a6jsw17xl3f6hqjpak5l682k2vz39spj4kmydg6k7"; })
+  (fetchNuGet { pname = "System.Threading.Tasks.Extensions"; version = "4.0.0"; sha256 = "1cb51z062mvc2i8blpzmpn9d9mm4y307xrwi65di8ri18cz5r1zr"; })
+  (fetchNuGet { pname = "System.Threading.Tasks.Extensions"; version = "4.3.0"; sha256 = "1xxcx2xh8jin360yjwm4x4cf5y3a2bwpn2ygkfkwkicz7zk50s2z"; })
+  (fetchNuGet { pname = "System.Threading.Thread"; version = "4.3.0"; sha256 = "0y2xiwdfcph7znm2ysxanrhbqqss6a3shi1z3c779pj2s523mjx4"; })
+  (fetchNuGet { pname = "System.Threading.ThreadPool"; version = "4.3.0"; sha256 = "027s1f4sbx0y1xqw2irqn6x161lzj8qwvnh2gn78ciiczdv10vf1"; })
+  (fetchNuGet { pname = "System.Threading.Timer"; version = "4.0.1"; sha256 = "15n54f1f8nn3mjcjrlzdg6q3520571y012mx7v991x2fvp73lmg6"; })
+  (fetchNuGet { pname = "System.Xml.ReaderWriter"; version = "4.0.11"; sha256 = "0c6ky1jk5ada9m94wcadih98l6k1fvf6vi7vhn1msjixaha419l5"; })
+  (fetchNuGet { pname = "System.Xml.ReaderWriter"; version = "4.3.0"; sha256 = "0c47yllxifzmh8gq6rq6l36zzvw4kjvlszkqa9wq3fr59n0hl3s1"; })
+  (fetchNuGet { pname = "System.Xml.XDocument"; version = "4.0.11"; sha256 = "0n4lvpqzy9kc7qy1a4acwwd7b7pnvygv895az5640idl2y9zbz18"; })
+  (fetchNuGet { pname = "System.Xml.XmlDocument"; version = "4.3.0"; sha256 = "0bmz1l06dihx52jxjr22dyv5mxv6pj4852lx68grjm7bivhrbfwi"; })
+  (fetchNuGet { pname = "System.Xml.XPath"; version = "4.3.0"; sha256 = "1cv2m0p70774a0sd1zxc8fm8jk3i5zk2bla3riqvi8gsm0r4kpci"; })
+  (fetchNuGet { pname = "System.Xml.XPath.XmlDocument"; version = "4.3.0"; sha256 = "1h9lh7qkp0lff33z847sdfjj8yaz98ylbnkbxlnsbflhj9xyfqrm"; })
+]
diff --git a/pkgs/applications/emulators/ryujinx/log.patch b/pkgs/applications/emulators/ryujinx/log.patch
new file mode 100644
index 00000000000..57e96e5c25c
--- /dev/null
+++ b/pkgs/applications/emulators/ryujinx/log.patch
@@ -0,0 +1,21 @@
+diff --git a/Ryujinx/Configuration/LoggerModule.cs b/Ryujinx/Configuration/LoggerModule.cs
+index 44631ea0..534576bc 100644
+--- a/Ryujinx/Configuration/LoggerModule.cs
++++ b/Ryujinx/Configuration/LoggerModule.cs
+@@ -1,6 +1,7 @@
+ using Ryujinx.Common;
+ using Ryujinx.Common.Logging;
+ using System;
++using System.IO;
+
+ namespace Ryujinx.Configuration
+ {
+@@ -74,7 +75,7 @@ namespace Ryujinx.Configuration
+             if (e.NewValue)
+             {
+                 Logger.AddTarget(new AsyncLogTargetWrapper(
+-                    new FileLogTarget(AppDomain.CurrentDomain.BaseDirectory, "file"),
++                    new FileLogTarget(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Ryujinx"), "file"),
+                     1000,
+                     AsyncLogTargetOverflowAction.Block
+                 ));
diff --git a/pkgs/applications/emulators/ryujinx/updater.sh b/pkgs/applications/emulators/ryujinx/updater.sh
new file mode 100755
index 00000000000..0861414f0bf
--- /dev/null
+++ b/pkgs/applications/emulators/ryujinx/updater.sh
@@ -0,0 +1,40 @@
+#! /usr/bin/env nix-shell
+#! nix-shell -i bash -p coreutils gnused curl common-updater-scripts nuget-to-nix nix-prefetch-git jq dotnet-sdk_6
+set -eo pipefail
+cd "$(dirname "${BASH_SOURCE[0]}")"
+
+deps_file="$(realpath "./deps.nix")"
+
+nix-prefetch-git https://github.com/ryujinx/ryujinx --quiet > repo_info
+new_hash="$(jq -r ".sha256" < repo_info)"
+new_rev="$(jq -r ".rev" < repo_info)"
+rm repo_info
+
+new_version="$(
+    curl -s https://ci.appveyor.com/api/projects/gdkchan/ryujinx/branch/master \
+        | grep -Po '"version":.*?[^\\]",' \
+        | sed  's/"version":"\(.*\)",/\1/'
+    )"
+old_version="$(sed -nE 's/\s*version = "(.*)".*/\1/p' ./default.nix)"
+
+if [[ "$new_version" == "$old_version" ]]; then
+  echo "Already up to date! Doing nothing"
+  exit 0
+fi
+
+cd ../../../..
+update-source-version ryujinx "$new_version" "$new_hash" --rev="$new_rev"
+
+store_src="$(nix-build . -A ryujinx.src --no-out-link)"
+src="$(mktemp -d /tmp/ryujinx-src.XXX)"
+cp -rT "$store_src" "$src"
+chmod -R +w "$src"
+pushd "$src"
+
+mkdir nuget_tmp.packages
+dotnet restore Ryujinx.sln --packages nuget_tmp.packages
+
+nuget-to-nix ./nuget_tmp.packages > "$deps_file"
+
+popd
+rm -r "$src"
diff --git a/pkgs/applications/emulators/sameboy/default.nix b/pkgs/applications/emulators/sameboy/default.nix
new file mode 100644
index 00000000000..6838a7baaf2
--- /dev/null
+++ b/pkgs/applications/emulators/sameboy/default.nix
@@ -0,0 +1,48 @@
+{ lib, stdenv, fetchFromGitHub, gtk3, rgbds, SDL2, wrapGAppsHook, glib }:
+
+stdenv.mkDerivation rec {
+  pname = "sameboy";
+  version = "0.14.7";
+
+  src = fetchFromGitHub {
+    owner = "LIJI32";
+    repo = "SameBoy";
+    rev = "v${version}";
+    sha256 = "sha256-rvcR1mp+lJ6ZFc9WYUK9FBVcG2vD5MoX6lY+AJsMaeQ=";
+  };
+
+  enableParallelBuilding = true;
+  # glib and wrapGAppsHook are needed to make the Open ROM menu work.
+  nativeBuildInputs = [ rgbds glib wrapGAppsHook ];
+  buildInputs = [ SDL2 ];
+
+  makeFlags = [
+    "CONF=release"
+    "FREEDESKTOP=true"
+    "PREFIX=$(out)"
+  ];
+
+  postPatch = ''
+    substituteInPlace OpenDialog/gtk.c \
+      --replace '"libgtk-3.so"' '"${gtk3}/lib/libgtk-3.so"'
+  '';
+
+  meta = with lib; {
+    homepage = "https://sameboy.github.io";
+    description = "Game Boy, Game Boy Color, and Super Game Boy emulator";
+
+    longDescription = ''
+      SameBoy is a user friendly Game Boy, Game Boy Color and Super
+      Game Boy emulator for macOS, Windows and Unix-like platforms.
+      SameBoy is extremely accurate and includes a wide range of
+      powerful debugging features, making it ideal for both casual
+      players and developers. In addition to accuracy and developer
+      capabilities, SameBoy has all the features one would expect from
+      an emulator – from save states to scaling filters.
+    '';
+
+    license = licenses.mit;
+    maintainers = with maintainers; [ NieDzejkob ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/simh/default.nix b/pkgs/applications/emulators/simh/default.nix
new file mode 100644
index 00000000000..1e939538cda
--- /dev/null
+++ b/pkgs/applications/emulators/simh/default.nix
@@ -0,0 +1,62 @@
+{ lib, stdenv
+, fetchFromGitHub
+, SDL2
+, SDL2_ttf
+, libpcap
+, vde2
+, pcre
+}:
+
+stdenv.mkDerivation rec {
+  pname = "simh";
+  version = "3.11-1";
+
+  src = fetchFromGitHub {
+    owner = "simh";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-65+YfOWpVXPeT64TZcSaWJY+ODQ0q/pwF9jb8xGdpIs=";
+  };
+
+  buildInputs = [ SDL2 SDL2_ttf libpcap vde2 pcre ];
+
+  dontConfigure = true;
+
+  makeFlags = [ "GCC=${stdenv.cc.targetPrefix}cc" "CC_STD=-std=c99" "LDFLAGS=-lm" ];
+
+  preInstall = ''
+    install -d ${placeholder "out"}/bin
+    install -d ${placeholder "out"}/share/simh
+  '';
+
+  installPhase = ''
+    runHook preInstall
+    for i in BIN/*; do
+      install -D $i ${placeholder "out"}/bin
+    done
+    for i in VAX/*bin; do
+      install -D $i ${placeholder "out"}/share/simh
+    done
+    runHook postInstall
+  '';
+
+  postInstall = ''
+    (cd $out/bin; for i in *; do ln -s $i simh-$i; done)
+  '';
+
+  meta = with lib; {
+    homepage = "http://simh.trailing-edge.com/";
+    description = "A collection of simulators of historic hardware";
+    longDescription = ''
+      SimH (History Simulator) is a collection of simulators for historically
+      significant or just plain interesting computer hardware and software from
+      the past. The goal of the project is to create highly portable system
+      simulators and to publish them as freeware on the Internet, with freely
+      available copies of significant or representative software.
+    '';
+    license = with licenses; mit;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = with platforms; unix;
+  };
+}
+# TODO: install documentation
diff --git a/pkgs/applications/emulators/simplenes/default.nix b/pkgs/applications/emulators/simplenes/default.nix
new file mode 100644
index 00000000000..d073098507e
--- /dev/null
+++ b/pkgs/applications/emulators/simplenes/default.nix
@@ -0,0 +1,33 @@
+{ lib, stdenv
+, fetchFromGitHub
+, cmake
+, sfml
+}:
+
+stdenv.mkDerivation rec {
+  pname = "simplenes";
+  version = "unstable-2019-03-13";
+
+  src = fetchFromGitHub {
+    owner = "amhndu";
+    repo = "SimpleNES";
+    rev = "4edb7117970c21a33b3bfe11a6606764fffc5173";
+    sha256 = "1nmwj431iwqzzcykxd4xinqmg0rm14mx7zsjyhcc5skz7pihz86g";
+  };
+
+  nativeBuildInputs = [ cmake ];
+  buildInputs = [ sfml ];
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp ./SimpleNES $out/bin
+  '';
+
+  meta = with lib; {
+    homepage = "https://github.com/amhndu/SimpleNES";
+    description = "An NES emulator written in C++";
+    license = licenses.gpl3;
+    maintainers = with maintainers; [ ivar ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/snes9x-gtk/default.nix b/pkgs/applications/emulators/snes9x-gtk/default.nix
new file mode 100644
index 00000000000..27f3400cc0b
--- /dev/null
+++ b/pkgs/applications/emulators/snes9x-gtk/default.nix
@@ -0,0 +1,36 @@
+{ lib, stdenv, fetchFromGitHub, meson, ninja, pkg-config, wrapGAppsHook
+, SDL2, zlib, gtk3, libxml2, libXv, libepoxy, minizip, pulseaudio, portaudio }:
+
+stdenv.mkDerivation rec {
+  pname = "snes9x-gtk";
+  version = "1.60";
+
+  src = fetchFromGitHub {
+    owner = "snes9xgit";
+    repo = "snes9x";
+    rev = version;
+    sha256 = "12hpn7zcdvp30ldpw2zf115yjqv55n1ldjbids7vx0lvbpr06dm1";
+  };
+
+  nativeBuildInputs = [ meson ninja pkg-config wrapGAppsHook ];
+  buildInputs = [ SDL2 zlib gtk3 libxml2 libXv libepoxy minizip pulseaudio portaudio ];
+
+  preConfigure = "cd gtk";
+
+  meta = with lib; {
+    homepage = "https://www.snes9x.com";
+    description = "Super Nintendo Entertainment System (SNES) emulator";
+
+    longDescription = ''
+      Snes9x is a portable, freeware Super Nintendo Entertainment System (SNES)
+      emulator. It basically allows you to play most games designed for the SNES
+      and Super Famicom Nintendo game systems on your PC or Workstation; which
+      includes some real gems that were only ever released in Japan.
+    '';
+
+    # see https://github.com/snes9xgit/snes9x/blob/master/LICENSE for exact details
+    license = licenses.unfreeRedistributable;
+    maintainers = with maintainers; [ qknight ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/stella/default.nix b/pkgs/applications/emulators/stella/default.nix
new file mode 100644
index 00000000000..212c0669046
--- /dev/null
+++ b/pkgs/applications/emulators/stella/default.nix
@@ -0,0 +1,45 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, pkg-config
+, SDL2
+}:
+
+stdenv.mkDerivation rec {
+  pname = "stella";
+  version = "6.6";
+
+  src = fetchFromGitHub {
+    owner = "stella-emu";
+    repo = pname;
+    rev = version;
+    hash = "sha256-+ZvSCnnoKGyToSFqUQOArolFdgUcBBFNjFw8aoVDkYI=";
+  };
+
+  nativeBuildInputs = [
+    pkg-config
+  ];
+
+  buildInputs = [
+    SDL2
+  ];
+
+  meta = with lib;{
+    homepage = "https://stella-emu.github.io/";
+    description = "An open-source Atari 2600 VCS emulator";
+    longDescription = ''
+      Stella is a multi-platform Atari 2600 VCS emulator released under the GNU
+      General Public License (GPL). Stella was originally developed for Linux by
+      Bradford W. Mott, and is currently maintained by Stephen Anthony. Since
+      its original release several people have joined the development team to
+      port Stella to other operating systems such as AcornOS, AmigaOS, DOS,
+      FreeBSD, IRIX, Linux, OS/2, MacOS, Unix, and Windows. The development team
+      is working hard to perfect the emulator and we hope you enjoy our effort.
+
+      As of its 3.5 release, Stella is officially donationware.
+    '';
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/applications/emulators/termtekst/default.nix b/pkgs/applications/emulators/termtekst/default.nix
new file mode 100644
index 00000000000..56f56cffad9
--- /dev/null
+++ b/pkgs/applications/emulators/termtekst/default.nix
@@ -0,0 +1,36 @@
+{ lib, fetchFromGitHub, python3Packages, ncurses }:
+
+python3Packages.buildPythonApplication rec {
+  pname = "termtekst";
+  version = "1.0";
+
+  src = fetchFromGitHub {
+    owner = "zevv";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "1gm7j5d49a60wm7px82b76f610i8pl8ccz4r6qsz90z4mp3lyw9b";
+  };
+
+  propagatedBuildInputs = with python3Packages; [ ncurses requests ];
+
+  patchPhase = ''
+    substituteInPlace setup.py \
+      --replace "assert" "assert 1==1 #"
+    substituteInPlace src/tt \
+      --replace "locale.setlocale" "#locale.setlocale"
+    '';
+
+  meta = with lib; {
+    description = "Console NOS Teletekst viewer in Python";
+    longDescription = ''
+      Small Python app using curses to display Dutch NOS Teletekst on
+      the Linux console. The original Teletekst font includes 2x6
+      raster graphics glyphs which have no representation in unicode;
+      as a workaround the braille set is abused to approximate the
+      graphics.
+    '';
+    license = licenses.mit;
+    maintainers = with maintainers; [ leenaars ];
+    platforms = platforms.all;
+  };
+}
diff --git a/pkgs/applications/emulators/tilem/default.nix b/pkgs/applications/emulators/tilem/default.nix
new file mode 100644
index 00000000000..bde706e2304
--- /dev/null
+++ b/pkgs/applications/emulators/tilem/default.nix
@@ -0,0 +1,30 @@
+{ stdenv
+, fetchurl
+, lib
+, pkg-config
+, glib
+, gtk2
+, libticonv
+, libtifiles2
+, libticables2
+, libticalcs2
+}:
+
+stdenv.mkDerivation rec {
+  pname = "tilem";
+  version = "2.0";
+  src = fetchurl {
+    url = "mirror://sourceforge/${pname}/${pname}-${version}.tar.bz2";
+    sha256 = "1ba38xzhp3yf21ip3cgql6jzy49jc34sfnjsl4syxyrd81d269zw";
+  };
+  nativeBuildInputs = [ pkg-config ];
+  buildInputs = [ glib gtk2 libticonv libtifiles2 libticables2 libticalcs2 ];
+  NIX_CFLAGS_COMPILE = [ "-lm" ];
+  meta = with lib; {
+    homepage = "http://lpg.ticalc.org/prj_tilem/";
+    description = "Emulator and debugger for Texas Instruments Z80-based graphing calculators";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ siraben luc65r ];
+    platforms = platforms.linux ++ platforms.darwin;
+  };
+}
diff --git a/pkgs/applications/emulators/uae/default.nix b/pkgs/applications/emulators/uae/default.nix
new file mode 100644
index 00000000000..64f311c4a8a
--- /dev/null
+++ b/pkgs/applications/emulators/uae/default.nix
@@ -0,0 +1,27 @@
+{lib, stdenv, fetchurl, pkg-config, gtk2, alsa-lib, SDL}:
+
+stdenv.mkDerivation rec {
+  pname = "uae";
+  version = "0.8.29";
+
+  src = fetchurl {
+    url = "https://web.archive.org/web/20130905032631/http://www.amigaemulator.org/files/sources/develop/uae-${version}.tar.bz2";
+    sha256 = "05s3cd1rd5a970s938qf4c2xm3l7f54g5iaqw56v8smk355m4qr4";
+  };
+
+  configureFlags = [ "--with-sdl" "--with-sdl-sound" "--with-sdl-gfx" "--with-alsa" ];
+
+  nativeBuildInputs = [ pkg-config ];
+  buildInputs = [ gtk2 alsa-lib SDL ];
+
+  hardeningDisable = [ "format" ];
+  LDFLAGS = [ "-lm" ];
+
+  meta = {
+    description = "Ultimate/Unix/Unusable Amiga Emulator";
+    license = lib.licenses.gpl2Plus;
+    homepage = "https://web.archive.org/web/20130901222855/http://www.amigaemulator.org/";
+    maintainers = [ lib.maintainers.sander ];
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/uxn/default.nix b/pkgs/applications/emulators/uxn/default.nix
new file mode 100644
index 00000000000..0b797e2e160
--- /dev/null
+++ b/pkgs/applications/emulators/uxn/default.nix
@@ -0,0 +1,54 @@
+{ lib
+, stdenv
+, fetchFromSourcehut
+, SDL2
+}:
+
+stdenv.mkDerivation rec {
+  pname = "uxn";
+  version = "0.pre+unstable=2021-08-30";
+
+  src = fetchFromSourcehut {
+    owner = "~rabbits";
+    repo = pname;
+    rev = "a2e40d9d10c11ef48f4f93d0dc86f5085b4263ce";
+    hash = "sha256-/hxDYi814nQydm2iQk4NID4vpJ3BcBcM6NdL0iuZk5M=";
+  };
+
+  buildInputs = [
+    SDL2
+  ];
+
+  dontConfigure = true;
+
+  # It is easier to emulate build.sh script
+  buildPhase = ''
+    runHook preBuild
+
+    cc -std=c89 -Wall -Wno-unknown-pragmas src/uxnasm.c -o uxnasm
+    cc -std=c89 -Wall -Wno-unknown-pragmas src/uxn.c src/uxncli.c -o uxncli
+    cc -std=c89 -Wall -Wno-unknown-pragmas src/uxn.c src/devices/ppu.c \
+       src/devices/apu.c src/uxnemu.c $(sdl2-config --cflags --libs) -o uxnemu
+
+    runHook postBuild
+  '';
+
+  installPhase = ''
+    runHook preInstall
+
+    install -d $out/bin/ $out/share/${pname}/
+
+    cp uxnasm uxncli uxnemu $out/bin/
+    cp -r projects $out/share/${pname}/
+
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    homepage = "https://wiki.xxiivv.com/site/uxn.html";
+    description = "An assembler and emulator for the Uxn stack machine";
+    license = with licenses; [ mit ];
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = with platforms; unix;
+  };
+}
diff --git a/pkgs/applications/emulators/vbam/default.nix b/pkgs/applications/emulators/vbam/default.nix
new file mode 100644
index 00000000000..bb5e7cea4e0
--- /dev/null
+++ b/pkgs/applications/emulators/vbam/default.nix
@@ -0,0 +1,67 @@
+{ lib, stdenv
+, cairo
+, cmake
+, fetchFromGitHub
+, fetchpatch
+, ffmpeg
+, gettext
+, libGLU, libGL
+, openal
+, pkg-config
+, SDL2
+, sfml
+, zip
+, zlib
+}:
+
+stdenv.mkDerivation rec {
+  pname = "visualboyadvance-m";
+  version = "2.1.4";
+  src = fetchFromGitHub {
+    owner = "visualboyadvance-m";
+    repo = "visualboyadvance-m";
+    rev = "v${version}";
+    sha256 = "1kgpbvng3c12ws0dy92zc0azd94h0i3j4vm7b67zc8mi3pqsppdg";
+  };
+
+  nativeBuildInputs = [ cmake pkg-config ];
+
+  buildInputs = [
+    cairo
+    ffmpeg
+    gettext
+    libGLU libGL
+    openal
+    SDL2
+    sfml
+    zip
+    zlib
+  ];
+
+  cmakeFlags = [
+    "-DCMAKE_BUILD_TYPE='Release'"
+    "-DENABLE_FFMPEG='true'"
+    "-DENABLE_LINK='true'"
+    "-DSYSCONFDIR=etc"
+    "-DENABLE_WX='false'"
+    "-DENABLE_SDL='true'"
+  ];
+
+  patches = [
+    (fetchpatch {
+      # https://github.com/visualboyadvance-m/visualboyadvance-m/pull/793
+      name = "fix-build-SDL-2.0.14.patch";
+      url = "https://github.com/visualboyadvance-m/visualboyadvance-m/commit/619a5cce683ec4b1d03f08f316ba276d8f8cd824.patch";
+      sha256 = "099cbzgq4r9g83bvdra8a0swfl1vpfng120wf4q7h6vs0n102rk9";
+    })
+  ];
+
+  meta =  with lib; {
+    description = "A merge of the original Visual Boy Advance forks";
+    license = licenses.gpl2;
+    maintainers = with maintainers; [ lassulus ];
+    homepage = "https://vba-m.com/";
+    platforms = lib.platforms.linux;
+    badPlatforms = [ "aarch64-linux" ];
+  };
+}
diff --git a/pkgs/applications/emulators/vice/default.nix b/pkgs/applications/emulators/vice/default.nix
new file mode 100644
index 00000000000..ca0de2f8276
--- /dev/null
+++ b/pkgs/applications/emulators/vice/default.nix
@@ -0,0 +1,91 @@
+{ lib
+, stdenv
+, fetchurl
+, bison
+, flex
+, perl
+, libpng
+, giflib
+, libjpeg
+, alsa-lib
+, readline
+, libGLU
+, libGL
+, libXaw
+, pkg-config
+, gtk2
+, SDL
+, SDL_image
+, autoreconfHook
+, makeDesktopItem
+, dos2unix
+, xa
+, file
+}:
+
+stdenv.mkDerivation rec {
+  pname = "vice";
+  version = "3.6.1";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/vice-emu/vice-${version}.tar.gz";
+    sha256 = "sha256-IN+EyFGq8vUABRCSf20xsy8mmRbTUUZcNm3Ar8ncFQw=";
+  };
+
+  nativeBuildInputs = [
+    autoreconfHook
+    bison
+    dos2unix
+    file
+    flex
+    pkg-config
+  ];
+
+  buildInputs = [
+    alsa-lib
+    giflib
+    gtk2
+    libGL
+    libGLU
+    libXaw
+    libjpeg
+    libpng
+    perl
+    readline
+    SDL
+    SDL_image
+    xa
+  ];
+  dontDisableStatic = true;
+  configureFlags = [ "--enable-fullscreen" "--enable-gnomeui" "--disable-pdf-docs" ];
+
+  desktopItem = makeDesktopItem {
+    name = "vice";
+    exec = "x64";
+    comment = "Commodore 64 emulator";
+    desktopName = "VICE";
+    genericName = "Commodore 64 emulator";
+    categories = "Emulator;";
+  };
+
+  preBuild = ''
+    for i in src/resid src/resid-dtv
+    do
+      mkdir -pv $i/src
+      ln -sv ../../wrap-u-ar.sh $i/src
+    done
+  '';
+
+  postInstall = ''
+    mkdir -p $out/share/applications
+    cp ${desktopItem}/share/applications/* $out/share/applications
+  '';
+
+  meta = {
+    description = "Commodore 64, 128 and other emulators";
+    homepage = "https://vice-emu.sourceforge.io/";
+    license = lib.licenses.gpl2Plus;
+    maintainers = [ lib.maintainers.sander ];
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/wine/base.nix b/pkgs/applications/emulators/wine/base.nix
new file mode 100644
index 00000000000..480fc009504
--- /dev/null
+++ b/pkgs/applications/emulators/wine/base.nix
@@ -0,0 +1,167 @@
+{ stdenv, lib, pkgArches, callPackage,
+  name, version, src, mingwGccs, monos, geckos, platforms,
+  bison, flex, fontforge, makeWrapper, pkg-config,
+  autoconf, hexdump, perl, nixosTests,
+  supportFlags,
+  patches,
+  vkd3dArches,
+  buildScript ? null, configureFlags ? []
+}:
+
+with import ./util.nix { inherit lib; };
+
+let
+  patches' = patches;
+  prevName = name;
+  prevPlatforms = platforms;
+  prevConfigFlags = configureFlags;
+in
+stdenv.mkDerivation ((lib.optionalAttrs (buildScript != null) {
+  builder = buildScript;
+}) // rec {
+  inherit src;
+
+  name = if supportFlags.waylandSupport then "${prevName}-wayland" else prevName;
+
+  # Fixes "Compiler cannot create executables" building wineWow with mingwSupport
+  strictDeps = true;
+
+  nativeBuildInputs = [
+    bison
+    flex
+    fontforge
+    makeWrapper
+    pkg-config
+
+    # Required by staging
+    autoconf
+    hexdump
+    perl
+  ]
+  ++ lib.optionals supportFlags.mingwSupport mingwGccs;
+
+  buildInputs = toBuildInputs pkgArches (with supportFlags; (pkgs:
+  [ pkgs.freetype pkgs.perl ]
+  ++ lib.optional stdenv.isLinux         pkgs.libcap
+  ++ lib.optional cupsSupport            pkgs.cups
+  ++ lib.optional gettextSupport         pkgs.gettext
+  ++ lib.optional dbusSupport            pkgs.dbus
+  ++ lib.optional openalSupport          pkgs.openal
+  ++ lib.optional cairoSupport           pkgs.cairo
+  ++ lib.optional odbcSupport            pkgs.unixODBC
+  ++ lib.optional netapiSupport          pkgs.samba4
+  ++ lib.optional cursesSupport          pkgs.ncurses
+  ++ lib.optional vaSupport              pkgs.libva
+  ++ lib.optional pcapSupport            pkgs.libpcap
+  ++ lib.optional v4lSupport             pkgs.libv4l
+  ++ lib.optional saneSupport            pkgs.sane-backends
+  ++ lib.optional gphoto2Support         pkgs.libgphoto2
+  ++ lib.optional ldapSupport            pkgs.openldap
+  ++ lib.optional fontconfigSupport      pkgs.fontconfig
+  ++ lib.optional alsaSupport            pkgs.alsa-lib
+  ++ lib.optional pulseaudioSupport      pkgs.libpulseaudio
+  ++ lib.optional (xineramaSupport && !waylandSupport) pkgs.xorg.libXinerama
+  ++ lib.optional udevSupport            pkgs.udev
+  ++ lib.optional vulkanSupport          pkgs.vulkan-loader
+  ++ lib.optional sdlSupport             pkgs.SDL2
+  ++ vkd3dArches
+  ++ lib.optionals gstreamerSupport      (with pkgs.gst_all_1;
+    [ gstreamer gst-plugins-base gst-plugins-good gst-plugins-ugly gst-libav
+    (gst-plugins-bad.override { enableZbar = false; }) ])
+  ++ lib.optionals gtkSupport    [ pkgs.gtk3 pkgs.glib ]
+  ++ lib.optionals openclSupport [ pkgs.opencl-headers pkgs.ocl-icd ]
+  ++ lib.optionals tlsSupport    [ pkgs.openssl pkgs.gnutls ]
+  ++ lib.optionals (openglSupport && !stdenv.isDarwin) [ pkgs.libGLU pkgs.libGL pkgs.mesa.osmesa pkgs.libdrm ]
+  ++ lib.optionals stdenv.isDarwin (with pkgs.buildPackages.darwin.apple_sdk.frameworks; [
+     CoreServices Foundation ForceFeedback AppKit OpenGL IOKit DiskArbitration Security
+     ApplicationServices AudioToolbox CoreAudio AudioUnit CoreMIDI OpenAL OpenCL Cocoa Carbon
+  ])
+  ++ lib.optionals (stdenv.isLinux && !waylandSupport) (with pkgs.xorg; [
+     libX11 libXi libXcursor libXrandr libXrender libXxf86vm libXcomposite libXext
+  ])
+  ++ lib.optionals waylandSupport (with pkgs; [
+     wayland libxkbcommon wayland-protocols wayland.dev libxkbcommon.dev
+  ])));
+
+  patches = [ ] ++ patches';
+
+  configureFlags = prevConfigFlags
+    ++ lib.optionals supportFlags.waylandSupport [ "--with-wayland" ]
+    ++ lib.optionals supportFlags.vulkanSupport [ "--with-vulkan" ]
+    ++ lib.optionals supportFlags.vkd3dSupport [ "--with-vkd3d" ];
+
+  # Wine locates a lot of libraries dynamically through dlopen().  Add
+  # them to the RPATH so that the user doesn't have to set them in
+  # LD_LIBRARY_PATH.
+  NIX_LDFLAGS = toString (map (path: "-rpath " + path) (
+      map (x: "${lib.getLib x}/lib") ([ stdenv.cc.cc ] ++ buildInputs)
+      # libpulsecommon.so is linked but not found otherwise
+      ++ lib.optionals supportFlags.pulseaudioSupport (map (x: "${lib.getLib x}/lib/pulseaudio")
+          (toBuildInputs pkgArches (pkgs: [ pkgs.libpulseaudio ])))
+      ++ lib.optionals supportFlags.waylandSupport (map (x: "${lib.getLib x}/share/wayland-protocols")
+          (toBuildInputs pkgArches (pkgs: [ pkgs.wayland-protocols ])))
+    ));
+
+  # Don't shrink the ELF RPATHs in order to keep the extra RPATH
+  # elements specified above.
+  dontPatchELF = true;
+
+  ## FIXME
+  # Add capability to ignore known failing tests
+  # and enable doCheck
+  doCheck = false;
+
+  postInstall = let
+    links = prefix: pkg: "ln -s ${pkg} $out/${prefix}/${pkg.name}";
+  in lib.optionalString supportFlags.embedInstallers ''
+    mkdir -p $out/share/wine/gecko $out/share/wine/mono/
+    ${lib.strings.concatStringsSep "\n"
+          ((map (links "share/wine/gecko") geckos)
+        ++ (map (links "share/wine/mono")  monos))}
+  '' + lib.optionalString supportFlags.gstreamerSupport ''
+    # Wrapping Wine is tricky.
+    # https://github.com/NixOS/nixpkgs/issues/63170
+    # https://github.com/NixOS/nixpkgs/issues/28486
+    # The main problem is that wine-preloader opens and loads the wine(64) binary, and
+    # breakage occurs if it finds a shell script instead of the real binary. We solve this
+    # by setting WINELOADER to point to the original binary. Additionally, the locations
+    # of the 32-bit and 64-bit binaries must differ only by the presence of "64" at the
+    # end, due to the logic Wine uses to find the other binary (see get_alternate_loader
+    # in dlls/kernel32/process.c). Therefore we do not use wrapProgram which would move
+    # the binaries to ".wine-wrapped" and ".wine64-wrapped", but use makeWrapper directly,
+    # and move the binaries to ".wine" and ".wine64".
+    for i in wine wine64 ; do
+      prog="$out/bin/$i"
+      if [ -e "$prog" ]; then
+        hidden="$(dirname "$prog")/.$(basename "$prog")"
+        mv "$prog" "$hidden"
+        makeWrapper "$hidden" "$prog" \
+          --argv0 "" \
+          --set WINELOADER "$hidden" \
+          --prefix GST_PLUGIN_SYSTEM_PATH_1_0 ":" "$GST_PLUGIN_SYSTEM_PATH_1_0"
+      fi
+    done
+  '';
+
+  enableParallelBuilding = true;
+
+  # https://bugs.winehq.org/show_bug.cgi?id=43530
+  # https://github.com/NixOS/nixpkgs/issues/31989
+  hardeningDisable = [ "bindnow" ]
+    ++ lib.optional (stdenv.hostPlatform.isDarwin) "fortify"
+    ++ lib.optional (supportFlags.mingwSupport) "format";
+
+  passthru = {
+    inherit pkgArches;
+    tests = { inherit (nixosTests) wine; };
+  };
+  meta = {
+    inherit version;
+    homepage = "https://www.winehq.org/";
+    license = with lib.licenses; [ lgpl21Plus ];
+    description = if supportFlags.waylandSupport then "An Open Source implementation of the Windows API on top of OpenGL and Unix (with experimental Wayland support)" else "An Open Source implementation of the Windows API on top of X, OpenGL, and Unix";
+    platforms = if supportFlags.waylandSupport then (lib.remove "x86_64-darwin" prevPlatforms) else prevPlatforms;
+    maintainers = with lib.maintainers; [ avnik raskin bendlas jmc-figueira ];
+    mainProgram = "wine";
+  };
+})
diff --git a/pkgs/applications/emulators/wine/builder-wow.sh b/pkgs/applications/emulators/wine/builder-wow.sh
new file mode 100644
index 00000000000..0dd3194dc53
--- /dev/null
+++ b/pkgs/applications/emulators/wine/builder-wow.sh
@@ -0,0 +1,31 @@
+## build described at http://wiki.winehq.org/Wine64
+
+source $stdenv/setup
+preFlags="${configureFlags}"
+
+unpackPhase
+cd $TMP/$sourceRoot
+patchPhase
+
+configureScript=$TMP/$sourceRoot/configure
+mkdir -p $TMP/wine-wow $TMP/wine64
+
+cd $TMP/wine64
+sourceRoot=`pwd`
+configureFlags="${preFlags} --enable-win64"
+configurePhase
+buildPhase
+# checkPhase
+
+cd $TMP/wine-wow
+sourceRoot=`pwd`
+configureFlags="${preFlags} --with-wine64=../wine64"
+configurePhase
+buildPhase
+# checkPhase
+
+eval "$preInstall"
+cd $TMP/wine-wow && make install
+cd $TMP/wine64 && make install
+eval "$postInstall"
+fixupPhase
diff --git a/pkgs/applications/emulators/wine/cert-path.patch b/pkgs/applications/emulators/wine/cert-path.patch
new file mode 100644
index 00000000000..f0727f422f8
--- /dev/null
+++ b/pkgs/applications/emulators/wine/cert-path.patch
@@ -0,0 +1,15 @@
+diff --git a/dlls/crypt32/unixlib.c b/dlls/crypt32/unixlib.c
+index 7cb521eb98b..5804b88be84 100644
+--- a/dlls/crypt32/unixlib.c
++++ b/dlls/crypt32/unixlib.c
+@@ -654,6 +654,10 @@ static void load_root_certs(void)
+ 
+     for (i = 0; i < ARRAY_SIZE(CRYPT_knownLocations) && list_empty(&root_cert_list); i++)
+         import_certs_from_path( CRYPT_knownLocations[i], TRUE );
++
++    char *nix_cert_file = getenv("NIX_SSL_CERT_FILE");
++    if (nix_cert_file != NULL)
++        import_certs_from_path(nix_cert_file, TRUE);
+ }
+ 
+ static NTSTATUS enum_root_certs( void *args )
diff --git a/pkgs/applications/emulators/wine/default.nix b/pkgs/applications/emulators/wine/default.nix
new file mode 100644
index 00000000000..191fd4b2980
--- /dev/null
+++ b/pkgs/applications/emulators/wine/default.nix
@@ -0,0 +1,63 @@
+## Configuration:
+# Control you default wine config in nixpkgs-config:
+# wine = {
+#   release = "stable"; # "stable", "unstable", "staging", "wayland"
+#   build = "wineWow"; # "wine32", "wine64", "wineWow"
+# };
+# Make additional configurations on demand:
+# wine.override { wineBuild = "wine32"; wineRelease = "staging"; };
+{ lib, stdenv, callPackage,
+  wineRelease ? "stable",
+  wineBuild ? if stdenv.hostPlatform.system == "x86_64-linux" then "wineWow" else "wine32",
+  gettextSupport ? false,
+  fontconfigSupport ? false,
+  alsaSupport ? false,
+  gtkSupport ? false,
+  openglSupport ? false,
+  tlsSupport ? false,
+  gstreamerSupport ? false,
+  cupsSupport ? false,
+  dbusSupport ? false,
+  openalSupport ? false,
+  openclSupport ? false,
+  cairoSupport ? false,
+  odbcSupport ? false,
+  netapiSupport ? false,
+  cursesSupport ? false,
+  vaSupport ? false,
+  pcapSupport ? false,
+  v4lSupport ? false,
+  saneSupport ? false,
+  gphoto2Support ? false,
+  ldapSupport ? false,
+  pulseaudioSupport ? false,
+  udevSupport ? false,
+  xineramaSupport ? false,
+  vulkanSupport ? false,
+  sdlSupport ? false,
+  vkd3dSupport ? false,
+  mingwSupport ? wineRelease != "stable",
+  waylandSupport ? wineRelease == "wayland",
+  embedInstallers ? false # The Mono and Gecko MSI installers
+}:
+
+let wine-build = build: release:
+      lib.getAttr build (callPackage ./packages.nix {
+        wineRelease = release;
+        supportFlags = {
+          inherit
+            cupsSupport gettextSupport dbusSupport openalSupport cairoSupport
+            odbcSupport netapiSupport cursesSupport vaSupport pcapSupport
+            v4lSupport saneSupport gphoto2Support ldapSupport fontconfigSupport
+            alsaSupport pulseaudioSupport xineramaSupport gtkSupport openclSupport
+            tlsSupport openglSupport gstreamerSupport udevSupport vulkanSupport
+            sdlSupport vkd3dSupport mingwSupport waylandSupport embedInstallers;
+        };
+      });
+
+in if wineRelease == "staging" then
+  callPackage ./staging.nix {
+    wineUnstable = wine-build wineBuild "unstable";
+  }
+else
+  wine-build wineBuild wineRelease
diff --git a/pkgs/applications/emulators/wine/fonts.nix b/pkgs/applications/emulators/wine/fonts.nix
new file mode 100644
index 00000000000..0ee1b3973d8
--- /dev/null
+++ b/pkgs/applications/emulators/wine/fonts.nix
@@ -0,0 +1,22 @@
+{ stdenv, lib, callPackage }:
+let src = (callPackage ./sources.nix {}).stable;
+in
+stdenv.mkDerivation {
+  pname = "wine-fonts";
+  inherit (src) version;
+
+  sourceRoot = "wine-${src.version}/fonts";
+  inherit src;
+
+  installPhase = ''
+    install *.ttf -Dt $out/share/fonts/wine
+  '';
+
+  meta = {
+    description = "Microsoft replacement fonts by the Wine project";
+    homepage = "https://wiki.winehq.org/Create_Fonts";
+    license = with lib.licenses; [ lgpl21Plus ];
+    platforms = lib.platforms.all;
+    maintainers = with lib.maintainers; [ avnik raskin bendlas johnazoidberg ];
+  };
+}
diff --git a/pkgs/applications/emulators/wine/packages.nix b/pkgs/applications/emulators/wine/packages.nix
new file mode 100644
index 00000000000..cb857daef0a
--- /dev/null
+++ b/pkgs/applications/emulators/wine/packages.nix
@@ -0,0 +1,44 @@
+{ stdenv_32bit, lib, pkgs, pkgsi686Linux, pkgsCross, callPackage,
+  wineRelease ? "stable",
+  supportFlags
+}:
+
+let
+  src = lib.getAttr wineRelease (callPackage ./sources.nix {});
+  vkd3d = pkgs.callPackage ./vkd3d.nix {};
+  vkd3d_i686 = pkgsi686Linux.callPackage ./vkd3d.nix {};
+in with src; {
+  wine32 = pkgsi686Linux.callPackage ./base.nix {
+    name = "wine-${version}";
+    inherit src version supportFlags patches;
+    pkgArches = [ pkgsi686Linux ];
+    vkd3dArches = lib.optionals supportFlags.vkd3dSupport [ vkd3d_i686 ];
+    geckos = [ gecko32 ];
+    mingwGccs = with pkgsCross; [ mingw32.buildPackages.gcc ];
+    monos =  [ mono ];
+    platforms = [ "i686-linux" "x86_64-linux" ];
+  };
+  wine64 = callPackage ./base.nix {
+    name = "wine64-${version}";
+    inherit src version supportFlags patches;
+    pkgArches = [ pkgs ];
+    vkd3dArches = lib.optionals supportFlags.vkd3dSupport [ vkd3d ];
+    mingwGccs = with pkgsCross; [ mingwW64.buildPackages.gcc ];
+    geckos = [ gecko64 ];
+    monos =  [ mono ];
+    configureFlags = [ "--enable-win64" ];
+    platforms = [ "x86_64-linux" "x86_64-darwin" ];
+  };
+  wineWow = callPackage ./base.nix {
+    name = "wine-wow-${version}";
+    inherit src version supportFlags patches;
+    stdenv = stdenv_32bit;
+    pkgArches = [ pkgs pkgsi686Linux ];
+    vkd3dArches = lib.optionals supportFlags.vkd3dSupport [ vkd3d vkd3d_i686 ];
+    geckos = [ gecko32 gecko64 ];
+    mingwGccs = with pkgsCross; [ mingw32.buildPackages.gcc mingwW64.buildPackages.gcc ];
+    monos =  [ mono ];
+    buildScript = ./builder-wow.sh;
+    platforms = [ "x86_64-linux" ];
+  };
+}
diff --git a/pkgs/applications/emulators/wine/sources.nix b/pkgs/applications/emulators/wine/sources.nix
new file mode 100644
index 00000000000..b98aceddbd4
--- /dev/null
+++ b/pkgs/applications/emulators/wine/sources.nix
@@ -0,0 +1,93 @@
+{ pkgs ? import <nixpkgs> {} }:
+## we default to importing <nixpkgs> here, so that you can use
+## a simple shell command to insert new sha256's into this file
+## e.g. with emacs C-u M-x shell-command
+##
+##     nix-prefetch-url sources.nix -A {stable{,.mono,.gecko64,.gecko32}, unstable, staging, winetricks}
+
+# here we wrap fetchurl and fetchFromGitHub, in order to be able to pass additional args around it
+let fetchurl = args@{url, sha256, ...}:
+  pkgs.fetchurl { inherit url sha256; } // args;
+    fetchFromGitHub = args@{owner, repo, rev, sha256, ...}:
+  pkgs.fetchFromGitHub { inherit owner repo rev sha256; } // args;
+    fetchFromGitLab = args@{domain, owner, repo, rev, sha256, ...}:
+  pkgs.fetchFromGitLab { inherit domain owner repo rev sha256; } // args;
+in rec {
+
+  stable = fetchurl rec {
+    version = "7.0";
+    url = "https://dl.winehq.org/wine/source/7.0/wine-${version}.tar.xz";
+    sha256 = "sha256-W0PifVwIXLGPlzlORhgDENXu98HZHGiVQyo4ibLeCGs=";
+
+    ## see http://wiki.winehq.org/Gecko
+    gecko32 = fetchurl rec {
+      version = "2.47.2";
+      url = "https://dl.winehq.org/wine/wine-gecko/${version}/wine-gecko-${version}-x86.msi";
+      sha256 = "07d6nrk2g0614kvwdjym1wq21d2bwy3pscwikk80qhnd6rrww875";
+    };
+    gecko64 = fetchurl rec {
+      version = "2.47.2";
+      url = "https://dl.winehq.org/wine/wine-gecko/${version}/wine-gecko-${version}-x86_64.msi";
+      sha256 = "0iffhvdawc499nbn4k99k33cr7g8sdfcvq8k3z1g6gw24h87d5h5";
+    };
+
+    ## see http://wiki.winehq.org/Mono
+    mono = fetchurl rec {
+      version = "7.0.0";
+      url = "https://dl.winehq.org/wine/wine-mono/${version}/wine-mono-${version}-x86.msi";
+      sha256 = "sha256-s35vyeWQ5YIkPcJdcqX8wzDDp5cN/cmKeoHSOEW6iQA=";
+    };
+
+    patches = [
+      # Also look for root certificates at $NIX_SSL_CERT_FILE
+      ./cert-path.patch
+    ];
+  };
+
+  unstable = fetchurl rec {
+    # NOTE: Don't forget to change the SHA256 for staging as well.
+    version = "7.2";
+    url = "https://dl.winehq.org/wine/source/7.x/wine-${version}.tar.xz";
+    sha256 = "sha256-38ZBUjyNvGZBaLYXREFjPZcSdUVr9n3i3KqZyNql7hU=";
+    inherit (stable) gecko32 gecko64 patches;
+
+    mono = fetchurl rec {
+      version = "7.1.1";
+      url = "https://dl.winehq.org/wine/wine-mono/${version}/wine-mono-${version}-x86.msi";
+      sha256 = "sha256-ncjlYDt7xkNU65SuTqD2ghQkdno/9E/w0Z40akkMEeo=";
+    };
+  };
+
+  staging = fetchFromGitHub rec {
+    # https://github.com/wine-staging/wine-staging/releases
+    inherit (unstable) version;
+    sha256 = "sha256-Ec9rienlsDg+2QkJqPrGorDb5NycG1/iGWhnqLZOrwg=";
+    owner = "wine-staging";
+    repo = "wine-staging";
+    rev = "v${version}";
+
+    disabledPatchsets = [ ];
+  };
+
+  wayland = fetchFromGitLab rec {
+    version = "7.0-rc2";
+    sha256 = "sha256-FU9L8cyIIfFQ+8f/AUg7IT+RxTpyNTuSfL0zBnur0SA=";
+    domain = "gitlab.collabora.com";
+    owner = "alf";
+    repo = "wine";
+    rev = "95f0154c96a4b7d81e783ee5ba2f5d9cc7cda351";
+
+    inherit (unstable) gecko32 gecko64;
+
+    inherit (unstable) mono;
+  };
+
+  winetricks = fetchFromGitHub rec {
+    # https://github.com/Winetricks/winetricks/releases
+    version = "20210825";
+    sha256 = "sha256-exMhj3dS8uXCEgOaWbftaq94mBOmtZIXsXb9xNX5ha8=";
+    owner = "Winetricks";
+    repo = "winetricks";
+    rev = version;
+  };
+}
diff --git a/pkgs/applications/emulators/wine/staging.nix b/pkgs/applications/emulators/wine/staging.nix
new file mode 100644
index 00000000000..c6bdb401245
--- /dev/null
+++ b/pkgs/applications/emulators/wine/staging.nix
@@ -0,0 +1,28 @@
+{ lib, callPackage, wineUnstable }:
+
+with callPackage ./util.nix {};
+
+let patch = (callPackage ./sources.nix {}).staging;
+    build-inputs = pkgNames: extra:
+      (mkBuildInputs wineUnstable.pkgArches pkgNames) ++ extra;
+in assert lib.getVersion wineUnstable == patch.version;
+
+(lib.overrideDerivation wineUnstable (self: {
+  buildInputs = build-inputs [ "perl" "util-linux" "autoconf" "gitMinimal" ] self.buildInputs;
+
+  name = "${self.name}-staging";
+
+  prePatch = self.prePatch or "" + ''
+    patchShebangs tools
+    cp -r ${patch}/patches .
+    chmod +w patches
+    cd patches
+    patchShebangs gitapply.sh
+    ./patchinstall.sh DESTDIR="$PWD/.." --all ${lib.concatMapStringsSep " " (ps: "-W ${ps}") patch.disabledPatchsets}
+    cd ..
+  '';
+})) // {
+  meta = wineUnstable.meta // {
+    description = wineUnstable.meta.description + " (with staging patches)";
+  };
+}
diff --git a/pkgs/applications/emulators/wine/util.nix b/pkgs/applications/emulators/wine/util.nix
new file mode 100644
index 00000000000..cd5bd03130b
--- /dev/null
+++ b/pkgs/applications/emulators/wine/util.nix
@@ -0,0 +1,9 @@
+{ lib }:
+rec {
+  toPackages = pkgNames: pkgs:
+    map (pn: lib.getAttr pn pkgs) pkgNames;
+  toBuildInputs = pkgArches: archPkgs:
+    lib.concatLists (map archPkgs pkgArches);
+  mkBuildInputs = pkgArches: pkgNames:
+    toBuildInputs pkgArches (toPackages pkgNames);
+}
diff --git a/pkgs/applications/emulators/wine/vkd3d.nix b/pkgs/applications/emulators/wine/vkd3d.nix
new file mode 100644
index 00000000000..303d33df217
--- /dev/null
+++ b/pkgs/applications/emulators/wine/vkd3d.nix
@@ -0,0 +1,26 @@
+{ lib, stdenv, fetchurl, vulkan-headers, spirv-headers, vulkan-loader }:
+
+#TODO: MoltenVK
+#TODO: unstable
+
+stdenv.mkDerivation rec {
+  pname = "vkd3d";
+  version = "1.2";
+
+  src = fetchurl {
+    url = "https://dl.winehq.org/vkd3d/source/vkd3d-${version}.tar.xz";
+    sha256 = "0szr1lw3xbgi9qjm13d1q4gyzzwv8i5wfxiwjg6dmwphrc7h6jxh";
+  };
+
+  buildInputs = [ vulkan-headers spirv-headers vulkan-loader ];
+
+  enableParallelBuilding = true;
+
+  meta = with lib; {
+    description = "A 3d library build on top on Vulkan with a similar api to DirectX 12";
+    homepage = "https://source.winehq.org/git/vkd3d.git";
+    license = licenses.lgpl21;
+    platforms = platforms.linux;
+    maintainers = [ maintainers.marius851000 ];
+  };
+}
diff --git a/pkgs/applications/emulators/wine/winetricks.nix b/pkgs/applications/emulators/wine/winetricks.nix
new file mode 100644
index 00000000000..61ca6515c44
--- /dev/null
+++ b/pkgs/applications/emulators/wine/winetricks.nix
@@ -0,0 +1,33 @@
+{ lib, stdenv, callPackage, perl, which, coreutils, zenity, curl
+, cabextract, unzip, p7zip, gnused, gnugrep, bash } :
+
+stdenv.mkDerivation rec {
+  pname = "winetricks";
+  version = src.version;
+
+  src = (callPackage ./sources.nix {}).winetricks;
+
+  buildInputs = [ perl which ];
+
+  # coreutils is for sha1sum
+  pathAdd = lib.makeBinPath [
+    perl which coreutils zenity curl cabextract unzip p7zip gnused gnugrep bash
+  ];
+
+  makeFlags = [ "PREFIX=$(out)" ];
+
+  doCheck = false; # requires "bashate"
+
+  postInstall = ''
+    sed -i \
+      -e '2i PATH="${pathAdd}:$PATH"' \
+      "$out/bin/winetricks"
+  '';
+
+  meta = {
+    description = "A script to install DLLs needed to work around problems in Wine";
+    license = lib.licenses.lgpl21;
+    homepage = "https://github.com/Winetricks/winetricks";
+    platforms = with lib.platforms; linux;
+  };
+}
diff --git a/pkgs/applications/emulators/xcpc/default.nix b/pkgs/applications/emulators/xcpc/default.nix
new file mode 100644
index 00000000000..633d44bb5ae
--- /dev/null
+++ b/pkgs/applications/emulators/xcpc/default.nix
@@ -0,0 +1,29 @@
+{ lib, stdenv, fetchurl, pkg-config, glib, libXaw, libX11, libXext
+  , libDSKSupport ? true, libdsk
+  , motifSupport ? false, lesstif
+}:
+
+with lib;
+stdenv.mkDerivation rec {
+  version = "20070122";
+  pname = "xcpc";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/xcpc/${pname}-${version}.tar.gz";
+    sha256 = "0hxsbhmyzyyrlidgg0q8izw55q0z40xrynw5a1c3frdnihj9jf7n";
+  };
+
+  nativeBuildInputs = [ pkg-config ];
+
+  buildInputs = [ glib libdsk libXaw libX11 libXext ]
+    ++ optional libDSKSupport libdsk
+    ++ optional motifSupport lesstif;
+
+  meta = {
+    description = "A portable Amstrad CPC 464/664/6128 emulator written in C";
+    homepage = "https://www.xcpc-emulator.net";
+    license = licenses.gpl2Plus;
+    maintainers = [ ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/yabause/0001-Fixes-for-Qt-5.11-upgrade.patch b/pkgs/applications/emulators/yabause/0001-Fixes-for-Qt-5.11-upgrade.patch
new file mode 100644
index 00000000000..43539ef4ca5
--- /dev/null
+++ b/pkgs/applications/emulators/yabause/0001-Fixes-for-Qt-5.11-upgrade.patch
@@ -0,0 +1,67 @@
+From 3140afd6fb7dad7a25296526a71b005fb9eae048 Mon Sep 17 00:00:00 2001
+From: Samuel Dionne-Riel <samuel@dionne-riel.com>
+Date: Sat, 8 Sep 2018 00:44:08 -0400
+Subject: [PATCH] Fixes for Qt 5.11 upgrade
+
+---
+ src/qt/ui/UICheatRaw.cpp | 2 --
+ src/qt/ui/UICheatRaw.h   | 2 +-
+ src/qt/ui/UICheats.cpp   | 2 ++
+ src/qt/ui/UIHexInput.h   | 2 ++
+ 4 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/src/qt/ui/UICheatRaw.cpp b/src/qt/ui/UICheatRaw.cpp
+index 4ad82d77..3f78486b 100755
+--- a/src/qt/ui/UICheatRaw.cpp
++++ b/src/qt/ui/UICheatRaw.cpp
+@@ -20,8 +20,6 @@
+ #include "UIHexInput.h"

+ #include "../QtYabause.h"

+ 

+-#include <QButtonGroup>

+-

+ UICheatRaw::UICheatRaw( QWidget* p )

+ 	: QDialog( p )

+ {

+diff --git a/src/qt/ui/UICheatRaw.h b/src/qt/ui/UICheatRaw.h
+index d97b429d..20318c67 100755
+--- a/src/qt/ui/UICheatRaw.h
++++ b/src/qt/ui/UICheatRaw.h
+@@ -21,7 +21,7 @@
+ 

+ #include "ui_UICheatRaw.h"

+ 

+-class QButtonGroup;

++#include <QButtonGroup>

+ 

+ class UICheatRaw : public QDialog, public Ui::UICheatRaw

+ {

+diff --git a/src/qt/ui/UICheats.cpp b/src/qt/ui/UICheats.cpp
+index c6027972..44d341c3 100755
+--- a/src/qt/ui/UICheats.cpp
++++ b/src/qt/ui/UICheats.cpp
+@@ -21,6 +21,8 @@
+ #include "UICheatRaw.h"
+ #include "../CommonDialogs.h"
+ 
++#include <QButtonGroup>
++
+ UICheats::UICheats( QWidget* p )
+ 	: QDialog( p )
+ {
+diff --git a/src/qt/ui/UIHexInput.h b/src/qt/ui/UIHexInput.h
+index f333b016..4bd8aed4 100644
+--- a/src/qt/ui/UIHexInput.h
++++ b/src/qt/ui/UIHexInput.h
+@@ -22,6 +22,8 @@
+ #include "ui_UIHexInput.h"

+ #include "../QtYabause.h"

+ 

++#include <QValidator>

++

+ class HexValidator : public QValidator

+ {

+    Q_OBJECT

+-- 
+2.16.4
+
diff --git a/pkgs/applications/emulators/yabause/default.nix b/pkgs/applications/emulators/yabause/default.nix
new file mode 100644
index 00000000000..17b7b563c15
--- /dev/null
+++ b/pkgs/applications/emulators/yabause/default.nix
@@ -0,0 +1,36 @@
+{ mkDerivation, lib, fetchurl, cmake, pkg-config, qtbase, qt5, libGLU, libGL
+, freeglut ? null, openal ? null, SDL2 ? null }:
+
+mkDerivation rec {
+  pname = "yabause";
+  version = "0.9.15";
+
+  src = fetchurl {
+    url = "https://download.tuxfamily.org/yabause/releases/${version}/${pname}-${version}.tar.gz";
+    sha256 = "1cn2rjjb7d9pkr4g5bqz55vd4pzyb7hg94cfmixjkzzkw0zw8d23";
+  };
+
+  nativeBuildInputs = [ cmake pkg-config ];
+  buildInputs = [ qtbase qt5.qtmultimedia libGLU libGL freeglut openal SDL2 ];
+
+  patches = [
+    ./linkage-rwx-linux-elf.patch
+    # Fixes derived from
+    # https://github.com/Yabause/yabause/commit/06a816c032c6f7fd79ced6e594dd4b33571a0e73
+    ./0001-Fixes-for-Qt-5.11-upgrade.patch
+  ];
+
+  cmakeFlags = [
+    "-DYAB_NETWORK=ON"
+    "-DYAB_OPTIMIZED_DMA=ON"
+    "-DYAB_PORTS=qt"
+  ] ;
+
+  meta = with lib; {
+    description = "An open-source Sega Saturn emulator";
+    homepage = "https://yabause.org/";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/applications/emulators/yabause/linkage-rwx-linux-elf.patch b/pkgs/applications/emulators/yabause/linkage-rwx-linux-elf.patch
new file mode 100644
index 00000000000..bb0491b373f
--- /dev/null
+++ b/pkgs/applications/emulators/yabause/linkage-rwx-linux-elf.patch
@@ -0,0 +1,20 @@
+--- a/src/sh2_dynarec/linkage_x64.s	2013-03-11 20:29:53.112870900 +0100
++++ b/src/sh2_dynarec/linkage_x64.s	2013-03-11 20:31:48.856778600 +0100
+@@ -747,3 +747,7 @@ breakpoint:
+ 	ret
+ 	/* Set breakpoint here for debugging */
+ 	.size	breakpoint, .-breakpoint
++
++#if defined(__linux__) && defined(__ELF__)
++.section .note.GNU-stack,"",%progbits
++#endif
+--- a/src/sh2_dynarec/linkage_x86.s	2013-03-11 20:30:08.157693100 +0100
++++ b/src/sh2_dynarec/linkage_x86.s	2013-03-11 20:32:30.993310600 +0100
+@@ -743,3 +743,7 @@ breakpoint:
+ 	ret
+ 	/* Set breakpoint here for debugging */
+ 	.size	breakpoint, .-breakpoint
++
++#if defined(__linux__) && defined(__ELF__)
++.section .note.GNU-stack,"",%progbits
++#endif
diff --git a/pkgs/applications/emulators/yapesdl/default.nix b/pkgs/applications/emulators/yapesdl/default.nix
new file mode 100644
index 00000000000..5f4b7771fb5
--- /dev/null
+++ b/pkgs/applications/emulators/yapesdl/default.nix
@@ -0,0 +1,43 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, pkg-config
+, SDL2
+}:
+
+stdenv.mkDerivation rec {
+  pname = "yapesdl";
+  version = "0.70.2";
+
+  src = fetchFromGitHub {
+    owner = "calmopyrin";
+    repo = pname;
+    rev = "v${version}";
+    hash = "sha256-51P6wNaSfVA3twu+yRUKXguEmVBvuuEnHxH1Zl1vsCc=";
+  };
+
+  nativeBuildInputs = [
+    pkg-config
+  ];
+  buildInputs = [
+    SDL2
+  ];
+
+  makeFlags = [ "CC=${stdenv.cc.targetPrefix}c++" ];
+
+  installPhase = ''
+    runHook preInstall
+    install --directory $out/bin $out/share/doc/$pname
+    install yapesdl $out/bin/
+    install README.SDL $out/share/doc/$pname/
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    homepage = "http://yape.plus4.net/";
+    description = "Multiplatform Commodore 64 and 264 family emulator";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/applications/emulators/yuzu/base.nix b/pkgs/applications/emulators/yuzu/base.nix
new file mode 100644
index 00000000000..aff09134fae
--- /dev/null
+++ b/pkgs/applications/emulators/yuzu/base.nix
@@ -0,0 +1,86 @@
+{ pname, version, src, branchName
+, stdenv, lib, wrapQtAppsHook
+, cmake, pkg-config
+, libpulseaudio, libjack2, alsa-lib, sndio
+, vulkan-loader, vulkan-headers
+, qtbase, qtwebengine, qttools
+, nlohmann_json, rapidjson
+, zlib, zstd, libzip, lz4
+, glslang
+, boost173
+, catch2
+, fmt_8
+, SDL2
+, udev
+, libusb1
+, ffmpeg
+}:
+
+stdenv.mkDerivation rec {
+  inherit pname version src;
+
+  nativeBuildInputs = [ cmake pkg-config wrapQtAppsHook ];
+  buildInputs = [
+    libpulseaudio libjack2 alsa-lib sndio
+    vulkan-loader vulkan-headers
+    qtbase qtwebengine qttools
+    nlohmann_json rapidjson
+    zlib zstd libzip lz4
+    glslang
+    boost173
+    catch2
+    fmt_8
+    SDL2
+    udev
+    libusb1
+    ffmpeg
+  ];
+
+  cmakeFlags = [
+    "-DYUZU_USE_BUNDLED_QT=OFF"
+    "-DYUZU_USE_BUNDLED_SDL2=OFF"
+    "-DYUZU_USE_BUNDLED_FFMPEG=OFF"
+    "-DENABLE_QT_TRANSLATION=ON"
+    "-DYUZU_USE_QT_WEB_ENGINE=ON"
+    "-DUSE_DISCORD_PRESENCE=ON"
+  ];
+
+  # This changes `ir/opt` to `ir/var/empty` in `externals/dynarmic/src/dynarmic/CMakeLists.txt`
+  # making the build fail, as that path does not exist
+  dontFixCmake = true;
+
+  preConfigure = ''
+    # Trick the configure system. This prevents a check for submodule directories.
+    rm -f .gitmodules
+
+    # see https://github.com/NixOS/nixpkgs/issues/114044, setting this through cmakeFlags does not work.
+    cmakeFlagsArray+=(
+      "-DTITLE_BAR_FORMAT_IDLE=yuzu ${branchName} ${version}"
+      "-DTITLE_BAR_FORMAT_RUNNING=yuzu ${branchName} ${version} | {3}"
+    )
+  '';
+
+  # Fix vulkan detection
+  postFixup = ''
+    wrapProgram $out/bin/yuzu --prefix LD_LIBRARY_PATH : ${vulkan-loader}/lib
+    wrapProgram $out/bin/yuzu-cmd --prefix LD_LIBRARY_PATH : ${vulkan-loader}/lib
+  '';
+
+  meta = with lib; {
+    homepage = "https://yuzu-emu.org";
+    description = "The ${branchName} branch of an experimental Nintendo Switch emulator written in C++";
+    longDescription = ''
+      An experimental Nintendo Switch emulator written in C++.
+      Using the mainline branch is recommanded for general usage.
+      Using the early-access branch is recommanded if you would like to try out experimental features, with a cost of stability.
+    '';
+    license = with licenses; [
+      gpl2Plus
+      # Icons
+      cc-by-nd-30 cc0
+    ];
+    maintainers = with maintainers; [ ivar joshuafern sbruder ];
+    platforms = platforms.linux;
+    broken = stdenv.isAarch64; # Currently aarch64 is not supported.
+  };
+}
diff --git a/pkgs/applications/emulators/yuzu/default.nix b/pkgs/applications/emulators/yuzu/default.nix
new file mode 100644
index 00000000000..9e45ba0cd2c
--- /dev/null
+++ b/pkgs/applications/emulators/yuzu/default.nix
@@ -0,0 +1,28 @@
+{ branch ? "mainline", libsForQt5, fetchFromGitHub }:
+let
+  inherit libsForQt5 fetchFromGitHub;
+in {
+  mainline = libsForQt5.callPackage ./base.nix rec {
+    pname = "yuzu-mainline";
+    version = "882";
+    branchName = branch;
+    src = fetchFromGitHub {
+      owner = "yuzu-emu";
+      repo = "yuzu-mainline";
+      rev = "mainline-0-${version}";
+      sha256 = "17j845laxnaq50icwl32yisdivwcnwa59fxdr297yxrz4hmfzhxq";
+      fetchSubmodules = true;
+    };
+  };
+  early-access = libsForQt5.callPackage ./base.nix rec {
+    pname = "yuzu-ea";
+    version = "2432";
+    branchName = branch;
+    src = fetchFromGitHub {
+      owner = "pineappleEA";
+      repo = "pineapple-src";
+      rev = "EA-${version}";
+      sha256 = "0zqab61rphgjzyxk52idhr7dqwwxih0f8b9hig3zvrwkdry9wfh4";
+    };
+  };
+}.${branch}
diff --git a/pkgs/applications/emulators/zesarux/default.nix b/pkgs/applications/emulators/zesarux/default.nix
new file mode 100644
index 00000000000..4df6cfafbc0
--- /dev/null
+++ b/pkgs/applications/emulators/zesarux/default.nix
@@ -0,0 +1,89 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, fetchpatch
+, SDL2
+, aalib
+, alsa-lib
+, libXext
+, libXxf86vm
+, libcaca
+, libpulseaudio
+, libsndfile
+, ncurses
+, openssl
+, which
+}:
+
+stdenv.mkDerivation rec {
+  pname = "zesarux";
+  version = "10.0";
+
+  src = fetchFromGitHub {
+    owner = "chernandezba";
+    repo = pname;
+    rev = version;
+    hash = "sha256-cxV2dAzGnIzJiCRdq8vN/Cl4AQeJqjmiCAahijIJQ9k=";
+  };
+
+  nativeBuildInputs = [
+    which
+  ];
+
+  buildInputs = [
+    SDL2
+    aalib
+    alsa-lib
+    libXxf86vm
+    libXext
+    libcaca
+    libpulseaudio
+    libsndfile
+    ncurses
+    openssl
+  ];
+
+  patches = [
+    # Patch the shell scripts; remove it when the next version arrives
+    (fetchpatch {
+      name = "000-fix-shebangs.patch";
+      url = "https://github.com/chernandezba/zesarux/commit/4493439b38f565c5be7c36239ecaf0cf80045627.diff";
+      sha256 = "sha256-f+21naPcPXdcVvqU8ymlGfl1WkYGOeOBe9B/WFUauTI=";
+    })
+  ];
+
+  postPatch = ''
+    cd src
+    patchShebangs ./configure *.sh
+  '';
+
+  configureFlags = [
+    "--prefix=${placeholder "out"}"
+    "--c-compiler ${stdenv.cc.targetPrefix}cc"
+    "--enable-cpustats"
+    "--enable-memptr"
+    "--enable-sdl2"
+    "--enable-ssl"
+    "--enable-undoc-scfccf"
+    "--enable-visualmem"
+  ];
+
+  installPhase = ''
+    runHook preInstall
+
+    ./generate_install_sh.sh
+    patchShebangs ./install.sh
+    ./install.sh
+
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    homepage = "https://github.com/chernandezba/zesarux";
+    description = " ZX Second-Emulator And Released for UniX";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = platforms.unix;
+  };
+}
+# TODO: Darwin support
diff --git a/pkgs/applications/emulators/zsnes/default.nix b/pkgs/applications/emulators/zsnes/default.nix
new file mode 100644
index 00000000000..ba2f5d6bdc1
--- /dev/null
+++ b/pkgs/applications/emulators/zsnes/default.nix
@@ -0,0 +1,64 @@
+{ lib, stdenv, fetchFromGitHub, nasm, SDL, zlib, libpng, ncurses, libGLU, libGL
+, makeDesktopItem }:
+
+let
+  desktopItem = makeDesktopItem {
+    name = "zsnes";
+    exec = "zsnes";
+    icon = "zsnes";
+    comment = "A SNES emulator";
+    desktopName = "zsnes";
+    genericName = "zsnes";
+    categories = "Game;";
+  };
+
+in stdenv.mkDerivation {
+  pname = "zsnes";
+  version = "1.51";
+
+  src = fetchFromGitHub {
+    owner = "emillon";
+    repo = "zsnes";
+    rev = "fc160b2538738995f600f8405d23a66b070dac02";
+    sha256 = "1gy79d5wdaacph0cc1amw7mqm7i0716n6mvav16p1svi26iz193v";
+  };
+
+  buildInputs = [ nasm SDL zlib libpng ncurses libGLU libGL ];
+
+  prePatch = ''
+    for i in $(cat debian/patches/series); do
+      echo "applying $i"
+      patch -p1 < "debian/patches/$i"
+    done
+  '';
+
+  preConfigure = ''
+    cd src
+    sed -i "/^STRIP/d" configure
+    sed -i "/\$STRIP/d" configure
+  '';
+
+  configureFlags = [ "--enable-release" ];
+
+  postInstall = ''
+    function installIcon () {
+        mkdir -p $out/share/icons/hicolor/$1/apps/
+        cp icons/$1x32.png $out/share/icons/hicolor/$1/apps/zsnes.png
+    }
+    installIcon "16x16"
+    installIcon "32x32"
+    installIcon "48x48"
+    installIcon "64x64"
+
+    mkdir -p $out/share/applications
+    ln -s ${desktopItem}/share/applications/* $out/share/applications/
+  '';
+
+  meta = {
+    description = "A Super Nintendo Entertainment System Emulator";
+    license = lib.licenses.gpl2Plus;
+    maintainers = [ lib.maintainers.sander ];
+    homepage = "https://www.zsnes.com";
+    platforms = [ "i686-linux" "x86_64-linux" ];
+  };
+}