Compare commits
11
Commits
7ff3f0b47d
...
testing
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e4f764847 | ||
|
|
17aed35d5b | ||
|
|
c1c5363c63 | ||
|
|
83dfa99aa3 | ||
|
|
edf8e8e104 | ||
|
|
38a9b2cd39 | ||
|
|
4112aa3bda | ||
|
|
4f11130369 | ||
|
|
850cd37364 | ||
|
|
d4db802645 | ||
|
|
993f838404 |
@@ -1,3 +1,4 @@
|
||||
*.x.c
|
||||
*.x
|
||||
music/
|
||||
/game.log
|
||||
|
||||
+125
-12
@@ -40,15 +40,41 @@ set_wine_env() {
|
||||
|
||||
# Note: install_wine function removed - we now use system wine with simplified bottle management
|
||||
|
||||
enable_winetricks_usage_reporting() {
|
||||
local winetricksCache="${XDG_CACHE_HOME:-$HOME/.cache}/winetricks"
|
||||
|
||||
mkdir -p "$winetricksCache"
|
||||
if [[ ! -e "${winetricksCache}/track_usage" ]]; then
|
||||
printf '1\n' > "${winetricksCache}/track_usage"
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_speechsdk_cache() {
|
||||
local winetricksCache="${XDG_CACHE_HOME:-$HOME/.cache}/winetricks"
|
||||
local speechsdkPayload="${winetricksCache}/speechsdk/SpeechSDK51.exe"
|
||||
|
||||
enable_winetricks_usage_reporting
|
||||
if [[ -f "$speechsdkPayload" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Downloading Speech SDK for the Winetricks cache..."
|
||||
# ipfs and cache are populated by the main script before bottle setup.
|
||||
# shellcheck disable=SC2154
|
||||
download "${ipfs[speechsdk]}"
|
||||
if ! unzip -oq "${cache}/speechsdk.zip" -d "$winetricksCache"; then
|
||||
echo "Could not extract Speech SDK into the Winetricks cache."
|
||||
return 1
|
||||
fi
|
||||
if [[ ! -f "$speechsdkPayload" ]]; then
|
||||
echo "The Speech SDK archive did not contain speechsdk/SpeechSDK51.exe."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
winetricks() {
|
||||
# Report used packages to the winetricks maintainer so he knows they are being used.
|
||||
if ! [[ -e "${XDG_CACHE_HOME:-$HOME/.cache}/winetricks/track_usage" ]]; then
|
||||
mkdir -p "${XDG_CACHE_HOME:-$HOME/.cache}/winetricks/"
|
||||
echo "1" > "${XDG_CACHE_HOME:-$HOME/.cache}/winetricks/track_usage"
|
||||
fi
|
||||
# Temporary work around for winetricks git bugs. Requires winetricks be installed from package manager.
|
||||
/usr/bin/winetricks "$@"
|
||||
return
|
||||
enable_winetricks_usage_reporting
|
||||
# Download or update agm's copy of winetricks
|
||||
if [[ ! -e "${winetricksPath}/winetricks" ]]; then
|
||||
checkWinetricksUpdate="true"
|
||||
@@ -58,17 +84,104 @@ winetricks() {
|
||||
else
|
||||
if [[ "$checkWinetricksUpdate" != "true" ]]; then
|
||||
checkWinetricksUpdate="true"
|
||||
${winetricksPath}/winetricks --self-update
|
||||
"${winetricksPath}/winetricks" --self-update
|
||||
fi
|
||||
fi
|
||||
# Run the requested winetricks parameters
|
||||
if command -v FEXLoader &> /dev/null ; then
|
||||
WINE="" FEXLoader -- ${winetricksPath}/winetricks "$@"
|
||||
WINE="" FEXLoader -- "${winetricksPath}/winetricks" "$@"
|
||||
else
|
||||
${winetricksPath}/winetricks "$@"
|
||||
"${winetricksPath}/winetricks" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
install_winespeak() {
|
||||
local installerName="winespeak.exe"
|
||||
local installerPath="${cache}/${installerName}"
|
||||
local installerSha256="8007004cd024b391e8f1962455ffe2a8b241cfdf52641a2bc1aa2274bc80f236"
|
||||
local wrapperPath="${WINEPREFIX}/drive_c/Program Files (x86)/espeak-ng-sapi/EspeakSAPI.dll"
|
||||
local wrapperSha256="2282da4a23f18b40e6601a4b9a880f484196bf2f5138881e76428be10d8dbe76"
|
||||
local cscriptPath="${WINEPREFIX}/drive_c/windows/syswow64/cscript.exe"
|
||||
local verifyScriptPath="${WINEPREFIX}/drive_c/windows/temp/verify_winespeak.vbs"
|
||||
local actualSha256
|
||||
local verificationAttempt
|
||||
local registryOutput
|
||||
local voiceOutput
|
||||
local voiceStatus
|
||||
local defaultToken='HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\Espeak-ng US English'
|
||||
|
||||
if [[ -z "${wineSpeakInstaller:-}" ]]; then
|
||||
echo "WineSpeak download URL is not configured."
|
||||
return 1
|
||||
fi
|
||||
|
||||
for ((verificationAttempt = 1; verificationAttempt <= 3; verificationAttempt++)); do
|
||||
download "$wineSpeakInstaller"
|
||||
actualSha256="$(sha256sum "$installerPath" | awk '{print $1}')"
|
||||
if [[ "$actualSha256" == "$installerSha256" ]]; then
|
||||
break
|
||||
fi
|
||||
echo "WineSpeak installer failed its SHA-256 check (attempt ${verificationAttempt} of 3)."
|
||||
rm -f "$installerPath"
|
||||
if ((verificationAttempt == 3)); then
|
||||
return 1
|
||||
fi
|
||||
echo "Downloading WineSpeak again."
|
||||
done
|
||||
|
||||
if ! wine "$installerPath" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-; then
|
||||
echo "WineSpeak installer failed."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$wrapperPath" ]]; then
|
||||
echo "WineSpeak did not install its 32-bit SAPI wrapper."
|
||||
return 1
|
||||
fi
|
||||
actualSha256="$(sha256sum "$wrapperPath" | awk '{print $1}')"
|
||||
if [[ "$actualSha256" != "$wrapperSha256" ]]; then
|
||||
echo "WineSpeak installed an unexpected 32-bit SAPI wrapper."
|
||||
return 1
|
||||
fi
|
||||
|
||||
registryOutput="$(wine reg query 'HKCU\Software\Microsoft\Speech\Voices' /v DefaultTokenId 2>/dev/null)"
|
||||
if ! grep -Fq "$defaultToken" <<< "$registryOutput"; then
|
||||
echo "WineSpeak did not become the default SAPI voice."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$cscriptPath" ]]; then
|
||||
echo "Wine's 32-bit cscript.exe was not found."
|
||||
return 1
|
||||
fi
|
||||
mkdir -p "${verifyScriptPath%/*}"
|
||||
cat > "$verifyScriptPath" <<'EOF'
|
||||
dim speechobject
|
||||
dim voiceDescription
|
||||
set speechobject=createobject("sapi.spvoice")
|
||||
voiceDescription=speechobject.voice.getdescription
|
||||
if instr(1, voiceDescription, "Espeak-ng US English", 1)=0 then
|
||||
wscript.echo voiceDescription
|
||||
wscript.quit 2
|
||||
end if
|
||||
EOF
|
||||
voiceStatus=0
|
||||
voiceOutput="$(wine "$cscriptPath" //nologo 'c:\windows\temp\verify_winespeak.vbs' 2>&1)" || voiceStatus=$?
|
||||
if [[ "$voiceStatus" -ne 0 ]]; then
|
||||
if [[ "$voiceStatus" -eq 2 ]]; then
|
||||
echo "WineSpeak's 32-bit SAPI verification returned an unexpected voice."
|
||||
else
|
||||
echo "WineSpeak's 32-bit SAPI voice could not be created."
|
||||
fi
|
||||
if [[ -n "$voiceOutput" ]]; then
|
||||
echo "$voiceOutput"
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "WineSpeak US English is the default SAPI voice."
|
||||
}
|
||||
|
||||
install_rhvoice() {
|
||||
if [[ -d "${WINEPREFIX}/drive_c/Program Files/Olga Yakovleva/" ]]; then
|
||||
return
|
||||
@@ -168,7 +281,7 @@ install_wine_bottle() {
|
||||
if [[ ${#regularDeps[@]} -gt 0 ]]; then
|
||||
echo "Installing additional dependencies: ${regularDeps[*]}"
|
||||
{
|
||||
env WINE="$WINE" WINESERVER="$WINESERVER" DISPLAY="${DISPLAY:-:0}" winetricks -q isolate_home "${regularDeps[@]}" ${winetricksSettings}
|
||||
WINE="$WINE" WINESERVER="$WINESERVER" DISPLAY="${DISPLAY:-:0}" winetricks -q isolate_home "${regularDeps[@]}" ${winetricksSettings}
|
||||
} | agm_progressbox "Wine Setup" "Installing additional dependencies..."
|
||||
fi
|
||||
|
||||
@@ -176,7 +289,7 @@ install_wine_bottle() {
|
||||
if [[ "$needsSpeechsdk" == "true" ]]; then
|
||||
echo "Installing speechsdk with WINETRICKS_FORCE=1"
|
||||
{
|
||||
env WINE="$WINE" WINESERVER="$WINESERVER" DISPLAY="${DISPLAY:-:0}" WINETRICKS_FORCE=1 winetricks -q speechsdk
|
||||
WINE="$WINE" WINESERVER="$WINESERVER" DISPLAY="${DISPLAY:-:0}" WINETRICKS_FORCE=1 winetricks -q speechsdk
|
||||
} | agm_progressbox "Wine Setup" "Installing Speech SDK..."
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -7,6 +7,8 @@ declare -Ag ipfs=(
|
||||
[nvdaControllerClient32]="${ipfsGateway}/ipfs/QmTrRrT4QFKSkZ8ivfUawA6iJ6adEyyogccE3nLDTfSK8u?filename=nvdaControllerClient32.dll"
|
||||
[nvdaControllerClient64]="${ipfsGateway}/ipfs/QmaYE7RFDtwHCiXCVLcuA3esfFx6E7koidtvrck9AwPuuN?filename=nvdaControllerClient64.dll"
|
||||
[nvda2speechd]="${ipfsGateway}/ipfs/QmPxhoNsoFoJC7bCfioBBCcK8tEoSoYpm342z6u7KjFsVz?filename=nvda2speechd"
|
||||
[speechsdk]="${ipfsGateway}/ipfs/QmXKp7xKoaLmpLJ8GoGJbQcGXnfMkfoqq5PDpyWHWnL9DB?filename=speechsdk.zip"
|
||||
[winespeak]="https://stormgames.wolfe.casa/downloads/winespeak.exe"
|
||||
|
||||
# Games (alphabetical order)
|
||||
[BG 15 Puzzle]="${ipfsGateway}/ipfs/QmQiocMpMXoxejDftKKvmrR5xxpj1qcWcgkhBBwTcyijXg?filename=FPB32Setup10a.exe"
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
install_wine_bottle
|
||||
download "https://terraformers.nu/terraformers-install1.03.exe"
|
||||
download "https://terraformers.nu/pinTFLicKey.txt.zip"
|
||||
wine "${cache}/terraformers-install1.03.exe" /silent
|
||||
install_with_progress unzip "Extracting game license key..." -d "${WINEPREFIX}/drive_c/Program Files (x86)/Terraformers/Prefs" "${cache}/pinTFLicKey.txt.zip"
|
||||
add_launcher "c:\Program Files (x86)\Terraformers\Game.exe"
|
||||
+17
-16
@@ -285,11 +285,14 @@ check_wine32() {
|
||||
# Ensure wine64 bottle exists with all dependencies (wine32 no longer needed!)
|
||||
ensure_wine_bottles() {
|
||||
local wine64Bottle="$HOME/.local/wine64"
|
||||
local setupMarker="${wine64Bottle}/.agm-winespeak-setup-pending"
|
||||
|
||||
# Create wine64 bottle if missing - now includes SAPI support via WINETRICKS_FORCE=1
|
||||
if [[ ! -d "$wine64Bottle" ]] || [[ ! -f "$wine64Bottle/system.reg" ]]; then
|
||||
if [[ ! -d "$wine64Bottle" ]] || [[ ! -f "$wine64Bottle/system.reg" ]] || [[ -f "$setupMarker" ]]; then
|
||||
{
|
||||
echo "# Creating wine64 bottle for modern games..."
|
||||
mkdir -p "$wine64Bottle"
|
||||
touch "$setupMarker"
|
||||
|
||||
# Set up environment for wine64
|
||||
export WINEPREFIX="$wine64Bottle"
|
||||
@@ -300,6 +303,9 @@ ensure_wine_bottles() {
|
||||
# Initialize wine64 bottle
|
||||
echo "# Initializing wine64 environment..."
|
||||
DISPLAY="" wine wineboot -u
|
||||
|
||||
# Seed Winetricks with the Speech SDK payload before installing dependencies.
|
||||
prepare_speechsdk_cache || return 1
|
||||
|
||||
# Install mono and gecko
|
||||
echo "# Installing .NET Framework..."
|
||||
@@ -324,24 +330,17 @@ ensure_wine_bottles() {
|
||||
|
||||
# Install Speech SDK for SAPI compatibility (experimental - requires WINETRICKS_FORCE=1)
|
||||
echo "# Installing Speech SDK for wine64 SAPI support..."
|
||||
env WINE="$WINE" WINESERVER="$WINESERVER" DISPLAY="${DISPLAY:-:0}" WINETRICKS_FORCE=1 winetricks -q speechsdk
|
||||
WINE="$WINE" WINESERVER="$WINESERVER" DISPLAY="${DISPLAY:-:0}" WINETRICKS_FORCE=1 winetricks -q speechsdk
|
||||
|
||||
# Restore win10 after speechsdk (speechsdk sets winxp)
|
||||
winetricks -q win10
|
||||
|
||||
# Initialize SAPI and set Microsoft Mike as default voice
|
||||
echo "# Setting Microsoft Mike as default voice..."
|
||||
mkdir -p "${WINEPREFIX}/drive_c/windows/temp"
|
||||
cat << "EOF" > "${WINEPREFIX}/drive_c/windows/temp/init_sapi.vbs"
|
||||
dim speechobject
|
||||
set speechobject=createobject("sapi.spvoice")
|
||||
speechobject.speak ""
|
||||
EOF
|
||||
wine cscript "c:\\windows\\temp\\init_sapi.vbs"
|
||||
|
||||
wine reg add "HKCU\\SOFTWARE\\Microsoft\\Speech\\Voices" /v "DefaultTokenId" /t REG_SZ /d "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\MSMike" /f
|
||||
wine reg add "HKCU\\SOFTWARE\\Microsoft\\Speech\\Voices" /v "DefaultTTSRate" /t REG_DWORD /d "7" /f
|
||||
echo "Set Microsoft Mike as default voice for wine64"
|
||||
# Install and verify the default 32-bit SAPI voice.
|
||||
echo "# Installing WineSpeak US English..."
|
||||
if ! install_winespeak; then
|
||||
echo "# WineSpeak installation or SAPI verification failed."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Setup nvda2speechd for accessibility if needed
|
||||
if ! ss -ltnp | grep 3457 | grep -q 'cthulhu'; then
|
||||
@@ -353,6 +352,7 @@ EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f "$setupMarker"
|
||||
echo "# Wine64 bottle creation complete."
|
||||
} > >(agm_progressbox "Wine Bottle Setup" "Creating unified wine64 bottle with SAPI support (this may take several minutes)...")
|
||||
fi
|
||||
@@ -945,13 +945,14 @@ source "${scriptDir}/.includes/update.sh"
|
||||
export nvdaControllerClient32Dll="${ipfs[nvdaControllerClient32]}"
|
||||
export nvdaControllerClient64Dll="${ipfs[nvdaControllerClient64]}"
|
||||
export nvda2speechdBinary="${ipfs[nvda2speechd]}"
|
||||
export wineSpeakInstaller="${ipfs[winespeak]}"
|
||||
|
||||
# Check minimum requirements
|
||||
check_requirements || exit 1
|
||||
# Wine32 no longer needed - all games use wine64 with SAPI support via WINETRICKS_FORCE=1
|
||||
# check_wine32 # Disabled - wine32 eliminated 2025-12-06
|
||||
# Ensure wine bottles exist with dependencies
|
||||
ensure_wine_bottles
|
||||
ensure_wine_bottles || exit 1
|
||||
# Check for updates
|
||||
update
|
||||
# Get latest news if available
|
||||
|
||||
@@ -13,4 +13,6 @@ if [[ $newver -gt $myver ]]; then
|
||||
download "https://kaldobsky.com/audiogames/swamp2_update.zip"
|
||||
install_with_progress unzip "Extracting game files..." -d "${swamphouse}" "${cache}/swamp2_update.zip"
|
||||
rm "${cache}/swamp2_update.zip"
|
||||
else
|
||||
agm_msgbox "Nothing to do; your game is up to date."
|
||||
fi
|
||||
|
||||
Executable
+116
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
export WINEPREFIX="${WINEPREFIX:-${HOME}/.local/wine64}"
|
||||
export WINEDEBUG="${WINEDEBUG:--all}"
|
||||
|
||||
installerUrl="${WINESPEAK_INSTALLER_URL:-https://stormgames.wolfe.casa/downloads/winespeak.exe}"
|
||||
installerName="winespeak.exe"
|
||||
installerSha256="${WINESPEAK_INSTALLER_SHA256:-8007004cd024b391e8f1962455ffe2a8b241cfdf52641a2bc1aa2274bc80f236}"
|
||||
cacheDir="${XDG_CACHE_HOME:-${HOME}/.cache}/audiogame-manager"
|
||||
installerPath="${cacheDir}/${installerName}"
|
||||
partialPath="${installerPath}.part"
|
||||
wrapperPath="${WINEPREFIX}/drive_c/Program Files (x86)/espeak-ng-sapi/EspeakSAPI.dll"
|
||||
wrapperSha256="2282da4a23f18b40e6601a4b9a880f484196bf2f5138881e76428be10d8dbe76"
|
||||
cscriptPath="${WINEPREFIX}/drive_c/windows/syswow64/cscript.exe"
|
||||
verifyScriptPath="${WINEPREFIX}/drive_c/windows/temp/verify_winespeak.vbs"
|
||||
voiceToken="HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\Espeak-ng US English"
|
||||
|
||||
fail() {
|
||||
printf 'Error: %s\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
require_command() {
|
||||
command -v "$1" > /dev/null 2>&1 || fail "Required command not found: $1"
|
||||
}
|
||||
|
||||
verify_sha256() {
|
||||
local file="$1"
|
||||
local expected="$2"
|
||||
local actual
|
||||
|
||||
actual="$(sha256sum "$file" | awk '{print $1}')"
|
||||
[[ "$actual" == "$expected" ]]
|
||||
}
|
||||
|
||||
download_installer() {
|
||||
mkdir -p "$cacheDir"
|
||||
|
||||
if [[ -s "$installerPath" ]] && verify_sha256 "$installerPath" "$installerSha256"; then
|
||||
printf 'Using cached WineSpeak installer.\n'
|
||||
return
|
||||
fi
|
||||
|
||||
rm -f "$installerPath" "$partialPath"
|
||||
printf 'Downloading WineSpeak...\n'
|
||||
if ! curl -L4 --fail --retry 3 --output "$partialPath" "$installerUrl"; then
|
||||
rm -f "$partialPath"
|
||||
fail 'Could not download WineSpeak.'
|
||||
fi
|
||||
|
||||
if ! verify_sha256 "$partialPath" "$installerSha256"; then
|
||||
rm -f "$partialPath"
|
||||
fail 'The downloaded WineSpeak installer failed its SHA-256 check.'
|
||||
fi
|
||||
|
||||
mv "$partialPath" "$installerPath"
|
||||
}
|
||||
|
||||
install_winespeak() {
|
||||
local registryOutput
|
||||
local voiceOutput
|
||||
|
||||
download_installer
|
||||
|
||||
wineserver -k || true
|
||||
printf 'Installing WineSpeak into %s...\n' "$WINEPREFIX"
|
||||
if ! wine "$installerPath" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-; then
|
||||
fail 'WineSpeak installation failed.'
|
||||
fi
|
||||
|
||||
if [[ ! -f "$wrapperPath" ]]; then
|
||||
fail 'WineSpeak did not install its 32-bit SAPI wrapper.'
|
||||
fi
|
||||
if ! verify_sha256 "$wrapperPath" "$wrapperSha256"; then
|
||||
fail 'WineSpeak installed an unexpected 32-bit SAPI wrapper.'
|
||||
fi
|
||||
|
||||
printf 'Setting WineSpeak US English as the default SAPI voice...\n'
|
||||
if ! wine reg add 'HKCU\Software\Microsoft\Speech\Voices' \
|
||||
/v DefaultTokenId /t REG_SZ /d "$voiceToken" /f > /dev/null; then
|
||||
fail 'Could not set the default SAPI voice.'
|
||||
fi
|
||||
|
||||
registryOutput="$(wine reg query 'HKCU\Software\Microsoft\Speech\Voices' /v DefaultTokenId 2>/dev/null)"
|
||||
if ! grep -Fq "$voiceToken" <<< "$registryOutput"; then
|
||||
fail 'Could not verify the default SAPI voice.'
|
||||
fi
|
||||
|
||||
if [[ ! -f "$cscriptPath" ]]; then
|
||||
fail "Wine's 32-bit cscript.exe was not found. Install speechsdk in this prefix first."
|
||||
fi
|
||||
mkdir -p "${verifyScriptPath%/*}"
|
||||
printf '%s\n' \
|
||||
'dim speechobject' \
|
||||
'set speechobject=createobject("sapi.spvoice")' \
|
||||
'wscript.echo speechobject.voice.getdescription' > "$verifyScriptPath"
|
||||
if ! voiceOutput="$(wine "$cscriptPath" //nologo 'c:\windows\temp\verify_winespeak.vbs' 2>&1)"; then
|
||||
fail "WineSpeak's 32-bit SAPI voice could not be created: ${voiceOutput}"
|
||||
fi
|
||||
if ! grep -Fq 'Espeak-ng US English' <<< "$voiceOutput"; then
|
||||
fail "WineSpeak's 32-bit SAPI verification returned an unexpected voice: ${voiceOutput}"
|
||||
fi
|
||||
|
||||
printf 'WineSpeak is installed and US English is the default SAPI voice.\n'
|
||||
}
|
||||
|
||||
if [[ ! -d "${WINEPREFIX}/drive_c" ]]; then
|
||||
fail "Wine prefix does not exist: ${WINEPREFIX}"
|
||||
fi
|
||||
|
||||
for commandName in curl wine wineserver sha256sum awk grep; do
|
||||
require_command "$commandName"
|
||||
done
|
||||
|
||||
install_winespeak
|
||||
Reference in New Issue
Block a user