#!/bin/sh
# Native Steam, the 32-bit graphics stack it needs, and the optional extras around it.
#
# WHY THIS IS A HOOK AND NOT A LINE IN steam-tv-box.list.chroot
# ------------------------------------------------------------
# live-build installs config/package-lists/* BEFORE it runs config/hooks/normal/*, and
# `steam-installer` is unusable until i386 is a known architecture: it is an amd64
# package whose entire job is to pull in an i386 dependency chain. Enabling multiarch
# has to happen first, and the only place in a live-build tree that can run a command
# before apt sees a package name is here.
#
# `steam-installer` (not `steam`) is Debian's own wrapper: it fetches Valve's bootstrap
# on first launch and keeps itself updated from Valve thereafter, which is what you
# want for a client that talks to a moving service. It lives in contrib, so
# build-steam-tv-box-iso.sh passes `--archive-areas "main contrib non-free
# non-free-firmware"` to `lb config`; without that this hook fails on the first
# apt-get install and the image comes up with no Steam at all.
set -eu

. /etc/steamtv-agent/config.env

export DEBIAN_FRONTEND=noninteractive

echo "0300-steam: enabling i386 multiarch"
dpkg --add-architecture i386
apt-get update

# --- The 32-bit graphics/audio stack -----------------------------------------------
# Proton's own runtime is 64-bit, but a great many shipped Linux builds and every
# pre-2015 title in a Steam library are 32-bit, and they fail with an opaque "failed to
# create GL context" rather than anything that names the missing library. Installing
# these up front is much cheaper than diagnosing that on a TV with a gamepad.
I386_PACKAGES="
libgl1-mesa-dri:i386
libglx-mesa0:i386
mesa-vulkan-drivers:i386
libvulkan1:i386
libasound2-plugins:i386
libpulse0:i386
libsdl2-2.0-0:i386
libopenal1:i386
"

# shellcheck disable=SC2086
if apt-get install -y --no-install-recommends $I386_PACKAGES; then
  echo "0300-steam: installed the i386 graphics/audio stack."
else
  echo "0300-steam: WARNING — the i386 stack did not install cleanly. 64-bit titles will"
  echo "  still run; 32-bit ones will fail with GL/Vulkan context errors. Retry on the"
  echo "  booted image with:  sudo apt-get install $(echo $I386_PACKAGES | tr '\n' ' ')"
fi

# --- Steam itself ------------------------------------------------------------------
# steam-devices ships the udev rules for Steam Controllers, Steam Decks used as pads,
# and the DualShock/DualSense/Xbox families. Without it the pads are visible only to
# root and Big Picture shows no controller at all — which on a machine with no keyboard
# in front of it is indistinguishable from a broken image.
if apt-get install -y steam-installer steam-devices; then
  echo "0300-steam: installed steam-installer + steam-devices."
else
  echo "0300-steam: ERROR — could not install steam-installer. The most likely cause is"
  echo "  that contrib is missing from the archive areas (see this file's header), or"
  echo "  the chroot had no network. This image will boot to the media session with no"
  echo "  Steam on it. Fix and rebuild rather than shipping it."
fi

# --- gamescope (optional) ----------------------------------------------------------
# The micro-compositor Valve uses on the Steam Deck. On a TV it is what gives Big
# Picture a fixed resolution and refresh rate independent of the desktop, integer
# scaling, and a framerate limiter — noticeably better than handing a game the raw
# output. Not required: /usr/local/bin/steam-big-picture detects it at launch and runs
# Steam directly under Xwayland when it is absent, so this failing is cosmetic.
if apt-get install -y --no-install-recommends gamescope; then
  echo "0300-steam: installed gamescope; Big Picture will run nested inside it."
else
  echo "0300-steam: note — gamescope is not available in this release. steam-big-picture"
  echo "  will fall back to plain Xwayland, which works but has no framerate limiter"
  echo "  and no integer scaling."
fi

# --- Vendor GPU driver -------------------------------------------------------------
# GPU_VENDOR comes from `gpu_vendor` in CoreSystemConfig.json. AMD and Intel need
# nothing beyond the Mesa packages already in the package list plus the firmware blobs;
# NVIDIA needs its own non-free driver, and installing that on an AMD box actively
# breaks it, which is why this is a config value and not a guess.
case "${GPU_VENDOR:-amd}" in
  nvidia)
    echo "0300-steam: GPU_VENDOR=nvidia — installing the non-free NVIDIA driver"
    # libnvidia-gl:i386 is the 32-bit GL/Vulkan half, the exact counterpart of the
    # Mesa i386 packages above and needed for the same 32-bit titles.
    if apt-get install -y nvidia-driver libnvidia-gl-535:i386 2>/dev/null \
       || apt-get install -y nvidia-driver nvidia-driver-libs:i386; then
      echo "0300-steam: NVIDIA driver installed."
      echo "0300-steam: VERIFY ON FIRST BOOT — sway on NVIDIA still wants"
      echo "  WLR_NO_HARDWARE_CURSORS=1 on some driver versions; kiosk-session sets it"
      echo "  when GPU_VENDOR=nvidia. Check \`vulkaninfo | head\` reports the NVIDIA ICD."
    else
      echo "0300-steam: WARNING — the NVIDIA driver did not install. Check that non-free"
      echo "  is in the archive areas and that the driver package name matches this"
      echo "  release, then install it on the booted machine."
    fi
    ;;
  intel)
    echo "0300-steam: GPU_VENDOR=intel — Mesa (already installed) is the whole driver."
    if ! apt-get install -y --no-install-recommends intel-media-va-driver-non-free; then
      echo "0300-steam: note — intel-media-va-driver-non-free unavailable; video decode"
      echo "  falls back to the free driver, which is fine for games and slower for 4K video."
    fi
    ;;
  *)
    echo "0300-steam: GPU_VENDOR=${GPU_VENDOR:-amd} — Mesa (already installed) is the whole driver."
    ;;
esac

# --- Let games ask for more file descriptors and memory maps -----------------------
# Proton/DXVK open a lot of both, and the distro defaults are what produce the
# "shader cache failed" and "vm.max_map_count" class of crashes late in a session.
cat > /etc/security/limits.d/90-steam-tv-box.conf <<'EOF'
# Proton and DXVK hold thousands of file descriptors open per running game.
*   soft  nofile  1048576
*   hard  nofile  1048576
EOF

cat > /etc/sysctl.d/90-steam-tv-box.conf <<'EOF'
# Several Proton titles (and anything using esync/fsync) exceed the default map count
# and die with an allocation failure that names nothing useful.
vm.max_map_count = 2147483642
EOF

apt-get clean
