Skip to content

Instantly share code, notes, and snippets.

@fsworld009
Last active January 1, 2026 13:33
Show Gist options
  • Select an option

  • Save fsworld009/191e19cdd551543a9e44846c70fd3f40 to your computer and use it in GitHub Desktop.

Select an option

Save fsworld009/191e19cdd551543a9e44846c70fd3f40 to your computer and use it in GitHub Desktop.
Bazzite + GPD Win 4 notes

Prerequisite:

  1. Turn on Secure Boot
  2. https://github.com/hhd-dev/hhd?tab=readme-ov-file#extra-steps-gpd-win-devices
    1. set L4 to SYSRQ and R4 to PAUSE

Decky https://github.com/honjow/GPD-WinControl https://github.com/hhd-dev/hhd-decky

fixes

https://github.com/aarron-lee/gpd-win-tricks/blob/main/win4-gyro-suspend-fix/README.md

GTK theme

It's blank by default. Flatpak apps seems using the dark theme fine out of box.

I changed the setting once and couldn't revert it back, now flatpak apps won't use dark theme.

Current workaround is to add global env var in Flatseal GTK_THEME=adw-gtk3-dark

Note: The default theme in ~/.config/gtk-3.0/settings.ini and ~/.config/gtk-4.0/settings.ini in a new install is empty (no entry)

Alternatively, install org.gtk.Gtk3theme.Breeze then set it in KDE settings

Desktop mode lock screen

No lock screen feature by default.

Can follow https://github.com/RHOPKINS13/SteamDeckScreenLock, but need to change the exec to

Exec=loginctl lock-session

Ref: https://www.reddit.com/r/kde/comments/av3riz/command_to_lock_the_screen/

Bonus: relax failure unlock timeouts https://gist.github.com/fsworld009/cb9a402ede96fa6087a2562d987e82be#relax-the-rule-to-lock-out-10-mins-after-3-login-fails

Meta+L shortcut: KDE shortcut settings -> add application shortcut -> Select the .desktop file we just created

Proton-Qt

  1. Doesn't detect Lutris: run lutris once
  2. Old GE-Proton version not listed anymore: manual download and extract to ~/.steam/root/compatibilitytools.d/

Syncthing

https://www.reddit.com/r/SteamDeck/comments/10pdz5m/nonsteam_cloud_saves_between_steam_deck_and /

change port from 8080 to 8384 https://www.reddit.com/r/SteamDeck/comments/xjmal2/psa_for_anyone_using_syncthing_and_decky_at_the/

https://github.com/theCapypara/steamdeck-decky-syncthing

Startup movie

https://www.reddit.com/r/SteamDeck/comments/1ctg62q/is_there_anyway_to_have_steam_play_a_custom_boot/

Not sure why it's not in one installation but you can copy it from another install (from ~/.local/share/Steam/config/uioverrides/movies)

fcitx5

Built in, but no https://github.com/openvanilla/fcitx5-mcbopomofo

Tried follow the guide to build on fedora distrobox, failed with

CMake Error at /usr/share/cmake/Modules/CMakeCompilerIdDetection.cmake:127 (message):
  No preprocessor test for "PathScale"
Call Stack (most recent call first):
  /usr/share/cmake/Modules/CMakeDetermineCompilerId.cmake:340 (compiler_id_detection)
  /usr/share/cmake/Modules/CMakeDetermineCompilerId.cmake:359 (CMAKE_DETERMINE_COMPILER_ID_WRITE)
  /usr/share/cmake/Modules/CMakeDetermineCompilerId.cmake:8 (CMAKE_DETERMINE_COMPILER_ID_BUILD)
  /usr/share/cmake/Modules/CMakeDetermineCompilerId.cmake:64 (__determine_compiler_id_test)
  /usr/share/cmake/Modules/CMakeDetermineCCompiler.cmake:123 (CMAKE_DETERMINE_COMPILER_ID)
  CMakeLists.txt:2 (project)

Use flatpak fcitx5 for now. However this seems to disable the built-in fcitx5 install so I have to install Mozc on flatpak as well, even though it was installed in system already.

Konsole as default terminal

The default terminal in vanilla KDE is Konsole. However, Konsole has been removed by in bazzite image even if using KDE flavor.

It was an intended change by devs ublue-os/bazzite#1933

As a result it's better to install Konsole from flatpak.

(Optional) Install Konsole as system package

If you insist installing konsole as system package:

sudo rpm-ostree install konsole

Note that this means every update would require additional step to reinstall konsole and its dependencies. Should be fine in this case since konsole doesn't require any other dependency on top of bazzite image.

Change default terminal

Default terminal is set to ptyxis which is the Gnome terminal. To us Konsole, change it to Konsole in KDE settings.

If using system konsole

After doing it there will be a new shortcut ~/.local/share/applications/konsole.desktop, can update it to

[Desktop Entry]
Exec=/usr/bin/konsole
Name=Konsole
Type=Application
Icon=utilities-terminal

So it's visible in start menu

Alternatively you can use https://github.com/dnkmmr69420/enable-konsole-on-bazzite

Regenerate Grub menu

https://universal-blue.discourse.group/t/dual-boot-preliminary-setup-and-post-setup-guide/2743

ujust regenerate-grub

Built-in Lutris

Cannot use Wine game -> Open Bash terminal option (no window opened)

observed from lutris -d that it is trying to run

/usr/bin/ptyxis -e /home/fsworld009/.cache/lutris/run_in_term.sh

Run it manually would result in

Unkwon option -e

Solution is to change Preferences -> Toggle "Advanced" Global options -> Text based game emulator -> change to /usr/bin/konsole

Current blocker: tried (WineGE 8-12 + Sonic P06), the game cannot detect Steam Input. The same setup works when using flatpak Lutris.

Decky Loader

Some plugins may be unable to run shell commands due to linked library error. This is observed in two plugins currently:

  1. decky-recorder: unable to run ffmpeg
    ffmpeg: /tmp/_MEIMA8QQr/libssl.so.3: version `OPENSSL_3.2.0' not found (required by /lib64/libcurl.so.4)
    
  2. decky-syncthing
    /usr/bin/flatpak: /tmp/_MEIMA8QQr/libssl.so.3: version `OPENSSL_3.2.0' not found (required by /lib64/libcurl.so.4)
    

For decky-recorder, I manually grabed the actual commands in terminal, it would work. Further debugging showed that plugin processes have this env var injected:

LD_LIBRARY_PATH=/tmp/_MEIMA8QQr/

If I added it to my terminal session then I can get the same error.

It doesn't seem like decky-loader is injecting this var on purpose, but the main loader is packaged by PyInstaller, which would utilize this env var, according to their doc: https://pyinstaller.org/en/stable/runtime-information.html#ld-library-path-libpath-considerations

For now we will need to manually unset this env var in plugin scripts as workaround.

Decky recorder

Need manual patches due to issue mentioned above. https://github.com/fsworld009/decky-recorder-fork/releases/tag/v0.0.1-bazzite-patch

More detailed report SDH-Stewardship/decky-recorder-fork#47 (comment)

Curently enabling recording would break screenshot. Observed the same with the new Steam Game Recording, reported to ValveSoftware/gamescope#1489

decky-syncthing

The main script is not python, cannot edit directly in bin, but we can change the main.py to launch the bin without this env var:

Update env passed in at https://github.com/theCapypara/steamdeck-decky-syncthing/blob/v0.1.0/main.py#L102 to

env={**dict(os.environ), **{'LD_LIBRARY_PATH': ''}}

systemctl

Game mode related services

systemctl --user status gamescope-session-plus@steam
systemctl status return-to-gamemode

Use differnet gamescope binary for game mode

For testing if the bug is only presented in current build

systenctl --user edit gamescope-session-plus@steam

Add GAMESCOPE_BIN override

[Service]
Environment="GAMESCOPE_BIN=/home/deck/.local/bin/gamescope_sd"

then save and exit. An service override will be created.

Note: doesn't work with gamescope installed on distrobox

Ref: https://serverfault.com/questions/413397/how-to-set-environment-variable-in-systemd-service

Distrobox

Create a container that can run gamescope without root

Ref

distrobox create gamescope --image ghcr.io/ublue-os/fedora-distrobox:latest --init-hooks "install -o 1000 -g 1000 -d /tmp/.X11-unix-new; mount --bind /tmp/.X11-unix-new /tmp/.X11-unix"
dsitrobox enter gamescope
sudo dnf install gamescope-3.14.2-1.fc40.x86_64
distrobox-export -b /usr/bin/gamescope
exit
~/.local/bin/gamescope

However, cannot use this binary as the GAMESCOPE_BIN in gamescope-session, would result in

vulkan: selecting physical device 'AMD Radeon 780M (RADV GFX1103_R1)': queue family 1 (general queue family 0)
vulkan: physical device supports DRM format modifiers
wlserver: [backend/headless/backend.c:67] Creating headless backend
wlserver: [libseat] [libseat/backend/seatd.c:64] Could not connect to socket /run/seatd.sock: No such file or directory
wlserver: [libseat] [libseat/libseat.c:76] Backend 'seatd' failed to open seat, skipping
wlserver: [libseat] [libseat/libseat.c:76] Backend 'logind' failed to open seat, skipping
wlserver: [libseat] [libseat/libseat.c:79] No backend was able to open a seat
wlserver: [backend/session/session.c:83] Unable to create seat: Function not implemented
wlserver: [backend/session/session.c:248] Failed to load session backend
wlserver: Failed to create session
Failed to initialize Wayland session
Failed to create backend.

I assume this is because the process inside distrobox cannot see host init processes

Add folders to lookup .so files

https://www.tecmint.com/understanding-shared-libraries-in-linux/

Add a new file in /etc/ld.so.conf.d for new paths, then run sudo ldconfig to refresh cache

(General linux ver) copy Steam games from other drive

If not using game mode, make sure you go to settings -> compatibility to choose a proton version as default.

Otherwise, Steam will think it cannot run Windows games and delete game files in common folder and and you will need to redownload them.

Downgrade built-in packages

ublue-os/bazzite#1914 (comment)

Example: downgrade ibus from 1.5.31 to 1.5.30

# Get an empty working folder
$ mkdir ibus-fix && cd ibus-fix

# Download packages
$ wget https://kojipkgs.fedoraproject.org/packages/ibus/1.5.30/6.fc41/x86_64/ibus-1.5.30-6.fc41.x86_64.rpm
$ wget https://kojipkgs.fedoraproject.org/packages/ibus/1.5.30/6.fc41/x86_64/ibus-gtk2-1.5.30-6.fc41.x86_64.rpm
$ wget https://kojipkgs.fedoraproject.org/packages/ibus/1.5.30/6.fc41/x86_64/ibus-gtk3-1.5.30-6.fc41.x86_64.rpm
$ wget https://kojipkgs.fedoraproject.org/packages/ibus/1.5.30/6.fc41/x86_64/ibus-gtk4-1.5.30-6.fc41.x86_64.rpm
$ wget https://kojipkgs.fedoraproject.org/packages/ibus/1.5.30/6.fc41/x86_64/ibus-libs-1.5.30-6.fc41.x86_64.rpm
$ wget https://kojipkgs.fedoraproject.org/packages/ibus/1.5.30/6.fc41/x86_64/ibus-panel-1.5.30-6.fc41.x86_64.rpm
$ wget https://kojipkgs.fedoraproject.org/packages/ibus/1.5.30/6.fc41/noarch/ibus-setup-1.5.30-6.fc41.noarch.rpm

# Perform downgrade
$ sudo rpm-ostree override replace * --remove ibus-xinit

# Reboot to apply changes
# Delete the `ibus-fix` folder if you want to

Veracrypt

Use official AppImage release.

Filesystem is Read-only when mounting NTFS partitions

First tried https://sourceforge.net/p/veracrypt/discussion/general/thread/71c9346768/ adding mount options as described (Settings -> Preferences -> Mount options)

uid=1000,gid=1000,umask=0022

(Use id command to get gid and uid). Doesn't work.

https://hardforum.com/threads/solved-linux-and-ntfs-read-only-volume-which-is-an-encrypted-container.1978265/

sudo ntfsfix /dev/mapper/veracrypt1

Then remount the partition.

Back to Windows, when mounting the drive, veracrypt warns disk error and prompt to run disk repair. Doing so seems to fix read/write on both Windows and Linux.

Waydroid

(Framework 13) https://docs.bazzite.gg/Installing_and_Managing_Software/Waydroid_Setup_Guide/

Document is outdated, now Waydroid defaults to Android 13 (Lineage 20)

# ujust setup-waydroid -> init
        This might take a bit, please be patient
[17:51:33] Found directory /etc/waydroid-extra/images but missing system or vendor image, ignoring...
[17:51:34] Downloading https://sourceforge.net/projects/waydroid/files/images/system/lineage/waydroid_x86_64/lineage-20.0-20250726-VANILLA-waydroid_x86_64-system.zip/download
[Downloading] 830.73 MB/830.79 MB    38199.49 kbps(approx.)[17:51:56] Validating system image
[17:51:57] Extracting to /var/lib/waydroid/images
[17:52:01] Downloading https://sourceforge.net/projects/waydroid/files/images/vendor/waydroid_x86_64/lineage-20.0-20250726-MAINLINE-waydroid_x86_64-vendor.zip/download
[Downloading]  171.9 MB/171.96 MB    38620.67 kbps(approx.)[17:52:06] Validating vendor image
[17:52:06] Extracting to /var/lib/waydroid/images

Need to manually download and place images for Android 11 waydroid/waydroid#1662 (comment)

But Android 13 is better in general.

GApps and ARM translator

ujust setup-waydroid

Install gapps + libhoudini

Sonic Rumble

Need to use libhoudini even on AMD GPU.

Game caps at 30fps, it's set by game, nothing can be done here.

Clipboard sharing

Should work, but seems only start working after copy once inside Waydroid.

(FW16)

need to switch to dGPU, and cannot use waydroid-launcher properly (click doesn't work)

Need to reconfig GPU after any ujust setup-waydroid changes

Configs after init setup

  1. Volume too low -> change in Settings
  2. Start button triggers Google assistant -> Change default assistant app to None
  3. Install GBoard for CHT/JAP input (Shift+Space cycle throughs IMEs)
  4. Disable bg input? Seems break controller input in multi window mode https://docs.bazzite.gg/Installing_and_Managing_Software/Waydroid_Setup_Guide/#disable-inputs-to-waydroid-when-unfocused

(Optional) Multi window modedow https://docs.waydro.id/usage/install-on-desktops#launch-waydroid-in-multi-window-mode

Some apps like Line are displayed like a regular Linux win. Some games still run in fullscreen, need to workaround with scrcpy in this case, see below.

Shared folder

https://docs.waydro.id/faq/setting-up-a-shared-folder

Shortcuts

On Android 11, all apps will have shortcuts automatically creeated in ~/.local/usr/applications, seems not the case anymore in 13 images.

But we can still manually create with below template

waydroid.com.android.settings.desktop

[Desktop Entry]
Type=Application
Name=Settings
Exec=waydroid app launch com.android.settings
Icon=/home/fsworld009/.local/share/waydroid/data/icons/com.android.settings.png
Categories=X-WayDroid-App;
X-Purism-FormFactor=Workstation;Mobile;
Actions=app_settings;

[Desktop Action app_settings]
Name=App Settings
Exec=waydroid app intent android.settings.APPLICATION_DETAILS_SETTINGS package:com.android.settings
Icon=/home/fsworld009/.local/share/waydroid/data/icons/com.android.settings.png

com.android.settings is the app ID for Settings App. change it to the app you want to launch

Can also use waydroid app list to get all installed apps and their ID.

scrcpy tricks

https://ivonblog.com/posts/waydroid-scrcpy/

Can workaround fullscreen games

Flatpak: guiscrcpy also works

To set custom resolution, use these scrcpy args:

--window-width 2560 --window-height 1440

If Waydroid ADB is not started: https://docs.waydro.id/faq/using-adb-with-waydroid

mouse click not working

It seems that mouse only works in internal screen when running waydroid-launch

The only workaround I can find now is to manually start session waydroid session start, then use scrcpy to connect

Custom width / height

It seems the Width and height flags used by waydroid-launcher doesn't really work.

We need to instead edit the waydroid prop directly

# permanent
sudo waydroid prop set persist.waydroid.width 1920
sudo waydroid prop set persist.waydroid.height 1080
# Temp
sudo waydroid shell wm size 1920x1080

Then launching scrcpy with the matched resolution would work.

2025/11/15 Cannot copy from host to Wine app

https://www.reddit.com/r/Bazzite/comments/1orvi8f/cant_copy_from_linux_app_to_wine_game/

https://bugs.kde.org/show_bug.cgi?id=511063 Fixed in Plasma 6.5.2

Potential Workaround https://forums.eveonline.com/t/proton-on-wayland-broken-clipboard-paste-potential-fix-for-it/499995

Hibernate

Open a terminal and edit the systemd sleep configuration file with administrative privileges (using sudo or similar). bash sudo nano /etc/systemd/sleep.conf Locate the line containing #HibernateDelaySec=. Uncomment the line (remove the # at the beginning) and set the value to 20min (or 1200 seconds). The file section should look like this:

[Sleep]
# ... other settings
HibernateDelaySec=20min
# ... other settings

Save the file and exit the editor.

Restart the systemd logind service for the changes to take effect immediately without a full reboot. bash

sudo systemctl restart systemd-logind

Mount APFS partition

Need distrobox root container

sudo dnf install apfs-fuse
sudo apfs-fuse -o uid=1000,gid=1000,allow_other /dev/sda1 /mnt/mac_drive

Veracrypt + NTFS

  1. Create the VeraCrypt volume without a filesystem
  2. Mount the volume
  3. sudo mkfs.ntfs /dev/mapper/veracrypt1
    

Use gamescope in desktop mode

For steam game, need to set DISPLAY in order to have Steam overlay enabled properly:

ValveSoftware/gamescope#835

gamescope -W 1920 -H 1080 & DISPLAY=:1 %command%

Note the value of DISPLAY might change (based on how many monitors are in use?). It's better to run gamescope in terminal once to see the assigned display

> gamescope
...
[gamescope] [Info]  wlserver: [xwayland/server.c:107] Starting Xwayland on :1

eGPU

https://github.com/ewagner12/all-ways-egpu

  1. Guided setup
  2. lookup primary eGPU -> set to eGPU (y to confirm)
  3. lookup iGPU -> set phoenix to iGPU (y to confirm)
  4. extra options: y for method 1 (for enabling igpu afterboot), 2, and 3
  5. Add polkat rule for fallback to igpu https://github.com/ewagner12/all-ways-egpu?tab=readme-ov-file#extra-steps

Game settings

MAME Snow bros 2

Machine Configuration -> change to Japan region for better character mugshots.m

Rom hacks

Rockman & Forte

MSU-1 https://www.zeldix.net/t1478-rockman-forte-msu-1 Multiple Equipment: https://www.romhacking.net/reviews/9861/

ips apply order should be MSU-1 -> Multiple Equipment

Mega Man 7

Redux -> MSU1

Mega Man X3 Zero Project

Zero pj 4.8 -> mmx3_msu1_drlight_zero_new.ips

Extreme Gear Lab Sonic Riders

Patch is done by their program, which only targets Windows

Lutris -> create new game, runner wine-10.10-amd64-wow64 (Seems require manually select x64 prefix) winetricks: corefonts dotnetdesktop8 Manually download and install 7zip and dotnet desktop runtime 5 https://dotnet.microsoft.com/en-us/download/dotnet/5.0

Now you should be able to run patcher

dotnetdesktop 7 -> Used by DX dotnetdesktop5 -> Used by Regravitified

Shadow the hedgehog reloaded + JP Voice

US ISO

  1. Apply Reloaded US Widescreen
  2. Extract ISO
  3. Backup sound/B81_FINALDOOM.ml
  4. Apply US_JPVoice_Retranslate (don't apply csdFiles folders, need fonts folder because it contains retranslation scripts)
  5. Revert B81_FINALDOOM.ml
  6. Test the game by adding path/to/sys folder
  7. Reconstruct ISO (Right click -> Convert file)

JP ISO Region and audio becomne US after apply Reloaded, not preffered.

Irregular Hunter X vile music patch

There is one for US version (MHX), can we do the same to JP version?

https://www.romhacking.net/hacks/6350/

Or use undub patch https://archive.org/details/mega_man_mhx_undub_patch

The patch only touched rockx_pack.dat, so we should see how to patch it for JP version.

rockx_pack.dat archive extractor script https://www.zenhax.com/viewtopic.php@t=1278.html

extract_link.bms

# extract the rockx_pack.dat/.loc from Maverick Hunter
# written by AlphaTwentyThree of Zenhax
# script for QuickBMS http://quickbms.aluigi.org

include "func_getTYPE.bms"
open FDDE loc 0
open FDDE dat 1

get FILES asize 0
math FILES /= 8

for i = 1 <= FILES
   get OFFSET long 0
   get SIZE long 0
   get NAME basename 0
   string NAME p= "%s_%d" NAME i
   savepos MYOFF 0
   putVarChr MEMORY_FILE SIZE 0
   log MEMORY_FILE 0 0
   append
   log MEMORY_FILE OFFSET SIZE 1
   append
   callfunction getTYPE 1
   goto MYOFF 0
   string NAME += EXT
   log NAME 0 SIZE MEMORY_FILE
   # callfunction write_unlisted 1

next i

startfunction write_unlisted
   savepos MYOFF 0
   math OFFSET += SIZE
   if i != FILES
      get OFFSET2 long 0
   else
      get OFFSET2 asize 1
   endif
   goto MYOFF 0
   if OFFSET2 > OFFSET
      set SIZE OFFSET2
      math SIZE -= OFFSET
      string NAME p= "unlisted/%s.unlisted" NAME
      log NAME OFFSET SIZE 1
   endif
endfunction

extract_dat.bms

# extract *.link files from Maverick Hunter X
# written by AlphaTwentyThree of Zenhax
# script for QuickBMS http://quickbms.aluigi.org

include "func_getTYPE.bms"

idstring "LINK"
get FILES byte
get VER byte
get UNK short
for i = 1 <= FILES
   get UNK short
   get TYPE short
   get OFFSET long
   get SIZE long
   get ZERO long
   get NAME basename
   string NAME p= "%s_%d" NAME i
   putVarChr MEMORY_FILE SIZE 0
   log MEMORY_FILE 0 0
   append
   log MEMORY_FILE OFFSET SIZE
   append
   callfunction getTYPE 1
   string NAME += EXT
   log NAME 0 SIZE MEMORY_FILE
next i

Need quickbms

func_getTYPE.bms 2013 ver https://github.com/clowd81/rift_datamine_tools/blob/master/Audio%20Tools/func_getTYPE.bms 2022 ver https://reshax.com/files/file/751-func_gettypebms/

func_getTYPE.bms

# determine file type via various heuristics
# (c) 2022-01-10 by AlphaTwentyThree of XeNTaX

startfunction getTYPE
	set TQUIT 0 # quit marker
	set EXT ""
	set TYPESTRING ""
	set ZNAME ""
	endian little
	goto 0 MEMORY_FILE
	get MSIZE asize MEMORY_FILE
	if MSIZE > 3
		for STR = 1 <= 4 # determine if string identifier (only first three bytes)
			get TEST byte MEMORY_FILE
			if TEST < 0x20
				break
			elif TEST > 0x7e
				break
			endif
		next STR
		math STR -= 1
		goto 0 MEMORY_FILE
		if STR == 4
			getDstring TYPE 4 MEMORY_FILE
			if TYPE == ""
			elif TYPE == "<?xm"
				set EXT ".xml"
			elif TYPE == "BFFB"
				set EXT ".bf"
			elif TYPE == "CIDS"
				set EXT ".cid"
			elif TYPE == "PAD "
				set EXT ".pad"
			elif TYPE == "GAWB"
				set EXT ".gawb"
			elif TYPE == "PBUK"
				set EXT ".pbuk"
			elif TYPE == "0DAW"
				set EXT ".wad"
			elif TYPE == "PROT"
				set EXT == ".prot"
			elif TYPE == "PINF"
				set EXT == ".pinf"
			elif TYPE == "FACE"
				set EXT == ".face"
			elif TYPE == "DBLB"
				set EXT == ".dblb"
			elif TYPE == "SCPT"
				set EXT == ".scpt"
			elif TYPE == "<!--"
				set EXT == ".xml"
			elif TYPE == "OMG."
				set EXT ".omg"
			elif TYPE == "MIG."
				set EXT ".mig"
			elif TYPE == "1SNh"
				set EXT ".tgv" # Electronic Arts TGV movie
			elif TYPE == "TAE "
				set EXT ".tae"
			elif TYPE == "30GF"
				set EXT ".fpg" # FPG archive
			elif TYPE == "49SB"
				set EXT ".49sb" # Summer Stars 2012 archive
			elif TYPE == "4ACS"
				set EXT ".sca" # NDS-specific
			elif TYPE == "AIXF"
				set EXT ".aix" # Cri Engine aix audio file
			elif TYPE == "AKPK"
				set EXT ".pak" # AKPK pack
			elif TYPE == "BCA0"
				goto 8 MEMORY_FILE
				get SSIZE long MEMORY_FILE
				if SSIZE == MSIZE
					set EXT ".nsbca" # NDS 3d graphic
				endif
			elif TYPE == "BG"
				goto 0 MEMORY_FILE
				get TYPE long MEMORY_FILE
				if TYPE == 0x1002742
					goto 8 MEMORY_FILE
					get SSIZE long MEMORY_FILE
					math SSIZE += 0x14
					if SSIZE == MSIZE
						set EXT ".bmp" # bitmap picture
					endif
				endif
			elif TYPE == "BIKi"
				goto 4 MEMORY_FILE
				get SSIZE long MEMORY_FILE
				math SSIZE += 8
				if SSIZE == MSIZE
					set EXT ".bik" # bink video
				endif
			elif TYPE == "BKHD"
				set EXT ".bnk" # Wwise sound bank
			elif TYPE == "BMD0"
				set EXT ".nsbmd" # NDS-specific
			elif TYPE == "BND3"
				set EXT ".bnd"
			elif TYPE == "BTX0"
				goto 8 MEMORY_FILE
				get SSIZE long MEMORY_FILE
				if SSIZE == MSIZE
					set EXT ".nsbtx" # NDS-specific
				endif
			elif TYPE == "CHNK"
				set EXT ".pak.xen" # Guitar Hero compressed audio file
			elif TYPE == "CPK "
				set EXT ".cpk" # CRI cpk archive
			elif TYPE == "CRUS"
				goto 0 MEMORY_FILE
				getDstring TYPE 8
				if TYPE == "CRUSHDM!"
					set EXT ".ds" # NDS-specific
				endif
			elif TYPE == "DCX"
				set EXT ".dcx"
			elif TYPE == "DDS "
				set EXT ".dds" # DDS model
			elif TYPE == "DDSx"
				set EXT ".ddsx" # Extended DDS model
			elif TYPE == "DIFF"
				set EXT ".diff" # NDS-specific
			elif TYPE == "DNBW"
				set EXT ".xwb" # Xact Wave Bank
			elif TYPE == "ea3"
				goto 0xa MEMORY_FILE
				getDstring IDENT 4 MEMORY_FILE
				if IDENT == "GEOB"
					set EXT ".aa3" # Atrac3+ audio file
				endif
			elif TYPE == "Exte"
				set EXT ".xm" # Extended Module (Tracker)
			elif TYPE == "EZ00"
				set EXT ".ez" # EZ-compressed file
			elif TYPE == "EZ10"
				set EXT ".ez" # EZ-compressed file
			elif TYPE == "FEVl"
				set EXT ".fev" # FEV file
			elif TYPE == "FEV1"
				set EXT ".fev"
			elif TYPE == "fknc"
				set EXT ".crf" # CRF 3D model
			elif TYPE == "FORM"
				goto 0x8 MEMORY_FILE
				getDstring CODE 4 MEMORY_FILE
				if CODE == "AIFF"
					set EXT ".aiff" # AIFF sound form
				endif
			elif TYPE == "FSB3"
				set EXT ".fsb" # FSB3 archive
			elif TYPE == "FSB4"
				set EXT ".fsb" # FSB4 archive
			elif TYPE == "FSB5"
				set EXT ".fsb" # FSB5 archive
			elif TYPE == "FSGX"
				set EXT ".xgs" # Xact GS descriptor
			elif TYPE == "FUNl"
				set EXT ".fun" # MIB: Alien Crisis FUN container
			elif TYPE == "GRP1"
				set EXT ".grp" # GRP archive
			elif TYPE == "HVQM"
				set EXT ".h4m" # H4M movie
			elif TYPE == "INDA"
				set EXT ".data" # data pack (Agricultural Simulator)
			elif TYPE == "Inno"
				set ZNAME "unins000.dat" # uninstall data file
			elif TYPE == "KBDS"
				set EXT ".xsb" # Xact Sound Bank
			elif TYPE == "mhwa"
				set EXT ".mh" # NDS-specific
			elif TYPE == "MIPh"
				set EXT ".mip"
			elif TYPE == "MODS"
				set EXT ".mods" # NDS mods movie
			elif TYPE == "MOIK"
				set EXT ".kev_bdl" # Worms: Reloaded bundle
			elif TYPE == "MSCF"
				set EXT ".cab" # CAB archive
			elif TYPE == "mshd"
				set EXT ".mshdf" # Xbox 360 mshd file
			elif TYPE == "MULA"
				set EXT ".mula" # MIB3 MULA archive
			elif TYPE == "MUSX"
				set EXT ".musx" # MUSX sound container
			elif TYPE == "NARC"
				goto 8 MEMORY_FILE
				get SSIZE long MEMORY_FILE
				if SSIZE == MSIZE
					set EXT ".narc" # NDS-specific
				endif
			elif TYPE == "NTRO"
				goto 4 MEMORY_FILE
				get SSIZE long MEMORY_FILE
				if SSIZE == MSIZE
					set EXT ".nitro_archive" # NDS nitro archive
				endif
			elif TYPE == "OggS"
				goto 0x1c MEMORY_FILE
				get TEST string MEMORY_FILE
				if TEST == "fishead"
					set EXT ".ogm"
				else
					set EXT ".ogg" # ogg container
				endif
			elif TYPE == "PACK"
				set EXT ".pac" # NDS-specific
			elif TYPE == "PAL1"
				set EXT ".pal" # palette
			elif TYPE == "PIRS"
				set EXT ".pirs" # XBLA pirs archive
			elif TYPE == "PSIS"
				goto 0 MEMORY_FILE
				getDstring TEST 8 MEMORY_FILE
				if TEST == "PSISOIMG"
					set EXT ".psar" # Playstation emulation image (PSN)
				endif
			elif TYPE == "QRK."
				set EXT ".qrk" # NDS-specific
			elif TYPE == "RGCN"
				goto 8 MEMORY_FILE
				get SSIZE long MEMORY_FILE
				if SSIZE == MSIZE
					set EXT ".ncgr" # NDS-specific
				endif
			elif TYPE == "RIFF"
				callfunction getWaveType 1
			elif TYPE == "RIFX"
				endian big
				callfunction getWaveType 1
				endian little
			elif TYPE == "RLCN"
				goto 8 MEMORY_FILE
				get SSIZE long MEMORY_FILE
				if SSIZE == MSIZE 
					set EXT ".nclr" # NDS graphic
				endif
			elif TYPE == "RPF4"
				set EXT ".rpf" # RPF4 container
			elif TYPE == "RPGN"
				set EXT ".npgr" # NDS-specific
			elif TYPE == "RTFN"
				set EXT ".nftr" # NDS-specific
			elif TYPE == "sawh"
				goto 0x14 MEMORY_FILE
				get SSIZE long MEMORY_FILE
				math SSIZE += 0x200
				if SSIZE == MSIZE
					set EXT ".hwas" # NDS IMA ADPCM audio
				endif
			elif TYPE == "SDAT"
				goto 8 MEMORY_FILE
				get SSIZE long MEMORY_FILE
				if SSIZE == MSIZE
					set EXT ".sdat" # Nintendo DS sdat sound archive
				endif
			elif TYPE == "SMPK"
				set EXT ".spk" # NDS sound pack
			elif TYPE == "SMV1"
				set EXT ".smv" # smv movie
			elif TYPE == "SWAV"
				goto 8 MEMORY_FILE
				get SSIZE long MEMORY_FILE
				if SSIZE == MSIZE
					set EXT ".swav" # swav audio
				endif
			elif TYPE == "TEX1"
				set EXT ".tex" # texture
			elif TYPE == "TEX2"
				set EXT ".tex" # texture
			elif TYPE == "THP"
				set EXT ".thp" # THP multimedia file
			elif TYPE == "TNFS"
				set EXT ".fnt" # font
			elif TYPE == "TPF"
				set EXT ".tpf"
			elif TYPE == "VXDS"
				goto 0x28 MEMORY_FILE
				get SSIZE long MEMORY_FILE
				math SSIZE += 8
				if SSIZE == MSIZE
					set EXT ".vx" # Nintendo DS VX movie
				endif
			elif TYPE == "XEX2"
				set EXT ".xex" # Xbox 360 xex file
			elif TYPE == "XPR2"
				set EXT ".xpr"
			elif TYPE == "VRFS"
				goto 4 MEMORY_FILE
				getDstring TYPE 3 MEMORY_FILE
				if TYPE == "X360"
					set EXT ".vromfs.bin" # Xbox 360 rom file
				endif
			elif TYPE == "XMNP"
				set EXT ".manifest" # Xbox 360 $SystemUpdate manifest
			elif TYPE == "BDF3"
				set EXT ".bdt" # Dark Souls bdt archive
			elif TYPE == "BHF3"
				set EXT ".bhd"
			elif TYPE == "MVhd"
				set EXT ".vp6" # Electronic Arts VP6 video
			elif TYPE == "BGFA"
				set EXT ".ast" # Electronic Arts BGFA container
			elif TYPE == "GD.S"
				set EXT ".gd"
			elif TYPE == "LOCH"
				set EXT ".loc" # location file
			elif TYPE == "SEVT"
				set EXT ".sev"
			elif TYPE == "CPK0"
				set EXT ".cpk" # Capcom cpk file (unknown usage)
			elif TYPE == "AAAp"
				set EXT ".aaa" # stereo VAG audio file
			elif TYPE == "VAGp"
				set EXT ".vag" # mono Playstation ADPCM file
			elif TYPE == "BJBO"
				set EXT ".bjb"
			elif TYPE == "CFOM"
				set EXT ".cfo"
			elif TYPE == "RFOM"
				set EXT ".rfo"
			elif TYPE == "PLZP"
				set EXT ".plz"
			elif TYPE == "PIFF"
				set EXT ".pif"
			elif TYPE == "LANG"
				set EXT ".lang"
			elif TYPE == "PSND"
				set EXT ".psnd"
			elif TYPE == "VBSP"
				set EXT ".bsp" # Half-Life 2 map
			elif TYPE == "pmCx"
				set EXT ".xz_" # compressed Half-Life 2 archive
			elif TYPE == "DMAV"
				set EXT == "dmav"
			elif TYPE == "AUS "
				set EXT ".aus"
			elif TYPE == "WANM"
				set EXT ".wan"
			elif TYPE == "MSF0"
				set EXT ".msf"
			elif TYPE == "MUPS"
				set EXT ".mups"
			elif TYPE == "D11M"
				set EXT ".mesh"
			endif
			if EXT != ""
				set TQUIT 1
			endif
		elif STR == 3
			goto 0 MEMORY_FILE
			getDstring TYPE 3 MEMORY_FILE
			if TYPE == "SG2"
				set EXT ".sg2" # XBLA sg2 file
				goto 0x14 MEMORY_FILE
				get ZNAME string MEMORY_FILE
			elif TYPE == "RSF"
				set EXT ".rsf" # rsf file
			elif TYPE == "LOC"
				set EXT ".loc" # location file
			elif TYPE == "DCX"
				set EXT ".dcx"
			elif TYPE == "DRB"
				set EXT ".drb"
			elif TYPE == "TPF"
				set EXT ".tpf"
			elif TYPE == "TAE"
				set EXT ".tae"
			elif TYPE == "ID3"
				set EXT ".mp3"
			elif TYPE == "MYP" # SW:TOR archive
				set EXT ".tor"
			endif
			if MSIZE > 0x10
				goto 0xc MEMORY_FILE
				getDstring TYPE 4 MEMORY_FILE
				if TYPE == "NTRJ"
					set EXT ".srl" # NDS-specific
				endif
			endif
			if EXT != ""
				set TQUIT 1
			endif
		elif STR == 2
			goto 0 MEMORY_FILE
			getDstring TYPE 2 MEMORY_FILE
			if TYPE == "MZ"
				goto 0xd0 MEMORY_FILE
				get TEST string MEMORY_FILE
				if TEST == "PE"
					set EXT ".exe" # Executable Program
				elif TEST == "Rich"
					set EXT ".dll" # dynamic link library (dll)
				endif
			elif TYPE == "DB"
				set EXT ".db" # database file
			elif TYPE == "SD"
				set EXT ".sd"
			endif
			if EXT != ""
				set TQUIT 1
			endif
		elif STR == 1
			goto 0 MEMORY_FILE
			get TYPE long MEMORY_FILE
			if TYPE == 0x6e003c
				set EXT ".node"
				set TQUIT 1
			elif TYPE == 0x210a0d21
				set EXT ".particle"
				set TQUIT 1
			endif
		elif STR == 0 # REMEMBER: set TQUIT to 1 if valid type is found!
			get TYPE long MEMORY_FILE
			if TYPE == 0x20000080
				set EXT ".adx" # CRI adx or ahx audio
				set TQUIT 1
			elif TYPE == 0x3cbfbbef
				set EXT ".xml"
				set TQUIT 1
			elif TYPE == 0x24000080
				set EXT ".adx" # CRI adx audio
				set TQUIT 1
			elif TYPE == 0x1c010080
				set EXT ".adx" # CRI adx audio file
				set TQUIT 1
			elif TYPE == 0x0d0d0d0d
				set EXT ".p256" # NDS 256p video
				set TQUIT 1
			elif TYPE == 0x401000
				goto 6 MEMORY_FILE
				getDstring TYPE 3
				if TYPE == "spx"
					set EXT ".spx" # NDS-specific
					set TQUIT 1
				endif
			elif TYPE == 0x474e5089
				set EXT ".png" # PNG picture
				set TQUIT 1
			elif TYPE == 0x75b22630
				set EXT ".wmv" # WMV video
				set TQUIT 1
			elif TYPE == 0x3032802
				set EXT ".ubipack" # Ubisoft sound pack
				set TQUIT 1
			elif TYPE == 0x80087322
				set EXT ".lds" # lds file (Worms: Reloaded)
				set TQUIT 1
			elif TYPE == 0xc000048
				set EXT ".sps" # EA sps audio file
				set TQUIT 1
			elif TYPE == 0x20000000
				goto 4 MEMORY_FILE
				getDstring TYPE 8 MEMORY_FILE
				if TYPE == "ftypM4A "
					set EXT ".m4a" # m4a audio file
					set TQUIT 1
				endif
			elif TYPE == 0xba010000
				set EXT ".mpg" # MPG video file
				set TQUIT 1
			elif TYPE == 0xba010000
				get TEST long MEMORY_FILE
				if TEST == 0x040044
					set EXT ".pss" # PSS movie (PS2)
					set TQUIT 1
				endif
			elif TYPE == 0xba010000
				set EXT ".pss"
				set TQUIT 1
			endif # type without string
			if TQUIT == 0
				goto 0 MEMORY_FILE
				get TYPE short MEMORY_FILE
				if TYPE == 0x7c1f
					set EXT ".tsb" # NDS-specific
					set TQUIT 1
				elif TYPE == 0xfbff
					set EXT ".mp3" # MPEG Layer3 audio file
					set TQUIT 1
				endif
			endif # TQUIT
			if TQUIT == 0
				goto 0 MEMORY_FILE
				get TYPE threebyte MEMORY_FILE
				if TYPE == 0x445242
					set EXT ".brd"
					set TQUIT 1
				endif
			endif # TQUIT
			if TQUIT == 0
				if MSIZE > 0x8
					goto 4 MEMORY_FILE
					getDstring TYPE 4 MEMORY_FILE
					if TYPE == "DAEH"
						set EXT ".ppp" # NDS ppp graphic
						set TQUIT 1
					endif
					if TQUIT == 0
						goto 5 MEMORY_FILE
						getDstring TYPE 3 MEMORY_FILE
						if TYPE == "TSF"
							set EXT ".tsf" # NDS tsf graphic
							set TQUIT 1
						endif
					endif
					if TQUIT == 0
						goto 4 MEMORY_FILE
						get TYPE threebyte MEMORY_FILE
						if TYPE == 0x041203
							set EXT ".adx" # CRI audio file
							set TQUIT 1
						endif
					endif
				endif
			endif
			if TQUIT == 0
				if MSIZE > 0xa
					goto 6 MEMORY_FILE
					getDstring TYPE 4 MEMORY_FILE
					if TYPE == "JFIF"
						set EXT ".jpg" # JPG picture
						set TQUIT 1
					elif TYPE == "Exif"
						set EXT ".jpg" # JPG picture
						set TQUIT 1
					endif
				endif
				if TQUIT == 0
					if MSIZE > 0x10
						goto 8 MEMORY_FILE
						getDstring TYPE 8 MEMORY_FILE
						if TYPE == "matroska"
							set EXT ".mkv" # MKV video
						endif
					endif
				endif
			endif # TQUIT
		endif # no string at start
	endif
	if TQUIT == 0
		if MSIZE >= 4
			goto 0 MEMORY_FILE
			get TYPE long MEMORY_FILE
			reverselong TYPE
			string TYPE p= ".%08x" TYPE
			set EXT TYPE
			set TYPESTRING "unknown (identifier: 0x%TYPE%)"
		else
			set TYPESTRING "unknown (file too small)"
		endif
	endif
	string NAME p "%s%s" NAME EXT
endfunction
startfunction getWaveType
	goto 8 MEMORY_FILE
	getDstring TYPE 8 MEMORY_FILE
	if TYPE == "WAVEfmt "
		goto 0x14 MEMORY_FILE
		get CODEC short MEMORY_FILE
		if CODEC == 0x0165
			set EXT ".xma"
		elif CODEC == 0x0166
			set EXT ".xma"
		elif CODEC == 0x6501
			set EXT ".xma"
		elif CODEC == 0x6601
			set EXT ".xma"
		elif CODEC == 0x7002
			set EXT ".at3"
		elif CODEC == 0x161
			set EXT ".xWMA"
		elif CODEC == 0xffff
			set EXT ".wem"
		elif CODEC == 0x69
			set EXT ".lwav"
		elif CODEC == 0x11
			set EXT ".lwav"
		elif CODEC == 2
			set EXT ".lwav"
		elif CODEC == 1
			set EXT ".wav"
		elif CODEC == 0xfffe
			set EXT ".at3"
		else
			set EXT ".wav_unknown"
		endif
	elif TYPE == "AVI LIST"
		set EXT ".avi" # avi movie
	elif TYPE == "MVI_LIST"
		set EXT ".mvi" # mvi movie
	elif TYPE == "XWMAfmt "
		set EXT ".xwma" # Extended WMA
	else
		set EXT ".wav_unknown"
		set TYPESTRING "unknown wave format"
	endif
endfunction

Rename rockx_pack.loc to rockx_pack.LOC

./quickbms  ../extract_dat.bms ../MHX/PSP_GAME/USRDIR/rockx_pack.dat ../MHX/extracted/
./quickbms  ../extract_link.bms ../MHX/extracted/ ../MHX/extracted/link

Seems generating the same results (some files are unable to be extracted):

 signature of 4 bytes at offset 0x00000000 doesn't match the one
  expected by the script:

  this one: "PSMF"
  50 53 4d 46                                       PSMF

  expected: "LINK"
  4c 49 4e 4b                                       LINK

Compare vanilla v.s. vile music fix patched MHX with md5sum https://askubuntu.com/questions/421712/comparing-the-contents-of-two-directories

❯ diff -u MHX.txt MHX_patched.txt
--- MHX.txt	2025-07-26 13:38:16.372918641 +0800
+++ MHX_patched.txt	2025-07-26 13:38:51.588760691 +0800
@@ -592,7 +592,7 @@
-4341b4a2c7456fd90bb403ea15327aff  ./MHX/extracted/link/rockx_pack_26_114.wav_unknown
+9d7dbe8185ec8395f90ed8fba1c71929  ./MHX/extracted/link/rockx_pack_26_114.at3
@@ -921,7 +921,7 @@
-4341b4a2c7456fd90bb403ea15327aff  ./MHX/extracted/link/rockx_pack_30_126.wav_unknown
+630fca3876b902805f670e762a7dfa1b  ./MHX/extracted/link/rockx_pack_30_126.wav_unknown
@@ -1216,7 +1216,7 @@
-4341b4a2c7456fd90bb403ea15327aff  ./MHX/extracted/link/rockx_pack_34_121.wav_unknown
+dc6210511ccc5c9fc98beca82e725984  ./MHX/extracted/link/rockx_pack_34_121.at3
@@ -1544,7 +1544,7 @@
-4341b4a2c7456fd90bb403ea15327aff  ./MHX/extracted/link/rockx_pack_38_140.wav_unknown
+ce0f8e104f90cfd92245e1917c49ecee  ./MHX/extracted/link/rockx_pack_38_140.at3
@@ -1821,7 +1821,7 @@
-4341b4a2c7456fd90bb403ea15327aff  ./MHX/extracted/link/rockx_pack_42_116.wav_unknown
+8ac6ad915ee70319de472d8b99c22b72  ./MHX/extracted/link/rockx_pack_42_116.at3
@@ -2099,7 +2099,7 @@
-4341b4a2c7456fd90bb403ea15327aff  ./MHX/extracted/link/rockx_pack_46_118.wav_unknown
+c85e77ecc910d96038816814a18157ba  ./MHX/extracted/link/rockx_pack_46_118.at3
@@ -2505,7 +2505,7 @@
-4341b4a2c7456fd90bb403ea15327aff  ./MHX/extracted/link/rockx_pack_51_101.wav_unknown
+06708d5d33377bd08574aef8be7a6585  ./MHX/extracted/link/rockx_pack_51_101.at3
@@ -2621,7 +2621,7 @@
-4341b4a2c7456fd90bb403ea15327aff  ./MHX/extracted/link/rockx_pack_52_101.wav_unknown
+06708d5d33377bd08574aef8be7a6585  ./MHX/extracted/link/rockx_pack_52_101.at3
@@ -2973,7 +2973,7 @@
-4341b4a2c7456fd90bb403ea15327aff  ./MHX/extracted/link/rockx_pack_56_96.wav_unknown
+0593bc39fbaa534246e7291dbb17ee0b  ./MHX/extracted/link/rockx_pack_56_96.at3

It looks like vile theme is copied multiple times in the archive, and the vile music patch is to replace them with corresponding stage themes.

If we want to do this for JP version, we will need to know

  1. correctly extract all files in archive
  2. how to repack them after file replacement.

For now I think playing US version with undub patch is good enough.

More info on cpk (3D model?) extraction

QuickBMS reimport guide

https://zenhax.com/viewtopic.php@t=22.html

2025/12/16

Vava Music patch for JP version created (no public link yet)

The general idea is to patch the 9 related pack files in rockx_pack.dat, then replace this file in the ISO.

Steps:

  1. Prepare pack files, new music with correct file names

We already know the target packs and files based on diff. The extract script would add CRC and extension names on extract, we need to remove them before reimport:

(rockx_pack_XX_XXX is the music file from patched US version and rockx_pack_XX is the pack file extracted from rockx_pack.dat)

├── 26
│   └── rockx_pack_26_114
├── 30
│   └── rockx_pack_30_126
├── 34
│   └── rockx_pack_34_121
├── 38
│   └── rockx_pack_38_140
├── 42
│   └── rockx_pack_42_116
├── 46
│   └── rockx_pack_46_118
├── 51
│   └── rockx_pack_51_101
├── 52
│   └── rockx_pack_52_101
├── 56
│   └── rockx_pack_56_96
└── packs
    ├── rockx_pack_26
    ├── rockx_pack_30
    ├── rockx_pack_34
    ├── rockx_pack_38
    ├── rockx_pack_42
    ├── rockx_pack_46
    ├── rockx_pack_51
    ├── rockx_pack_52
    └── rockx_pack_56
  1. Reimport new music to pack files This would utilize quickbms's reimport mode, which require the extractor script

See https://zenhax.com/viewtopic.php@t=22.html for general guide.

#!/bin/sh

PACKS=("26" "30" "34" "38" "42" "46" "51" "52" "56")

for i in "${PACKS[@]}"
do
   echo "process pack_$i"
   ./quickbms -w -r ../extract_link.bms ../IHX/extracted/packs/rockx_pack_$i ../IHX/extracted/$i/
done

packs under packs folder would be overwritten after the script.

  1. Reimport packs into rockx_pack.dat

This also requires the extractor script

./quickbms -w -r ../extract_dat.bms ../IHX/PSP_GAME/USRDIR/rockx_pack.dat ../IHX/extracted/packs/

rockx_pack.dat would be overwritten after the command

  1. Use UMDGen to replace rockx_pack.dat in the original ISO, then save as a new ISO.
  2. Generate xdelta based on original and the new ISO. (DeltaPatcher is useful for this),

Goal

  1. No Emudeck
  2. No RetroArch, only standalone emus
  3. Steam Rom Manager to add games
    1. Tried Pegasus but games launched from it isn't considered a sub process by Steam (tried Mednaffe and mGBA)
      1. This issue only happens in Flatpak release
  4. Steam launches Pegasus in game mode
    1. Steam input support
      1. Easier to customize control since all controller profiles will be presented in one game (Pegasus)
    2. Don't need to add individual games
    3. Resolution override applies to all games

Steam Rom Manager

  1. Check if the EMU has template we can use
  2. Change title to {{Title}} so the original file name is kept
  3. Override artwork: by default it also overrides title, remember to delete it.

Steam Input

Currently Steam Input don't work with flatpak apps out of Game mode: ValveSoftware/steam-for-linux#10551

To configure gamepad, add emu to steam & launch emulator from game mode in order to grab controllers from Steam Input

Mednaffe

Flatpak install The UI and emu executable (mednafen) conflicts Handheld Daemon, need to disable it for all games. For these platforms Xbox controller is way more than enough so it should be fine.

(Copied from my old note:)

  1. Global Settings -> Sound -> Device: sexyal-literal-default
  2. Video -> Enable fullscreen, default driver: opengl
  3. Miscellaneous: Automatically load/save state on game load/save
  4. Input -> uncheck "Update physical...." a. This prevents joystick input while window is not in focus
  5. Key assignments: ?
    1. Seems no "Pause Menu" feature to access all emu functionalities via controller, everything has to bound to a key on keyboard or gamepad
    2. Currently mapped to keyboard and use Steam virtual keyboard
    3. If using rewind, need to manually toggle on every time you run emulator

System settings:

  1. Control: Launch Mednaffe with Steam so Gamepad device matches
  2. Graphics:
    1. System -> Correct the aspect ratio
    2. Windowed -> scale to x1 (easier to test in desktop mode)
    3. Fullscreen -> aspect
    4. Scale/Filter -> Interpolation 1, Special video scaler nny2x

Steam Rom manager

  1. Executable: /usr/bin/flatpak
  2. Arguments: run --command=mednafen com.github.AmatCoder.mednaffe "${filePath}"

Other reference: https://github.com/n1ckoates/steamdeck-emulation/blob/main/emulators/mednaffe.md

BizHawk

Benefit:

  1. Multi platform

  2. Can enable auto save/load, can rebind hotkeys.

  3. For DS, there's hotkey to swap layout. not usable since touch screen doesn't work in game mode

  4. Support --fullscreen option

  5. Download linux binary https://gitlab.com/TASVideos/BizHawk/-/pipelines/1407943455/ (or newer dev builds)

    1. it's still .exe because it's a C# (.net) project. We will use mono to run it.
  6. Create a fedora39 distrobox container and install runtime dependencies

 sudo dnf install glibc mono-complete lua lsb_release openal-soft gtk2
  1. bash EmuHawkMono.sh from the container

Note: 2.9.1 has major bug that would cause emu to freeze

  1. With default config, if I enable Autosave Last Slot or Autoload Last Slot, the emulator will freeze on game close or on game load when there's a state. (For load, I have confirmed the state on disk is good). a. If I disable View -> Display Messages, then both features work fine.
  2. Other observation:
    1. If I enable "Display Input", then resize the window during the game, the emulator will freeze
    2. If I enable messages, and manually save state, and resize the window before the save state message is gone, the emulator will freeze
    3. I can't reproduce this with Display FPS, so it seems only certain texts are causing the freeze.

Detect controller changes

Due to distrobox sandboxing, it's not possible to detect new controllers and if the current controllers is unplugged and re-plugged, we need to restart the program to re-detect it.

This might be fine consider BizHawk has auto save and load state support.

To resolve this the container needs to be root container (created with --root flag).

See 89luca89/distrobox#762

However, running container would require sudo password, which might be an issue for Steam game mode integration.

To avoid sudo password, set NOPASSWD rule to podman command

/etc/sudoers.d/fsworld009

fsworld009 ALL=(ALL:ALL) NOPASSWD: /usr/bin/podman

Full explained 89luca89/distrobox#1739 (comment)

"click the blue sillhouette below for onboarding" message

Set "FirstBoot": false in config.ini

Quit on closse Rom

There is no launch option similar to -batch in Duck station to close emu on close rom. However we can use a lua script:

while true do
    key=input.get();
    if key["Q"]==true then
        client.exit()
    end
    emu.frameadvance()
end

This will close EMU on pressing Q. It also actually saves state if Auto save is enabled (refer to Observation below regarding to force close)

Script for game mode

Create a BizHawk.sh

#!/bin/sh
distrobox enter bizhawk -- bash "$HOME/games/emu/BizHawk_devbuild/EmuHawkMono.sh" --fullscreen --lua="path/to/CloseEmuByQ.lua" "$@"

This script can then be used for Steam Rom Manager

/usr/bin/bash /path/to/script "${filepath}"

Shaders

Config -> Display -> Scaling Filter -> User -> Select. There isn't much shaders built-in. However, we could use glsl shaders from https://github.com/libretro/glsl-shaders

Need to rename *.glslp files to *.cgp

xbrz-freescale seems work great.

Observation:

  1. If closing the game from Steam Menu, auto save state won't kick in. Observed the same with Ctrl+C intruption
  2. N64: Bad performance
  3. NDS: touch screen doesn't work in game mode.

Pegasus FE

Need to use the build from EmuDeck https://github.com/dragoonDorise/pegasus-temp/ Official build requires runtime lib dependencies, had to use distrobox, but it doesn't launch host emulators in game mode (even though it works in desktop mode with distrobox-host-exec)

Problem: BizHawk AltF4 doesn't work in game mode.

Theme

https://github.com/ZagonAb/Flat-Ozone

Add shortName: (iconname) to metadata to show icon in collection list. Name is the file name under assets/systems. e.g. shortName: gba

Duck station

  1. Remove confirm on power off in option
  2. launch command: flatpak run org.duckstation.DuckStation -fullscreen -batch -resume -- "{file.path}"

chd CD format

To unpack chd format for unsupported EMUs, install MAME from Flatpak and run:

 flatpak run --command=chdman org.mamedev.MAME extractcd -i "/path/to/chd" -o "output.cue"

Flatpak: Need to grant access to folders if games are on external drives / SSDs

Dolphin

  1. No command line arg to start in fullscreen, default that in Graphic setting
  2. https://forums.launchbox-app.com/topic/43703-dolphin-please-confirm-box-when-exit-within-big-box/ remove confirm dialog on eit
  3. There's no command line option to quit after close rom, but we can assign quit button in hot key setting to achieve he same.
  4. Can assign WiiMote control scheme by game with game in tile -> right click -> properties -> Game config -> Editor
    [Controls]
    WiimoteProfile1=SonicSecretRing
    
  5. Controller profile is bound to joystick ID, hence, need to open it in game mode and rebind controller to steam virtual pad

PCSX2

There is auto save and load state feature. However, cli argunment doesn't support resume state https://forums.launchbox-app.com/topic/75069-configuring-launchbox-to-utliize-pcsx2-resume-save-states/

If we want this to work now we need to manuallly specify launch command for each game to point to each game's resume state file (constructed by game ID and CRC), might not worth the trouble? Manuall save/load state is easier for now.

Flatpak: Need to grant access to folders if games are on external drives / SSDs

PPSSPP

To convert chd

flatpak run --command=chdman org.mamedev.MAME createdvd -hs 2048 -i "input.iso" -o "output.chd"

to avoid bad CHD file warning. See hrydgard/ppsspp#18925

Change Window size: Edit WindowWidth and WindowHeight in ~/.var/app/org.ppsspp.PPSSPP/config/ppsspp/PSP/SYSTEM/ppsspp.ini Couldn't find a way to change in in settings menu (Render Resolution setting doesn't affect window size)

WindowWidth = 1920
WindowHeight = 1088

for 1080p

Melon DS

Flatpak: Need to grant access to folders if games are on external drives / SSDs

Rosalie's Mupen GUI

Flatpak: Need to grant access to folders if games are on external drives / SSDs

Mame flatpak

configs are stored in ~/.mame

Clones in merged set

For example rockmanj is a clone of megaman.

When megaman.zip is presented, we can create a dummy file called rockmanj.zip, as long as it's in ROM path, MAME will display the clone as playable (and it would read the parent zip).

Default to full screen and not maximize

window                    1
maximize                  0
resolution                1920x1080

Make sure to disable other resolution settings (like resolution0) in mame.ini

Using shaders

https://docs.mamedev.org/advanced/bgfx.html

bgfx_path                 /app/share/mame/bgfx
bgfx_backend              vulkan
bgfx_debug                0
bgfx_screen_chains        xbr-lv3,xbr-lv3,xbr-lv3

Chain names could be find in /var/lib/flatpak/app/org.mamedev.MAME/current/active/files/share/mame/bgfx/chains/ (json files). Set 3 shaders because there are games with multiple monitors

If the filter is not working, it could be that the chain has been set for that game, check ~/.config/mame/cfg/{gameid}.cfg, delete chain attribute in screen tag

Per game configuration

https://docs.mamedev.org/advanced/multiconfig.html

For example set resolution for a specific game by creating ~/.mame/snowbro2.ini with

resolution                1440x1080

obs-vkcapture integration

In order to capture game, we need to run the game directly from cmd.

OBS_VKCAPTURE=1 flatpak run org.mamedev.MAME path/to/game

I assume this is due to mame UI running games by spawning separate processes and doesn't carry over env var or obs-gamecapture process.

Pass command line arguments to Windows Emulators

If we run emulators on Windos through Lutris, note that lutris doesn't support passing arguments from Linux terminal to Windows exe https://forums.lutris.net/t/run-app-game-exe-from-command-line-and-passing-command-line-arguments/8055/10

Meaning you can't pass Rom names to open them via command line when managing these Emulators in DEs like Pegasus.

However, it does support passing envvar via lutris -> Wine -> Windows terminals in Wine session

env TESTVAR=abc lutris
# pick a Windows game and choose open wine console
echo %TESTVAR%
abc

So this can be used to pass rom name.

Alternatively, set a bash script to store Rom name to a text file, then inside Wine session, run a batch script to read the text file and pass Rom name to emulator.

Monster Hunter Wilds

Broken UI display

https://www.reddit.com/r/linux_gaming/comments/1j1fupc/ui_display_bug_in_mh_wilds/

Fixed by changing config.ini

TextureLoadLevelBias=0

Ref: https://www.reddit.com/r/linux_gaming/comments/1j1fupc/comment/mgr11ck/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button

General info:

https://www.reddit.com/r/linux_gaming/comments/1j1fupc/comment/mfjbwqw/ There's separate mesa and dxvck cache outside steam (however the post doesn't explain how to flush them, need further research)

Also found that the monster icon in quest information tab is broken when selecting quests, fixed by copying options in config.ini from laptop. One or more of the following should be responsible:

GIPointCloudMinLod=0
AllowMeshShader=Enable
EffectRayTracingVolume=0
ShrinkShadowmapFilterSampleWidthMax=64
ShadowCacheEnable=False
RayTracingGIEnable=false
RayTracingReflectionEnable=false
RayTracingShadowEnable=false
RayTracingTransparentEnable=false

Spec: 2023 model, 7840U, 32G Ram, 2TB SSD

GPD Win 4: Del to bios, make sure secure boot is off. F7 to access boot menu

By default it creates a 300GB partition for Windows and the most of the rest as D:, we will replace D: with Linux.

Joystick dead zone fix https://www.reddit.com/r/gpdwin/comments/16oz9zp/gpd_win_4_deadzone_fix_posted_to_discord/

Useful tools & Some Bazzite specific guides https://github.com/aarron-lee/gpd-win-tricks

Apply the suspend fix https://github.com/aarron-lee/gpd-win-tricks?tab=readme-ov-file#recommended-settings-to-change-in-game-mode

Enable secure boot mode, need Custom mode? https://www.google.com/search?q=secure+boot+mode+standard+or+custom+&client=firefox-b-d&sca_esv=ecca4e17a2edffed&ei=g_GxZrz8AqvM1e8PueKBkAg&ved=0ahUKEwj8ybebi-CHAxUrZvUHHTlxAIIQ4dUDCBA&uact=5&oq=secure+boot+mode+standard+or+custom+&gs_lp=Egxnd3Mtd2l6LXNlcnAiJHNlY3VyZSBib290IG1vZGUgc3RhbmRhcmQgb3IgY3VzdG9tIDIKEAAYgAQYQxiKBTIFEAAYgAQyBBAAGB4yBBAAGB4yBBAAGB4yBBAAGB4yCBAAGIAEGKIEMggQABiABBiiBDIGEAAYBRgeMgYQABgFGB5I4A5QjwpYjwpwAngAkAEAmAE0oAFoqgEBMrgBA8gBAPgBAZgCA6ACPcICChAAGLADGNYEGEeYAwCIBgGQBgqSBwEzoAf-Cg&sclient=gws-wiz-serp

Debloat Win11 Home

https://github.com/Raphire/Win11Debloat

Desktop mode in Game mode

Since there's physical keyboard, it would be ideal to be able to run desktop mode with fcitx IME support so we can open browser in game mode

The built-in screen is quite small so I also need 150% scaling.

  1. Copy /usr/bin/steamos-nested-desktop to somewhere (e.g. ~/scripts/steamos-nested-desktop)
  2. Modify kwin_wayland_wrapper command to
    /usr/bin/kwin_wayland_wrapper --width ${STEAMOS_NESTED_DESKTOP_WIDTH:-1280} --height ${STEAMOS_NESTED_DESKTOP_HEIGHT:-800} --scale ${STEAMOS_NESTED_DESKTOP_SCALE:-1} --no-lockscreen \$@
    
  3. Set the script to executable, add to Steam
  4. Set launch option
    XMODIFIERS=@im=fcitx MOZ_ENABLE_WAYLAND=1 STEAMOS_NESTED_DESKTOP_WIDTH=1920 STEAMOS_NESTED_DESKTOP_HEIGHT=1080 STEAMOS_NESTED_DESKTOP_SCALE=0.75
    
  5. Profit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment