Skip to content

Latest commit

 

History

History
329 lines (248 loc) · 13.2 KB

File metadata and controls

329 lines (248 loc) · 13.2 KB

Jane's Fighters Anthology with ControllerBuddy on Linux

📖 Description

This guide describes the installation of Jane's Fighters Anthology for use with ControllerBuddy on Linux via the Proton compatibility layer.

What you get with this setup:

  • An installation of Jane's Fighters Anthology that is nicely integrated into your Steam library.
  • ControllerBuddy will start automatically when you start the game, load the correct profile, and exit when you quit the game.

🧩 Prerequisites

🪜 Steps

Important

Before starting with the steps, make sure to read the Important Notes section in the README of this repository.

  1. Mount the FA_1_00F.iso disc image to a temporary directory:
    export CDROM_DIR=$(mktemp -d cdrom-XXXX) &&
    sudo mount -o loop FA_1_00F.iso "$CDROM_DIR" &&
    echo "setup.exe located at: $CDROM_DIR/setup.exe"

Important

All subsequent commands must be executed within the same shell session to retain the CDROM_DIR environment variable.

  1. Add setup.exe as a Non-Steam game.

  2. Rename the setup.exe Steam shortcut to Jane's Fighters Anthology.

  3. Select Proton 11.0 (Beta) as compatibility tool.

  4. Launch the Jane's Fighters Anthology Steam shortcut and install Jane's Fighters Anthology.
    During the setup, select "Full Install - Digital Music".

  5. Obtain the APP_ID of the Proton prefix:

    export APP_ID=$(flatpak run com.github.Matoking.protontricks -l \
        | grep "^Non-Steam shortcut: Jane's Fighters Anthology ([0-9]\+)$" \
        | sed -E 's/.*\(([0-9]+)\).*/\1/' \
        | head -n1)
    echo "APP ID: $APP_ID"

Important

All subsequent commands must be executed within the same shell session to retain the APP_ID environment variable.

  1. Download fae102.exe with your browser:

    xdg-open https://jkpeterson.net/fa/misc/fae102.exe &
  2. Install the fae102.exe patch using Protontricks:

    cd $(xdg-user-dir DOWNLOAD) &&
    flatpak run com.github.Matoking.protontricks -c 'wine fae102.exe' "$APP_ID"

Important

During the patch installation, C:\JANES\Fighters Anthology\FA.EXE must be selected via My Computer.

  1. Download the FAno-cd.zip no-disc patch with your browser:

    xdg-open https://jkpeterson.net/fa/misc/FAno-cd.zip &
  2. Extract the FAno-cd.zip no-disc patch to your Fighters Anthology installation directory:

    cd $(xdg-user-dir DOWNLOAD) &&
    unzip -o FAno-cd.zip -x README.txt -d "$HOME/.local/share/Steam/steamapps/compatdata/$APP_ID/pfx/drive_c/JANES/Fighters Anthology"
  3. Replace the fake fa_7.lib of the no-disc patch with fa_7.lib from the disc image:

    cp "$CDROM_DIR/fa_7.lib" "$HOME/.local/share/Steam/steamapps/compatdata/$APP_ID/pfx/drive_c/JANES/Fighters Anthology/"

Important

Do not replace the fake fa_4c.lib with the one from the disc, as it will cause a crash to desktop during startup.

  1. Unmount the FA_1_00F.iso file and delete the temporary directory:

    sudo umount "$CDROM_DIR" &&
    rm -rf "$CDROM_DIR"
  2. Make sure all your game controllers are connected.

  3. Hide all game controllers from the Proton prefix, except for ControllerBuddy's UINPUT joystick device:

    reg_file=$(mktemp -p '' joysticks-XXXX.reg) &&
    python3 - <<'EOF' "$reg_file" &&
    import ctypes
    import ctypes.util
    import sys
    
    sdl2_path = ctypes.util.find_library("SDL2")
    if not sdl2_path:
        raise RuntimeError("Could not find SDL2 library")
    
    sdl = ctypes.CDLL(sdl2_path)
    
    Uint16 = ctypes.c_uint16
    Uint32 = ctypes.c_uint32
    class SDL_JoystickGUID(ctypes.Structure):
        _fields_ = [("data", ctypes.c_uint8 * 16)]
    
    sdl.SDL_Init.argtypes = [ctypes.c_uint32]
    sdl.SDL_Init.restype = ctypes.c_int
    
    sdl.SDL_Quit.argtypes = []
    sdl.SDL_Quit.restype = None
    
    sdl.SDL_NumJoysticks.argtypes = []
    sdl.SDL_NumJoysticks.restype = ctypes.c_int
    
    sdl.SDL_JoystickNameForIndex.argtypes = [ctypes.c_int]
    sdl.SDL_JoystickNameForIndex.restype = ctypes.c_char_p
    
    sdl.SDL_JoystickGetDeviceGUID.argtypes = [ctypes.c_int]
    sdl.SDL_JoystickGetDeviceGUID.restype = SDL_JoystickGUID
    
    sdl.SDL_GetJoystickGUIDInfo.argtypes = [SDL_JoystickGUID, ctypes.POINTER(Uint16), ctypes.POINTER(Uint16), ctypes.POINTER(Uint16), ctypes.POINTER(Uint16)]
    sdl.SDL_GetJoystickGUIDInfo.restype = None
    
    SDL_INIT_JOYSTICK = 0x00002000
    
    if sdl.SDL_Init(SDL_INIT_JOYSTICK) != 0:
        print("SDL_Init failed:", sdl.SDL_GetError().decode("utf-8"))
        sys.exit(1)
    
    # see: https://github.com/wine-mirror/wine/blob/master/dlls/hidclass.sys/device.c
    device_strings = {
        (0x045E, 0x028E): "Controller (XBOX 360 For Windows)",
        (0x045E, 0x028F): "Controller (XBOX 360 For Windows)",
        (0x045E, 0x02D1): "Controller (Xbox One For Windows)",
        (0x045E, 0x02DD): "Controller (Xbox One For Windows)",
        (0x045E, 0x02E3): "Controller (Xbox One For Windows)",
        (0x045E, 0x02EA): "Controller (Xbox One For Windows)",
        (0x045E, 0x02FD): "Controller (Xbox One For Windows)",
        (0x045E, 0x0719): "Controller (XBOX 360 For Windows)",
        (0x045E, 0x0B00): "Controller (Xbox One For Windows)",
        (0x045E, 0x0B05): "Controller (Xbox One For Windows)",
        (0x045E, 0x0B12): "Controller (Xbox One For Windows)",
        (0x045E, 0x0B13): "Controller (Xbox One For Windows)",
        (0x054C, 0x05C4): "Wireless Controller",
        (0x054C, 0x09CC): "Wireless Controller",
        (0x054C, 0x0BA0): "Wireless Controller",
        (0x054C, 0x0CE6): "Wireless Controller",
        (0x054C, 0x0DF2): "Wireless Controller",
    }
    
    count = sdl.SDL_NumJoysticks()
    joysticks = []
    
    for i in range(count):
        name_ptr = sdl.SDL_JoystickNameForIndex(i)
        if not name_ptr:
            continue
        name = name_ptr.decode("utf-8")
    
        if name == "ControllerBuddy Joystick":
            continue
    
        guid = sdl.SDL_JoystickGetDeviceGUID(i)
        vendor = Uint16()
        product = Uint16()
        version = Uint16()
        crc16 = Uint16()
        sdl.SDL_GetJoystickGUIDInfo(guid, ctypes.byref(vendor), ctypes.byref(product), ctypes.byref(version), ctypes.byref(crc16))
    
        key = (vendor.value, product.value)
        if key in device_strings:
            name = device_strings[key]
    
        joysticks.append(name)
    
    sdl.SDL_Quit()
    
    if not joysticks:
        print("Error: No joysticks detected on this system.", file=sys.stderr)
        sys.exit(1)
    
    def escape_reg_string(s: str) -> str:
        return s.replace('"', '""')
    
    print("Found the following joysticks:")
    for name in joysticks:
        print(f" {name}")
    
    if len(sys.argv) > 1:
        path = sys.argv[1]
        with open(path, "w", encoding="utf-16") as f:
            f.write("\ufeffWindows Registry Editor Version 5.00\n\n")
            f.write("[HKEY_CURRENT_USER\\Software\\Wine\\DirectInput\\Joysticks]\n")
            for name in joysticks:
                safe_name = escape_reg_string(name)
                f.write(f"\"{safe_name}\"=\"disabled\"\n")
        print(f"Wrote registry file: {path}")
    EOF
    flatpak run --filesystem="$reg_file":ro com.github.Matoking.protontricks -c "wine reg import '$reg_file'" "$APP_ID"
    rm -f "$reg_file"

Important

In the following step the placeholders denoted by <...> must be replaced accordingly to the following table:

Placeholder Description
<USER> Your username
<APP_ID> The Proton prefix APP ID obtained in step 6
  1. Update the Jane's Fighters Anthology Steam shortcut as follows:

    TARGET:

    "/home/<USER>/.local/share/Steam/steamapps/compatdata/<APP_ID>/pfx/drive_c/JANES/Fighters Anthology/FA.EXE"
    

    START IN:

    "/home/<USER>/.local/share/Steam/steamapps/compatdata/<APP_ID>/pfx/drive_c/JANES/Fighters Anthology"
    

    LAUNCH OPTIONS:

    "${STEAM_RUNTIME}"/scripts/switch-runtime.sh --runtime='' -- flatpak run de.bwravencl.ControllerBuddy -autostart local -profile /app/share/ControllerBuddy-Profiles/Fighters_Anthology.json -tray & timeout=15; timeout "$timeout" bash -c 'until grep -q "ControllerBuddy Joystick" /proc/bus/input/devices ; do sleep 1 ; done' && %command% || { [ $? -eq 124 ] && zenity --error --text="Launch aborted because ControllerBuddy wasn't ready within $timeout seconds.\n\nCheck if your controller is connected." --width 500 ; } ; killall -q ControllerBuddy
  2. Launch the Jane's Fighters Anthology Steam shortcut and configure the controls according to the screenshots:

    Joystick

    Rudder

    Throttle

🎮 Steam Deck Specifics

Launching from Gaming Mode

To allow launching Jane's Fighters Anthology with ControllerBuddy from the Steam Deck's Gaming Mode, a custom second shortcut must be created. If the normal shortcut is used, ControllerBuddy will launch but the overlay will not be visible.

  1. Create a new text file named Fighters_Anthology.sh in your home directory with the following content:

    #!/bin/bash
    
    # replace placeholder value manually
    SteamAppId=<APP_ID>
    
    game_dir="$HOME/.local/share/Steam/steamapps/compatdata/$SteamAppId/pfx/drive_c/JANES/Fighters Anthology"
    exe_file=FA.EXE
    proton_version='Proton 11.0'
    cb_profile=Fighters_Anthology.json
    
    export STEAM_COMPAT_CLIENT_INSTALL_PATH="$HOME/.steam/root/"
    export STEAM_COMPAT_DATA_PATH="$HOME/.local/share/Steam/steamapps/compatdata/$SteamAppId"
    
    flatpak run de.bwravencl.ControllerBuddy -autostart local -profile "/app/share/ControllerBuddy-Profiles/$cb_profile" -tray &
    
    trap 'killall -q ControllerBuddy' EXIT
    
    timeout=15
    cb_device_name="ControllerBuddy Joystick"
    
    i=0
    while ! grep -q "$cb_device_name" /proc/bus/input/devices
    do
        if ! pgrep -f 'flatpak-spawn --host /bin/bash -c FLATPAK_ID=de.bwravencl.ControllerBuddy' > /dev/null
        then
            (( i++ ))
            if [ "$i" -ge "$timeout" ]
            then
                zenity --error --text="Launch aborted because $cb_device_name wasn't ready within $timeout seconds.\n\nCheck if your controller is connected." --width 500
                exit 1
            fi
        fi
        sleep 1
    done
    
    cd "$game_dir" &&
    "$HOME/.local/share/Steam/ubuntu12_32/steam-launch-wrapper" -- \
        "$HOME/.local/share/Steam/ubuntu12_32/reaper" SteamLaunch AppId="$SteamAppId" -- \
        "$HOME/.local/share/Steam/steamapps/common/SteamLinuxRuntime_sniper/_v2-entry-point" --verb=waitforexitandrun -- \
        "$HOME/.local/share/Steam/steamapps/common/$proton_version/proton" waitforexitandrun \
        "$game_dir/$exe_file"
  2. Replace the placeholder <APP_ID> in the script with the actual APP ID obtained in step 6 of the main guide.

  3. Make the script executable:

    chmod +x "$HOME/Fighters_Anthology.sh"
  4. Add the Fighters_Anthology.sh launch script as a Non-Steam game to your Steam library.

  5. Rename the Fighters_Anthology.sh Steam shortcut to Jane's Fighters Anthology (Gaming Mode).

Important

The other Steam shortcut must not be deleted, as this would also delete the Proton prefix.

Configure Touchpads

Important

Since the Steam Deck's controller hardware is exposed to games via Steam Input, even if you do not care for the touchpad controls, you must at least apply the default Steam Input layout called Gamepad With Camera Controls to the Jane's Fighters Anthology (Gaming Mode) shortcut to ensure the controller can be detected by ControllerBuddy.

There is a special ControllerBuddy Steam Input controller layout available which configures the Steam Deck's touchpads to act as a mouse replacement.

Control Function
Right Touchpad Move mouse cursor
Right Touchpad Click Left mouse button
Left Touchpad Click Right mouse button
Left Touchpad Y-Axis Scroll up/down

To use this layout:

  1. Add the ControllerBuddy Steam Input layout to your Steam controller layouts:

    xdg-open steam://controllerconfig/3259858387/3672925155
  2. Apply the layout to both Jane's Fighters Anthology shortcuts in your Steam library.