Espeak now set as default voice for new installs. Install_espeak.sh helper script added in speech.
This commit is contained in:
@@ -69,6 +69,77 @@ winetricks() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
install_winespeak() {
|
||||||
|
local installerName="winespeak.exe"
|
||||||
|
local installerPath="${cache}/${installerName}"
|
||||||
|
local installerSha256="187d4db69f3af7c1bca1c100a04489b76732048be7c38449781da360ed7b2d66"
|
||||||
|
local wrapperPath="${WINEPREFIX}/drive_c/Program Files (x86)/espeak-ng-sapi/EspeakSAPI.dll"
|
||||||
|
local wrapperSha256="8009750dad82ca6665871814033dcee6844bb424f033130c109f47e188c5364b"
|
||||||
|
local cscriptPath="${WINEPREFIX}/drive_c/windows/syswow64/cscript.exe"
|
||||||
|
local verifyScriptPath="${WINEPREFIX}/drive_c/windows/temp/verify_winespeak.vbs"
|
||||||
|
local actualSha256
|
||||||
|
local registryOutput
|
||||||
|
local voiceOutput
|
||||||
|
local defaultToken='HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\TokenEnums\eSpeak-NG\English (America)'
|
||||||
|
|
||||||
|
if [[ -z "${wineSpeakInstaller:-}" ]]; then
|
||||||
|
echo "WineSpeak download URL is not configured."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
download "$wineSpeakInstaller"
|
||||||
|
actualSha256="$(sha256sum "$installerPath" | awk '{print $1}')"
|
||||||
|
if [[ "$actualSha256" != "$installerSha256" ]]; then
|
||||||
|
echo "WineSpeak installer failed its SHA-256 check."
|
||||||
|
rm -f "$installerPath"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
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
|
||||||
|
set speechobject=createobject("sapi.spvoice")
|
||||||
|
wscript.echo speechobject.voice.getdescription
|
||||||
|
EOF
|
||||||
|
if ! voiceOutput="$(wine "$cscriptPath" //nologo 'c:\windows\temp\verify_winespeak.vbs' 2>&1)"; then
|
||||||
|
echo "WineSpeak's 32-bit SAPI voice could not be created."
|
||||||
|
echo "$voiceOutput"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if ! grep -Fq "English (America)" <<< "$voiceOutput"; then
|
||||||
|
echo "WineSpeak's 32-bit SAPI verification returned an unexpected voice."
|
||||||
|
echo "$voiceOutput"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "WineSpeak English (America) is the default SAPI voice."
|
||||||
|
}
|
||||||
|
|
||||||
install_rhvoice() {
|
install_rhvoice() {
|
||||||
if [[ -d "${WINEPREFIX}/drive_c/Program Files/Olga Yakovleva/" ]]; then
|
if [[ -d "${WINEPREFIX}/drive_c/Program Files/Olga Yakovleva/" ]]; then
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ declare -Ag ipfs=(
|
|||||||
[nvdaControllerClient32]="${ipfsGateway}/ipfs/QmTrRrT4QFKSkZ8ivfUawA6iJ6adEyyogccE3nLDTfSK8u?filename=nvdaControllerClient32.dll"
|
[nvdaControllerClient32]="${ipfsGateway}/ipfs/QmTrRrT4QFKSkZ8ivfUawA6iJ6adEyyogccE3nLDTfSK8u?filename=nvdaControllerClient32.dll"
|
||||||
[nvdaControllerClient64]="${ipfsGateway}/ipfs/QmaYE7RFDtwHCiXCVLcuA3esfFx6E7koidtvrck9AwPuuN?filename=nvdaControllerClient64.dll"
|
[nvdaControllerClient64]="${ipfsGateway}/ipfs/QmaYE7RFDtwHCiXCVLcuA3esfFx6E7koidtvrck9AwPuuN?filename=nvdaControllerClient64.dll"
|
||||||
[nvda2speechd]="${ipfsGateway}/ipfs/QmPxhoNsoFoJC7bCfioBBCcK8tEoSoYpm342z6u7KjFsVz?filename=nvda2speechd"
|
[nvda2speechd]="${ipfsGateway}/ipfs/QmPxhoNsoFoJC7bCfioBBCcK8tEoSoYpm342z6u7KjFsVz?filename=nvda2speechd"
|
||||||
|
[winespeak]="https://stormgames.wolfe.casa/downloads/winespeak.exe"
|
||||||
|
|
||||||
# Games (alphabetical order)
|
# Games (alphabetical order)
|
||||||
[BG 15 Puzzle]="${ipfsGateway}/ipfs/QmQiocMpMXoxejDftKKvmrR5xxpj1qcWcgkhBBwTcyijXg?filename=FPB32Setup10a.exe"
|
[BG 15 Puzzle]="${ipfsGateway}/ipfs/QmQiocMpMXoxejDftKKvmrR5xxpj1qcWcgkhBBwTcyijXg?filename=FPB32Setup10a.exe"
|
||||||
|
|||||||
+13
-15
@@ -285,11 +285,14 @@ check_wine32() {
|
|||||||
# Ensure wine64 bottle exists with all dependencies (wine32 no longer needed!)
|
# Ensure wine64 bottle exists with all dependencies (wine32 no longer needed!)
|
||||||
ensure_wine_bottles() {
|
ensure_wine_bottles() {
|
||||||
local wine64Bottle="$HOME/.local/wine64"
|
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
|
# 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..."
|
echo "# Creating wine64 bottle for modern games..."
|
||||||
|
mkdir -p "$wine64Bottle"
|
||||||
|
touch "$setupMarker"
|
||||||
|
|
||||||
# Set up environment for wine64
|
# Set up environment for wine64
|
||||||
export WINEPREFIX="$wine64Bottle"
|
export WINEPREFIX="$wine64Bottle"
|
||||||
@@ -329,19 +332,12 @@ ensure_wine_bottles() {
|
|||||||
# Restore win10 after speechsdk (speechsdk sets winxp)
|
# Restore win10 after speechsdk (speechsdk sets winxp)
|
||||||
winetricks -q win10
|
winetricks -q win10
|
||||||
|
|
||||||
# Initialize SAPI and set Microsoft Mike as default voice
|
# Install and verify the default 32-bit SAPI voice.
|
||||||
echo "# Setting Microsoft Mike as default voice..."
|
echo "# Installing WineSpeak English (America)..."
|
||||||
mkdir -p "${WINEPREFIX}/drive_c/windows/temp"
|
if ! install_winespeak; then
|
||||||
cat << "EOF" > "${WINEPREFIX}/drive_c/windows/temp/init_sapi.vbs"
|
echo "# WineSpeak installation or SAPI verification failed."
|
||||||
dim speechobject
|
return 1
|
||||||
set speechobject=createobject("sapi.spvoice")
|
fi
|
||||||
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"
|
|
||||||
|
|
||||||
# Setup nvda2speechd for accessibility if needed
|
# Setup nvda2speechd for accessibility if needed
|
||||||
if ! ss -ltnp | grep 3457 | grep -q 'cthulhu'; then
|
if ! ss -ltnp | grep 3457 | grep -q 'cthulhu'; then
|
||||||
@@ -353,6 +349,7 @@ EOF
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
rm -f "$setupMarker"
|
||||||
echo "# Wine64 bottle creation complete."
|
echo "# Wine64 bottle creation complete."
|
||||||
} > >(agm_progressbox "Wine Bottle Setup" "Creating unified wine64 bottle with SAPI support (this may take several minutes)...")
|
} > >(agm_progressbox "Wine Bottle Setup" "Creating unified wine64 bottle with SAPI support (this may take several minutes)...")
|
||||||
fi
|
fi
|
||||||
@@ -945,13 +942,14 @@ source "${scriptDir}/.includes/update.sh"
|
|||||||
export nvdaControllerClient32Dll="${ipfs[nvdaControllerClient32]}"
|
export nvdaControllerClient32Dll="${ipfs[nvdaControllerClient32]}"
|
||||||
export nvdaControllerClient64Dll="${ipfs[nvdaControllerClient64]}"
|
export nvdaControllerClient64Dll="${ipfs[nvdaControllerClient64]}"
|
||||||
export nvda2speechdBinary="${ipfs[nvda2speechd]}"
|
export nvda2speechdBinary="${ipfs[nvda2speechd]}"
|
||||||
|
export wineSpeakInstaller="${ipfs[winespeak]}"
|
||||||
|
|
||||||
# Check minimum requirements
|
# Check minimum requirements
|
||||||
check_requirements || exit 1
|
check_requirements || exit 1
|
||||||
# Wine32 no longer needed - all games use wine64 with SAPI support via WINETRICKS_FORCE=1
|
# Wine32 no longer needed - all games use wine64 with SAPI support via WINETRICKS_FORCE=1
|
||||||
# check_wine32 # Disabled - wine32 eliminated 2025-12-06
|
# check_wine32 # Disabled - wine32 eliminated 2025-12-06
|
||||||
# Ensure wine bottles exist with dependencies
|
# Ensure wine bottles exist with dependencies
|
||||||
ensure_wine_bottles
|
ensure_wine_bottles || exit 1
|
||||||
# Check for updates
|
# Check for updates
|
||||||
update
|
update
|
||||||
# Get latest news if available
|
# Get latest news if available
|
||||||
|
|||||||
Executable
+93
@@ -0,0 +1,93 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
export WINEPREFIX="${WINEPREFIX:-${HOME}/.local/wine64}"
|
||||||
|
export WINEDEBUG="${WINEDEBUG:--all}"
|
||||||
|
|
||||||
|
installerUrl="https://stormgames.wolfe.casa/downloads/winespeak.exe"
|
||||||
|
installerName="winespeak.exe"
|
||||||
|
installerSha256="187d4db69f3af7c1bca1c100a04489b76732048be7c38449781da360ed7b2d66"
|
||||||
|
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="8009750dad82ca6665871814033dcee6844bb424f033130c109f47e188c5364b"
|
||||||
|
voiceToken="HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices\\TokenEnums\\eSpeak-NG\\English (America)"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
download_installer
|
||||||
|
|
||||||
|
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 English (America) 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
|
||||||
|
|
||||||
|
printf 'WineSpeak is installed and English (America) is the default SAPI voice.\n'
|
||||||
|
}
|
||||||
|
|
||||||
|
for commandName in curl wine sha256sum awk grep; do
|
||||||
|
require_command "$commandName"
|
||||||
|
done
|
||||||
|
|
||||||
|
install_winespeak
|
||||||
Reference in New Issue
Block a user