diff --git a/docs/assets/extras/linuxkonami/sp2x-linux-setup.sh b/docs/assets/extras/linuxkonami/sp2x-linux-setup.sh new file mode 100644 index 0000000..f08971f --- /dev/null +++ b/docs/assets/extras/linuxkonami/sp2x-linux-setup.sh @@ -0,0 +1,356 @@ +#!/usr/bin/env bash +# Original Author: NotAkitake +# Revised by gnosticJade, see https://github.com/asterisk727/two-torial/pull/8 +# sp2x-linux-setup.sh +# Place this script in your game directory before running +# OR export GAME_DIR with your game directory (the one containing the contents directory) + +set -euo pipefail + +# Colors +if [ -t 1 ]; then + RED='\033[0;31m' + GREEN='\033[0;32m' + YELLOW='\033[1;33m' + BLUE='\033[0;34m' + CYAN='\033[0;36m' + MAGENTA='\033[0;35m' + BOLD='\033[1m' + NC='\033[0m' +else + RED='' GREEN='' YELLOW='' BLUE='' CYAN='' MAGENTA='' BOLD='' NC='' +fi + +# Print functions +print_error() { echo -e "${RED}✗ ERROR:${NC} $1" >&2; } +print_success() { echo -e "${GREEN}✓${NC} $1"; } +print_info() { echo -e "${CYAN}➜${NC} $1"; } +print_warn() { echo -e "${YELLOW}⚠ ${NC} $1"; } +print_header() { echo -e "\n${BOLD}${BLUE}===${NC} ${BOLD}$1${NC} ${BOLD}${BLUE}===${NC}\n"; } +print_step() { echo -e "\n${MAGENTA}▶${NC} ${BOLD}$1${NC}"; } + +# Configuration +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +GAME_DIR="${GAME_DIR:-$SCRIPT_DIR}" # If GAME_DIR wasn't already set, use script_dir +MODULES_DIR="$GAME_DIR/contents/modules" + +# Check dependencies +print_step "Checking dependencies" +MISSING_TOOLS=() +command -v wine &>/dev/null || MISSING_TOOLS+=("wine") +command -v winetricks &>/dev/null || MISSING_TOOLS+=("winetricks") +command -v curl &>/dev/null || MISSING_TOOLS+=("curl") +command -v unzip &>/dev/null || MISSING_TOOLS+=("unzip") + +if [[ ${#MISSING_TOOLS[@]} -ne 0 ]]; then + print_error "Missing required tools: ${MISSING_TOOLS[*]}" + echo " Install with: sudo pacman -S ${MISSING_TOOLS[*]} (Arch/Manjaro)" + echo " or: sudo apt install ${MISSING_TOOLS[*]} (Debian/Ubuntu)" + echo " or: sudo dnf install ${MISSING_TOOLS[*]} (Fedora/RHEL)" + exit 1 +fi + +# Check for contents dir +print_step "Verifying game directory" +if [[ ! -d "$GAME_DIR/contents" ]]; then + print_error "Game contents directory not found at $GAME_DIR/contents" + echo " Please ensure your game files are in the correct location." + echo " The directory structure should be:" + echo " $GAME_DIR/contents/modules/.dll" + exit 1 +fi +print_success "contents directory found" + +# Game detection +print_step "Detecting game..." +GAME_ID="" +GAME_NAME="" +GAME_INSTRUCTIONS="" +GAME_DLL="" +GAME_DLL_ARCH=0 +GAME_PORTRAIT=0 +SPICE_EXE="" +STUBS=0 + +if [[ -f "$MODULES_DIR/gamemdx.dll" ]]; then + GAME_ID="ddr" + GAME_NAME="DanceDanceRevolution" + GAME_INSTRUCTIONS=" 1. Verify DDR World is detected + 2. Bind your game buttons" + GAME_DLL="gamemdx.dll" + STUBS=1 +elif [[ -f "$MODULES_DIR/soundvoltex.dll" ]]; then + GAME_ID="sdvx" + GAME_NAME="SOUND VOLTEX" + GAME_INSTRUCTIONS=" 1. Verify SOUND VOLTEX is detected + 2. Bind your game buttons + 3. Go to the Patches tab + 4. Import patches from URL: https://patcher.573.moe + 5. Enable Shared mode WASAPI patch and whatever else you want + 6. Enable Auto apply patches on game start" + GAME_DLL="soundvoltex.dll" + GAME_PORTRAIT=1 + STUBS=1 +elif [[ -f "$MODULES_DIR/kamunity.dll" && -f "$GAME_DIR/contents/game/MFGClient_Data/app.info" ]]; then + GAME_ID="mfg" + GAME_NAME="Mahjong Fight Girl" + GAME_INSTRUCTIONS=" 1. Verify Mahjong Fight Girl is detected + 2. Bind your game buttons" + GAME_DLL="kamunity.dll" +else + print_error "No supported game detected in $MODULES_DIR" + exit 1 +fi + +if file "$MODULES_DIR/$GAME_DLL" | grep -q "PE32+ executable"; then + GAME_DLL_ARCH=64 + SPICE_EXE="spice64.exe" +elif file "$MODULES_DIR/$GAME_DLL" | grep -q "PE32 executable"; then + GAME_DLL_ARCH=32 + SPICE_EXE="spice.exe" +else + print_error "Could not find whether $GAME_DLL is 32 or 64 bit" + exit 1 +fi + +print_success "Detected $GAME_NAME" +WINEPREFIX="$GAME_DIR/prefix" +PORTRAIT_MODE=0 + +# Ask about portrait mode if applicable to the game +if [[ "$GAME_PORTRAIT" -eq 1 ]]; then + echo -en "\n${CYAN}Will you set your monitor to portrait mode before playing? [y/N]:${NC} " + read -r PORTRAIT_ANSWER + if [[ "$PORTRAIT_ANSWER" =~ ^[Yy]$ ]]; then + PORTRAIT_MODE=0 + print_info "Will use your native monitor orientation" + else + PORTRAIT_MODE=1 + print_info "Will emulate 1080x1920 in a virtual desktop" + fi +fi + +# Prompt user before proceeding +print_header "$GAME_NAME - Linux Setup" + +print_info "Game: $GAME_NAME ($GAME_ID)" +print_info "Script directory: $SCRIPT_DIR" +print_info "Game directory: $GAME_DIR" +print_info "Prefix directory: $WINEPREFIX" +if [[ "$GAME_PORTRAIT" -eq 1 ]]; then + if [[ "$PORTRAIT_MODE" -eq 1 ]]; then + print_info "Portrait handling: Virtual desktop for use in landscape mode" + else + print_info "Portrait handling: Manual (will need to set monitor to portrait mode before launching the game)" + fi +fi + +echo -en "\n${CYAN}Is this correct and do you want to proceed with setup? [y/N]:${NC} " +read -r PROCEED_ANSWER +if [[ ! "$PROCEED_ANSWER" =~ ^[Yy]$ ]]; then + print_info "Cancelling setup" + exit 1 +fi + +# Download spice2x if not present +print_step "Setting up spice2x" +if [[ ! -d "$GAME_DIR/spice2x" ]]; then + print_info "Downloading latest spice2x release..." + + # get the latest zip url from api manifest + # likely in the format of https://[...]/spice2x-yy-mm-dd-full.zip + DOWNLOAD_URL=$(curl -s https://api.github.com/repos/spice2x/spice2x.github.io/releases/latest | + grep -o 'https://.*\.zip' | head -1) + + if [[ -z "$DOWNLOAD_URL" ]]; then + print_error "Failed to get spice2x download URL" + exit 1 + fi + + # strips the rest of the URL, leaving just spice2x-yy-mm-dd-full.zip + # download to /tmp/spice2x-yy-mm-dd-full.zip + ZIP_FILE=$(basename "$DOWNLOAD_URL") + curl -L --progress-bar "$DOWNLOAD_URL" -o "/tmp/$ZIP_FILE" + + print_info "Extracting spice2x..." + unzip -q -o "/tmp/$ZIP_FILE" -d "/tmp/spice2x" + mv /tmp/spice2x "$GAME_DIR/" + rm "/tmp/$ZIP_FILE" + + print_info "Copying $SPICE_EXE..." + cp "$GAME_DIR/spice2x/$SPICE_EXE" "$GAME_DIR/contents/" + + if [[ "$STUBS" -eq 1 ]]; then + print_info "Copying nvidia stubs ($GAME_DLL_ARCH)..." + cp "$GAME_DIR/spice2x/stubs/$GAME_DLL_ARCH/"* "$GAME_DIR/contents/modules/" + fi + + rm -r "$GAME_DIR/spice2x" + + print_success "spice2x installed" +else + print_success "spice2x already present" +fi + +# Create Wine prefix +print_step "Creating Wine prefix" +export WINEARCH=win64 +export WINEPREFIX="$GAME_DIR/prefix" + +if [[ ! -d "$WINEPREFIX" ]]; then + print_info "Initializing Wine prefix at $WINEPREFIX..." + # Call wineboot and skip gecko/mono prompts + WINEDLLOVERRIDES="mscoree=d;mshtml=d" wineboot &>/dev/null + print_success "Wine prefix created" +else + print_warn "Wine prefix already exists, skipping creation" +fi + +print_step "Configuring Wine" +if [[ $PORTRAIT_MODE -eq 1 ]]; then + print_info "Setting up virtual desktop (1080x1920)..." + cat >/tmp/wine_desktop.reg <<'EOF' +Windows Registry Editor Version 5.00 + +[HKEY_CURRENT_USER\Software\Wine\Explorer] +"Desktop"="Default" + +[HKEY_CURRENT_USER\Software\Wine\Explorer\Desktops] +"Default"="1080x1920" +EOF + wine regedit /tmp/wine_desktop.reg &>/dev/null + rm /tmp/wine_desktop.reg + print_success "Virtual desktop configured" +fi + +# Install Wine dependencies +print_step "Installing Wine dependencies" +print_info "Installing DXVK, D3D compilers (this may take a while)..." +# common +winetricks -q dxvk d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 &>/dev/null || { + print_warn "Winetricks installation had some warnings, continuing..." +} +# required for ddr video playback +if [[ "$GAME_ID" = "ddr" ]]; then + print_info "Installing quartz, devenum, amstream, windowscodecs (this may take a while)..." + winetricks -q quartz devenum amstream windowscodecs &>/dev/null || { + print_warn "Winetricks installation had some warnings, continuing..." + } +fi +print_success "Wine dependencies installed" + +# Install audio dependencies +print_step "Installing audio dependencies" +if command -v pacman &>/dev/null; then + print_info "Installing GStreamer packages..." + sudo pacman -S --needed --noconfirm gstreamer gst-plugins-good gst-plugins-ugly gst-libav || { + print_warn "Failed to install some audio packages, you may need to install them manually" + } + print_success "Audio dependencies installed" +else + print_warn "Not on Arch Linux - please install gstreamer, gst-plugins-good, gst-plugins-ugly, and gst-libav manually" +fi + +# Setup PipeWire virtual sink +print_step "Configuring audio (PipeWire)" +echo -en "\n${CYAN}Do you want to set up a PipeWire virtual sink? [Y/n]:${NC} " +read -r AUDIO_SETUP +AUDIO_SETUP=${AUDIO_SETUP:-Y} + +if [[ "$AUDIO_SETUP" =~ ^[Yy]$ ]]; then + # Detect audio output device + print_info "Creating PipeWire virtual sink configuration..." + mkdir -p "$HOME/.config/pipewire/pipewire.conf.d" + + cat >"$HOME/.config/pipewire/pipewire.conf.d/virtual-sink.conf" <"$GAME_DIR/launch-$GAME_ID.sh" <"$GAME_DIR/config-$GAME_ID.sh" <