135 lines
6.1 KiB
Bash
135 lines
6.1 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# Run setup in this shell so WINEDLLPATH remains available to the launcher.
|
|
prepare_prism_speech() {
|
|
local title="$1"
|
|
shift
|
|
local logDir="${XDG_CACHE_HOME:-$HOME/.cache}/audiogame-manager/prism-wine"
|
|
local logFile details
|
|
if ! mkdir -p "$logDir" || ! logFile="$(mktemp "${logDir}/setup.XXXXXX.log")"; then
|
|
agm_msgbox "$title" "$title" "Could not prepare Prism Wine speech support: unable to create a diagnostic log in ${logDir}. Check directory permissions and free disk space."
|
|
return 1
|
|
fi
|
|
if "$@" > "$logFile" 2>&1; then
|
|
cat "$logFile"
|
|
rm -f "$logFile"
|
|
return 0
|
|
fi
|
|
cat "$logFile" >&2
|
|
details="$(tail -n 15 "$logFile")"
|
|
agm_msgbox "$title" "$title" "Could not prepare Prism Wine speech support.
|
|
|
|
${details}
|
|
|
|
Full diagnostic log: ${logFile}"
|
|
return 1
|
|
}
|
|
|
|
# Build the host bridge from the same release as the application's Prism DLL.
|
|
# Wine does not implement RpcMgmtInqIfIds, which Prism uses to detect NVDA.
|
|
build_prism_speech_bridge() (
|
|
local prismVersion="$1"
|
|
local bridgeDir="$2"
|
|
local buildRoot sourceRoot tool
|
|
local -a missingTools=()
|
|
|
|
for tool in curl tar cmake make winegcc wineg++ winebuild pkg-config; do
|
|
command -v "$tool" >/dev/null || missingTools+=("$tool")
|
|
done
|
|
if [[ ${#missingTools[@]} -gt 0 ]]; then
|
|
echo "Missing Prism Wine speech build tools: ${missingTools[*]}. Install these tools using your distribution's package manager, then launch the game again." >&2
|
|
return 1
|
|
fi
|
|
if ! pkg-config --exists speech-dispatcher; then
|
|
echo "Missing Speech Dispatcher development files (libspeechd). Install your distribution's Speech Dispatcher development package, then launch the game again." >&2
|
|
return 1
|
|
fi
|
|
if ! mkdir -p "${bridgeDir%/*}" || ! buildRoot="$(mktemp -d "${bridgeDir%/*}/.build.XXXXXX")"; then
|
|
echo "Could not create the Prism build directory. Check cache directory permissions and free disk space." >&2
|
|
return 1
|
|
fi
|
|
trap 'rm -rf "$buildRoot"' EXIT
|
|
echo "Preparing Prism ${prismVersion} Wine speech support..."
|
|
if ! curl -fsSL --retry 3 "https://codeload.github.com/ethindp/prism/tar.gz/refs/tags/v${prismVersion}" -o "${buildRoot}/source.tar.gz"; then
|
|
echo "Could not download Prism ${prismVersion}. Check your internet connection and whether this Prism release is available, then try again." >&2
|
|
return 1
|
|
fi
|
|
if ! tar -xzf "${buildRoot}/source.tar.gz" -C "$buildRoot"; then
|
|
echo "Could not extract Prism ${prismVersion}. Check free disk space and the archive error above." >&2
|
|
return 1
|
|
fi
|
|
sourceRoot="${buildRoot}/prism-${prismVersion}"
|
|
if ! cmake -S "${sourceRoot}/winelibs" -B "${buildRoot}/build" \
|
|
-DCMAKE_TOOLCHAIN_FILE="${sourceRoot}/cmake/winelib-toolchain.cmake" \
|
|
-DCMAKE_BUILD_TYPE=Release; then
|
|
echo "Could not configure Prism ${prismVersion} Wine speech support. See the CMake error above." >&2
|
|
return 1
|
|
fi
|
|
if ! cmake --build "${buildRoot}/build" --target \
|
|
prism_speech_dispatcher_bridge prism_speech_dispatcher_bridge_placeholder -j2; then
|
|
echo "Could not compile Prism ${prismVersion} Wine speech support. See the compiler error above." >&2
|
|
return 1
|
|
fi
|
|
if ! mkdir -p "$bridgeDir" || ! cp "${buildRoot}/build/speechd/prism_speech_dispatcher_bridge.dll.so" \
|
|
"${buildRoot}/build/speechd/placeholder/prism_speech_dispatcher_bridge.dll" \
|
|
"$bridgeDir/"; then
|
|
echo "Could not save the Prism speech bridge to the cache. Check directory permissions and free disk space." >&2
|
|
return 1
|
|
fi
|
|
)
|
|
|
|
prepare_arcadelux_prism_bridge() {
|
|
local gameDir="$1"
|
|
local prismVersion
|
|
local -a metadataFiles=("${gameDir}"/_internal/prismatoid-*.dist-info/METADATA)
|
|
if [[ ${#metadataFiles[@]} -ne 1 || ! -f "${metadataFiles[0]}" ]]; then
|
|
echo "Could not identify Arcadelux's bundled Prism version: expected one _internal/prismatoid-*.dist-info/METADATA file. Update or reinstall Arcadelux, then try again." >&2
|
|
return 1
|
|
fi
|
|
prismVersion="$(sed -n 's/^Version: //p' "${metadataFiles[0]}" | tr -d '\r')"
|
|
if [[ ! "$prismVersion" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
echo "Unsupported Prism version: ${prismVersion}" >&2
|
|
return 1
|
|
fi
|
|
prepare_prism_bridge "$gameDir" "$prismVersion" "Arcadelux.exe"
|
|
}
|
|
|
|
# App wrappers identify their bundled Prism release before sharing bridge setup.
|
|
prepare_prism_bridge() {
|
|
local gameDir="$1"
|
|
local prismVersion="$2"
|
|
local gameExecutable="$3"
|
|
local bridgeDir
|
|
if [[ ! "$prismVersion" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
echo "Unsupported Prism version: ${prismVersion}" >&2
|
|
return 1
|
|
fi
|
|
if [[ "$(uname -m)" != "x86_64" ]] || ! file -b "${gameDir}/${gameExecutable}" | grep -q 'PE32+'; then
|
|
echo "Prism Wine speech requires an x86_64 host and 64-bit game." >&2
|
|
return 1
|
|
fi
|
|
bridgeDir="${XDG_CACHE_HOME:-$HOME/.cache}/audiogame-manager/prism-wine/${prismVersion}-x86_64"
|
|
if [[ ! -f "${bridgeDir}/prism_speech_dispatcher_bridge.dll" ||
|
|
! -f "${bridgeDir}/prism_speech_dispatcher_bridge.dll.so" ]]; then
|
|
build_prism_speech_bridge "$prismVersion" "$bridgeDir" || return 1
|
|
fi
|
|
# Updates replace the game directory, so restore the placeholder each launch.
|
|
if ! cp "${bridgeDir}/prism_speech_dispatcher_bridge.dll" "$gameDir/"; then
|
|
echo "Could not copy the Prism speech bridge into the game directory. Check directory permissions and free disk space." >&2
|
|
return 1
|
|
fi
|
|
export WINEDLLPATH="${bridgeDir}${WINEDLLPATH:+:$WINEDLLPATH}"
|
|
}
|
|
|
|
prepare_tekken3_prism_bridge() {
|
|
local gameDir="$1"
|
|
local prismHash
|
|
# Only this Prism 0.18.3 DLL is supported by the Tekken integration.
|
|
prismHash="$(sha256sum "${gameDir}/T3Access/prism.dll")" || return 1
|
|
if [[ "${prismHash%% *}" != "7c7d09c8c7306e8e1a0c46d603ccb2a391c194c77843400c11b746e7dd56a467" ]]; then
|
|
echo "Tekken 3 Access has an unrecognized Prism DLL; update its AGM integration before launching." >&2
|
|
return 1
|
|
fi
|
|
prepare_prism_bridge "$gameDir" "0.18.3" "Tekken3.exe"
|
|
}
|