Unpacking the zip anywhere now yields one self-contained RP412\ directory instead of scattering ~1000 files into the extraction folder. The -Zip step stages a copy under the temp dir as RP412\ and compresses that folder. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
289 lines
12 KiB
PowerShell
289 lines
12 KiB
PowerShell
# ============================================================================
|
|
# pack-dist.ps1 - assemble a runnable Red Planet 4.12 package into dist\
|
|
# ============================================================================
|
|
#
|
|
# Collects everything the game needs at run time:
|
|
# - Release\rpl4opt.exe (+ .pdb for crash debugging)
|
|
# - game data from assets\RP411 (AUDIO, GAUGE, VIDEO, INIs, RPL4.RES,
|
|
# TEST.EGG) - but not the arcade launch scripts or the old 4.10 exe
|
|
# - libsndfile-1.dll beside the exe; OpenAL32.dll copied from the system
|
|
# when installed, with oalinst.exe included as the fallback installer
|
|
# - a desktop environ.ini (PAD;KEYBOARD controls, on-screen plasma)
|
|
# - start-windowed.bat and a README
|
|
#
|
|
# Usage: powershell -ExecutionPolicy Bypass -File pack-dist.ps1 [-Zip]
|
|
#
|
|
param(
|
|
[switch]$Zip
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$root = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
$dist = Join-Path $root 'dist'
|
|
$assets = Join-Path $root 'assets\RP411'
|
|
$exe = Join-Path $root 'Release\rpl4opt.exe'
|
|
|
|
if (-not (Test-Path $exe)) {
|
|
throw "Release\rpl4opt.exe not found - build first (see BUILD.md 2)."
|
|
}
|
|
|
|
# Refuse to touch a dist the game is currently running from.
|
|
$running = Get-Process rpl4opt -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.Path -like "$dist\*" }
|
|
if ($running) {
|
|
throw "rpl4opt.exe is running from $dist (PID $($running.Id)) - close the game first."
|
|
}
|
|
|
|
Write-Host "Packing into $dist"
|
|
if (Test-Path $dist) { Remove-Item -Recurse -Force $dist }
|
|
New-Item -ItemType Directory -Force "$dist\SPOOLS" | Out-Null
|
|
|
|
# --- game binary -----------------------------------------------------------
|
|
Copy-Item $exe $dist
|
|
$pdb = Join-Path $root 'Release\rpl4opt.pdb'
|
|
if (Test-Path $pdb) { Copy-Item $pdb $dist }
|
|
|
|
# steam_api.dll: the exe imports it (RP412_STEAM build). The Steam wire
|
|
# only activates with RP412STEAM=1; plain desktop runs never touch it.
|
|
Copy-Item (Join-Path $root 'extern\steamworks_sdk_164\sdk\redistributable_bin\steam_api.dll') $dist
|
|
|
|
# steam_appid.txt: until RP412 has its own AppID, Steam testing runs
|
|
# under Spacewar (480). Without this file SteamAPI_Init fails and the
|
|
# game falls back to plain TCP - which is exactly the confusing symptom
|
|
# testers hit when the file goes missing. Delete it once we ship under
|
|
# our own AppID (the Steam client provides it then).
|
|
Set-Content -Path "$dist\steam_appid.txt" -Encoding ascii -Value '480'
|
|
|
|
# --- game data -------------------------------------------------------------
|
|
foreach ($dir in 'AUDIO', 'GAUGE', 'VIDEO') {
|
|
Write-Host " copying $dir..."
|
|
Copy-Item -Recurse (Join-Path $assets $dir) $dist
|
|
}
|
|
foreach ($file in 'RPDPL.INI', 'JOYSTICK.INI', 'RPL4.RES', 'TEST.EGG',
|
|
'libsndfile-1.dll', 'oalinst.exe') {
|
|
Copy-Item (Join-Path $assets $file) $dist
|
|
}
|
|
|
|
# --- OpenAL runtime --------------------------------------------------------
|
|
# The exe links OpenAL32.dll (32-bit). Prefer shipping the already-installed
|
|
# runtime beside the exe; oalinst.exe covers machines where that misses.
|
|
$openal = "$env:WINDIR\SysWOW64\OpenAL32.dll"
|
|
if (-not (Test-Path $openal)) { $openal = "$env:WINDIR\System32\OpenAL32.dll" }
|
|
if (Test-Path $openal) {
|
|
Copy-Item $openal $dist
|
|
$wrap = Join-Path (Split-Path $openal) 'wrap_oal.dll'
|
|
if (Test-Path $wrap) { Copy-Item $wrap $dist }
|
|
Write-Host " OpenAL runtime copied from $(Split-Path $openal)"
|
|
} else {
|
|
Write-Warning "OpenAL32.dll not found on this system - dist relies on oalinst.exe"
|
|
}
|
|
|
|
# --- desktop configuration -------------------------------------------------
|
|
Set-Content -Path "$dist\environ.ini" -Encoding ascii -Value @"
|
|
# ============================================================================
|
|
# environ.ini - Red Planet 4.12 configuration
|
|
# ============================================================================
|
|
# One KEY=VALUE per line, read at game start. Lines starting with # or ;
|
|
# are comments; anything without an = is ignored. Delete a line (or
|
|
# comment it out) to fall back to the built-in default.
|
|
#
|
|
# Input bindings live in bindings.txt beside the exe (written with the
|
|
# full documented layout on first run; delete it to restore defaults).
|
|
|
|
# ---- Core (the shipped configuration) --------------------------------------
|
|
|
|
# Control stack: tokens separated by ; or , processed left to right.
|
|
# PAD the virtual RIO (XInput controller + keyboard,
|
|
# rebindable via bindings.txt)
|
|
# RIO real serial cockpit hardware on COM1
|
|
# RIO:COMn same, on another port (RIO:COM3, ...)
|
|
# KEYBOARD the engine keyboard handler
|
|
# MOUSE, JOYSTICK, FLIGHTSTICKPRO, THRUSTMASTER, DIJOYSTICK
|
|
# legacy pointer/joystick drivers (untested here)
|
|
# Unset falls back to KEYBOARD alone.
|
|
L4CONTROLS=PAD;KEYBOARD
|
|
|
|
# Renderer bring-up argument. Only its presence is checked (the DPL
|
|
# resolution parsing it once fed is gone) and the game refuses to start
|
|
# without it - any non-empty value works. Leave as shipped.
|
|
DPLARG=1
|
|
|
|
# DPL (renderer/scene) configuration file, searched beside the exe.
|
|
# Any notation file name; RPDPL.INI is the one that ships.
|
|
L4DPLCFG=RPDPL.INI
|
|
|
|
# Gauge (MFD/instrument) canvas. Must name a page of GAUGE\L4GAUGE.INI:
|
|
# 640x480x8 | 640x480x16 | 800x600x16
|
|
# Unset disables the gauge renderer (and with it all MFDs).
|
|
L4GAUGE=640x480x16
|
|
|
|
# Plasma display.
|
|
# SCREEN render the pod's plasma glass in-window (currently
|
|
# parked off-layout)
|
|
# COM1, COM2... drive real plasma glass on that serial port
|
|
# (9600 baud, N81)
|
|
# Unset = no plasma display.
|
|
L4PLASMA=SCREEN
|
|
|
|
# 0 = classic separate gauge windows; 1 = the single-window glass
|
|
# cockpit (all seven displays composed on a locked 1920x1080 canvas
|
|
# around the viewscreen); 2 = exploded diagnostic view (each display
|
|
# in its own native-resolution desktop window - MFDs 640x480, map
|
|
# 480x640 - decoded exactly as the pod's VDB split them, no downscale).
|
|
L4MFDSPLIT=1
|
|
|
|
# Simulation/render frame rate, integer frames/second. The desktop
|
|
# default is 60; the arcade pods shipped at 25.
|
|
TARGETFPS=60
|
|
|
|
# 1 = Steam networking (lobbies, FakeIP mesh). Needs the Steam client
|
|
# running and steam_appid.txt beside the exe; without them the game
|
|
# logs the reason and falls back to plain TCP. 0 = TCP only.
|
|
RP412STEAM=1
|
|
|
|
# ---- Optional ---------------------------------------------------------------
|
|
|
|
# RGB keyboard lamp mirror (Windows Dynamic Lighting): keys bound to
|
|
# lamp buttons glow with the panel, flash modes and all.
|
|
# Unset or nonzero = on (the default); 0 = off.
|
|
#RP412KEYLIGHT=0
|
|
|
|
# Invert the stick on top of whatever bindings.txt produces:
|
|
# X = invert X only, Y = invert Y only, XY = both (case-insensitive).
|
|
#L4PADFLIP=XY
|
|
|
|
# Anti-aliasing sample count, passed straight to Direct3D 9:
|
|
# 0 = off, else 2..16 as the GPU supports (1 selects the driver's
|
|
# "nonmaskable" mode; unsupported counts fail device creation).
|
|
#MULTISAMPLE=0
|
|
|
|
# Particle budget, integer. Default 8192.
|
|
#MAXPARTICLES=8192
|
|
|
|
# On-screen plasma glass (L4PLASMA=SCREEN only). SCALE = integer pixel
|
|
# size 1..16, default 4 (out-of-range values are ignored). POS = window
|
|
# top-left as X,Y screen coordinates; unset = auto, parked below the
|
|
# main window.
|
|
#L4PLASMASCALE=4
|
|
#L4PLASMAPOS=0,0
|
|
|
|
# Fixed random seed (repeatable runs): any unsigned integer.
|
|
# Unset seeds from the clock.
|
|
#RANDOM=12345
|
|
|
|
# ---- LAN play without Steam -------------------------------------------------
|
|
# Host a race over plain TCP: list the member pods' console channels
|
|
# (members run: rpl4opt.exe -windowed -res 1920 1080 -net 1501).
|
|
# RP412HOSTPODS comma-separated IP[:port] list, one entry per member
|
|
# pod; port defaults to 1501 per entry
|
|
# RP412HOSTPORT this machine's console port, integer > 0
|
|
# (default 1501)
|
|
# RP412HOSTADDR this machine's LAN IP as members can reach it
|
|
# (default 127.0.0.1)
|
|
#RP412HOSTPODS=192.168.1.20:1501,192.168.1.21:1501
|
|
#RP412HOSTPORT=1501
|
|
#RP412HOSTADDR=192.168.1.10
|
|
|
|
# ---- Developer / testing ----------------------------------------------------
|
|
|
|
# Nonzero arms the debug keys: Alt+W wireframe, Alt+V predator vision,
|
|
# Alt+F frame dump, Alt+/ perf stats, Alt+E event-queue dump.
|
|
# 0 or unset = off. (Alt+Q, the mission abort, is always live.)
|
|
#RP412DEVKEYS=1
|
|
|
|
# Console race-length override, integer seconds (short test races).
|
|
# Values <= 0 are ignored.
|
|
#L4CONSOLELEN=30
|
|
|
|
# Nonzero = Steam transport loopback self-test at boot (logs PASS/FAIL).
|
|
#RP412STEAMSELFTEST=1
|
|
|
|
# ---- Arcade heritage (multi-monitor pods; not used on the desktop) ----------
|
|
# PRIMGAUGE / SECGAUGE / MFDGAUGE / MFDGAUGE2 pin a display to a monitor
|
|
# by adapter index (0, 1, 2...). SPANDISABLE: 0 = let the MFDs span one
|
|
# wide surface, nonzero = separate windows (setting MFDGAUGE2 alone also
|
|
# forces spanning off). L4EYES = "x y z xrot yrot zrot [type]" floats
|
|
# for a detached camera; a type starting with r offsets it relative to
|
|
# the pod. L4INTERCOM enables the crew intercom - only its presence
|
|
# matters (traditionally COM2). NOMODES skips the mode/lamp programming;
|
|
# presence alone triggers it, even NOMODES=0. LOGSIZE > 0 sizes the
|
|
# trace log in dev builds compiled with tracing.
|
|
#PRIMGAUGE=1
|
|
#SECGAUGE=2
|
|
#MFDGAUGE=3
|
|
#MFDGAUGE2=4
|
|
#SPANDISABLE=1
|
|
#L4EYES=1
|
|
#L4INTERCOM=COM2
|
|
#NOMODES=1
|
|
#LOGSIZE=1000000
|
|
"@
|
|
|
|
Set-Content -Path "$dist\start-windowed.bat" -Encoding ascii -Value @"
|
|
@echo off
|
|
rem Red Planet 4.12 - desktop prototype. Boots into the game-setup
|
|
rem front end; the cockpit canvas is 1920x1080 and -res matches it.
|
|
rem (Add -egg TEST.EGG to skip the menu and run the canned mission.)
|
|
cd /d "%~dp0"
|
|
start rpl4opt.exe -windowed -res 1920 1080
|
|
"@
|
|
|
|
Set-Content -Path "$dist\README.txt" -Encoding ascii -Value @"
|
|
Red Planet 4.12.2
|
|
=================
|
|
|
|
Run start-windowed.bat (or: rpl4opt.exe -windowed -res 800 600 -egg TEST.EGG).
|
|
No cockpit hardware needed. If there is no sound, run oalinst.exe once.
|
|
|
|
Controls (XInput controller and/or keyboard) - EVERY input is
|
|
rebindable: edit bindings.txt beside the exe (written with the full
|
|
documented default layout on first run; delete it to restore).
|
|
|
|
Left stick / NumPad 8462 joystick (8=fwd 2=back 4=left 6=right)
|
|
LT / RT or NumPad 7,9 left / right pedal
|
|
Right stick Y throttle (holds position)
|
|
Shift / Ctrl throttle up / down
|
|
A / Space / NumPad 0 joystick trigger
|
|
RB / Alt reverse thrust
|
|
DPad / arrow keys joystick hat (look)
|
|
Start,Back / 9,0 config buttons
|
|
Number+letter rows MFD bank buttons (as printed on the panel)
|
|
F1-F12 secondary / screen columns
|
|
Alt+Q abort the mission (score banked)
|
|
|
|
The full pod cockpit comes up in a single window: three green MFDs
|
|
across the top, the 3D viewscreen centered with the orange plasma glass
|
|
at its left, and the lower MFDs flanking the portrait map. The red
|
|
buttons around each MFD and the amber buttons beside the map are the
|
|
pod's real button banks: click them with the mouse, and they light up
|
|
as the game commands their lamps.
|
|
environ.ini is self-documenting: every option ships in the file with
|
|
a comment (Steam networking, keyboard lighting, stick inversion, LAN
|
|
hosting, developer keys, and more).
|
|
|
|
Known prototype notes: pods race untextured (the player1-8 skins come
|
|
from the presets system, not shipped data), and text drawn on the plasma
|
|
glass may appear rotated.
|
|
|
|
Source: https://gitea.mysticmachines.com/VWE/RP412
|
|
"@
|
|
|
|
# --- summary / optional zip ------------------------------------------------
|
|
$size = (Get-ChildItem $dist -Recurse | Measure-Object Length -Sum).Sum
|
|
Write-Host ("dist ready: {0:N1} MB" -f ($size / 1MB))
|
|
|
|
if ($Zip) {
|
|
$zipPath = Join-Path $root 'RedPlanet-4.12.2.zip'
|
|
Write-Host "zipping to $zipPath..."
|
|
|
|
# Everything lives under a single RP412\ folder inside the zip, so
|
|
# unpacking anywhere gives one self-contained game directory instead
|
|
# of scattering files into the extraction folder.
|
|
$stage = Join-Path ([System.IO.Path]::GetTempPath()) 'rp412-zipstage'
|
|
if (Test-Path $stage) { Remove-Item -Recurse -Force $stage }
|
|
New-Item -ItemType Directory -Force "$stage\RP412" | Out-Null
|
|
Copy-Item "$dist\*" "$stage\RP412" -Recurse -Force
|
|
Compress-Archive -Path "$stage\RP412" -DestinationPath $zipPath -Force
|
|
Remove-Item -Recurse -Force $stage
|
|
}
|