Initial re-upload
This commit is contained in:
commit
570f9247c2
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/monitor_by_id
|
||||
*.pyc
|
66
0005731108.py
Normal file
66
0005731108.py
Normal file
@ -0,0 +1,66 @@
|
||||
""" Game fix for IIDX (UID:0005731108)
|
||||
"""
|
||||
# Protonfix for games supporting Windows 8 prefix
|
||||
# This protonfix expects prefix shared between multiple titles
|
||||
# Explicitely set overrides for all dlls fetched here even when not using them
|
||||
# pylint: disable=C0103
|
||||
|
||||
import os
|
||||
from protonfixes import util
|
||||
|
||||
|
||||
def main():
|
||||
# Generic environment (may be overwritten by subpatch)
|
||||
util.protontricks("win8")
|
||||
util.protontricks("sound=alsa")
|
||||
|
||||
# Apply optional patches (without bloating protonfixes)
|
||||
patches = (os.getenv("PROTON_STYLE_PATCH") or "").strip(":")
|
||||
try:
|
||||
for patch in patches.split(":") if len(patches) else []:
|
||||
globals()[f"iidx_{patch}"]()
|
||||
except KeyError as err:
|
||||
print(f"gamefix: no patch available for {err}")
|
||||
|
||||
def iidx_30():
|
||||
# probably qpro etc., shader compilation fails for D3DXAssembleShader() - crash with missing callback Direct3DShaderValidatorCreate()
|
||||
util.protontricks("d3dcompiler_43")
|
||||
util.protontricks("d3dx9_43")
|
||||
# this exact override needed for subscreen to be created
|
||||
util.set_environment("WINEDLLOVERRIDES", "d3dcompiler_43=n,b")
|
||||
|
||||
|
||||
def iidx_29():
|
||||
# probably qpro etc., shader compilation fails for D3DXAssembleShader() - crash with missing callback Direct3DShaderValidatorCreate()
|
||||
util.protontricks("d3dcompiler_43")
|
||||
util.protontricks("d3dx9_43")
|
||||
# this exact override needed for subscreen to be created
|
||||
util.set_environment("WINEDLLOVERRIDES", "d3dcompiler_43=n,b")
|
||||
|
||||
def iidx_28():
|
||||
# probably qpro etc., shader compilation fails for D3DXAssembleShader() - crash with missing callback Direct3DShaderValidatorCreate()
|
||||
util.protontricks("d3dcompiler_43")
|
||||
util.protontricks("d3dx9_43")
|
||||
# this exact override needed for subscreen to be created
|
||||
util.set_environment("WINEDLLOVERRIDES", "d3dcompiler_43=n,b")
|
||||
|
||||
|
||||
def iidx_27():
|
||||
# crash at 0x180176996, shader compilation fails for D3DXAssembleShader() - crash with missing callback Direct3DShaderValidatorCreate()
|
||||
util.protontricks("d3dcompiler_43")
|
||||
util.protontricks("d3dx9_43")
|
||||
# this exact override needed for subscreen to be created
|
||||
util.set_environment("WINEDLLOVERRIDES", "d3dcompiler_43=n,b")
|
||||
|
||||
def iidx_26():
|
||||
# explicit to keep constant behaviour with other games (iidx27)
|
||||
util.set_environment("WINEDLLOVERRIDES", "d3dcompiler_43,d3dx9_43=b,n")
|
||||
|
||||
def iidx_25():
|
||||
# explicit to keep constant behaviour with other games (iidx27)
|
||||
util.set_environment("WINEDLLOVERRIDES", "d3dcompiler_43,d3dx9_43=b,n")
|
||||
|
||||
def tests():
|
||||
# Most dlls that may or may not be required
|
||||
util.set_environment("WINEDLLOVERRIDES", "quartz,devenum,dmime,dmsynth,dmloader,dmusic,dsound,dsdmo,msdmo,bmsound-wine,d3dx9_41,d3dx9d_41,d3dx9_43,d3dcompiler_43=n,b")
|
||||
pass
|
10
README.md
Normal file
10
README.md
Normal file
@ -0,0 +1,10 @@
|
||||
# Preface
|
||||
|
||||
This repo may seem erratic with no documentation whatsoever.
|
||||
This is because resources listed here are part of a bigger private repository.
|
||||
|
||||
You don't have to use anything from this repo to get games running as these are just there to make process feel more seamless.
|
||||
|
||||
That being said part of a guide listed at pages may be harder to follow without any system integration whatsoever, therefore this repository exists, providing the minimal wrappers setup that should work with guide provided.
|
||||
|
||||
If it doesn't, create a new issue here, as some wrappers here may be outdated.
|
20
array_format_to_hex.py
Executable file
20
array_format_to_hex.py
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env python3
|
||||
# Transform array visually to display 16 elements per line
|
||||
import sys
|
||||
import pyperclip
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
exit(1)
|
||||
stin = pyperclip.paste() if sys.argv[1] == "clip" else sys.argv[1]
|
||||
|
||||
asarr = [x.strip() for x in stin.strip().split(",")]
|
||||
|
||||
output = ""
|
||||
for i in range(0, len(asarr), 16):
|
||||
output += ", ".join(map(str, asarr[i : i + 16])) + ",\n"
|
||||
output = output.rstrip("\n").rstrip(",")
|
||||
|
||||
if sys.argv[1] == "clip":
|
||||
stin = pyperclip.copy(output)
|
||||
else:
|
||||
print(output)
|
21
bytepatch_intern_to_mon.py
Executable file
21
bytepatch_intern_to_mon.py
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
# Translates internal documentation patch notations into js format expected by BemaniPatcher
|
||||
import sys
|
||||
import pyperclip
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
exit(1)
|
||||
stin = pyperclip.paste() if sys.argv[1] == "clip" else sys.argv[1]
|
||||
|
||||
|
||||
[*rest, addr, on] = stin.split(":")
|
||||
[off, on, *rest] = on.split("->")
|
||||
off = ", ".join([f"0x{x}" for x in off.strip().split(" ")])
|
||||
on = ", ".join([f"0x{x}" for x in on.strip().split(" ")])
|
||||
addr = addr.strip()
|
||||
|
||||
output = f"{{ offset: {addr}, off: [{off}], on: [{on}] }},"
|
||||
if sys.argv[1] == "clip":
|
||||
stin = pyperclip.copy(output)
|
||||
else:
|
||||
print(output)
|
361
ep_bm2dxnix
Executable file
361
ep_bm2dxnix
Executable file
@ -0,0 +1,361 @@
|
||||
#!/bin/bash
|
||||
# Dump directory expects dir structure like this Beatmania IIDX 26/contents;Beatmania IIDX 26/devel;
|
||||
|
||||
## Constant ##
|
||||
_C_scriptDir="$(dirname -- "$(realpath -- "$0")")"
|
||||
_C_scriptName="$(basename -- "$(realpath -- "$0")")"
|
||||
# These constants are config overridable, but it is not recommended to do so (ex. hooks may not work)
|
||||
_C_dll_override="bm2dx.dll"
|
||||
_C_lightning_model="--iidxtdj"
|
||||
_C_rtname="proton-ge-8.16"
|
||||
_C_pfxname="u573_bm2dx_w8"
|
||||
# Audio native ASIO -iidxsounddevice is 27+ only
|
||||
_C_audio_asio1=(-iidxasio ASIO4ALL -iidxsounddevice asio)
|
||||
_C_audio_asio2=(-iidxasio FlexASIO -iidxsounddevice asio)
|
||||
_C_audio_asio3=(-iidxasio WineASIO -iidxsounddevice asio)
|
||||
# Audio native(dsound,24-)/wasapi(25+)
|
||||
_C_audio_native=(-audiohookdisable)
|
||||
_C_audio_wasapi=(-iidxsounddevice wasapi)
|
||||
# Audio spice dummy routing (25+ only, uses wasapi exclusive internally, which gets routed to specific audiobackend)
|
||||
_C_audio_dummy_asio=(-iidxsounddevice wasapi -audiodummy -audiobackend asio -asiodriverid 0)
|
||||
_C_audio_dummy_waveout=(-iidxsounddevice wasapi -audiodummy -audiobackend waveout)
|
||||
_C_audio_dummy_none=(-iidxsounddevice wasapi -audiodummy -audiobackend none)
|
||||
_C_audio_dummy_pipewire=(-iidxsounddevice wasapi -audiodummy -audiobackend pipewire)
|
||||
# Network spice builtin endpoint
|
||||
_C_net_dummy_maint=(-eamaint 1 -ea)
|
||||
_C_net_dummy_local=(-ea)
|
||||
|
||||
## Core ##
|
||||
_G_root="$_C_scriptDir/../.steam/root"
|
||||
_G_ep=("$_C_scriptDir/ep_protonnix")
|
||||
_G_exec=""
|
||||
_G_args=()
|
||||
_G_style=""
|
||||
_G_dumps=""
|
||||
_G_debug=0
|
||||
|
||||
## Game config ##
|
||||
_G_video="stable"
|
||||
_G_display=0
|
||||
_G_refresh_rate=0
|
||||
_G_fsr=-1
|
||||
_G_url=""
|
||||
_G_pcbid=""
|
||||
_G_hooks=()
|
||||
_G_devel=()
|
||||
|
||||
|
||||
print_help() {
|
||||
cat <<EOF
|
||||
ep_nix:ver:bm2dx
|
||||
Usage: ${_C_scriptName} [EXiV] [opt-args]
|
||||
Available arguments:
|
||||
EXiV style (numeric, required)
|
||||
--cfg launch config tool (spicecfg)
|
||||
--dbg launch debug environment (--dbg2 if no value provided, available steps through OR blitting 1: spice, 2: x64dbg, 4: wine, 8: style reserved flag)
|
||||
--root steam library root directory location override (this is where prefixes/runtimes are saved)
|
||||
--dumps game dumps root directory location override (assuming steam library if not provided)
|
||||
--exec run anything inside prefix (allows for running any application aside, you may provide arguments after --)
|
||||
-- arguments past this are passed to executable instead of defaults (read spice etc.)
|
||||
-h
|
||||
--help show help
|
||||
|
||||
Examples:
|
||||
${_C_scriptName} 26 --root /mnt/steamhdd --cfg (launches /mnt/steamhdd/steamapps/common/Beatmania IIDX 26/contents/spicecfg.exe)
|
||||
${_C_scriptName} 26 (launches $_G_root/steamapps/common/Beatmania IIDX 26/contents/spice64.exe)
|
||||
${_C_scriptName} 26 --exec /tmp/server.exe -- -p 1108 (runs /tmp/server.exe -p 1108 in IIDX26's environment)
|
||||
${_C_scriptName} 26 --dbg\$((4 | 1)) (launches second example with only additional wine and spice debug steps)
|
||||
EOF
|
||||
}
|
||||
|
||||
abort() {
|
||||
echo "[EXIT] Aborting due to failure at ${FUNCNAME[1]}($1)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
arg_parse() {
|
||||
while [ ! -z ${1+x} ]; do
|
||||
case "$1" in
|
||||
--help | -h)
|
||||
shift
|
||||
print_help
|
||||
exit 0
|
||||
;;
|
||||
--exec)
|
||||
shift
|
||||
_G_exec="$1"
|
||||
shift
|
||||
;;
|
||||
--cfg)
|
||||
: ${_G_exec:="spicecfg.exe"}
|
||||
shift
|
||||
;;
|
||||
--dbg*)
|
||||
_G_debug="${1:5}"
|
||||
[ -n "$_G_debug" ] || _G_debug=2
|
||||
shift
|
||||
;;
|
||||
--root)
|
||||
shift
|
||||
: ${_G_root:="${1%/}"}
|
||||
shift
|
||||
;;
|
||||
--dumps)
|
||||
shift
|
||||
: ${_G_dumps:="${1%/}"}
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
_G_args+=("${@}")
|
||||
;;
|
||||
"")
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
[ -z "${1##*[!0-9]*}" ] || _G_style="$1"
|
||||
[ -n "$_G_style" ] || {
|
||||
echo "Unknown option: $1"
|
||||
exit 2
|
||||
}
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
cfg_parse() {
|
||||
# Optional config
|
||||
cfgjson="$(jq -c "." "$_G_dumps/Beatmania IIDX ${_G_style}/contents/prop/linux.json" 2>/dev/null || echo {})"
|
||||
|
||||
# Video
|
||||
_G_video="$(jq -cr ".video.profile // \"$_G_video\"" <<<"$cfgjson")"
|
||||
_G_display="$(jq -cr ".video.display // \"$_G_display\"" <<<"$cfgjson")"
|
||||
_G_refresh_rate="$(jq -cr ".video.refresh_rate // \"$_G_refresh_rate\"" <<<"$cfgjson")"
|
||||
_G_fsr="$(jq -cr ".video.fsr // \"$_G_fsr\"" <<<"$cfgjson")"
|
||||
|
||||
# Network
|
||||
_G_url="$(jq -cr ".network.url // \"$_G_url\"" <<<"$cfgjson")"
|
||||
_G_pcbid="$(jq -cr ".network.pcbid // \"$_G_pcbid\"" <<<"$cfgjson")"
|
||||
|
||||
# Extra
|
||||
while read -r entry; do _G_hooks+=("$entry"); done < <(jq -cr '.extra.hooks // [] | .[]' <<<"$cfgjson")
|
||||
while read -r entry; do _G_devel+=("$entry"); done < <(jq -cr '.extra.devel // [] | .[]' <<<"$cfgjson")
|
||||
[ "$(jq -cr ".extra.lightning_support" <<<"$cfgjson")" == "false" ] && _C_lightning_model=""
|
||||
_C_game_module="$(jq -cr ".extra.dll_override // \"$_C_game_module\"" <<<"$cfgjson")"
|
||||
_C_rtname="$(jq -cr ".extra.rt_override // \"$_C_rtname\"" <<<"$cfgjson")"
|
||||
_C_pfxname="$(jq -cr ".extra.pfx_override // \"$_C_pfxname\"" <<<"$cfgjson")"
|
||||
}
|
||||
|
||||
monitor_by_id() {
|
||||
if [ ! $(command -v ./monitor_by_id) ]; then
|
||||
gcc "$_C_scriptDir/monitor_by_id.c" -o "$_C_scriptDir/monitor_by_id" -lX11 -lXrandr || return
|
||||
fi
|
||||
"$_C_scriptDir/monitor_by_id" $1
|
||||
}
|
||||
|
||||
args_iidx22() {
|
||||
# dummy audio unsupported, fullscreen working fine
|
||||
_G_args+=("${_C_audio_native[@]}")
|
||||
[ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter)
|
||||
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_local[@]}")
|
||||
}
|
||||
|
||||
args_iidx30() {
|
||||
# pipewire supported, fullscreen partially? working subscreen
|
||||
_G_args+=("${_C_audio_dummy_pipewire[@]}" "${_C_lightning_model[@]}" -nolegacy -touchemuforce)
|
||||
[ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter)
|
||||
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}")
|
||||
}
|
||||
|
||||
args_iidx29() {
|
||||
# pipewire supported, fullscreen working subscreen
|
||||
_G_args+=("${_C_audio_dummy_pipewire[@]}" "${_C_lightning_model[@]}" -nolegacy -touchemuforce)
|
||||
[ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter)
|
||||
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}")
|
||||
}
|
||||
|
||||
args_iidx28() {
|
||||
if ((_G_debug & 8)); then
|
||||
# Workaround for audio initializing for ALSA driver (not recommended)
|
||||
#export PULSE_LATENCY_MSEC=10
|
||||
export PIPEWIRE_LATENCY=411/44100
|
||||
export FIX_RATE=44100
|
||||
export FIX_CHANNELS="[ FL FR ]"
|
||||
export FIX_FORMAT="S16LE"
|
||||
rate=$(pw-metadata -n settings 0 clock.rate)
|
||||
rate="${rate#*value:\'}"
|
||||
rate="${rate%%\'*}"
|
||||
pw-metadata -n settings 0 clock.force-rate 44100
|
||||
#pw-metadata -n settings 0 clock.force-quantum 441
|
||||
nohup bash -c "sleep 30; pw-metadata -n settings 0 clock.force-rate $rate; sleep 1; pw-metadata -n settings 0 clock.force-rate --delete;" >/dev/null 2>&1 &
|
||||
# Results in desync prone audio with alsa, static with pulse
|
||||
_G_args+=("${_C_audio_wasapi[@]}" "${_C_audio_native[@]}" "${_C_lightning_model[@]}")
|
||||
else
|
||||
# pipewire supported, fullscreen working subscreen
|
||||
_G_args+=("${_C_audio_dummy_pipewire[@]}" "${_C_lightning_model[@]}" -nolegacy -touchemuforce)
|
||||
[ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter)
|
||||
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}")
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
args_iidx27() {
|
||||
# pipewire supported, fullscreen working subscreen
|
||||
_G_args+=("${_C_audio_dummy_pipewire[@]}" "${_C_lightning_model[@]}" -nolegacy -touchemuforce)
|
||||
[ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter)
|
||||
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}")
|
||||
}
|
||||
|
||||
args_iidx26() {
|
||||
# pipewire supported, fullscreen breaks on window unfocus
|
||||
_G_args+=("${_C_audio_dummy_pipewire[@]}")
|
||||
[ "$_G_video" != "stable" ] || _G_args+=(-w)
|
||||
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}")
|
||||
}
|
||||
|
||||
args_iidx25() {
|
||||
# pipewire supported, fullscreen breaks on window unfocus
|
||||
_G_args+=("${_C_audio_dummy_pipewire[@]}")
|
||||
[ "$_G_video" != "stable" ] || _G_args+=(-w)
|
||||
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_local[@]}")
|
||||
}
|
||||
|
||||
gen_args() {
|
||||
# Skip for override (--) mode
|
||||
[ "${#_G_args[@]}" -eq 0 ] || {
|
||||
_G_ep+=(--args "${_G_args[*]}")
|
||||
return 0
|
||||
}
|
||||
|
||||
# Basic
|
||||
_G_args+=(-io -iidx -modules modules "$_C_dll_override")
|
||||
|
||||
# Style
|
||||
if [[ $(type -t "args_iidx${_G_style}") == function ]]; then
|
||||
"args_iidx${_G_style}"
|
||||
else
|
||||
_G_args+=("${_C_net_dummy[@]}" "${_C_audio_native[@]}")
|
||||
fi
|
||||
|
||||
# Video
|
||||
_G_args+=(-monitor $_G_display)
|
||||
[ "$_G_refresh_rate" -gt 0 ] && _G_args+=(-graphics-force-refresh $_G_refresh_rate)
|
||||
if [ "$_G_video" = "force_window" ]; then
|
||||
_G_args+=(-w)
|
||||
elif [ "$_G_video" = "force_fullscreen" ]; then
|
||||
_G_args+=(-graphics-force-single-adapter)
|
||||
fi
|
||||
|
||||
# Network
|
||||
[ -n "$_G_url" ] && [ "$_G_url" != "dummy" ] && _G_args+=(-url "$_G_url")
|
||||
[ -n "$_G_pcbid" ] && _G_args+=(-p "$_G_pcbid")
|
||||
|
||||
# Hooks
|
||||
for hook in "${_G_hooks[@]}"; do _G_args+=(-k "$hook"); done
|
||||
|
||||
# Devel
|
||||
((_G_debug & 1)) && _G_args+=(${_G_devel[@]})
|
||||
if ((_G_debug & 2)); then
|
||||
# _REV: could write line directly into db/*.cmdline instead
|
||||
echo "[INFO] x64dbg session argument recommendation: '${_G_args[*]} -w'"
|
||||
else
|
||||
_G_ep+=(--args "${_G_args[*]}")
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
gen_base() {
|
||||
# Core setup
|
||||
styledir="$_G_dumps/Beatmania IIDX ${_G_style}"
|
||||
patchid="0005731108"
|
||||
if [ "$_G_style" -lt "25" ]; then
|
||||
arch=32
|
||||
else
|
||||
arch=64
|
||||
fi
|
||||
|
||||
# Proton setup
|
||||
[ -n "$LD_LIBRARY_PATH" ] && LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:"
|
||||
[ -n "$WINEDLLPATH" ] && LD_LIBRARY_PATH="${WINEDLLPATH}:"
|
||||
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}${styledir}/contents/modules"
|
||||
WINEDLLPATH="${WINEDLLPATH}${styledir}/contents/modules"
|
||||
export WINEDLLPATH
|
||||
export LD_LIBRARY_PATH
|
||||
if ((_G_debug & 4)); then
|
||||
: ${PROTON_LOG_DIR:="$styledir/contents"}
|
||||
: ${PROTON_LOG:=1}
|
||||
: ${WINEDEBUG:="+loaddll,+module"}
|
||||
export WINEDEBUG
|
||||
export PROTON_LOG
|
||||
export PROTON_LOG_DIR
|
||||
echo "[INFO] Proton log file: '$PROTON_LOG_DIR/steam-${patchid}.log'"
|
||||
fi
|
||||
export PROTON_STYLE_PATCH="$PROTON_STYLE_PATCH:$_G_style"
|
||||
|
||||
# Video fixes (AMD FSR, NVidia VSync)
|
||||
WINE_FULLSCREEN_FSR=0
|
||||
[ -z ${__GL_SYNC_DISPLAY_DEVICE+x} ] && __GL_SYNC_DISPLAY_DEVICE="$(monitor_by_id $_G_display)"
|
||||
if [ "$_G_fsr" -ge 0 ]; then
|
||||
WINE_FULLSCREEN_FSR=1
|
||||
export WINE_FULLSCREEN_FSR_STRENGTH=$_G_fsr
|
||||
if [ "$_G_style" -ge "30" ]; then
|
||||
export WINE_FULLSCREEN_FSR_CUSTOM_MODE=1920x1080
|
||||
elif [ "$_G_style" -ge "20" ]; then
|
||||
export WINE_FULLSCREEN_FSR_CUSTOM_MODE=1280x720
|
||||
else
|
||||
export WINE_FULLSCREEN_FSR_CUSTOM_MODE=640x480
|
||||
fi
|
||||
fi
|
||||
export WINE_FULLSCREEN_FSR
|
||||
export __GL_SYNC_DISPLAY_DEVICE
|
||||
|
||||
# Debug/normal environment generation
|
||||
if ((_G_debug & 2)); then
|
||||
styledir="$styledir/devel/debug/x64dbg/x${arch}"
|
||||
[ -n "$_G_exec" ] || _G_exec="x${arch}dbg.exe"
|
||||
else
|
||||
styledir="$styledir/contents"
|
||||
[ -n "$_G_exec" ] || if [ "$arch" -eq "32" ]; then _G_exec="spice.exe"; else _G_exec="spice${arch}.exe"; fi
|
||||
fi
|
||||
|
||||
# Apply environment
|
||||
cd "$styledir" || abort "INVALID PATH"
|
||||
_G_ep+=(--exec "$_G_exec" --uniqueid "$patchid" --runtime "$_G_root/steamapps/common/$_C_rtname" --prefix "$_G_root/steamapps/compatdata/$_C_pfxname" --steam-dir "$_G_root")
|
||||
}
|
||||
|
||||
sanity_check() {
|
||||
# IIDX
|
||||
[ -n "$_G_style" ] || abort "INVALID STYLE"
|
||||
[ -n "$_G_dumps" ] || _G_dumps="$_G_root/steamapps/common"
|
||||
[ -d "$_G_dumps" ] || abort "INVALID PATH"
|
||||
|
||||
# Proton
|
||||
[ -d "$_G_root/steamapps/common" ] || abort "INVALID PATH"
|
||||
[ -d "$_G_root/steamapps/compatdata" ] || abort "INVALID PATH"
|
||||
|
||||
# Manual features warnings
|
||||
[ -z ${__GL_SYNC_DISPLAY_DEVICE+x} ] || echo "[WARN] User envar override detected, if game runs at wrong framerates, try unsetting __GL_SYNC_DISPLAY_DEVICE"
|
||||
|
||||
# Test only
|
||||
echo "_G_display: $_G_display"
|
||||
echo "_G_refresh_rate: $_G_refresh_rate"
|
||||
echo "_G_fsr: $_G_fsr"
|
||||
echo "_G_url: $_G_url"
|
||||
echo "_G_pcbid: $_G_pcbid"
|
||||
echo "_G_hooks[${#_G_hooks[@]}]: ${_G_hooks[*]}"
|
||||
echo "_G_devel[${#_G_devel[@]}]: ${_G_devel[*]}"
|
||||
|
||||
}
|
||||
|
||||
# Set-up environment
|
||||
arg_parse "${@}"
|
||||
cfg_parse "${@}"
|
||||
sanity_check
|
||||
|
||||
# command generation
|
||||
gen_base
|
||||
gen_args
|
||||
|
||||
#abort "__GL_SYNC_DISPLAY_DEVICE=$__GL_SYNC_DISPLAY_DEVICE ${_G_ep[*]}"
|
||||
exec "${_G_ep[@]}"
|
283
ep_protonnix
Executable file
283
ep_protonnix
Executable file
@ -0,0 +1,283 @@
|
||||
#!/usr/bin/env bash
|
||||
# Minified version
|
||||
|
||||
_C_scriptName="$(basename -- "$(realpath -- "$0")")"
|
||||
_C_scriptDir="$(dirname -- "$(realpath -- "$0")")"
|
||||
_C_rootDir="$(dirname -- "$_C_scriptDir")"
|
||||
_G_runtime=""
|
||||
_G_prefix=""
|
||||
_G_exec=""
|
||||
_G_args=""
|
||||
_G_root=""
|
||||
_G_steamlib=("$HOME/.local/share/Steam")
|
||||
_G_runmode=()
|
||||
|
||||
print_help() {
|
||||
cat <<EOF
|
||||
ep_nix:ver:proton
|
||||
Usage: ${_C_scriptName} [EXiV] [opt-args]
|
||||
Available arguments:
|
||||
--runtime path to proton runtime dir root
|
||||
--prefix path to proton compatdata appid dir root (proton specific wine prefix)
|
||||
--exec windows binary entry point path (for advanced uses look below)
|
||||
--args args to provide exec binary (this input is not sanitized and follows escape rules of shell so to pass "val with space" use --args "-arg \"arg with space\"")
|
||||
--root windows game root (if not set uses working directory)
|
||||
--uniqueid provide to enable fixes for specific AppID (must be numeric, overrides detected AppID if any, for custom id use 0 padded 10 digit ID ex. custom 21 0000000021 to evade SteamID clashes)
|
||||
--steam-dir provide each additional steam library roots (with valid libraryfolder.vdf in root)
|
||||
--async enable simultaneous execution inside the same prefix (uses run instead waitforexitandrun)
|
||||
--info-hud enable information overlay (provided through mangohud)
|
||||
--local-only disable internet access
|
||||
--srpt enable steam remote play together through spoofing the game, needs appid of game chosen as dummy (installed and configured to use helper_steamct as compatibility tool)
|
||||
-h
|
||||
--help show help
|
||||
|
||||
--exec advanced usage (by value):
|
||||
eg:// protocol to trigger epic games store simplification wrapper (via legendary)
|
||||
eg://<APP-ID> APP-ID as used internally by legendary (obtainable through list, App name entry)
|
||||
eg://by-title/<MATCH-STRING>
|
||||
MATCH-STRING used to find first matched APP-ID for this title
|
||||
st:// protocol to trigger steam store simplification wrapper (directly launching games)
|
||||
EOF
|
||||
}
|
||||
|
||||
arg_parse() {
|
||||
#echo $PROTON_NO_D3D11
|
||||
echo "$@"
|
||||
while [ ! -z ${1+x} ]; do
|
||||
case "$1" in
|
||||
--help | -h)
|
||||
shift
|
||||
print_help
|
||||
exit 0
|
||||
;;
|
||||
--runtime)
|
||||
shift
|
||||
: ${_G_runtime:="${1%/}"}
|
||||
shift
|
||||
;;
|
||||
--steam-dir)
|
||||
shift
|
||||
_G_steamlib+=("${1%/}")
|
||||
shift
|
||||
;;
|
||||
--prefix)
|
||||
shift
|
||||
: ${_G_prefix:="${1%/}"}
|
||||
shift
|
||||
;;
|
||||
--exec)
|
||||
shift
|
||||
: ${_G_exec:="${1%/}"}
|
||||
if [[ "${_G_exec}" == "eg://"* ]]; then
|
||||
_G_exec="${_G_exec:5}"
|
||||
_G_runmode+=('__exec_eg')
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
--args)
|
||||
shift
|
||||
: ${_G_args:="${1}"}
|
||||
shift
|
||||
;;
|
||||
--root)
|
||||
shift
|
||||
: ${_G_root:="${1%/}"}
|
||||
shift
|
||||
;;
|
||||
--uniqueid)
|
||||
shift
|
||||
[ -z "${1##*[!0-9]*}" ] || export STEAM_COMPAT_APP_ID="$1"
|
||||
shift
|
||||
;;
|
||||
--async)
|
||||
_G_runmode+=('__async')
|
||||
shift
|
||||
;;
|
||||
--srpt)
|
||||
_G_runmode+=('__srpt')
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--info-hud)
|
||||
shift
|
||||
_G_runmode+=('__mango')
|
||||
;;
|
||||
--local-only)
|
||||
shift
|
||||
_G_runmode+=('__local')
|
||||
;;
|
||||
--no-debug)
|
||||
shift
|
||||
_G_runmode+=('__silent')
|
||||
;;
|
||||
--dry-run)
|
||||
shift
|
||||
_G_runmode+=('__dry')
|
||||
;;
|
||||
"")
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
exit 2
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Finds path where steamapp has been installed (first occurence)
|
||||
find_steamapp() {
|
||||
for el in "${_G_steamlib[@]}"; do
|
||||
elParse="$el/steamapps/common/$1"
|
||||
if [ -d "$elParse" ]; then
|
||||
printf "$elParse"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
setup_legendary() {
|
||||
# Adjust exec line to represent Epic Games app name based on protocol extension
|
||||
if [[ "${_G_exec}" == "by-title/"* ]]; then
|
||||
_G_exec="${_G_exec:9}"
|
||||
_G_exec="$(/opt/Heroic/resources/app.asar.unpacked/build/bin/linux/legendary list | grep -m 1 -i -- "${_G_exec}" | grep -Po '^.*?\K(?<=App name: ).*?(?= | Version)')"
|
||||
fi
|
||||
|
||||
# Adjust execution to use legendary wrappers
|
||||
prefix="$prefix /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/legendary launch $_G_exec --no-wine --wrapper \"" # add --dry-run before --no-wine to test
|
||||
_G_exec=""
|
||||
suffix="\" $suffix"
|
||||
|
||||
}
|
||||
|
||||
setup_srpt() {
|
||||
routeappid="0"
|
||||
args=()
|
||||
while [ ! -z ${1+x} ]; do
|
||||
case "$1" in
|
||||
--srpt)
|
||||
shift
|
||||
[ -z "${1##*[!0-9]*}" ] || routeappid="$1"
|
||||
[ "$routeappid" -ne "0" ] || routeappid="1860860"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
args+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
#echo steam -applaunch "$routeappid" ep_protonnix --cd "$(pwd)" "${args[@]}"
|
||||
exec steam -applaunch "$routeappid" ep_protonnix --cd "$(pwd)" "${args[@]}"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Disable network access
|
||||
setup_network_block() {
|
||||
# no systemd (gamemode fails dbus connection, since permissions)
|
||||
if pidof systemd; then
|
||||
prefix="systemd-run --scope -p IPAddressDeny=any ${prefix}"
|
||||
else
|
||||
prefix="unshare -r -n ${prefix}"
|
||||
fi
|
||||
#print_log INFO "Disabling network access"
|
||||
}
|
||||
|
||||
# Setup steam variables
|
||||
setup_environment() {
|
||||
# Steam
|
||||
if [ -n "$STEAM_COMPAT_MOUNTS" ]; then STEAM_COMPAT_MOUNTS="$STEAM_COMPAT_MOUNTS:"; fi # preserve preset additional mounts if any
|
||||
export STEAM_COMPAT_MOUNTS="${STEAM_COMPAT_MOUNTS}$(find_steamapp "Steamworks Shared"):$_G_runtime:$(find_steamapp "SteamLinuxRuntime_soldier"):$(find_steamapp "Proton EasyAntiCheat Runtime")"
|
||||
[ -z "${STEAM_COMPAT_APP_ID}" ] && export STEAM_COMPAT_APP_ID="${_G_prefix##*/}" # truncate to string after last occurence of /
|
||||
[ -z "${STEAM_COMPAT_APP_ID##*[!0-9]*}" ] && export STEAM_COMPAT_APP_ID=0 # set to null if not numeric
|
||||
export SteamAppId="$STEAM_COMPAT_APP_ID"
|
||||
export SteamGameId="$STEAM_COMPAT_APP_ID"
|
||||
export STEAM_COMPAT_INSTALL_PATH="$(realpath -- "$PWD")"
|
||||
export STEAM_COMPAT_DATA_PATH="$_G_prefix"
|
||||
export STEAM_COMPAT_SHADER_PATH="${_G_steamlib[${#_G_steamlib[@]} - 1]}/steamapps/shadercache/${_G_prefix##*/}" # ..../steam/steamapps/shadercache/739630
|
||||
export STEAM_COMPAT_CLIENT_INSTALL_PATH="$HOME/.local/share/Steam/"
|
||||
export STEAM_COMPAT_TOOL_PATHS="$_G_runtime:$(find_steamapp "SteamLinuxRuntime_soldier")" #:$(find_steamapp "Proton EasyAntiCheat Runtime")"
|
||||
|
||||
# Proton
|
||||
: ${DXVK_STATE_CACHE:=1}
|
||||
export DXVK_STATE_CACHE
|
||||
: ${DXVK_ASYNC:=1}
|
||||
unset DXVK_ASYNC # removed as of GE-Proton7-45 (superseeded by in-drivers extension? VK_EXT_graphics_pipeline_library)
|
||||
#export RADV_PERFTEST=gpl # VK_EXT_graphics_pipeline_library support for AMD(RADV), for NVIDIA enabled in drivers since 515.49.10 without flag
|
||||
: ${VKD3D_CONFIG:=no_upload_hvv}
|
||||
export VKD3D_CONFIG
|
||||
|
||||
# Wine (usually preconfigured by proton)
|
||||
: ${WINEFSYNC:=1}
|
||||
export WINEFSYNC
|
||||
|
||||
# Epic Games Store
|
||||
if [[ "${_G_runmode[*]}" =~ "__exec_eg" ]]; then
|
||||
setup_legendary
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
# Set-up environment
|
||||
arg_parse "${@}"
|
||||
|
||||
# Set-up other
|
||||
if [ -z "$_G_runtime" ] || [ -z "$_G_prefix" ]; then
|
||||
print_help
|
||||
exit 0
|
||||
fi
|
||||
if [[ "${_G_runmode[*]}" =~ "__srpt" ]]; then
|
||||
setup_srpt "${@}"
|
||||
fi
|
||||
if [[ "${_G_runmode[*]}" =~ "__silent" ]]; then
|
||||
suffix="> /dev/null 2>&1"
|
||||
fi
|
||||
if [[ "${_G_runmode[*]}" =~ "__mango" ]]; then
|
||||
export MANGOHUD=1
|
||||
fi
|
||||
if [[ "${_G_runmode[*]}" =~ "__local" ]]; then
|
||||
setup_network_block
|
||||
fi
|
||||
if [ ! -z "$_G_root" ]; then
|
||||
cd "$_G_root" # change working dir to game root directory (as expected on windows)
|
||||
fi
|
||||
|
||||
# Setup environment variables
|
||||
setup_environment
|
||||
main_exec="'$_G_runtime/proton'"
|
||||
if [[ "${_G_runmode[*]}" =~ "__async" ]]; then
|
||||
main_exec="$main_exec run"
|
||||
else
|
||||
main_exec="$main_exec waitforexitandrun"
|
||||
fi
|
||||
test -n "$_G_exec" && main_exec="$main_exec '$_G_exec' $_G_args"
|
||||
|
||||
# For test runs
|
||||
if [[ "${_G_runmode[*]}" =~ "__dry" ]]; then
|
||||
echo "STEAM_COMPAT_SHADER_PATH $STEAM_COMPAT_SHADER_PATH"
|
||||
echo "STEAM_COMPAT_MOUNTS $STEAM_COMPAT_MOUNTS"
|
||||
echo "$prefix $main_exec $suffix : $STEAM_COMPAT_DATA_PATH"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Run proton instance (creates prefix if applies)
|
||||
if [[ ! -e "$_G_prefix" ]] ; then
|
||||
mkdir "$_G_prefix" || exit 1
|
||||
eval "'$_G_runtime/proton' run wineboot --init"
|
||||
fi
|
||||
echo "$prefix : $main_exec : $suffix"
|
||||
echo "Working dir: $PWD"
|
||||
#read
|
||||
|
||||
|
||||
eval "$prefix $main_exec $suffix"
|
||||
|
||||
|
||||
[ ! -f "$_C_scriptDir/test_cases.sh" ] || . "$_C_scriptDir/test_cases.sh"
|
||||
#sleep 600
|
||||
|
||||
|
||||
echo "COMMAND: $prefix $main_exec $suffix"
|
||||
echo "STEAM_COMPAT_APP_ID: $STEAM_COMPAT_APP_ID"
|
||||
|
||||
|
47
helper_steamct
Executable file
47
helper_steamct
Executable file
@ -0,0 +1,47 @@
|
||||
#!/bin/bash
|
||||
# Helper::Steam Compatibility Tools
|
||||
# Expects below formats (called directly from steam client, supports any ambiguous application through chainloading)
|
||||
# Launch current game while forcing native support (games steam doesn't list such feature for)
|
||||
# $this waitforexitandrun /full/path/to/steam/game/binary
|
||||
# Launch arbitrary EP process while emulating being a steam game in question (chainloading, may enable Remote Play Together etc.)
|
||||
# $this waitforexitandrun /full/path/to/steam/game/binary "ENTRYPOINTNAME" --cd "ACTUALWORKINGDIR" ..ALLENTRYPOINTARGUMENTS..
|
||||
_C_scriptName="$(basename -- "$(realpath -- "$0")")"
|
||||
_C_scriptDir="$(dirname -- "$(realpath -- "$0")")"
|
||||
|
||||
|
||||
# Support for generic native execution (no steam helpers support)
|
||||
[ "$1" = "waitforexitandrun" ] || exit 0
|
||||
args=("${@:2}")
|
||||
|
||||
# Support for routing arbitrary EP through current steam app (expects ep_* next to itself)
|
||||
argIndex=0
|
||||
for arg in "${args[@]}"; do
|
||||
[[ "$arg" == "ep_"* ]] && break
|
||||
((argIndex++))
|
||||
done
|
||||
if [ "${#args[@]}" -ne "$argIndex" ]; then
|
||||
# Set correct Entry Point
|
||||
argSwap=("${args[@]}")
|
||||
args=("$_C_scriptDir/${argSwap[$argIndex]}")
|
||||
((argIndex++))
|
||||
|
||||
# Restore expected working directory (if any)
|
||||
if [[ "${argSwap[$argIndex]}" == "--cd" ]]; then
|
||||
((argIndex++))
|
||||
cd "${argSwap[$argIndex]}"
|
||||
((argIndex++))
|
||||
fi
|
||||
|
||||
# Set corrent args for Entry Point
|
||||
args+=("${argSwap[@]:$argIndex}")
|
||||
fi
|
||||
|
||||
# for arg in "${args[@]}"; do
|
||||
# echo "ARG: $arg"
|
||||
# done
|
||||
|
||||
# Execute requested command
|
||||
echo "Command routed as [steam://run/$STEAM_COMPAT_APP_ID]:"
|
||||
echo "cd $(pwd)"
|
||||
echo "exec ${args[@]}"
|
||||
exec "${args[@]}"
|
33
monitor_by_id.c
Normal file
33
monitor_by_id.c
Normal file
@ -0,0 +1,33 @@
|
||||
// gcc monitor_by_id.c -o monitor_by_id -lX11 -lXrandr
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int vmajor = 0;
|
||||
int vminor = 0;
|
||||
int moni = -1;
|
||||
int monc = 0;
|
||||
if (argc == 2) moni = atoi(argv[1]);
|
||||
|
||||
Display *dpy = XOpenDisplay(NULL);
|
||||
if (!dpy || moni < 0) return 1;
|
||||
Window wnd = XDefaultRootWindow(dpy);
|
||||
|
||||
if (XRRQueryExtension(dpy, &vmajor, &vminor))
|
||||
{
|
||||
XRRQueryVersion(dpy, &vmajor, &vminor);
|
||||
XRRMonitorInfo *info = XRRGetMonitors(dpy, wnd, 0, &monc);
|
||||
if (moni >= monc) return 1;
|
||||
|
||||
printf("%s\n", XGetAtomName(dpy, info[moni].name));
|
||||
|
||||
XFree(info);
|
||||
}
|
||||
|
||||
XCloseDisplay(dpy);
|
||||
return 0;
|
||||
}
|
10
patch_pages
Executable file
10
patch_pages
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
shopt -s globstar
|
||||
|
||||
|
||||
# Patch html
|
||||
read -p "This action may modify all .html files at '$PWD'"
|
||||
for html in **/*.html ; do
|
||||
# Override relative links to open in current tab instead
|
||||
sed -i 's~href="patcher/" target="_blank"~href="patcher/"~g' "$html"
|
||||
done
|
11
proton.patch
Normal file
11
proton.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- upstream/proton
|
||||
+++ mod/proton
|
||||
@@ -1462,6 +1462,8 @@
|
||||
prepend_to_env_str(self.env, ld_path_var, g_proton.lib64_dir + ":" + g_proton.lib_dir, ":")
|
||||
|
||||
self.env["WINEDLLPATH"] = g_proton.lib64_dir + "/wine:" + g_proton.lib_dir + "/wine"
|
||||
+ if len(os.getenv("WINEDLLPATH") or ""):
|
||||
+ self.env["WINEDLLPATH"] = os.getenv("WINEDLLPATH").strip(":") + ":" + self.env["WINEDLLPATH"]
|
||||
|
||||
self.env["GST_PLUGIN_SYSTEM_PATH_1_0"] = g_proton.lib64_dir + "gstreamer-1.0" + ":" + g_proton.lib_dir + "gstreamer-1.0"
|
||||
self.env["WINE_GST_REGISTRY_DIR"] = g_compatdata.path("gstreamer-1.0/")
|
43
stacktrace.py
Normal file
43
stacktrace.py
Normal file
@ -0,0 +1,43 @@
|
||||
#!/usr/bin/python
|
||||
# Translates wine stacktraces to static adresses (so at 18h*Fh^7)
|
||||
# @1: append to old value (default 0)
|
||||
# @2: fallback source VA (default 0x0)
|
||||
# @3: fallback target VA (default 0x180000000)
|
||||
import sys
|
||||
|
||||
OLDADDRESS = sys.argv[1] == "1" if len(sys.argv) >= 2 else False
|
||||
VABASE_DEFAULT = int(sys.argv[2].rstrip("h"), 16) if len(sys.argv) >= 3 else 0x0
|
||||
VATARGET_DEFAULT = int(sys.argv[3].rstrip("h"), 16) if len(sys.argv) >= 4 else 0x180000000
|
||||
VABASE = VABASE_DEFAULT
|
||||
VATARGET = VATARGET_DEFAULT
|
||||
|
||||
print(f"Fallback source VA: {hex(VABASE)}", file=sys.stderr)
|
||||
print(f"Fallback target VA: {hex(VATARGET)}", file=sys.stderr)
|
||||
for line in sys.stdin:
|
||||
linebase = line
|
||||
try:
|
||||
if line.lower().strip().startswith("vabase:"):
|
||||
# Reconfigure VA for next lines
|
||||
valindex = line.lower().find("vabase:") + 7
|
||||
src, target, *_ = [x.strip() if len(x.strip()) else None for x in line[valindex:].strip().split("->") + [""]]
|
||||
if src == "SKIP":
|
||||
VABASE = 0
|
||||
VATARGET = 0
|
||||
else:
|
||||
VABASE = int(src.rstrip("h"), 16) if src else VABASE_DEFAULT
|
||||
VATARGET = int(target.rstrip("h"), 16) if target else VATARGET_DEFAULT
|
||||
|
||||
line = f"{line[:valindex]} {hex(VABASE)} -> {hex(VATARGET)}"
|
||||
elif VABASE == 0 and VATARGET == 0:
|
||||
# Lines to be untouched
|
||||
raise
|
||||
else:
|
||||
# Lines to be translated
|
||||
srcaddrstr = line.strip()[:16]
|
||||
valindex = line.find(srcaddrstr)
|
||||
tgtaddr = VATARGET + int(srcaddrstr, 16) - VABASE
|
||||
tgtaddrstr=f"{hex(tgtaddr)} : {srcaddrstr}" if OLDADDRESS else f"{hex(tgtaddr)}"
|
||||
line = f"{line[:valindex]}{tgtaddrstr}{line[valindex+16:].rstrip()}"
|
||||
print(f"{line}")
|
||||
except:
|
||||
print(f"{linebase}", end="")
|
Loading…
Reference in New Issue
Block a user