# Shared paths for HoMM / Whisky (source from other scripts in this folder). GAMES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" GAMES_CACHE_DIR="${GAMES_DIR}/cache" BOTTLE_ID="38412122-AAE1-4831-9F2E-6A0EB364B3F9" BOTTLE_NAME="HoMM-OldenEra" # franke Whisky 3 (Whisky.app) — канон; isaacmarovitz legacy после migrate-bottle-to-franke-whisky.sh _FRANKE_BOTTLE="${HOME}/Library/Containers/com.franke.Whisky/Bottles/${BOTTLE_ID}" _ISAAC_BOTTLE="${HOME}/Library/Containers/com.isaacmarovitz.Whisky/Bottles/${BOTTLE_ID}" if [[ -d "${_FRANKE_BOTTLE}/drive_c" ]]; then BOTTLE_DIR="${_FRANKE_BOTTLE}" WHISKY_LIBS="${HOME}/Library/Application Support/com.franke.Whisky" else BOTTLE_DIR="${_ISAAC_BOTTLE}" WHISKY_LIBS="${HOME}/Library/Application Support/com.isaacmarovitz.Whisky" fi unset _FRANKE_BOTTLE _ISAAC_BOTTLE WINE64="${WHISKY_LIBS}/Libraries/Wine/bin/wine64" WINE_LIB="${WHISKY_LIBS}/Libraries/Wine/lib" STEAM_DIR="${BOTTLE_DIR}/drive_c/Program Files (x86)/Steam" STEAM_EXE="${STEAM_DIR}/Steam.exe" STEAM_SETUP="${GAMES_CACHE_DIR}/SteamSetup.exe" LIBRARIES_TAR="${GAMES_CACHE_DIR}/Libraries.tar.gz" # GOG Galaxy 2.0 (полный offline setup ~290 MB; web stub GOG_Galaxy_2.0.exe — только загрузчик) GOG_SETUP="${GAMES_CACHE_DIR}/setup_galaxy.exe" GOG_SETUP_URL="${GOG_SETUP_URL:-}" GOG_DIR_X86="${BOTTLE_DIR}/drive_c/Program Files (x86)/GOG Galaxy" GOG_DIR_X64="${BOTTLE_DIR}/drive_c/Program Files/GOG Galaxy" GOG_EXE="${GOG_DIR_X86}/GalaxyClient.exe" # CEF (как Steam/Whisky #1220). Без -cef-in-process-gpu — меньше gpu-process CPU spin. GOG_GALAXY_BASE_ARGS="${GOG_GALAXY_BASE_ARGS:-/runWithoutUpdating /deelevated}" GOG_GALAXY_CEF_ARGS="${GOG_GALAXY_CEF_ARGS:--allosarches -cef-force-32bit -no-cef-sandbox -cef-disable-gpu}" homm_gog_cef_args_line() { printf '%s %s' "${GOG_GALAXY_BASE_ARGS}" "${GOG_GALAXY_CEF_ARGS}" } homm_gog_cef_args_array() { local _IFS=$IFS IFS=' ' # shellcheck disable=SC2206 local -a _a=(${GOG_GALAXY_BASE_ARGS} ${GOG_GALAXY_CEF_ARGS}) IFS=$_IFS printf '%s\n' "${_a[@]}" } homm_gog_exe() { if [[ -f "${GOG_EXE}" ]]; then echo "${GOG_EXE}" return 0 fi local found found="$(find "${BOTTLE_DIR}/drive_c/Program Files"* -maxdepth 3 -name 'GalaxyClient.exe' 2>/dev/null | head -1)" if [[ -n "${found}" ]]; then echo "${found}" return 0 fi return 1 } homm_wine_gog_running() { pgrep -f "${BOTTLE_ID}.*[Gg]alaxy[Cc]lient" >/dev/null 2>&1 \ || pgrep -f 'GOG Galaxy.*GalaxyClient' >/dev/null 2>&1 \ || pgrep -f 'GalaxyClient\.exe' >/dev/null 2>&1 } export_wine_env_gog() { export_wine_env unset WINEDLLOVERRIDES 2>/dev/null || true export WINEDEBUG="${WINEDEBUG:--all}" } # Heroes of Might and Magic: Olden Era (Steam) HOMM_APP_ID="3105440" HOMM_DIR="${STEAM_DIR}/steamapps/common/Heroes of Might and Magic Olden Era" HOMM_EXE="${HOMM_DIR}/HeroesOldenEra.exe" WINEPATH_BIN="${WHISKY_LIBS}/Libraries/Wine/bin/winepath" # Запуск игры: по умолчанию виртуальный стол Wine (часто лечит «двигается, ЛКМ нет»). # HOMM_USE_WINEVDESKTOP=0 — запуск напрямую без explorer /desktop (быстрый A/B тест). # HOMM_LAUNCH_DIRECT=1 — legacy-переключатель прямого запуска (оставлен для совместимости). # HOMM_VDESKTOP=WxH — размер виртуального стола. # # По умолчанию Unity принудительно в оконном режиме (-screen-fullscreen 0 …): # это часто восстанавливает ЛКМ на macOS+Wine при багах полноэкранного режима. # Выключить: HOMM_UNITY_WINDOWED=0 HOMM_VDESKTOP="${HOMM_VDESKTOP:-1920x1080}" HOMM_USE_WINEVDESKTOP="${HOMM_USE_WINEVDESKTOP:-1}" HOMM_LAUNCH_DIRECT="${HOMM_LAUNCH_DIRECT:-0}" HOMM_UNITY_WINDOWED="${HOMM_UNITY_WINDOWED:-1}" # Дополнительные аргументы Unity через пробел, напр.: "-popupwindow" HOMM_UNITY_EXTRA="${HOMM_UNITY_EXTRA:-}" # Steam CEF (steamwebhelper): без этих флагов в Whisky/Wine часто нет окна UI # (cef_log: message_window.cc Class does not exist, webhelper в цикле перезапуска). # Источник: Whisky #1220 — -allosarches -cef-force-32bit -cef-in-process-gpu -no-cef-sandbox HOMM_STEAM_CEF_ARGS="${HOMM_STEAM_CEF_ARGS:--allosarches -cef-force-32bit -cef-in-process-gpu -no-cef-sandbox -cef-disable-gpu}" # HOMM_STEAM_VDESKTOP=1 — запуск через explorer /desktop (если окно «теряется») HOMM_STEAM_VDESKTOP="${HOMM_STEAM_VDESKTOP:-0}" # Диск: APFS Data volume. Guard: block < HOMM_DISK_MIN_GB (3), warn < HOMM_DISK_WARN_PCT (10). homm_data_volume_path() { if [[ -d /System/Volumes/Data ]]; then echo /System/Volumes/Data elif [[ -n "${HOME:-}" && -d "${HOME}" ]]; then echo "${HOME}" else echo / fi } homm_disk_free_kb() { df -k "$(homm_data_volume_path)" | awk 'NR==2 {print $4}' } homm_disk_total_kb() { df -k "$(homm_data_volume_path)" | awk 'NR==2 {print $2}' } homm_disk_used_pct() { df -k "$(homm_data_volume_path)" | awk 'NR==2 {gsub(/%/,"",$5); print $5}' } homm_disk_free_pct() { local free_kb total_kb free_kb="$(homm_disk_free_kb)" total_kb="$(homm_disk_total_kb)" if [[ "${total_kb}" -gt 0 ]]; then echo $(( free_kb * 100 / total_kb )) else echo 0 fi } export_wine_env() { export WINEPREFIX="${BOTTLE_DIR}" export WINEMSYNC=1 export WINEESYNC=1 export DYLD_LIBRARY_PATH="${WINE_LIB}:${DYLD_LIBRARY_PATH:-}" } # Steam UI: без DXVK; dwrite=n,b — классический фикс пустого текста VGUI (см. fix-homm-steam-ui.sh). export_wine_env_steam() { export_wine_env unset DXVK_ASYNC DXVK_HUD 2>/dev/null || true export WINEDLLOVERRIDES="dwrite=n,b" } homm_kill_mac_steam() { pkill -9 -f 'Steam.AppBundle/Steam/Contents/MacOS/steam_osx' 2>/dev/null || true pkill -9 -f 'Steam.AppBundle/Steam/Contents/MacOS/ipcserver' 2>/dev/null || true pkill -9 -f 'Steam Helper.app/Contents/MacOS/Steam Helper' 2>/dev/null || true } homm_steam_cef_args() { # shellcheck disable=SC2206 echo ${HOMM_STEAM_CEF_ARGS} } homm_steam_connection_log() { echo "${STEAM_DIR}/logs/connection_log.txt" } # Последняя сессия в connection_log — Logged On? homm_steam_logged_on() { local log log="$(homm_steam_connection_log)" [[ -f "${log}" ]] || return 1 tail -25 "${log}" | grep -qE '\[Logged On' } # Steam.exe в bottle (Terminal start.sh или Whisky GUI — argv часто C:\…\Steam\steam.exe). # В regex избегать \S в "\Steam" — иначе ложные совпадения; используйте [/\\] или . homm_wine_steam_running() { pgrep -f "${BOTTLE_ID}.*[Ss]team\\.exe" >/dev/null 2>&1 \ || pgrep -f "Whisky/Bottles/${BOTTLE_ID}.*[Ss]team\\.exe" >/dev/null 2>&1 \ || pgrep -f 'Steam[/\\]steam\.exe' >/dev/null 2>&1 \ || pgrep -f 'steamwebhelper\.exe' >/dev/null 2>&1 } # Logged On + живой клиент (для play/game и сейвов). homm_steam_ready_for_game() { homm_steam_logged_on || return 1 homm_wine_steam_running } # Нативный Steam.app на Mac мешает bottle (login / CM / ipc). homm_mac_steam_running() { pgrep -f 'Steam\.AppBundle/Steam/Contents/MacOS/steam_osx' >/dev/null 2>&1 } homm_warn_mac_steam() { if homm_mac_steam_running; then echo "⚠️ Запущен нативный Steam на Mac (часто остаётся после удаления Steam.app из /Applications)." echo " Папка: ~/Library/Application Support/Steam/Steam.AppBundle/" echo " Остановить:" echo " pkill -f 'Steam.AppBundle/Steam/Contents/MacOS/steam_osx'" echo " pkill -f 'Steam.AppBundle/Steam/Contents/MacOS/ipcserver'" echo " Затем: bash ${GAMES_DIR}/start.sh reset && bash ${GAMES_DIR}/start.sh steam-ui" return 1 fi return 0 } # Olden Era (Unity DX11): Gcenx DXVK-macOS в system32 — см. install-dxvk-macos.sh export_wine_env_game() { export_wine_env export WINEDLLOVERRIDES="d3d11,d3d10core=n,b" export DXVK_ASYNC=1 export DXVK_HUD=0 # Меньше конфликтов fullscreen с macOS Stage Manager / края экрана export SDL_VIDEO_MAC_FULLSCREEN_SPACES="${SDL_VIDEO_MAC_FULLSCREEN_SPACES:-0}" }