summaryrefslogtreecommitdiff
path: root/defaults
diff options
context:
space:
mode:
authorxXJsonDeruloXx <danielhimebauch@gmail.com>2026-03-20 17:32:05 -0400
committerxXJsonDeruloXx <danielhimebauch@gmail.com>2026-03-20 17:32:05 -0400
commitca5db2231b8554d1377dd449f6fb9c736e3d6386 (patch)
tree0c3a52bebfa5602a6499b1fcaa1fea5539632c1e /defaults
parentef469a8036e3b3f129a753dad4cf04fad3ca92f7 (diff)
downloadDecky-Framegen-ca5db2231b8554d1377dd449f6fb9c736e3d6386.tar.gz
Decky-Framegen-ca5db2231b8554d1377dd449f6fb9c736e3d6386.zip
Implement prefix-managed OptiScaler runtime
Diffstat (limited to 'defaults')
-rwxr-xr-xdefaults/assets/fgmod-uninstaller.sh235
-rwxr-xr-xdefaults/assets/fgmod.sh335
2 files changed, 225 insertions, 345 deletions
diff --git a/defaults/assets/fgmod-uninstaller.sh b/defaults/assets/fgmod-uninstaller.sh
index 8c5e7b9..08e7113 100755
--- a/defaults/assets/fgmod-uninstaller.sh
+++ b/defaults/assets/fgmod-uninstaller.sh
@@ -1,175 +1,100 @@
#!/usr/bin/env bash
+set -euo pipefail
set -x
-exec > >(tee -i /tmp/fgmod-uninstaller.log) 2>&1
+exec > >(tee -i /tmp/fgmod-prefix-cleanup.log) 2>&1
+
+log() {
+ echo "$*"
+ logger -t fgmod-prefix-cleanup "$*"
+}
error_exit() {
- echo "โŒ $1"
- if [[ -n $STEAM_ZENITY ]]; then
- $STEAM_ZENITY --error --text "$1"
- else
- zenity --error --text "$1" || echo "Zenity failed to display error"
+ local message="$1"
+ echo "โŒ $message"
+ logger -t fgmod-prefix-cleanup "ERROR: $message"
+ if [[ -n "${STEAM_ZENITY:-}" ]]; then
+ "$STEAM_ZENITY" --error --text "$message" || true
+ elif command -v zenity >/dev/null 2>&1; then
+ zenity --error --text "$message" || true
fi
- logger -t fgmod-uninstaller "โŒ ERROR: $1"
exit 1
}
-if [ "$#" -lt 1 ]; then
- echo "Usage: $0 program [program_arguments...]"
- exit 1
+managed_dir_name="optiscaler-managed"
+manifest_name="manifest.env"
+default_proxy="${OPTISCALER_PROXY:-${DLL:-winmm}}"
+default_proxy="${default_proxy%.dll}"
+
+support_files=(
+ "OptiScaler.ini"
+ "OptiScaler.log"
+ "libxess.dll"
+ "libxess_dx11.dll"
+ "libxess_fg.dll"
+ "libxell.dll"
+ "amd_fidelityfx_dx12.dll"
+ "amd_fidelityfx_framegeneration_dx12.dll"
+ "amd_fidelityfx_upscaler_dx12.dll"
+ "amd_fidelityfx_vk.dll"
+ "nvngx.dll"
+ "dlssg_to_fsr3_amd_is_better.dll"
+ "fakenvapi.dll"
+ "fakenvapi.ini"
+ "dlssg_to_fsr3.ini"
+ "dlssg_to_fsr3.log"
+ "nvapi64.dll"
+ "nvapi64.dll.b"
+ "fakenvapi.log"
+ "dlss-enabler.dll"
+ "dlss-enabler-upscaler.dll"
+ "dlss-enabler.log"
+ "nvngx-wrapper.dll"
+ "_nvngx.dll"
+ "dlssg_to_fsr3_amd_is_better-3.0.dll"
+ "OptiScaler.asi"
+)
+
+[[ -n "${STEAM_COMPAT_DATA_PATH:-}" ]] || error_exit "STEAM_COMPAT_DATA_PATH is required. Use this wrapper from a Steam/Proton launch option."
+[[ $# -ge 1 ]] || error_exit "Usage: $0 program [program_arguments...]"
+
+compatdata_path="$STEAM_COMPAT_DATA_PATH"
+system32_path="$compatdata_path/pfx/drive_c/windows/system32"
+managed_root="$compatdata_path/$managed_dir_name"
+manifest_path="$managed_root/$manifest_name"
+proxy_name="$default_proxy"
+
+if [[ -f "$manifest_path" ]]; then
+ # shellcheck disable=SC1090
+ source "$manifest_path"
+ proxy_name="${MANAGED_PROXY:-$proxy_name}"
fi
-# === Resolve Game Path ===
-exe_folder_path=""
-if [[ "$1" == *.exe ]]; then
- exe_folder_path=$(dirname "$1")
-else
- for arg in "$@"; do
- if [[ "$arg" == *.exe ]]; then
- # Handle special cases for specific games
- [[ "$arg" == *"Cyberpunk 2077"* ]] && arg=${arg//REDprelauncher.exe/bin/x64/Cyberpunk2077.exe}
- [[ "$arg" == *"Witcher 3"* ]] && arg=${arg//REDprelauncher.exe/bin/x64_dx12/witcher3.exe}
- [[ "$arg" == *"Baldurs Gate 3"* ]] && arg=${arg//Launcher\/LariLauncher.exe/bin/bg3_dx11.exe}
- [[ "$arg" == *"HITMAN 3"* ]] && arg=${arg//Launcher.exe/Retail/HITMAN3.exe}
- [[ "$arg" == *"HITMAN World of Assassination"* ]] && arg=${arg//Launcher.exe/Retail/HITMAN3.exe}
- [[ "$arg" == *"SYNCED"* ]] && arg=${arg//Launcher\/sop_launcher.exe/SYNCED.exe}
- [[ "$arg" == *"2KLauncher"* ]] && arg=${arg//2KLauncher\/LauncherPatcher.exe/DoesntMatter.exe}
- [[ "$arg" == *"Warhammer 40,000 DARKTIDE"* ]] && arg=${arg//launcher\/Launcher.exe/binaries/Darktide.exe}
- [[ "$arg" == *"Warhammer Vermintide 2"* ]] && arg=${arg//launcher\/Launcher.exe/binaries_dx12/vermintide2_dx12.exe}
- [[ "$arg" == *"Satisfactory"* ]] && arg=${arg//FactoryGameSteam.exe/Engine/Binaries/Win64/FactoryGameSteam-Win64-Shipping.exe}
- [[ "$arg" == *"FINAL FANTASY XIV Online"* ]] && arg=${arg//boot\/ffxivboot.exe/game/ffxiv_dx11.exe}
- exe_folder_path=$(dirname "$arg")
- break
- fi
- done
-fi
+proxy_dll="${proxy_name}.dll"
+backup_dll="${proxy_name}-original.dll"
-for arg in "$@"; do
- if [[ "$arg" == lutris:rungameid/* ]]; then
- lutris_id="${arg#lutris:rungameid/}"
-
- # Get slug from Lutris JSON
- slug=$(lutris --list-games --json 2>/dev/null | jq -r ".[] | select(.id == $lutris_id) | .slug")
-
- if [[ -z "$slug" || "$slug" == "null" ]]; then
- echo "Could not find slug for Lutris ID $lutris_id"
- break
- fi
+for file_name in "${support_files[@]}"; do
+ rm -f "$system32_path/$file_name"
+done
- # Find matching YAML file using slug
- config_file=$(find ~/.config/lutris/games/ -iname "${slug}-*.yml" | head -1)
+rm -rf "$system32_path/plugins"
+rm -f "$system32_path/$proxy_dll"
- if [[ -z "$config_file" ]]; then
- echo "No config file found for slug '$slug'"
- break
- fi
+if [[ -f "$system32_path/$backup_dll" ]]; then
+ mv -f "$system32_path/$backup_dll" "$system32_path/$proxy_dll"
+fi
- # Extract executable path from YAML
- exe_path=$(grep -E '^\s*exe:' "$config_file" | sed 's/.*exe:[[:space:]]*//')
+rm -rf "$managed_root"
- if [[ -n "$exe_path" ]]; then
- exe_folder_path=$(dirname "$exe_path")
- echo "Resolved executable path: $exe_path"
- echo "Executable folder: $exe_folder_path"
- else
- echo "Executable path not found in $config_file"
- fi
+log "Cleaned prefix-managed OptiScaler files from $compatdata_path using proxy $proxy_name"
- break
- fi
+while [[ $# -gt 0 && "$1" == "--" ]]; do
+ shift
done
-# Fallback to STEAM_COMPAT_INSTALL_PATH when no path was found
-[[ -z "$exe_folder_path" && -n "$STEAM_COMPAT_INSTALL_PATH" ]] && exe_folder_path="$STEAM_COMPAT_INSTALL_PATH"
-
-# Check for Unreal Engine game paths
-if [[ -d "$exe_folder_path/Engine" ]]; then
- ue_exe_path=$(find "$exe_folder_path" -maxdepth 4 -mindepth 4 -path "*Binaries/Win64/*.exe" -not -path "*/Engine/*" | head -1)
- exe_folder_path=$(dirname "$ue_exe_path")
-fi
-
-# Verify the game folder exists
-[[ ! -d "$exe_folder_path" ]] && error_exit "Unable to locate the game folder: $exe_folder_path"
-
-# Avoid operating on the uninstaller's own directory
-script_dir=$(dirname "$(realpath "$0")")
-[[ "$(realpath "$exe_folder_path")" == "$script_dir" ]] && error_exit "The target directory matches the script's directory. Aborting to prevent accidental deletion."
-
-# Change to the game directory
-cd "$exe_folder_path" || error_exit "Failed to change directory to $exe_folder_path"
-
-# Verify current directory before proceeding
-[[ "$(pwd)" != "$exe_folder_path" ]] && error_exit "Unexpected working directory: $(pwd)"
-
-logger -t fgmod-uninstaller "๐ŸŸข Uninstalling from: $exe_folder_path"
-
-# === Remove OptiScaler Files ===
-echo "๐Ÿงน Removing OptiScaler files..."
-rm -f "OptiScaler.dll" "dxgi.dll" "winmm.dll" "dbghelp.dll" "version.dll" "wininet.dll" "winhttp.dll" "OptiScaler.asi"
-rm -f "OptiScaler.ini" "OptiScaler.log"
-
-# === Remove Nukem FG Mod Files ===
-echo "๐Ÿงน Removing Nukem FG Mod files..."
-rm -f "dlssg_to_fsr3_amd_is_better.dll" "dlssg_to_fsr3.ini" "dlssg_to_fsr3.log"
-rm -f "nvapi64.dll" "fakenvapi.ini" "fakenvapi.log"
-
-# === Remove Supporting Libraries ===
-echo "๐Ÿงน Removing supporting libraries..."
-rm -f "nvngx.dll" "nvngx.ini"
-# Only remove files if backups exist (to avoid removing restored originals)
-[[ -f "libxess.dll.b" ]] && rm -f "libxess.dll"
-[[ -f "libxess_dx11.dll.b" ]] && rm -f "libxess_dx11.dll"
-[[ -f "libxess_fg.dll.b" ]] && rm -f "libxess_fg.dll"
-[[ -f "libxell.dll.b" ]] && rm -f "libxell.dll"
-[[ -f "amd_fidelityfx_dx12.dll.b" ]] && rm -f "amd_fidelityfx_dx12.dll"
-[[ -f "amd_fidelityfx_framegeneration_dx12.dll.b" ]] && rm -f "amd_fidelityfx_framegeneration_dx12.dll"
-[[ -f "amd_fidelityfx_upscaler_dx12.dll.b" ]] && rm -f "amd_fidelityfx_upscaler_dx12.dll"
-[[ -f "amd_fidelityfx_vk.dll.b" ]] && rm -f "amd_fidelityfx_vk.dll"
-
-# === Remove FG Mod Files ===
-echo "๐Ÿงน Removing frame generation mod files..."
-rm -f "dlssg_to_fsr3_amd_is_better.dll" "dlssg_to_fsr3.ini"
-
-# === Remove NVAPI Files (Current and Legacy) ===
-echo "๐Ÿงน Removing NVAPI files..."
-rm -f "fakenvapi.dll" "fakenvapi.ini" # Current v0.9.0-pre4 approach
-rm -f "nvapi64.dll" "nvapi64.dll.b" # Legacy cleanup for older versions and backups
-
-# === Remove ASI Plugins ===
-echo "๐Ÿงน Removing ASI plugins directory..."
-rm -rf "plugins"
-
-# === Remove Legacy Files ===
-echo "๐Ÿงน Removing legacy files..."
-rm -f "dlss-enabler.dll" "dlss-enabler-upscaler.dll" "dlss-enabler.log"
-rm -f "nvngx-wrapper.dll" "_nvngx.dll"
-rm -f "dlssg_to_fsr3_amd_is_better-3.0.dll"
-
-# === Restore Original DLLs ===
-echo "๐Ÿ”„ Restoring original DLLs..."
-original_dlls=("d3dcompiler_47.dll" "amd_fidelityfx_dx12.dll" "amd_fidelityfx_framegeneration_dx12.dll" "amd_fidelityfx_upscaler_dx12.dll" "amd_fidelityfx_vk.dll" "libxess.dll" "libxess_dx11.dll" "libxess_fg.dll" "libxell.dll")
-for dll in "${original_dlls[@]}"; do
- if [[ -f "${dll}.b" ]]; then
- mv "${dll}.b" "$dll"
- echo "โœ… Restored original $dll"
- logger -t fgmod-uninstaller "โœ… Restored original $dll"
- fi
-done
+set +e
+"$@"
+exit_code=$?
+set -e
-# === Self-remove uninstaller ===
-echo "๐Ÿ—‘๏ธ Removing uninstaller..."
-rm -f "fgmod-uninstaller.sh"
-
-echo "โœ… fgmod removed from this game successfully!"
-logger -t fgmod-uninstaller "โœ… fgmod removed from $exe_folder_path"
-
-# === Execute original command if provided ===
-if [[ $# -gt 1 ]]; then
- echo "๐Ÿš€ Launching the game..."
- export SteamDeck=0
- export WINEDLLOVERRIDES="${WINEDLLOVERRIDES},dxgi=n,b"
- exec >/dev/null 2>&1
- exec "$@"
-else
- echo "โœ… Uninstallation complete. No game specified to run."
-fi \ No newline at end of file
+exit "$exit_code"
diff --git a/defaults/assets/fgmod.sh b/defaults/assets/fgmod.sh
index fa36558..7aa62bb 100755
--- a/defaults/assets/fgmod.sh
+++ b/defaults/assets/fgmod.sh
@@ -1,227 +1,182 @@
#!/usr/bin/env bash
+set -euo pipefail
set -x
-exec > >(tee -i /tmp/fgmod-install.log) 2>&1
+exec > >(tee -i /tmp/fgmod-prefix-managed.log) 2>&1
+
+log() {
+ echo "$*"
+ logger -t fgmod-prefix-managed "$*"
+}
error_exit() {
- echo "โŒ $1"
- if [[ -n $STEAM_ZENITY ]]; then
- $STEAM_ZENITY --error --text "$1"
- else
- zenity --error --text "$1" || echo "Zenity failed to display error"
+ local message="$1"
+ echo "โŒ $message"
+ logger -t fgmod-prefix-managed "ERROR: $message"
+ if [[ -n "${STEAM_ZENITY:-}" ]]; then
+ "$STEAM_ZENITY" --error --text "$message" || true
+ elif command -v zenity >/dev/null 2>&1; then
+ zenity --error --text "$message" || true
fi
- logger -t fgmod "โŒ ERROR: $1"
exit 1
}
-# === CONFIG ===
-fgmod_path="$HOME/fgmod"
-dll_name="${DLL:-dxgi.dll}"
-preserve_ini="${PRESERVE_INI:-true}"
-
-# === Resolve Game Path ===
-if [[ "$#" -lt 1 ]]; then
- error_exit "Usage: $0 program [program_arguments...]"
-fi
+bundle_root="${HOME}/fgmod"
+managed_dir_name="optiscaler-managed"
+manifest_name="manifest.env"
+proxy_name="${OPTISCALER_PROXY:-${DLL:-winmm}}"
+proxy_name="${proxy_name%.dll}"
+proxy_dll="${proxy_name}.dll"
+backup_dll="${proxy_name}-original.dll"
+
+support_files=(
+ "libxess.dll"
+ "libxess_dx11.dll"
+ "libxess_fg.dll"
+ "libxell.dll"
+ "amd_fidelityfx_dx12.dll"
+ "amd_fidelityfx_framegeneration_dx12.dll"
+ "amd_fidelityfx_upscaler_dx12.dll"
+ "amd_fidelityfx_vk.dll"
+ "nvngx.dll"
+ "dlssg_to_fsr3_amd_is_better.dll"
+ "fakenvapi.dll"
+ "fakenvapi.ini"
+)
+
+case "$proxy_name" in
+ winmm|dxgi|version|dbghelp|winhttp|wininet|d3d12) ;;
+ *) error_exit "Unsupported OPTISCALER_PROXY '$proxy_name'." ;;
+esac
+
+[[ -d "$bundle_root" ]] || error_exit "OptiScaler runtime not installed at $bundle_root"
+[[ -n "${STEAM_COMPAT_DATA_PATH:-}" ]] || error_exit "STEAM_COMPAT_DATA_PATH is required. Use this wrapper from a Steam/Proton launch option."
+[[ $# -ge 1 ]] || error_exit "Usage: $0 program [program_arguments...]"
+
+compatdata_path="$STEAM_COMPAT_DATA_PATH"
+system32_path="$compatdata_path/pfx/drive_c/windows/system32"
+managed_root="$compatdata_path/$managed_dir_name"
+manifest_path="$managed_root/$manifest_name"
+managed_ini="$managed_root/OptiScaler.ini"
+managed_plugins="$managed_root/plugins"
+
+cleanup_proxy_stage() {
+ local cleanup_proxy="$1"
+ local cleanup_proxy_dll="${cleanup_proxy}.dll"
+ local cleanup_backup_dll="${cleanup_proxy}-original.dll"
+
+ rm -f "$system32_path/$cleanup_proxy_dll"
+ if [[ -f "$system32_path/$cleanup_backup_dll" ]]; then
+ mv -f "$system32_path/$cleanup_backup_dll" "$system32_path/$cleanup_proxy_dll"
+ fi
+}
-exe_folder_path=""
-if [[ $# -eq 1 ]]; then
- [[ "$1" == *.exe ]] && exe_folder_path=$(dirname "$1") || exe_folder_path="$1"
-else
- for arg in "$@"; do
- if [[ "$arg" == *.exe ]]; then
- [[ "$arg" == *"Cyberpunk 2077"* ]] && arg=${arg//REDprelauncher.exe/bin/x64/Cyberpunk2077.exe}
- [[ "$arg" == *"Witcher 3"* ]] && arg=${arg//REDprelauncher.exe/bin/x64_dx12/witcher3.exe}
- [[ "$arg" == *"Baldurs Gate 3"* ]] && arg=${arg//Launcher\/LariLauncher.exe/bin/bg3_dx11.exe}
- [[ "$arg" == *"HITMAN 3"* ]] && arg=${arg//Launcher.exe/Retail/HITMAN3.exe}
- [[ "$arg" == *"HITMAN World of Assassination"* ]] && arg=${arg//Launcher.exe/Retail/HITMAN3.exe}
- [[ "$arg" == *"SYNCED"* ]] && arg=${arg//Launcher\/sop_launcher.exe/SYNCED.exe}
- [[ "$arg" == *"2KLauncher"* ]] && arg=${arg//2KLauncher\/LauncherPatcher.exe/DoesntMatter.exe}
- [[ "$arg" == *"Warhammer 40,000 DARKTIDE"* ]] && arg=${arg//launcher\/Launcher.exe/binaries/Darktide.exe}
- [[ "$arg" == *"Warhammer Vermintide 2"* ]] && arg=${arg//launcher\/Launcher.exe/binaries_dx12/vermintide2_dx12.exe}
- [[ "$arg" == *"Satisfactory"* ]] && arg=${arg//FactoryGameSteam.exe/Engine/Binaries/Win64/FactoryGameSteam-Win64-Shipping.exe}
- [[ "$arg" == *"FINAL FANTASY XIV Online"* ]] && arg=${arg//boot\/ffxivboot.exe/game/ffxiv_dx11.exe}
- exe_folder_path=$(dirname "$arg")
- break
- fi
+cleanup_stage_files() {
+ local cleanup_proxy="$1"
+ rm -f "$system32_path/OptiScaler.ini"
+ for file_name in "${support_files[@]}"; do
+ rm -f "$system32_path/$file_name"
done
-fi
-
-for arg in "$@"; do
- if [[ "$arg" == lutris:rungameid/* ]]; then
- lutris_id="${arg#lutris:rungameid/}"
-
- # Get slug from Lutris JSON
- slug=$(lutris --list-games --json 2>/dev/null | jq -r ".[] | select(.id == $lutris_id) | .slug")
-
- if [[ -z "$slug" || "$slug" == "null" ]]; then
- echo "Could not find slug for Lutris ID $lutris_id"
- break
- fi
-
- # Find matching YAML file using slug
- config_file=$(find ~/.config/lutris/games/ -iname "${slug}-*.yml" | head -1)
-
- if [[ -z "$config_file" ]]; then
- echo "No config file found for slug '$slug'"
- break
- fi
+ rm -f "$system32_path/OptiScaler.log"
+ rm -rf "$system32_path/plugins"
+ cleanup_proxy_stage "$cleanup_proxy"
+}
- # Extract executable path from YAML
- exe_path=$(grep -E '^\s*exe:' "$config_file" | sed 's/.*exe:[[:space:]]*//' )
+mkdir -p "$system32_path" "$managed_root" "$managed_plugins"
- if [[ -n "$exe_path" ]]; then
- exe_folder_path=$(dirname "$exe_path")
- echo "Resolved executable path: $exe_path"
- echo "Executable folder: $exe_folder_path"
- else
- echo "Executable path not found in $config_file"
- fi
+existing_proxy=""
+if [[ -f "$manifest_path" ]]; then
+ # shellcheck disable=SC1090
+ source "$manifest_path"
+ existing_proxy="${MANAGED_PROXY:-}"
+fi
- break
- fi
-done
+if [[ -n "$existing_proxy" && "$existing_proxy" != "$proxy_name" ]]; then
+ log "Switching managed proxy from $existing_proxy to $proxy_name"
+ cleanup_stage_files "$existing_proxy"
+fi
-[[ -z "$exe_folder_path" && -n "$STEAM_COMPAT_INSTALL_PATH" ]] && exe_folder_path="$STEAM_COMPAT_INSTALL_PATH"
+[[ -f "$bundle_root/OptiScaler.ini" ]] || error_exit "Missing OptiScaler.ini in runtime bundle"
+[[ -f "$bundle_root/update-optiscaler-config.py" ]] || error_exit "Missing update-optiscaler-config.py in runtime bundle"
-if [[ -d "$exe_folder_path/Engine" ]]; then
- ue_exe=$(find "$exe_folder_path" -maxdepth 4 -mindepth 4 -path "*Binaries/Win64/*.exe" -not -path "*/Engine/*" | head -1)
- exe_folder_path=$(dirname "$ue_exe")
+python_bin="python3"
+if ! command -v "$python_bin" >/dev/null 2>&1; then
+ python_bin="python"
fi
+command -v "$python_bin" >/dev/null 2>&1 || error_exit "Python interpreter not found"
-[[ ! -d "$exe_folder_path" ]] && error_exit "โŒ Could not resolve game directory!"
-[[ ! -w "$exe_folder_path" ]] && error_exit "๐Ÿ›‘ No write permission to the game folder!"
+if [[ ! -f "$managed_ini" ]]; then
+ cp -f "$bundle_root/OptiScaler.ini" "$managed_ini"
+fi
-logger -t fgmod "๐ŸŸข Target directory: $exe_folder_path"
-logger -t fgmod "๐Ÿงฉ Using DLL name: $dll_name"
-logger -t fgmod "๐Ÿ“„ Preserve INI: $preserve_ini"
+"$python_bin" "$bundle_root/update-optiscaler-config.py" "$managed_ini"
+sed -i 's/^UseHQFont[[:space:]]*=[[:space:]]*auto$/UseHQFont=false/' "$managed_ini" || true
-# === Cleanup Old Injectors ===
-rm -f "$exe_folder_path"/{dxgi.dll,winmm.dll,nvngx.dll,_nvngx.dll,nvngx-wrapper.dll,dlss-enabler.dll,OptiScaler.dll}
+if [[ -d "$bundle_root/plugins" ]]; then
+ rm -rf "$managed_plugins"
+ mkdir -p "$managed_plugins"
+ cp -f "$bundle_root/plugins"/* "$managed_plugins/" 2>/dev/null || true
+fi
-# === Optional: Backup Original DLLs ===
-original_dlls=("d3dcompiler_47.dll" "amd_fidelityfx_dx12.dll" "amd_fidelityfx_framegeneration_dx12.dll" "amd_fidelityfx_upscaler_dx12.dll" "amd_fidelityfx_vk.dll")
-for dll in "${original_dlls[@]}"; do
- [[ -f "$exe_folder_path/$dll" && ! -f "$exe_folder_path/$dll.b" ]] && mv -f "$exe_folder_path/$dll" "$exe_folder_path/$dll.b"
+for file_name in "${support_files[@]}"; do
+ if [[ -f "$bundle_root/$file_name" ]]; then
+ cp -f "$bundle_root/$file_name" "$system32_path/$file_name"
+ fi
done
-# === Remove nvapi64.dll and its backup (conflicts from previous fakenvapi versions) ===
-rm -f "$exe_folder_path/nvapi64.dll" "$exe_folder_path/nvapi64.dll.b"
-echo "๐Ÿงน Cleaned up nvapi64.dll and backup (legacy fakenvapi conflicts)"
+if [[ -d "$managed_plugins" ]]; then
+ rm -rf "$system32_path/plugins"
+ mkdir -p "$system32_path/plugins"
+ cp -f "$managed_plugins"/* "$system32_path/plugins/" 2>/dev/null || true
+fi
-# === Core Install ===
-if [[ -f "$fgmod_path/renames/$dll_name" ]]; then
- echo "โœ… Using pre-renamed $dll_name"
- cp "$fgmod_path/renames/$dll_name" "$exe_folder_path/$dll_name" || error_exit "โŒ Failed to copy $dll_name"
-else
- echo "โš ๏ธ Pre-renamed $dll_name not found, falling back to OptiScaler.dll"
- cp "$fgmod_path/OptiScaler.dll" "$exe_folder_path/$dll_name" || error_exit "โŒ Failed to copy OptiScaler.dll as $dll_name"
+if [[ -f "$system32_path/$proxy_dll" && ! -f "$system32_path/$backup_dll" ]]; then
+ mv -f "$system32_path/$proxy_dll" "$system32_path/$backup_dll"
fi
-# === OptiScaler.ini Handling ===
-if [[ "$preserve_ini" == "true" && -f "$exe_folder_path/OptiScaler.ini" ]]; then
- echo "๐Ÿ“„ Preserving existing OptiScaler.ini (user settings retained)"
- logger -t fgmod "๐Ÿ“„ Existing OptiScaler.ini preserved in $exe_folder_path"
+if [[ -f "$bundle_root/renames/$proxy_dll" ]]; then
+ cp -f "$bundle_root/renames/$proxy_dll" "$system32_path/$proxy_dll"
else
- echo "๐Ÿ“„ Installing OptiScaler.ini from plugin defaults"
- cp "$fgmod_path/OptiScaler.ini" "$exe_folder_path/OptiScaler.ini" || error_exit "โŒ Failed to copy OptiScaler.ini"
- logger -t fgmod "๐Ÿ“„ OptiScaler.ini installed to $exe_folder_path"
+ cp -f "$bundle_root/OptiScaler.dll" "$system32_path/$proxy_dll"
fi
-# === OptiScaler env variables Handling ===
-if [[ -f "$fgmod_path/update-optiscaler-config.py" ]]; then
- python "$fgmod_path/update-optiscaler-config.py" "$exe_folder_path/OptiScaler.ini"
+cp -f "$managed_ini" "$system32_path/OptiScaler.ini"
+
+runtime_version="unknown"
+if [[ -f "$bundle_root/version.txt" ]]; then
+ runtime_version="$(<"$bundle_root/version.txt")"
fi
-# OptiScaler 0.9.0-pre11 can assert on Proton when HQ font auto mode tries to load
-# an external TTF that is not present. Only normalize the default auto value.
-sed -i 's/^UseHQFont[[:space:]]*=[[:space:]]*auto$/UseHQFont=false/' "$exe_folder_path/OptiScaler.ini" || true
+cat > "$manifest_path" <<EOF
+MANAGED_PROXY="$proxy_name"
+BUNDLE_ROOT="$bundle_root"
+BUNDLE_VERSION="$runtime_version"
+SYSTEM32_PATH="$system32_path"
+EOF
-# === ASI Plugins Directory ===
-if [[ -d "$fgmod_path/plugins" ]]; then
- echo "๐Ÿ”Œ Installing ASI plugins directory"
- cp -r "$fgmod_path/plugins" "$exe_folder_path/" || true
- logger -t fgmod "๐Ÿ”Œ ASI plugins directory installed to $exe_folder_path"
+export SteamDeck=0
+if [[ -n "${WINEDLLOVERRIDES:-}" ]]; then
+ export WINEDLLOVERRIDES="${WINEDLLOVERRIDES},${proxy_name}=n,b"
else
- echo "โš ๏ธ No plugins directory found in fgmod"
+ export WINEDLLOVERRIDES="${proxy_name}=n,b"
fi
-# === Supporting Libraries ===
-cp -f "$fgmod_path/libxess.dll" "$exe_folder_path/" || true
-cp -f "$fgmod_path/libxess_dx11.dll" "$exe_folder_path/" || true
-cp -f "$fgmod_path/libxess_fg.dll" "$exe_folder_path/" || true
-cp -f "$fgmod_path/libxell.dll" "$exe_folder_path/" || true
-cp -f "$fgmod_path/amd_fidelityfx_dx12.dll" "$exe_folder_path/" || true
-cp -f "$fgmod_path/amd_fidelityfx_framegeneration_dx12.dll" "$exe_folder_path/" || true
-cp -f "$fgmod_path/amd_fidelityfx_upscaler_dx12.dll" "$exe_folder_path/" || true
-cp -f "$fgmod_path/amd_fidelityfx_vk.dll" "$exe_folder_path/" || true
-cp -f "$fgmod_path/nvngx.dll" "$exe_folder_path/" || true
-
-# === Nukem FG Mod Files (now in fgmod directory) ===
-cp -f "$fgmod_path/dlssg_to_fsr3_amd_is_better.dll" "$exe_folder_path/" || true
-# Note: dlssg_to_fsr3.ini is not included in v0.9.0-pre4 archive
-
-# === FakeNVAPI Files ===
-# Remove legacy nvapi64.dll to avoid conflicts
-# rm -f "$exe_folder_path/nvapi64.dll"
-# echo "๐Ÿงน Removed legacy nvapi64.dll"
-
-# Copy fakenvapi.dll with original name (v1.3.8.1)
-cp -f "$fgmod_path/fakenvapi.dll" "$exe_folder_path/" || true
-cp -f "$fgmod_path/fakenvapi.ini" "$exe_folder_path/" || true
-echo "๐Ÿ“ฆ Installed fakenvapi.dll and fakenvapi.ini"
-
-# === Additional Support Files ===
-# cp -f "$fgmod_path/d3dcompiler_47.dll" "$exe_folder_path/" || true
-
-# Note: d3dcompiler_47.dll is not included in v0.9.0-pre4 archive
-
-echo "โœ… Installation completed successfully!"
-echo "๐Ÿ“„ For Steam, add this to the launch options: \"$fgmod_path/fgmod\" %COMMAND%"
-echo "๐Ÿ“„ For Heroic, add this as a new wrapper: \"$fgmod_path/fgmod\""
-logger -t fgmod "๐ŸŸข Installation completed successfully for $exe_folder_path"
-
-# === Execute original command ===
-if [[ $# -gt 1 ]]; then
- # Log to both file and system journal
- logger -t fgmod "=================="
- logger -t fgmod "Debug Info (Launch Mode):"
- logger -t fgmod "Number of arguments: $#"
- for i in $(seq 1 $#); do
- logger -t fgmod "Arg $i: ${!i}"
- done
- logger -t fgmod "Final executable path: $exe_folder_path"
- logger -t fgmod "=================="
-
- # Execute the original command
- export SteamDeck=0
- export WINEDLLOVERRIDES="$WINEDLLOVERRIDES,dxgi=n,b"
-
- # Filter out leading -- separators (from Steam launch options)
- while [[ $# -gt 0 && "$1" == "--" ]]; do
- shift
- done
+while [[ $# -gt 0 && "$1" == "--" ]]; do
+ shift
+done
- exec >/dev/null 2>&1
- "$@"
-else
- echo "Done!"
- echo "----------------------------------------"
- echo "Debug Info (Standalone Mode):"
- echo "Number of arguments: $#"
- for i in $(seq 1 $#); do
- echo "Arg $i: ${!i}"
- done
- echo "Final executable path: $exe_folder_path"
- echo "----------------------------------------"
-
- # Also log standalone mode to journal
- logger -t fgmod "=================="
- logger -t fgmod "Debug Info (Standalone Mode):"
- logger -t fgmod "Number of arguments: $#"
- for i in $(seq 1 $#); do
- logger -t fgmod "Arg $i: ${!i}"
- done
- logger -t fgmod "Final executable path: $exe_folder_path"
- logger -t fgmod "=================="
+log "Using compatdata path: $compatdata_path"
+log "Using system32 path: $system32_path"
+log "Using prefix-managed proxy: $proxy_dll"
+log "Using WINEDLLOVERRIDES=$WINEDLLOVERRIDES"
+
+set +e
+"$@"
+exit_code=$?
+set -e
+
+if [[ -f "$system32_path/OptiScaler.ini" ]]; then
+ cp -f "$system32_path/OptiScaler.ini" "$managed_ini"
fi
+
+exit "$exit_code"