Compare commits

...

8 Commits

Author SHA1 Message Date
Storm Dragon
951fa7c1ba Update alert function messaging
Show the actual guidance in a single acknowledgement dialog instead of a generic OK prompt, and update alert-based installer instructions to use the new helper contract.
2026-03-02 23:01:50 -05:00
Storm Dragon
f9394f90c9 To comment out a game, it's now #// on the first line. Updated executioner's rage and hopefully fixed new keyboard problems. 2026-02-22 14:30:23 -05:00
Storm Dragon
1fd3fcd21f Updated shabang for dependency installation scripts. 2026-02-18 15:19:13 -05:00
abolfazl ebrahimi
cf1377d9e8 Added Linux Mint dependency installer script. 2026-02-18 15:16:19 -05:00
Storm Dragon
528ee7cd56 Added game Chopper Challenge. 2026-02-03 20:45:00 -05:00
Storm Dragon
9ebb52f48f Fix directory permissions in Shooter RW. 2026-01-12 17:52:51 -05:00
Storm Dragon
9d4e9b9a7f Shooter RW added. 2026-01-12 16:23:39 -05:00
Storm Dragon
0c8a749240 Added support for cthulhu's window reader plugin. 2026-01-12 11:52:07 -05:00
33 changed files with 402 additions and 115 deletions

View File

@@ -1,13 +1,31 @@
#!/usr/bin/env bash
# shellcheck disable=SC2034,SC2154 # sourced by audiogame-manager with shared globals and exported state
# Source IPFS game URLs
source "${BASH_SOURCE[0]%/*}/ipfs.sh"
# Alerts, for when user needs to read something.
alert() {
local title="Alert"
local backTitle=""
local message="Press OK to continue."
if [[ $# -eq 1 ]]; then
message="$1"
elif [[ $# -eq 2 ]]; then
title="$1"
backTitle="$1"
message="$2"
elif [[ $# -ge 3 ]]; then
title="$1"
backTitle="$2"
shift 2
message="$*"
fi
play -qnV0 synth 3 pluck D3 pluck A3 pluck D4 pluck F4 pluck A4 delay 0 .1 .2 .3 .4 remix - chorus 0.9 0.9 38 0.75 0.3 0.5 -t
echo
agm_msgbox "Alert" "" "Press OK to continue."
agm_msgbox "${title}" "${backTitle}" "${message}"
}
check_requirements() {
@@ -54,7 +72,7 @@ clear_cache() {
}
download() {
local source=($@)
local source=("$@")
for i in "${source[@]}" ; do
local dest="${i##*/}"
dest="${dest//%20/ }"
@@ -120,8 +138,7 @@ download() {
esac
if [[ $downloadError -ne 0 ]]; then
rm -fv "${cache}/${dest}"
agm_infobox "Audio Game Manager" "Audio Game Manager" "Error downloading \"${dest}\". Installation cannot continue."
alert
alert "Audio Game Manager" "Audio Game Manager" "Error downloading \"${dest}\". Installation cannot continue."
exit 1
fi
done
@@ -142,10 +159,10 @@ get_installer() {
if echo "$2" | xclip -selection clipboard 2> /dev/null ; then
message+="\n\nThe URL has been copied to the clipboard."
fi
agm_msgbox "Audiogame Manager" "Audiogame Manager" "$message"
alert "Audiogame Manager" "Audiogame Manager" "$message"
# Search the Desktop and Downloads directories for the installation file
for i in ~/Downloads ~/Desktop ; do
find $i -type f -name "$1" -exec cp -v {} "${cache}/" \;
find "$i" -type f -name "$1" -exec cp -v {} "${cache}/" \;
done
# If the file is still not available abort.
if [[ ! -f "${cache}/$1" ]]; then
@@ -157,8 +174,7 @@ get_installer() {
get_steam() {
# Arguments: $1 id of item for download, $2 url for game
trap "exit 0" SIGINT
echo "manual intervention required."
alert
alert "Audiogame Manager" "Audiogame Manager" "Manual intervention required."
agm_yesno "Audiogame Manager" "Audiogame Manager" "To install the game manually, place files in \"${WINEPREFIX}/drive_c/Program Files/${game}\". Continue with Steam installation?"
case $? in
0) echo "The next steps will install through steamcmd." ;;

View File

@@ -55,9 +55,9 @@ declare -Ag ipfs=(
[BG Word Yahtzee]="${ipfsGateway}/ipfs/QmdicAVDegDktY3euVAC2PPn4YBGz96KedxYXNe4WDQaoq?filename=BWY32Setup10.exe"
[BG Yahtzee]="${ipfsGateway}/ipfs/QmZebvkKgFAADnb1cgW6Bz7wTYdUh82X61QdtW66KcvmpF?filename=BGY32Setup10a.exe"
[Bloodshed]="${ipfsGateway}/ipfs/QmcTCTMep4zp5zTw8ZaXYpjtu9inNPn8bNzwhW6cX97egw?file=bloodshed.exe"
[Chopper Challenge]="${ipfsGateway}/ipfs/QmY1jmwVkmwEcqBs84i4mpancD3R1W4Vu6w1RdcrFUnbGx?filename=chopper%20challenge.zip"
[Christmas Chaos]="${ipfsGateway}/ipfs/QmYx11vsMDBgjPd1coZPGHxMXf2qtf4icqmB3Q9iUazyQv?filename=ChristmasChaos.zip"
[Kitchensinc Games]="${ipfsGateway}/ipfs/QmdkLPig6Kp3AZTwKAhjrhhsEuvhFCFhm6SHLUQVeNNYCb?filename=kitchen.tar.xz"
[Oh Shit]="${ipfsGateway}/ipfs/QmQnAJJrt5uABFziQc7enXYrJ74J9GKQSMi8Ry8ebsxfPV?filename=OhShit.zip"
[Villains From Beyond]="${ipfsGateway}/ipfs/QmWx271xuk3Mv9XTBoVu5BDJvXFZdasawC2nhtV21WAaUU?filename=villains_en.zip"
)

View File

@@ -1,9 +1,8 @@
# shellcheck shell=bash disable=SC2154 # cache and WINEPREFIX are set by audiogame-manager
download "https://github.com/matatk/agrip/releases/download/2020.0-beta1/AudioQuake+LDL_2020.0-beta1_Windows.zip" "https://stormgames.wolfe.casa/downloads/quake.zip"
export winVer="win7"
install_wine_bottle
install_with_progress unzip "Extracting game files..." -d "$WINEPREFIX/drive_c/Program Files" "${cache}/AudioQuake+LDL_2020.0-beta1_Windows.zip"
install_with_progress unzip "Extracting game files..." -d "$WINEPREFIX/drive_c/Program Files/AudioQuake/id1" "${cache}/quake.zip"
add_launcher "c:\Program Files\AudioQuake\AudioQuake.exe"
echo
echo "After you launch the game, press tab then enter and it should begin speaking."
alert
alert "After you launch the game, press tab then enter and it should begin speaking."

View File

@@ -1,4 +1,4 @@
#
#//
download "https://oriolgomez.com/games/beat_windows.zip"
# Sapi is broken on win64 for now, and this game doesn't support nvda it seems.
export WINEARCH=win64

View File

@@ -1,4 +1,4 @@
#Disable
#//Disable
download "https://nibblenerds.com/static/blades_of_glory.zip"
install_wine_bottle
install_with_progress unzip "Extracting game files..." -d "$WINEPREFIX/drive_c/Program Files/Blades of Glory" "${cache}/blades_of_glory.zip"

View File

@@ -1,4 +1,4 @@
#
#//
download "https://hirotaka2014.sakura.ne.jp/mh0406/game/breed_memorial.zip" "${nvdaControllerClient32Dll}"
export winVer="win7"
install_wine_bottle cjkfonts

View File

@@ -1,9 +1,4 @@
#
# Freezes at menu
download "https://www.agarchive.net/games/XSight/chopper%20challenge%20setup.exe"
download "${ipfs[Chopper Challenge]}"
install_wine_bottle vb6run dx8vb
wine "${cache}/chopper challenge setup.exe" /silent &
xdotool sleep 5 key y 2> /dev/null
wineserver -w
echo "$USER|n/a" >> "$WINEPREFIX/drive_c/Program Files/x-sight interactive/chopper challenge/config.dat"
add_launcher "c:\Program Files (x86)\x-sight interactive\chopper challenge\Chopper.exe"
install_with_progress unzip "Extracting game files..." -d "$WINEPREFIX/drive_c/Program Files" "${cache}/chopper challenge.zip"
add_launcher "c:\Program Files\chopper challenge\Chopper.exe"

View File

@@ -1,4 +1,4 @@
#
#//
export winVer="win7"
download "https://renovagames.com/bc/BC-Setup.exe"
install_wine_bottle cjkfonts

View File

@@ -1,4 +1,4 @@
#
#//
# No custom bottle needed - use standard wine path based on architecture
download "https://www.agarchive.net/games/pb/Dark-Destroyer-Setup.exe"
install_wine_bottle ie6

View File

@@ -1,4 +1,4 @@
#
#//
export winVer="win7"
install_wine_bottle
download "https://www.iamtalon.me/games/dragonpong.zip"

View File

@@ -1,4 +1,4 @@
# Borken, candidate for removal
#// Borken, candidate for removal
export WINEARCH="win64" # Migrated to wine64 with WINETRICKS_FORCE=1 - complex .NET dependencies, test carefully
download "http://blind-games.com/newentombed/EntombedSetup.exe" "https://download.microsoft.com/download/E/C/1/EC1B2340-67A0-4B87-85F0-74D987A27160/SSCERuntime-ENU.exe" "https://stormgames.wolfe.casa/downloads/Entombed.exe.config" "https://stormgames.wolfe.casa/downloads/mfplat.dll"
export winVer="win7"

View File

@@ -1,4 +1,4 @@
#
#//
export winVer="win7"
export winetricksSettings="vd=1024x768"
download "https://www.stefankiss.sk/files/eurofly2/Launcher_1.2.zip" "https://www.stefankiss.sk/files/eurofly2/Eurofly_2_ful_setup.exe"

View File

@@ -1,13 +1,14 @@
download "https://dl.tweesecake.app/rage/rage1.5.0.zip"
# shellcheck shell=bash disable=SC2154 # cache, WINEPREFIX, and game are set by audiogame-manager
gameVersion=2.4.1
download "https://dl.tweesecake.app/rage/rage${gameVersion}.zip"
export WINEARCH=win64
export winVer="win10"
install_wine_bottle
install_with_progress unzip "Extracting game files..." -d "$WINEPREFIX/drive_c/Program Files/" "${cache}/rage1.5.0.zip"
install_with_progress unzip "Extracting game files..." -d "$WINEPREFIX/drive_c/Program Files/" "${cache}/rage${gameVersion}.zip"
add_launcher "c:\Program Files\rage\rage.exe"
url="https://techcake.games/games/executioners-rage/"
echo "Before you can login, you need to create an account at:"
echo "$url"
message="Before you can login, you need to create an account at:\n${url}"
if echo "$url" | xclip -selection clipboard 2> /dev/null ; then
message+="\n\nThe URL has been copied to the clipboard."
fi
alert
alert "Executioner's Rage" "Executioner's Rage" "$message"

View File

@@ -1,4 +1,4 @@
#
#//
download "http://www.agarchive.net/games/bpc/fartman.exe"
install_wine_bottle dx8vb vb6run
wine "${cache}/fartman.exe" /silent

View File

@@ -1,8 +1,7 @@
# shellcheck shell=bash disable=SC2154 # cache and WINEPREFIX are set by audiogame-manager
get_installer "Galactic Strike 1.2.zip" "https://fusion-forged-games.itch.io/galactic-strike"
export winVer="win10"
install_wine_bottle
install_with_progress unzip "Extracting game files..." -d "$WINEPREFIX/drive_c/Program Files/Galactic Strike" "${cache}/Galactic Strike 1.2.zip"
add_launcher "c:\Program Files\Galactic Strike\Galactic Strike.exe"
echo "Use controls wasd to movi and navigate the menu."
echo "Use m to fire and select items from the menu."
alert
alert "Use controls wasd to movi and navigate the menu.\nUse m to fire and select items from the menu."

View File

@@ -1,6 +1,6 @@
# shellcheck shell=bash disable=SC2154 # cache and WINEPREFIX are set by audiogame-manager
download "https://stormgames.wolfe.casa/downloads/grizzly-gulch.zip"
install_wine_bottle vb6run mfc42
install_with_progress unzip "Extracting game files..." -d "$WINEPREFIX/drive_c/Program Files" "$cache/grizzly-gulch.zip"
add_launcher "c:\Program Files\grizzly-gulch\Grizzly Gulch.exe"
echo "If the combat sequences happen too slow for your tastes, while in the town square, you can use f12 to turn up the combat speed and f11 to lower it."
alert
alert "If the combat sequences happen too slow for your tastes, while in the town square, you can use f12 to turn up the combat speed and f11 to lower it."

View File

@@ -1,3 +1,4 @@
# shellcheck shell=bash disable=SC2154 # cache and WINEPREFIX are set by audiogame-manager
export WINEARCH="win64" # Migrated to wine64 with WINETRICKS_FORCE=1
export winVer="win7"
export winetricksSettings="vd=1024x768"
@@ -6,5 +7,4 @@ install_wine_bottle sapi vb6run dx8vb quartz
install_with_progress unzip "Extracting game files..." -d "$WINEPREFIX/drive_c/Program Files/lunimals" "${cache}/lunimals.zip"
wine 'c:\Program Files\lunimals\checkup.exe' /verysilent
add_launcher "c:\Program Files\lunimals\Lunimals.exe"
echo "Note: Lunimals installed. Once you start the game, you must press tab until you hear sapi on to get speech." >&2
alert
alert "Note: Lunimals installed. Once you start the game, you must press tab until you hear sapi on to get speech."

View File

@@ -1,4 +1,4 @@
#
#//
# Uses standard wine path based on architecture (win32/win64)
export winVer="win7"
install_wine_bottle

View File

@@ -1,3 +1,4 @@
# shellcheck shell=bash disable=SC2154 # cache and WINEPREFIX are set by audiogame-manager
export WINEARCH="win64" # Migrated to wine64
export winVer="win7"
@@ -8,13 +9,4 @@ sed -i 's/1024m/768m/g' "$WINEPREFIX/drive_c/Program Files/Mist World/mw.exe.vmo
cp "$WINEPREFIX/drive_c/Program Files/Mist World/"{mw.exe.vmoptions,update.exe.vmoptions}
mkdir "$WINEPREFIX/drive_c/Program Files/Mist World/"{user,users}
add_launcher 'c:\Program Files\Mist World\mw.exe'
echo
echo "If you do not have an account, There is a script in game-scripts to help."
echo "Launch the game, press enter on create account, then drop into a console so the game window does not lose focus."
echo "Change to the game-scripts directory and run"
echo "./mist_world_account_creator.sh and follow the prompts."
echo
echo "To login, type your email address, press tab, and type your password."
echo "If you want to enable automatic login, press tab two times followed by space, then tab and enter."
echo "If you do not want to auto login, you can just press enter after typing your password."
alert
alert "If you do not have an account, There is a script in game-scripts to help.\nLaunch the game, press enter on create account, then drop into a console so the game window does not lose focus.\nChange to the game-scripts directory and run\n./mist_world_account_creator.sh and follow the prompts.\n\nTo login, type your email address, press tab, and type your password.\nIf you want to enable automatic login, press tab two times followed by space, then tab and enter.\nIf you do not want to auto login, you can just press enter after typing your password."

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#//!/bin/bash
case "${game}" in
"MudSplat English")
a="a"

View File

@@ -1,4 +1,4 @@
#
#//
download "http://www.vgstorm.com/psycho_strike_installer.exe"
install_wine_bottle
wine "${cache}/psycho_strike_installer.exe" /silent

View File

@@ -1,4 +1,4 @@
#
#//
export winVer="win7"
download "http://www.samtupy.com/games/SCSetup.exe" "${nvdaControllerClient32Dll}"
install_wine_bottle

View File

@@ -1,8 +1,9 @@
# shellcheck shell=bash disable=SC2154 # cache and WINEPREFIX are set by audiogame-manager
# shellcheck disable=SC2034 # consumed by shared bottle setup
winetricksSettings="vd=1024x768"
export winVer="win7"
download "https://stevend.net/downloads/scramble_win32.zip"
install_wine_bottle
install_with_progress unzip "Extracting game files..." -d "$WINEPREFIX/drive_c/Program Files/" "${cache}/scramble_win32.zip"
echo "Note: When you first start the game, it will say that tts initialization failed. Please answer that you do not want to attempt initialization of tts when the game starts to allow easy speech through speech dispatcher."
alert
alert "Note: When you first start the game, it will say that tts initialization failed. Please answer that you do not want to attempt initialization of tts when the game starts to allow easy speech through speech dispatcher."
add_launcher "c:\Program Files\scramble_win32\scramble.exe"

View File

@@ -1,4 +1,5 @@
#Disable since it's not working
# shellcheck shell=bash disable=SC2154 # cache and WINEPREFIX are set by audiogame-manager
#//Disable since it's not working
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"
@@ -19,10 +20,4 @@ rm /tmp/bcrypt_override.reg
wineserver -k 2>/dev/null || true
mv -v "${cache}/language_en.dat" "${WINEPREFIX}/drive_c/Program Files (x86)/GalaxyLaboratory/ShadowRine_FullVoice/SystemData/language_en.dat"
add_launcher "c:\Program Files (x86)\GalaxyLaboratory\ShadowRine_FullVoice\play_sr.exe"
echo "Please set the language to English when the game opens."
echo "Go to options and press enter."
echo "Press down arrow 5 times and press enter."
echo "Press down arrow 1 time and press enter."
echo "Press up arrow 2 times and press enter."
echo "If everything worked as expected you should be back on the game menu and speech should work."
alert
alert "Please set the language to English when the game opens.\nGo to options and press enter.\nPress down arrow 5 times and press enter.\nPress down arrow 1 time and press enter.\nPress up arrow 2 times and press enter.\nIf everything worked as expected you should be back on the game menu and speech should work."

7
.install/Shooter_rw.sh Normal file
View File

@@ -0,0 +1,7 @@
export WINEARCH=win64
export winVer="win7"
get_installer "shooterrw-win.zip" "https://masonasons.itch.io/shooterrw"
install_wine_bottle
install_with_progress unzip "Extracting game files..." -d "$WINEPREFIX/drive_c/Program Files/shooter_rw" "${cache}/shooterrw-win.zip"
find "$WINEPREFIX/drive_c/Program Files/shooter_rw" -type d -exec chmod 755 "{}" +
add_launcher "c:\Program Files\shooter_rw\Shooter.exe"

View File

@@ -1,3 +1,4 @@
# shellcheck shell=bash disable=SC2154 # cache and WINEPREFIX are set by audiogame-manager
download "http://www.danielzingaro.com/superdeekout_setup.exe" "http://www.danielzingaro.com/sd_full.exe"
install_wine_bottle vb6run dx8vb
wine "${cache}/superdeekout_setup.exe" &
@@ -13,8 +14,7 @@ xdotool sleep 15 key --delay 250 alt+f 2> /dev/null
xdotool sleep 3 key --delay 250 n 2> /dev/null
wineserver -k
install_with_progress 7z "Extracting game files..." x -y -o"$WINEPREFIX/drive_c/Program Files/Super Deekout" "${cache}/sd_full.exe"
echo "Super Deekout needs some information before it will run:"
alert
alert "Super Deekout needs some information before it will run."
read -erp "Please enter your first name: " fname
read -erp "Please enter your last name: " lname
read -erp "Please enter your email address: " email

View File

@@ -1,4 +1,4 @@
#
#//
export winVer="win7"
download "http://www.vgstorm.com/the_gate_installer.exe"
install_wine_bottle

View File

@@ -1,3 +1,4 @@
# shellcheck shell=bash disable=SC2154 # cache and WINEPREFIX are set by audiogame-manager
get_installer "theyll-come-from-the-moon-windows.zip" "https://soundrascal.itch.io/theyll-come-from-the-moon"
export WINEARCH=win64
export winVer="win8"
@@ -7,5 +8,4 @@ install_with_progress unzip "Extracting game files..." -d "$WINEPREFIX/drive_c/P
winetricks -q usetakefocus=y
winetricks -q usetakefocus=n
add_launcher "c:\Program Files\tcftm\They'll Come from the Moon!.exe"
echo "When the game launches, press the enter key to load the game which will begin to speak."
alert
alert "When the game launches, press the enter key to load the game which will begin to speak."

View File

@@ -1,12 +1,8 @@
# shellcheck shell=bash disable=SC2154 # cache and WINEPREFIX are set by audiogame-manager
export WINEARCH="win64" # Migrated to wine64 with WINETRICKS_FORCE=1
export winVer="win7"
install_wine_bottle sapi vb6run dx8vb
wine "${cache}/vipmud20016.exe" /silent
mkdir -p "${HOME}/.local/wine/vip-mud/drive_c/users/${USER}/Documents/VIP Mud"
add_launcher "c:\Program Files (x86)\VIPMud 2.0\vipmud2.exe"
echo
echo "When you first launch VIP Mud You will be presented with several inaccessible dialogs."
echo "To bypass these dialogs, press alt+o, then press enter until speech starts."
echo "To be sure that each new dialog has had time to complete, wait a second between each press of enter."
echo "In each subsequent launch, you will need to hit enter a couple times before it starts speaking."
alert
alert "When you first launch VIP Mud You will be presented with several inaccessible dialogs.\nTo bypass these dialogs, press alt+o, then press enter until speech starts.\nTo be sure that each new dialog has had time to complete, wait a second between each press of enter.\nIn each subsequent launch, you will need to hit enter a couple times before it starts speaking."

View File

@@ -1,4 +1,5 @@
#!/usr/bin/env bash
# shellcheck disable=SC1091
# Get script directory for relative paths
scriptDir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -11,6 +12,234 @@ export DIALOGOPTS='--no-lines --visit-items'
# Wine32 version for SAPI compatibility
wineThirtyTwoVersion="9.0"
# Track nvda2speechd lifecycle for this launcher run.
nvda2speechdPid=""
nvda2speechdStarted="false"
customLaunchHandled="false"
cthulhuTitleReaderEnabled="false"
cthulhuTitleReaderTried="false"
takeFocusWorkaroundActive="false"
takeFocusRestoreMode="none"
takeFocusRestoreValue=""
log_msg() {
local logFile="${scriptDir}/game.log"
local timestamp=""
timestamp="$(date)"
echo "${1} [${timestamp}]" >> "$logFile"
}
start_nvda2speechd() {
if [[ "$nvda2speechdStarted" == "true" ]]; then
return
fi
if ! ss -ltnp | rg 3457 | grep -q 'cthulhu'; then
if [[ -x "${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/nvda2speechd" ]]; then
local translateSetting="${TRANSLATE:-unset}"
local translateFromSetting="${TRANSLATE_FROM:-unset}"
local translateToSetting="${TRANSLATE_TO:-unset}"
log_msg "Preparing nvda2speechd with TRANSLATE=${translateSetting} TRANSLATE_FROM=${translateFromSetting} TRANSLATE_TO=${translateToSetting}."
if [[ "${translateSetting,,}" == "true" ]] || [[ "$translateSetting" == "1" ]]; then
if ! command -v trans &> /dev/null; then
log_msg "TRANSLATE is enabled but 'trans' is missing; nvda2speechd may fail to start."
fi
fi
"${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/nvda2speechd" &> /dev/null &
nvda2speechdPid=$!
nvda2speechdStarted="true"
log_msg "Started nvda2speechd (pid ${nvda2speechdPid})."
else
log_msg "nvda2speechd binary not found or not executable; skipping start."
fi
else
log_msg "cthulhu is already listening on port 3457; skipping nvda2speechd start."
fi
}
stop_nvda2speechd() {
if [[ "$nvda2speechdStarted" != "true" ]]; then
return
fi
if [[ -n "$nvda2speechdPid" ]] && kill -0 "$nvda2speechdPid" 2>/dev/null; then
kill "$nvda2speechdPid" 2>/dev/null
wait "$nvda2speechdPid" 2>/dev/null
fi
nvda2speechdPid=""
nvda2speechdStarted="false"
}
enable_cthulhu_window_title_reader() {
if [[ "$cthulhuTitleReaderEnabled" == "true" ]]; then
return 0
fi
if [[ "$cthulhuTitleReaderTried" == "true" ]]; then
return 1
fi
cthulhuTitleReaderTried="true"
if ! command -v gdbus &> /dev/null; then
log_msg "gdbus not found; cannot enable Cthulhu WindowTitleReader."
return 1
fi
local dbusService="org.stormux.Cthulhu.Service"
local modulePath="/org/stormux/Cthulhu/Service/PluginSystemManager"
local titleModulePath="/org/stormux/Cthulhu/Service/Plugin_WindowTitleReader"
local moduleInterface="org.stormux.Cthulhu.Module"
local enableResult=""
local titleEnableResult=""
gdbus call --session --dest "$dbusService" \
--object-path "$modulePath" \
--method "${moduleInterface}.ExecuteCommand" \
"RescanPlugins" false &> /dev/null || true
enableResult="$(gdbus call --session --dest "$dbusService" \
--object-path "$modulePath" \
--method "${moduleInterface}.ExecuteParameterizedCommand" \
"SetPluginActive" \
'{"plugin_name": <"WindowTitleReader">, "active": <true>}' \
false 2>/dev/null || true)"
if [[ "$enableResult" != *"true"* ]]; then
log_msg "Failed to activate Cthulhu WindowTitleReader plugin via D-Bus."
return 1
fi
titleEnableResult="$(gdbus call --session --dest "$dbusService" \
--object-path "$titleModulePath" \
--method "${moduleInterface}.ExecuteParameterizedCommand" \
"SetEnabled" \
'{"enabled": <true>}' \
false 2>/dev/null || true)"
if [[ "$titleEnableResult" == *"true"* ]]; then
cthulhuTitleReaderEnabled="true"
log_msg "Enabled Cthulhu WindowTitleReader tracking via D-Bus."
return 0
fi
log_msg "Failed to enable Cthulhu WindowTitleReader tracking via D-Bus."
return 1
}
kill_nvda2speechd_listener() {
local nvdaPids=()
mapfile -t nvdaPids < <(pgrep -u "${USER}" -x nvda2speechd 2>/dev/null)
if [[ ${#nvdaPids[@]} -eq 0 ]]; then
log_msg "No nvda2speechd process found to stop."
return
fi
log_msg "Stopping nvda2speechd process(es): ${nvdaPids[*]}."
for pid in "${nvdaPids[@]}"; do
kill "$pid" 2>/dev/null
done
local remainingPids=()
mapfile -t remainingPids < <(pgrep -u "${USER}" -x nvda2speechd 2>/dev/null)
if [[ ${#remainingPids[@]} -gt 0 ]]; then
log_msg "nvda2speechd still running after stop attempt: ${remainingPids[*]}."
fi
}
cleanup_and_exit() {
restore_executioners_rage_focus_workaround
stop_nvda2speechd
}
set_use_take_focus_value() {
local takeFocusValue="${1^^}"
if [[ "$takeFocusValue" != "Y" ]] && [[ "$takeFocusValue" != "N" ]]; then
return 1
fi
wine reg add "HKCU\\Software\\Wine\\X11 Driver" /v UseTakeFocus /t REG_SZ /d "$takeFocusValue" /f &> /dev/null
}
unset_use_take_focus_value() {
wine reg delete "HKCU\\Software\\Wine\\X11 Driver" /v UseTakeFocus /f &> /dev/null
}
capture_use_take_focus_state() {
local queryOutput=""
local currentValue=""
takeFocusRestoreMode="none"
takeFocusRestoreValue=""
if ! wine reg query "HKCU\\Software\\Wine" &> /dev/null; then
takeFocusRestoreMode="unknown"
return 1
fi
queryOutput="$(wine reg query "HKCU\\Software\\Wine\\X11 Driver" /v UseTakeFocus 2>/dev/null || true)"
if [[ "$queryOutput" == *"UseTakeFocus"* ]]; then
currentValue="$(awk '/UseTakeFocus/ {print toupper($NF); exit}' <<< "$queryOutput")"
if [[ "$currentValue" == "Y" ]] || [[ "$currentValue" == "N" ]]; then
takeFocusRestoreMode="value"
takeFocusRestoreValue="$currentValue"
return 0
fi
takeFocusRestoreMode="unknown"
return 1
fi
takeFocusRestoreMode="delete"
return 0
}
apply_executioners_rage_focus_workaround() {
if [[ "${game[2]}" != "Executioner's Rage" ]]; then
return
fi
takeFocusWorkaroundActive="false"
if ! capture_use_take_focus_state; then
log_msg "Could not capture current UseTakeFocus state before launching Executioner's Rage."
fi
if set_use_take_focus_value "Y"; then
takeFocusWorkaroundActive="true"
log_msg "Enabled UseTakeFocus=Y before launching Executioner's Rage."
else
log_msg "Failed to enable UseTakeFocus=Y for Executioner's Rage."
fi
}
restore_executioners_rage_focus_workaround() {
if [[ "$takeFocusWorkaroundActive" != "true" ]]; then
return
fi
if [[ "${game[2]}" != "Executioner's Rage" ]]; then
takeFocusWorkaroundActive="false"
takeFocusRestoreMode="none"
takeFocusRestoreValue=""
return
fi
case "$takeFocusRestoreMode" in
value)
if set_use_take_focus_value "$takeFocusRestoreValue"; then
log_msg "Restored UseTakeFocus=${takeFocusRestoreValue} after closing Executioner's Rage."
else
log_msg "Failed to restore UseTakeFocus=${takeFocusRestoreValue} after closing Executioner's Rage."
fi
;;
delete)
if unset_use_take_focus_value; then
log_msg "Removed UseTakeFocus override after closing Executioner's Rage."
else
log_msg "Failed to remove UseTakeFocus override after closing Executioner's Rage."
fi
;;
*)
log_msg "Skipping UseTakeFocus restore after closing Executioner's Rage because prior state was unknown."
;;
esac
takeFocusWorkaroundActive="false"
takeFocusRestoreMode="none"
takeFocusRestoreValue=""
}
# Check and manage wine32 installation
check_wine32() {
local wine32Dir="${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/wine32"
@@ -137,10 +366,10 @@ game_installer() {
mapfile -t installedGames < <(sed -e '/^$/d' -e '/^[[:space:]]*#/d' "${configFile}" 2> /dev/null | cut -d '|' -f3)
# Create the menu of available games by reading from .install directory
declare -a menuList
# Get all .sh files from .install directory, excluding those starting with # as first line.
# Get all .sh files from .install directory, excluding those starting with #// as first line.
mapfile -t sortedGames < <(for f in "${scriptDir}/.install/"*.sh; do
# Skip if first line starts with #
[[ $(head -n1 "$f") == "#"* ]] && continue
# Skip if first line starts with #//
[[ $(head -n1 "$f") == "#//"* ]] && continue
echo "${f##*/%.sh}"
done | sort)
for i in "${sortedGames[@]}"; do
@@ -316,27 +545,33 @@ kill_game() {
# for games that require custom scripts before launch or custom launch parameters
custom_launch_parameters() {
if [[ "${game[2]}" == "Dragon Pong" ]]; then
"${scriptDir}/speech/speak_window_title.sh" DragonPong.exe &
if ! enable_cthulhu_window_title_reader; then
"${scriptDir}/speech/speak_window_title.sh" DragonPong.exe &
fi
start_nvda2speechd
pushd "$(winepath "$winePath")" || exit 1
wine "$wineExec"
popd || exit 1
exit 0
customLaunchHandled="true"
return 0
fi
if [[ "${game[2]}" == "Dreamland" ]]; then
"$WINE" "${game[1]}" &> /dev/null &
exit 0
start_nvda2speechd
"$WINE" "${game[1]}" &> /dev/null
customLaunchHandled="true"
return 0
fi
# executioner's-rage: DLL replacement now handled by update_nvda_dlls()
if [[ "${game[2]}" == "Laser Breakout" ]]; then
"${scriptDir}/speech/speak_window_title.sh" play.exe &
if ! enable_cthulhu_window_title_reader; then
"${scriptDir}/speech/speak_window_title.sh" play.exe &
fi
fi
if [[ "${game[2]}" == "Bokurano Daibouken 2" ]]; then
find "${WINEPREFIX}/drive_c/nyanchangame/bk2" -type f -name 'nvdaControllerClient.dll' -exec rm -v "{}" \;
"${scriptDir}/speech/clipboard_translator.sh" "play.exe" bokurano-daibouken2 &
export TRANSLATE=true
fi
if [[ "${game[2]}" == "Bokurano Daibouken" ]]; then
find "${WINEPREFIX}/drive_c/nyanchangame/bk" -type f -name 'nvdaControllerClient.dll' -exec rm -v "{}" \;
"${scriptDir}/speech/clipboard_translator.sh" "play.exe" bokurano-daibouken &
export TRANSLATE=true
fi
if [[ "${game[2]}" == "Bokurano Daibouken 3" ]]; then
dictPath="$(winepath "${winePath}")"
@@ -358,13 +593,19 @@ custom_launch_parameters() {
fi
fi
if [[ "${game[2]}" == "Bop It Emulator" ]]; then
"${scriptDir}/speech/speak_window_title.sh" bop.exe &
if ! enable_cthulhu_window_title_reader; then
"${scriptDir}/speech/speak_window_title.sh" bop.exe &
fi
fi
if [[ "${game[2]}" == "Road to Rage" ]]; then
"${scriptDir}/speech/speak_window_title.sh" trtr.exe &
if ! enable_cthulhu_window_title_reader; then
"${scriptDir}/speech/speak_window_title.sh" trtr.exe &
fi
fi
if [[ "${game[2]}" == "Axel Pong" ]]; then
"${scriptDir}/speech/speak_window_title.sh" axel_pong.exe &
if ! enable_cthulhu_window_title_reader; then
"${scriptDir}/speech/speak_window_title.sh" axel_pong.exe &
fi
fi
if [[ "${game[2]}" == "Sequence Storm" ]]; then
"${scriptDir}/speech/clipboard_reader.sh" SequenceStorm &
@@ -375,30 +616,40 @@ custom_launch_parameters() {
#fi
# sketchbook: DLL replacement now handled by update_nvda_dlls()
if [[ "${game[2]}" == "Audiodisc" ]]; then
start_nvda2speechd
wine "$winePath\\$wineExec"
exit 0
customLaunchHandled="true"
return 0
fi
if [[ "${game[2]}" == "Audioquake" ]]; then
start_nvda2speechd
wine "$winePath\\$wineExec"
exit 0
customLaunchHandled="true"
return 0
fi
if [[ "${game[2]}" == "Screaming Strike 2" ]]; then
start_nvda2speechd
pushd "$(winepath "$winePath")" || exit 1
wine "$wineExec"
popd || exit 1
exit 0
customLaunchHandled="true"
return 0
fi
if [[ "${game[2]}" == "Warsim" ]]; then
start_nvda2speechd
pushd "$(winepath "${game[1]%\\*}")" || exit 1
wine "${game[1]##*\\}"
popd || exit 1
exit 0
customLaunchHandled="true"
return 0
fi
if [[ "${game[2]}" == "Interceptor" ]]; then
start_nvda2speechd
pushd "$(winepath "$winePath")" || exit 1
wine "$wineExec"
popd || exit 1
exit 0
customLaunchHandled="true"
return 0
fi
}
@@ -474,14 +725,8 @@ game_launcher() {
[[ "$agmNoLaunch" == "true" ]] && return
# shellcheck source=.includes/bottle.sh
source "${scriptDir}/.includes/bottle.sh"
# Start nvda2speechd if available
if ! ss -ltnp | rg 3457 | grep -q 'cthulhu'; then
if [[ -x "${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/nvda2speechd" ]]; then
"${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/nvda2speechd" &> /dev/null &
fi
fi
# Ensure a clean nvda2speechd state before launching a new game.
kill_nvda2speechd_listener
# Replace NVDA controller client DLLs in wine64 bottle
update_nvda_dlls
mapfile -t lines < <(sed -e '/^$/d' -e '/^ *#/d' "${configFile}" 2> /dev/null | sort -t '|' -k3,3f)
@@ -568,15 +813,25 @@ game_launcher() {
fi
fi
process_launcher_flags
apply_executioners_rage_focus_workaround
customLaunchHandled="false"
custom_launch_parameters
if [[ "$debugGdb" == "1" ]]; then
# Change to game directory before launching
pushd "$(winepath "${game[1]%\\*}")" > /dev/null || exit 1
winedbg --gdb "${game[1]##*\\}"
popd > /dev/null || exit 1
else
wine start /d "${game[1]%\\*}" "${game[1]##*\\}" /realtime
if [[ "$customLaunchHandled" == "true" ]]; then
restore_executioners_rage_focus_workaround
exit 0
fi
start_nvda2speechd
# Change to game directory before launching (required for proper game operation)
pushd "$(winepath "${game[1]%\\*}")" > /dev/null || exit 1
if [[ "$debugGdb" == "1" ]]; then
winedbg --gdb "${game[1]##*\\}"
else
# Use direct wine execution instead of 'wine start' to ensure clipboard works
# See: https://bugs.winehq.org/show_bug.cgi?id=50598
wine "${game[1]##*\\}"
fi
popd > /dev/null || exit 1
restore_executioners_rage_focus_workaround
fi
exit 0
}
@@ -584,10 +839,12 @@ game_launcher() {
# main script
trap "exit 0" SIGINT
trap cleanup_and_exit EXIT
trap "cleanup_and_exit; exit 0" SIGINT SIGTERM
# Detect dialog interface type BEFORE potentially setting DISPLAY
# This must happen before we modify DISPLAY to preserve console detection
# shellcheck disable=SC2034
if [[ -z "$DISPLAY" ]]; then
dialogType="dialog"
elif command -v yad &> /dev/null; then

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Immediately exit if errors are encountered.
set -e
@@ -72,4 +72,4 @@ configure_arch() {
configure_arch
exit 0
exit 0

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Immediately exit if errors are encountered.
set -e

View File

@@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Immediately exit if errors are encountered.
set -e
# Wine dependencies installer for Debian/Ubuntu
# If this fails on your system, please contact storm_dragon@stormux.org
configure_debian() {
packageList=(
curl
dialog
gawk
gstreamer1.0-plugins-bad:i386
gstreamer1.0-plugins-good:i386
gstreamer1.0-plugins-ugly:i386
mono-complete
libncurses5-dev
w3m
winehq-stable
)
# Make sure 32-bit libraries are available.
sudo dpkg --add-architecture i386
sudo apt install --install-recommends "${packageList[@]}"
}
configure_debian
exit 0