diff --git a/.includes/bottle.sh b/.includes/bottle.sh index fe893ec..a3b5518 100644 --- a/.includes/bottle.sh +++ b/.includes/bottle.sh @@ -133,34 +133,94 @@ install_wine_bottle() { echo "Using pre-configured wine${architecture} bottle at $WINEPREFIX" + # Store winVer for per-app setting in add_launcher (don't set globally) + if [[ -n "$winVer" ]]; then + export gameWinVer="$winVer" + fi + # Install any additional game-specific dependencies if specified if [[ $# -gt 0 ]]; then # Filter out dependencies that are already installed in bottle creation local depsToInstall=() local alreadyInstalled="speechsdk sapi corefonts isolate_home" - + for dep in "$@"; do # Skip dependencies already installed during bottle creation + # Also skip winVer patterns - handled separately above if [[ ! " $alreadyInstalled " =~ " $dep " ]] && [[ ! "$dep" =~ ^win(7|8|10)$ ]]; then depsToInstall+=("$dep") fi done - + if [[ ${#depsToInstall[@]} -gt 0 ]]; then - echo "Installing additional dependencies: ${depsToInstall[*]}" - { - env WINE="$WINE" WINESERVER="$WINESERVER" DISPLAY="${DISPLAY:-:0}" WINETRICKS_FORCE=1 winetricks -q isolate_home "${depsToInstall[@]}" "${winVer:-win7}" ${winetricksSettings} - } | agm_progressbox "Wine Setup" "Installing additional dependencies..." + # Separate speechsdk (needs FORCE) from other deps + local regularDeps=() + local needsSpeechsdk=false + for dep in "${depsToInstall[@]}"; do + if [[ "$dep" == "speechsdk" ]]; then + needsSpeechsdk=true + else + regularDeps+=("$dep") + fi + done + + # Install regular deps without FORCE + if [[ ${#regularDeps[@]} -gt 0 ]]; then + echo "Installing additional dependencies: ${regularDeps[*]}" + { + env WINE="$WINE" WINESERVER="$WINESERVER" DISPLAY="${DISPLAY:-:0}" winetricks -q isolate_home "${regularDeps[@]}" ${winetricksSettings} + } | agm_progressbox "Wine Setup" "Installing additional dependencies..." + fi + + # Install speechsdk with FORCE if needed + 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 + } | agm_progressbox "Wine Setup" "Installing Speech SDK..." + fi fi fi } +# Set Windows version for a specific executable (per-app, not global) +# This allows different games to use different Windows versions in the same bottle +set_app_winver() { + local exePath="$1" + local winVersion="$2" + + if [[ -z "$exePath" ]] || [[ -z "$winVersion" ]]; then + return + fi + + # Extract just the exe filename from path (handles both / and \ separators) + local exeName="${exePath##*\\}" + exeName="${exeName##*/}" + + echo "Setting Windows version $winVersion for $exeName" + cat > /tmp/app_winver.reg << EOF +REGEDIT4 + +[HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\${exeName}] +"Version"="${winVersion}" +EOF + wine regedit /tmp/app_winver.reg + rm /tmp/app_winver.reg +} + add_launcher() { # Determine architecture from WINEPREFIX path instead of WINEARCH variable local architecture="win64" # default if [[ "$WINEPREFIX" =~ wine32 ]]; then architecture="win32" fi + + # Set per-app Windows version if specified + if [[ -n "$gameWinVer" ]]; then + set_app_winver "$1" "$gameWinVer" + unset gameWinVer + fi + local launchSettings="${architecture}|${1}|${game}" shift while [[ $# -gt 0 ]]; do diff --git a/.install/Shadow Line.sh b/.install/Shadow Line.sh index d421a17..7916505 100644 --- a/.install/Shadow Line.sh +++ b/.install/Shadow Line.sh @@ -1,7 +1,7 @@ download "https://www.mm-galabo.com/sr/Download_files_srfv/shadowrine_fullvoice3.171.exe" "https://raw.githubusercontent.com/LordLuceus/sr-english-localization/master/language_en.dat" export WINEARCH="win64" # Migrated to wine64 with WINETRICKS_FORCE=1 export winVer="win8" -install_wine_bottle +install_wine_bottle fakejapanese # Add bcrypt DLL override required for Shadow Line to run cat > /tmp/bcrypt_override.reg << 'EOF' [HKEY_CURRENT_USER\Software\Wine\DllOverrides] diff --git a/CLAUDE.md b/CLAUDE.md index 05ee2a4..b416d6e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -46,11 +46,13 @@ The project uses Wine with a unified architecture: **Discovery (2025-12-06)**: Setting `WINETRICKS_FORCE=1` enables reliable speechsdk installation in wine64+WOW64 bottles, eliminating the need for wine32 for most SAPI-dependent games. **Implementation:** -- `audiogame-manager.sh:95` - wine32 bottle creation uses `WINETRICKS_FORCE=1` -- `audiogame-manager.sh:157` - wine64 bottle creation now includes speechsdk with `WINETRICKS_FORCE=1` -- `.includes/bottle.sh:158` - All additional winetricks installations use `WINETRICKS_FORCE=1` +- `audiogame-manager.sh:96` - wine64 bottle creation includes speechsdk with `WINETRICKS_FORCE=1` +- `audiogame-manager.sh:99` - Restores win10 after speechsdk (see caveat below) +- `.includes/bottle.sh:176-181` - Only speechsdk installations use `WINETRICKS_FORCE=1` (other deps use regular winetricks) - Both bottles install Microsoft Mike as the default SAPI voice automatically +**CAVEAT**: The `speechsdk` winetricks verb sets `w_set_winver winxp` at the end, trampling any previously set Windows version. Always call `winetricks win10` AFTER installing speechsdk. + **Migrated SAPI Games (wine64):** - Bloodshed - Tested and confirmed working - Kitchensinc Games - Tested and confirmed working (VB6) @@ -63,9 +65,25 @@ The project uses Wine with a unified architecture: - Three D velocity - Already configured for wine64, now functional **Migrated Self-Voicing Games (wine64):** -- Shadow Line - Migrated, has issues (crashes after launch - needs further investigation) +- Shadow Line - Migrated, requires Windows 8 via per-app versioning - Villains From Beyond - Tested and confirmed working +#### Per-Application Windows Version + +**Problem (2025-12-08)**: Some games require specific Windows versions (e.g., Shadow Line needs win8) but with a unified bottle, `winetricks winXX` changes the version globally for ALL games. + +**Solution**: Use Wine's per-application settings via registry keys: +``` +[HKEY_CURRENT_USER\Software\Wine\AppDefaults\executable.exe] +"Version"="win8" +``` + +**Implementation:** +- Game installers set `export winVer="win8"` (or win7, win10) +- `install_wine_bottle()` stores this in `gameWinVer` (doesn't apply globally) +- `add_launcher()` calls `set_app_winver()` which writes the per-exe registry key +- Located in `.includes/bottle.sh:186-209` (`set_app_winver` function) + **Architecture Selection Logic:** - Games explicitly setting `WINEARCH=win64` will use wine64 (new behavior) - Games passing `sapi` dependency use wine64 with speechsdk pre-installed diff --git a/audiogame-manager.sh b/audiogame-manager.sh index 18cf3fc..b8fcc5f 100755 --- a/audiogame-manager.sh +++ b/audiogame-manager.sh @@ -95,6 +95,9 @@ ensure_wine_bottles() { echo "# Installing Speech SDK for wine64 SAPI support..." env 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"