Juegos que podes correr desde la TTY (si tiene soporte DRM DRKMS SDL) no estoy del todo seguro como se llama pero funcionan!


#!/usr/bin/env bash
# =============================================================================
#  instalar_juegos_tty.sh  —  Arch Linux
#
#  Clona, compila e instala juegos open source que corren desde la TTY
#  usando KMS/DRM via SDL2 (sin X11 ni Wayland necesario)
#
#  Juegos incluidos:
#    FPS/Arena  : Xonotic, GZDoom + Freedoom, Darkplaces + Quake shareware
#    RPG/Diablo : DevilutionX*, FLARE engine + game, FreedroidRPG
#    RTS        : Warzone 2100, OpenRA, Widelands
#    Racing     : Trigger Rally
#
#  (*) DevilutionX necesita diabdat.mpq del Diablo 1 original (GoG/CD)
#      Sin él igual corre con el shareware (spawn.mpq) que se descarga solo.
#
#  Uso:
#    chmod +x instalar_juegos_tty.sh
#    ./instalar_juegos_tty.sh                     # instala todo
#    ./instalar_juegos_tty.sh --solo devilutionx  # solo ese juego
#    ./instalar_juegos_tty.sh --solo flare
#    ./instalar_juegos_tty.sh --solo xonotic
#    ./instalar_juegos_tty.sh --solo gzdoom
#    ./instalar_juegos_tty.sh --solo darkplaces
#    ./instalar_juegos_tty.sh --solo warzone2100
#    ./instalar_juegos_tty.sh --solo openra
#    ./instalar_juegos_tty.sh --solo widelands
#    ./instalar_juegos_tty.sh --solo freedroidrpg
#    ./instalar_juegos_tty.sh --solo triggerrally
#    ./instalar_juegos_tty.sh --dir /opt/juegos   # directorio custom
#
#  Para jugar desde la TTY (sin X11/Wayland):
#    export SDL_VIDEODRIVER=kmsdrm
#    export SDL_AUDIODRIVER=alsa
#    ~/juegos/bin/<juego>
# =============================================================================

set -euo pipefail

# ─── Colores ──────────────────────────────────────────────────────────────────
RED='\033[0;31m'; GRN='\033[0;32m'; YEL='\033[1;33m'
BLU='\033[0;34m'; CYN='\033[0;36m'; BLD='\033[1m'; RST='\033[0m'

log()   { echo -e "${BLU}${BLD}[INFO]${RST} $*"; }
ok()    { echo -e "${GRN}${BLD}[ OK ]${RST} $*"; }
warn()  { echo -e "${YEL}${BLD}[WARN]${RST} $*"; }
err()   { echo -e "${RED}${BLD}[ERR ]${RST} $*" >&2; }
sep()   { echo -e "${CYN}${BLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RST}"; }
titulo(){ sep; echo -e "${BLD}$*${RST}"; sep; }

# ─── Argumentos ───────────────────────────────────────────────────────────────
SOLO=""
JUEGOS_DIR="${HOME}/juegos"
NJOBS=$(nproc 2>/dev/null || echo 4)

while [[ $# -gt 0 ]]; do
  case "$1" in
    --solo) SOLO="${2:-}"; shift 2 ;;
    --dir)  JUEGOS_DIR="${2:-}"; shift 2 ;;
    -h|--help)
      grep '^#' "$0" | head -45 | sed 's/^# \?//'
      exit 0 ;;
    *) err "Argumento desconocido: $1"; exit 1 ;;
  esac
done

SRC_DIR="${JUEGOS_DIR}/src"
BIN_DIR="${JUEGOS_DIR}/bin"
DATA_DIR="${JUEGOS_DIR}/data"
mkdir -p "${SRC_DIR}" "${BIN_DIR}" "${DATA_DIR}"

# ─── Helpers ──────────────────────────────────────────────────────────────────
debe_instalar() {
  [[ -z "${SOLO}" || "${SOLO}" == "$1" ]]
}

clonar_o_actualizar() {
  local url="$1" dest="$2"
  if [[ -d "${dest}/.git" ]]; then
    log "Actualizando $(basename "${dest}")..."
    git -C "${dest}" pull --ff-only || warn "Usando versión local sin actualizar"
  else
    log "Clonando $(basename "${dest}")..."
    git clone --depth=1 "${url}" "${dest}"
  fi
}

crear_launcher() {
  local nombre="$1"
  local f="${BIN_DIR}/${nombre}"
  cat > "${f}"
  chmod +x "${f}"
  ok "Launcher: ${f}"
}

pacman_instalar() {
  sudo pacman -S --needed --noconfirm "$@" 2>&1 | grep -v "^warning: .* is up to date" || true
}

# ═══════════════════════════════════════════════════════════════════════════════
#  DEPENDENCIAS BASE
# ═══════════════════════════════════════════════════════════════════════════════
instalar_deps_base() {
  titulo "Dependencias base del sistema"
  log "Actualizando repositorios pacman..."
  sudo pacman -Sy --noconfirm

  pacman_instalar \
    base-devel cmake git ninja python curl unzip \
    sdl2 sdl2_image sdl2_mixer sdl2_ttf sdl2_net \
    mesa libglvnd \
    alsa-lib alsa-utils openal \
    zlib bzip2 libpng libjpeg-turbo \
    libsodium fmt

  ok "Dependencias base listas"
}

# ═══════════════════════════════════════════════════════════════════════════════
#  1. XONOTIC
# ═══════════════════════════════════════════════════════════════════════════════
instalar_xonotic() {
  titulo "Xonotic — Arena FPS libre (tipo Quake3)"

  local dest="${DATA_DIR}/xonotic"
  local zip="${SRC_DIR}/xonotic.zip"
  local url="https://dl.xonotic.org/xonotic-0.8.6.zip"

  if [[ ! -f "${zip}" ]]; then
    log "Descargando Xonotic (~1.5 GB)..."
    curl -L --progress-bar -o "${zip}" "${url}"
  else
    log "Usando archivo ya descargado"
  fi

  if [[ ! -d "${dest}" ]]; then
    log "Extrayendo..."
    unzip -q "${zip}" -d "${DATA_DIR}/"
    [[ -d "${DATA_DIR}/Xonotic" ]] && mv "${DATA_DIR}/Xonotic" "${dest}"
  fi

  crear_launcher "xonotic" <<EOF
#!/bin/bash
export SDL_VIDEODRIVER=kmsdrm
export SDL_AUDIODRIVER=alsa
cd '${dest}'
./xonotic-linux64-sdl "\$@"
EOF
  ok "Xonotic → ${BIN_DIR}/xonotic"
}

# ═══════════════════════════════════════════════════════════════════════════════
#  2. GZDOOM + FREEDOOM
# ═══════════════════════════════════════════════════════════════════════════════
instalar_gzdoom() {
  titulo "GZDoom + Freedoom (Doom moderno, WADs libres)"

  pacman_instalar fluidsynth wildmidi gtk3 libjpeg-turbo bzip2

  # zmusic: intentar repo oficial primero, luego AUR
  if ! pacman -Q zmusic &>/dev/null 2>&1; then
    if pacman -Si zmusic &>/dev/null 2>&1; then
      pacman_instalar zmusic
    elif command -v yay &>/dev/null; then
      yay -S --noconfirm zmusic
    elif command -v paru &>/dev/null; then
      paru -S --noconfirm zmusic
    else
      warn "zmusic no encontrado; GZDoom compilará igual pero sin algunos formatos MIDI"
    fi
  fi

  local dir="${SRC_DIR}/gzdoom"
  clonar_o_actualizar "https://github.com/ZDoom/gzdoom.git" "${dir}"

  log "Compilando GZDoom..."
  cmake -S "${dir}" -B "${dir}/build" \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX="${JUEGOS_DIR}" \
    -Wno-dev 2>&1 | tail -5
  cmake --build "${dir}/build" -j "${NJOBS}" 2>&1 | tail -5
  cmake --install "${dir}/build" --prefix "${JUEGOS_DIR}"

  # Freedoom WADs libres
  local fdzip="${SRC_DIR}/freedoom.zip"
  local fddir="${DATA_DIR}/freedoom"
  local wad_dest="${JUEGOS_DIR}/share/games/doom"
  mkdir -p "${wad_dest}"

  if [[ ! -f "${fdzip}" ]]; then
    log "Descargando Freedoom WADs (~300 MB)..."
    curl -L --progress-bar \
      -o "${fdzip}" \
      "https://github.com/freedoom/freedoom/releases/download/v0.13.0/freedoom-0.13.0.zip"
  fi
  if [[ ! -d "${fddir}" ]]; then
    unzip -q "${fdzip}" -d "${DATA_DIR}/"
    find "${DATA_DIR}" -maxdepth 2 -name "freedoom*" -type d | head -1 | \
      xargs -I{} mv {} "${fddir}" 2>/dev/null || true
  fi
  find "${fddir}" -name "*.wad" -exec cp -n {} "${wad_dest}/" \; 2>/dev/null || true

  crear_launcher "gzdoom" <<EOF
#!/bin/bash
export SDL_VIDEODRIVER=kmsdrm
export SDL_AUDIODRIVER=alsa
# Freedoom Phase 1 por defecto; cambiá -iwad para otros WADs
'${JUEGOS_DIR}/bin/gzdoom' -iwad '${wad_dest}/freedoom1.wad' "\$@"
EOF

  crear_launcher "gzdoom-freedoom2" <<EOF
#!/bin/bash
export SDL_VIDEODRIVER=kmsdrm
export SDL_AUDIODRIVER=alsa
'${JUEGOS_DIR}/bin/gzdoom' -iwad '${wad_dest}/freedoom2.wad' "\$@"
EOF
  ok "GZDoom + Freedoom → ${BIN_DIR}/gzdoom"
}

# ═══════════════════════════════════════════════════════════════════════════════
#  3. DARKPLACES (motor Quake 1)
# ═══════════════════════════════════════════════════════════════════════════════
instalar_darkplaces() {
  titulo "Darkplaces — Motor Quake 1 mejorado"

  pacman_instalar libjpeg-turbo libpng openal curl libxrandr

  local dir="${SRC_DIR}/darkplaces"
  clonar_o_actualizar "https://github.com/DarkPlacesEngine/darkplaces.git" "${dir}"

  local q1dir="${DATA_DIR}/quake1"
  mkdir -p "${q1dir}/id1"

  log "Compilando Darkplaces..."
  make -C "${dir}" -j "${NJOBS}" cl-release 2>&1 | tail -8
  cp "${dir}/darkplaces-sdl" "${BIN_DIR}/darkplaces-bin"

  # Intentar descargar shareware de Quake 1
  local pak="${q1dir}/id1/pak0.pak"
  if [[ ! -f "${pak}" ]]; then
    log "Intentando descargar Quake 1 shareware..."
    curl -L --progress-bar \
      -o "${SRC_DIR}/q1sw.zip" \
      "https://downloads.sourceforge.net/quake/quakesw-1.06.zip" 2>/dev/null && \
    unzip -q -o "${SRC_DIR}/q1sw.zip" -d "${SRC_DIR}/q1sw_tmp/" 2>/dev/null && \
    find "${SRC_DIR}/q1sw_tmp" -iname "pak0.pak" -exec cp {} "${q1dir}/id1/" \; || \
    warn "No se pudo descargar pak0.pak automáticamente.
  Copialo manualmente a: ${q1dir}/id1/pak0.pak"
  fi

  crear_launcher "darkplaces" <<EOF
#!/bin/bash
export SDL_VIDEODRIVER=kmsdrm
export SDL_AUDIODRIVER=alsa
'${BIN_DIR}/darkplaces-bin' -basedir '${q1dir}' "\$@"
EOF
  ok "Darkplaces → ${BIN_DIR}/darkplaces"
  warn "Necesitás pak0.pak en: ${q1dir}/id1/"
}

# ═══════════════════════════════════════════════════════════════════════════════
#  4. DEVILUTIONX (Diablo 1)
# ═══════════════════════════════════════════════════════════════════════════════
instalar_devilutionx() {
  titulo "DevilutionX — Diablo 1 en sistemas modernos"

  pacman_instalar sdl2 sdl2_image sdl2_mixer sdl2_ttf libsodium libpng bzip2 fmt

  # smpq puede estar en AUR
  if ! pacman -Q smpq &>/dev/null 2>&1; then
    if command -v yay &>/dev/null; then
      yay -S --noconfirm smpq 2>/dev/null || warn "smpq no instalado (opcional)"
    elif command -v paru &>/dev/null; then
      paru -S --noconfirm smpq 2>/dev/null || warn "smpq no instalado (opcional)"
    fi
  fi

  local dir="${SRC_DIR}/devilutionx"
  clonar_o_actualizar "https://github.com/diasurgical/devilutionX.git" "${dir}"

  log "Compilando DevilutionX..."
  cmake -S "${dir}" -B "${dir}/build" \
    -DCMAKE_BUILD_TYPE=Release \
    -DBUILD_TESTING=OFF \
    -Wno-dev 2>&1 | tail -5
  cmake --build "${dir}/build" -j "${NJOBS}" 2>&1 | tail -5

  cp "${dir}/build/devilutionx" "${BIN_DIR}/devilutionx-bin"

  # Directorio de datos
  local mpq_dir="${HOME}/.local/share/diasurgical/devilution"
  mkdir -p "${mpq_dir}"

  # spawn.mpq = demo gratuita oficial
  if [[ ! -f "${mpq_dir}/spawn.mpq" && ! -f "${mpq_dir}/diabdat.mpq" ]]; then
    log "Descargando spawn.mpq (demo gratuita de Diablo 1)..."
    curl -L --progress-bar \
      -o "${mpq_dir}/spawn.mpq" \
      "https://github.com/diasurgical/devilutionx-assets/releases/download/v2/spawn.mpq" || \
      warn "No se pudo descargar spawn.mpq"
  fi

  crear_launcher "devilutionx" <<EOF
#!/bin/bash
export SDL_VIDEODRIVER=kmsdrm
export SDL_AUDIODRIVER=alsa
# Para Diablo 1 completo copiá diabdat.mpq a:
#   ${mpq_dir}/
# La demo (spawn.mpq) ya está instalada para jugar de inmediato.
'${BIN_DIR}/devilutionx-bin' "\$@"
EOF
  ok "DevilutionX → ${BIN_DIR}/devilutionx"
  echo -e "  ${YEL}Diablo 1 completo${RST}: copiá diabdat.mpq → ${mpq_dir}/"
  echo -e "  ${GRN}Demo gratuita${RST}   : spawn.mpq ya instalado"
}

# ═══════════════════════════════════════════════════════════════════════════════
#  5. FLARE engine + game (Empyrean Campaign)
# ═══════════════════════════════════════════════════════════════════════════════
instalar_flare() {
  titulo "FLARE — Action RPG tipo Diablo (100% libre)"

  pacman_instalar sdl2 sdl2_image sdl2_mixer sdl2_ttf cmake gcc

  # Engine
  local edir="${SRC_DIR}/flare-engine"
  clonar_o_actualizar "https://github.com/flareteam/flare-engine.git" "${edir}"
  log "Compilando FLARE engine..."
  cmake -S "${edir}" -B "${edir}/build" \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX="${JUEGOS_DIR}" \
    -Wno-dev 2>&1 | tail -3
  cmake --build "${edir}/build" -j "${NJOBS}" 2>&1 | tail -3
  cmake --install "${edir}/build" --prefix "${JUEGOS_DIR}"

  # Game data (Empyrean Campaign)
  local gdir="${SRC_DIR}/flare-game"
  clonar_o_actualizar "https://github.com/flareteam/flare-game.git" "${gdir}"
  log "Instalando datos Empyrean Campaign..."
  cmake -S "${gdir}" -B "${gdir}/build" \
    -DCMAKE_INSTALL_PREFIX="${JUEGOS_DIR}" \
    -Wno-dev 2>&1 | tail -3
  cmake --build "${gdir}/build" -j "${NJOBS}" 2>&1 | tail -3
  cmake --install "${gdir}/build" --prefix "${JUEGOS_DIR}" 2>/dev/null || \
    { mkdir -p "${JUEGOS_DIR}/share/flare/mods"
      cp -r "${gdir}/mods/"* "${JUEGOS_DIR}/share/flare/mods/" 2>/dev/null || true; }

  crear_launcher "flare" <<EOF
#!/bin/bash
export SDL_VIDEODRIVER=kmsdrm
export SDL_AUDIODRIVER=alsa
'${JUEGOS_DIR}/bin/flare' "\$@"
EOF
  ok "FLARE → ${BIN_DIR}/flare"
}

# ═══════════════════════════════════════════════════════════════════════════════
#  6. FREEDROIDRPG
# ═══════════════════════════════════════════════════════════════════════════════
instalar_freedroidrpg() {
  titulo "FreedroidRPG — RPG acción sci-fi tipo Diablo"

  pacman_instalar sdl2 sdl2_image sdl2_mixer sdl2_ttf \
    lua libogg libvorbis libpng libjpeg-turbo autoconf automake

  local dir="${SRC_DIR}/freedroidrpg"
  clonar_o_actualizar "https://gitlab.com/freedroid/freedroid-src.git" "${dir}"

  log "Generando sistema de build..."
  cd "${dir}"
  [[ ! -f configure ]] && autoreconf -fi 2>&1 | tail -3

  mkdir -p "${dir}/build_dir"
  cd "${dir}/build_dir"
  ../configure \
    --prefix="${JUEGOS_DIR}" \
    --disable-docs \
    2>&1 | tail -5

  log "Compilando FreedroidRPG (puede tardar)..."
  make -j "${NJOBS}" 2>&1 | tail -5
  make install

  crear_launcher "freedroidrpg" <<EOF
#!/bin/bash
export SDL_VIDEODRIVER=kmsdrm
export SDL_AUDIODRIVER=alsa
'${JUEGOS_DIR}/bin/freedroidRPG' "\$@"
EOF
  ok "FreedroidRPG → ${BIN_DIR}/freedroidrpg"
}

# ═══════════════════════════════════════════════════════════════════════════════
#  7. WARZONE 2100
# ═══════════════════════════════════════════════════════════════════════════════
instalar_warzone2100() {
  titulo "Warzone 2100 — RTS sci-fi"

  pacman_instalar sdl2 sdl2_image openal physfs \
    libpng libjpeg-turbo libvorbis libogg libtheora glew \
    vulkan-icd-loader zip

  local dir="${SRC_DIR}/warzone2100"
  clonar_o_actualizar "https://github.com/Warzone2100/warzone2100.git" "${dir}"

  log "Actualizando submódulos..."
  git -C "${dir}" submodule update --init --recursive --depth=1 2>&1 | tail -3

  log "Compilando Warzone 2100 (puede tardar bastante)..."
  cmake -S "${dir}" -B "${dir}/build" \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX="${JUEGOS_DIR}" \
    -DWZ_ENABLE_WARNINGS=OFF \
    -Wno-dev 2>&1 | tail -5
  cmake --build "${dir}/build" -j "${NJOBS}" 2>&1 | tail -5
  cmake --install "${dir}/build" --prefix "${JUEGOS_DIR}"

  crear_launcher "warzone2100" <<EOF
#!/bin/bash
export SDL_VIDEODRIVER=kmsdrm
export SDL_AUDIODRIVER=alsa
'${JUEGOS_DIR}/bin/warzone2100' "\$@"
EOF
  ok "Warzone 2100 → ${BIN_DIR}/warzone2100"
}

# ═══════════════════════════════════════════════════════════════════════════════
#  8. OPENRA
# ═══════════════════════════════════════════════════════════════════════════════
instalar_openra() {
  titulo "OpenRA — Command & Conquer / Red Alert open source"

  # OpenRA necesita .NET
  if ! command -v dotnet &>/dev/null; then
    log "Instalando .NET SDK..."
    if pacman -Si dotnet-sdk &>/dev/null 2>&1; then
      pacman_instalar dotnet-sdk
    elif command -v yay &>/dev/null; then
      yay -S --noconfirm dotnet-sdk-bin
    elif command -v paru &>/dev/null; then
      paru -S --noconfirm dotnet-sdk-bin
    else
      err "Necesitás dotnet-sdk. Instalá yay o paru para obtenerlo del AUR:"
      err "  yay -S dotnet-sdk-bin"
      err "Luego re-ejecutá: $0 --solo openra"
      return 1
    fi
  fi

  pacman_instalar sdl2 openal lua53 2>/dev/null || \
    pacman_instalar sdl2 openal lua

  local dir="${SRC_DIR}/openra"
  clonar_o_actualizar "https://github.com/OpenRA/OpenRA.git" "${dir}"

  log "Compilando OpenRA..."
  cd "${dir}"
  make all 2>&1 | tail -10

  for mod in ra cnc d2k ts; do
    crear_launcher "openra-${mod}" <<EOF
#!/bin/bash
export SDL_VIDEODRIVER=kmsdrm
export SDL_AUDIODRIVER=alsa
cd '${dir}'
./launch-game.sh Game.Mod=${mod} "\$@"
EOF
  done

  ok "OpenRA → ${BIN_DIR}/openra-ra  openra-cnc  openra-d2k  openra-ts"
}

# ═══════════════════════════════════════════════════════════════════════════════
#  9. WIDELANDS
# ═══════════════════════════════════════════════════════════════════════════════
instalar_widelands() {
  titulo "Widelands — Estrategia tipo Settlers"

  pacman_instalar sdl2 sdl2_image sdl2_mixer sdl2_ttf sdl2_net \
    glew python lua boost icu

  local dir="${SRC_DIR}/widelands"
  clonar_o_actualizar "https://github.com/widelands/widelands.git" "${dir}"

  log "Compilando Widelands (puede tardar)..."
  cmake -S "${dir}" -B "${dir}/build" \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX="${JUEGOS_DIR}" \
    -DOPTION_BUILD_TESTS=OFF \
    -Wno-dev 2>&1 | tail -5
  cmake --build "${dir}/build" -j "${NJOBS}" 2>&1 | tail -5
  cmake --install "${dir}/build" --prefix "${JUEGOS_DIR}"

  crear_launcher "widelands" <<EOF
#!/bin/bash
export SDL_VIDEODRIVER=kmsdrm
export SDL_AUDIODRIVER=alsa
'${JUEGOS_DIR}/bin/widelands' "\$@"
EOF
  ok "Widelands → ${BIN_DIR}/widelands"
}

# ═══════════════════════════════════════════════════════════════════════════════
#  10. TRIGGER RALLY
# ═══════════════════════════════════════════════════════════════════════════════
instalar_triggerrally() {
  titulo "Trigger Rally — Racing off-road SDL2"

  pacman_instalar sdl2 sdl2_image openal physfs libvorbis libogg

  local dir="${SRC_DIR}/trigger-rally"
  clonar_o_actualizar "https://github.com/trigger-rally/trigger-rally.git" "${dir}"

  log "Compilando Trigger Rally..."
  cmake -S "${dir}" -B "${dir}/build" \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX="${JUEGOS_DIR}" \
    -Wno-dev 2>&1 | tail -5
  cmake --build "${dir}/build" -j "${NJOBS}" 2>&1 | tail -5
  cmake --install "${dir}/build" --prefix "${JUEGOS_DIR}"

  crear_launcher "triggerrally" <<EOF
#!/bin/bash
export SDL_VIDEODRIVER=kmsdrm
export SDL_AUDIODRIVER=alsa
'${JUEGOS_DIR}/bin/trigger-rally' "\$@"
EOF
  ok "Trigger Rally → ${BIN_DIR}/triggerrally"
}

# ═══════════════════════════════════════════════════════════════════════════════
#  RESUMEN
# ═══════════════════════════════════════════════════════════════════════════════
mostrar_resumen() {
  sep
  echo -e "${BLD}${GRN}  ✔  INSTALACIÓN COMPLETADA${RST}"
  sep
  echo ""
  echo -e "${BLD}  Launchers en: ${CYN}${BIN_DIR}/${RST}"
  echo ""

  while IFS= read -r f; do
    echo -e "    ${GRN}$(basename "${f}")${RST}"
  done < <(find "${BIN_DIR}" -maxdepth 1 -type f -executable 2>/dev/null | sort)

  echo ""
  echo -e "${BLD}  Cómo jugar desde la TTY:${RST}"
  echo ""
  echo -e "    ${YEL}# Agregá a ~/.bash_profile o ~/.zprofile:${RST}"
  echo -e "    export SDL_VIDEODRIVER=kmsdrm"
  echo -e "    export SDL_AUDIODRIVER=alsa"
  echo -e "    export PATH=\"\$PATH:${BIN_DIR}\""
  echo ""
  echo -e "    ${YEL}# Permisos KMS/DRM (si todavía no los tenés):${RST}"
  echo -e "    sudo usermod -aG video,input \$USER"
  echo -e "    ${GRN}# luego cerrá sesión y volvé a entrar${RST}"
  echo ""

  if debe_instalar "devilutionx"; then
    local mpq="${HOME}/.local/share/diasurgical/devilution"
    echo -e "${BLD}  DevilutionX — para Diablo 1 completo:${RST}"
    echo -e "    Copiá ${YEL}diabdat.mpq${RST}${mpq}/"
    echo -e "    (conseguilo en GoG.com → Diablo 1)"
    echo ""
  fi

  if debe_instalar "darkplaces"; then
    echo -e "${BLD}  Darkplaces — para Quake 1:${RST}"
    echo -e "    Copiá ${YEL}pak0.pak${RST}${DATA_DIR}/quake1/id1/"
    echo ""
  fi

  sep
}

# ═══════════════════════════════════════════════════════════════════════════════
#  MAIN
# ═══════════════════════════════════════════════════════════════════════════════
main() {
  sep
  echo -e "${BLD}${CYN}  instalar_juegos_tty.sh  —  Arch Linux + KMS/DRM${RST}"
  sep
  echo ""
  log "Directorio base  : ${JUEGOS_DIR}"
  log "Fuentes (src)    : ${SRC_DIR}"
  log "Launchers (bin)  : ${BIN_DIR}"
  log "Datos (data)     : ${DATA_DIR}"
  log "Jobs de compilación: ${NJOBS}"
  [[ -n "${SOLO}" ]] && log "Solo instalando  : ${SOLO}"
  echo ""

  if ! command -v pacman &>/dev/null; then
    err "Este script es solo para Arch Linux (pacman no encontrado)"
    exit 1
  fi

  # Advertencia permisos KMS/DRM
  if ! groups | grep -qE '\bvideo\b|\bseat\b'; then
    warn "Tu usuario no está en el grupo 'video' ni 'seat'"
    warn "KMS/DRM puede no funcionar sin estos permisos:"
    echo  "    sudo usermod -aG video,input \$USER"
    echo  "    (cerrá sesión y volvé a entrar)"
    echo ""
  fi

  instalar_deps_base

  debe_instalar "xonotic"      && instalar_xonotic      || true
  #debe_instalar "gzdoom"       && instalar_gzdoom        || true
  debe_instalar "darkplaces"   && instalar_darkplaces    || true
  debe_instalar "devilutionx"  && instalar_devilutionx   || true
  debe_instalar "flare"        && instalar_flare          || true
  debe_instalar "freedroidrpg" && instalar_freedroidrpg  || true
  debe_instalar "warzone2100"  && instalar_warzone2100    || true
  debe_instalar "openra"       && instalar_openra         || true
  debe_instalar "widelands"    && instalar_widelands      || true
  debe_instalar "triggerrally" && instalar_triggerrally   || true

  mostrar_resumen
}

main "$@"