Files
firestorm/build-env/build-resources.ps1
T
456e197822 Fix ConLobbyMission time list (18 entries) and build-resources ddraw handling
ConLobbyMission.script:
- Expand MP time-limit dropdown from 9 to 18 entries (1-15, 20, 25, 30 min)
  with max_displayed=10 so the list scrolls cleanly.
- Fix bare else-if syntax (missing braces) that caused null-reference crash
  on console lobby load when this was merged from main.
- Fix i==5 vs i==6 max_displayed assignment for time vs radar dropdowns.

build-resources.ps1:
- DDrawCompat's ddraw.dll is fatal to MW4pro.exe in FULLSCREEN but works
  in WINDOWED mode. Don't move it aside; instead run the builder with
  -window when ddraw.dll is present. This fixes builds on VMs with generic
  display adapters (no hardware DirectDraw) and avoids the EnterWindowMode
  CreateSurface crash on Win10/11 without a functioning DWM shim.
- Also temporarily set options.ini bitdepth=32 when running without any
  ddraw interceptor (bare-metal fallback), restored in finally block.
- Remove stale comment about ddraw being fatal; update interceptor detection
  to correctly identify DDrawCompat vs dgVoodoo2 via dgVoodoo.conf presence.

Co-authored-by: Claude Sonnet 4.6 (Anthropic) <noreply@anthropic.com>
Co-authored-by: GitHub Copilot <copilot@github.com>
2026-07-18 15:39:42 -05:00

152 lines
8.4 KiB
PowerShell

<#
build-resources.ps1 - (re)pack the runtime resource packages (resource\*.mw4) from the
Content\ source tree, using the in-exe resource compiler.
The resource compiler lives INSIDE the game executable and only runs in a LAB_ONLY config
(Debug/Armor/Profile) when launched with -build. We use the Profile exe (MW4pro.exe);
Release MW4.exe silently ignores -build. See build-env\RESOURCE-BUILD.md for the full writeup.
What it does:
1. Overlays the freshly built MW4pro.exe (+ companion DLLs) into the source tree so the
build uses CURRENT binaries -> the .mw4 files carry the matching VER_CONTENTVERSION that
our freshly built game/editor expect.
2. Runs MW4pro.exe -armorlevel 3 -build -norun -window -nosound -nocd -noeula with the
working directory set to the source tree (which holds Content\MechWarrior4.build and
where resource\*.mw4 are written).
3. The build is INCREMENTAL (.dep timestamps + content version): only packages whose source
changed are rebuilt, so re-runs are fast. A package's whole source set must be present, or
the LAB_ONLY exe pops a modal STOP -- the -Timeout guard below kills a hung build and
reports it rather than blocking the deploy forever.
NOTE: this writes into $Runtime\resource (the canonical dev resources). That is intentional:
it keeps the dev tree's compiled packages current, and the editor (which junctions this tree)
picks them up automatically.
#>
param(
[string]$Runtime = "c:\VWE\firestorm\Gameleap\mw4", # source tree: Content\ + resource\
[string]$BinDir = "c:\VWE\firestorm\Gameleap\code\rel.bin", # our freshly built MW4pro.exe
[int] $TimeoutSec = 1800 # kill a hung (modal-STOP) build
)
$ErrorActionPreference = "Stop"
Write-Host "== Packing resources (resource\*.mw4) ==" -ForegroundColor Cyan
Write-Host " source : $Runtime"
Write-Host " builder: $BinDir\MW4pro.exe (Profile / LAB_ONLY)`n"
$proExe = Join-Path $BinDir "MW4pro.exe"
if (-not (Test-Path $proExe)) {
throw "MW4pro.exe not found in $BinDir. Build 'MW4Application - Win32 Profile' first (Release MW4.exe cannot -build)."
}
$master = Join-Path $Runtime "Content\MechWarrior4.build"
if (-not (Test-Path $master)) {
throw "Master manifest not found: $master (the full Content\ source tree must be present to pack resources)."
}
# 1) Overlay the fresh LAB_ONLY builder + companion DLLs so the build's content version matches
# the binaries we deploy. (Static libs are linked into the exe; the few runtime DLLs we build
# are copied too for consistency.)
Write-Host "[pack 1/3] staging fresh builder into source tree ..." -ForegroundColor Yellow
foreach ($a in "MW4pro.exe","ctcls.dll","MissionLang.dll","ScriptStrings.dll") {
$s = Join-Path $BinDir $a
if (Test-Path $s) { Copy-Item $s (Join-Path $Runtime $a) -Force; Write-Host " + $a" }
}
# 2) DirectDraw 16-bit compat shim for the builder exe path (GameOS still inits even with -norun).
$builder = Join-Path $Runtime "MW4pro.exe"
$layers = "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
if (-not (Test-Path $layers)) { New-Item -Path $layers -Force | Out-Null }
Set-ItemProperty -Path $layers -Name $builder -Value "DWM8And16BitMitigation HIGHDPIAWARE" -Type String
# Snapshot resource\ mtimes so we can report what got rebuilt.
$resDir = Join-Path $Runtime "resource"
$before = @{}
if (Test-Path $resDir) {
Get-ChildItem $resDir -Recurse -Filter *.mw4 -EA SilentlyContinue | ForEach-Object { $before[$_.FullName] = $_.LastWriteTimeUtc }
}
$startUtc = (Get-Date).ToUniversalTime()
# 3) Run the in-exe resource compiler (build-and-exit), guarded by a timeout.
# - FULLSCREEN (no -window): the windowed DirectDraw/D3D7 path fails on Win11 (the editor's
# "No 3D acceleration"/"No software rasterizer" problem). The fullscreen-exclusive path
# works (it's how the game runs) and the DWM shim applied above covers it.
# - /gosnodialogs: makes graphics warnings auto-continue and turns a fatal content STOP into
# a clean process EXIT (caught via exit code below) instead of an unattended modal hang.
# (CheckOption strips the token, so it does NOT trip the LAB_ONLY "/gos" help-and-exit trap.)
Write-Host "[pack 2/3] running resource compiler (this can take a while) ..." -ForegroundColor Yellow
# DDrawCompat's ddraw.dll is fatal to MW4pro.exe in FULLSCREEN (it tries to set an
# exclusive display mode that DDrawCompat rejects with a Fatal Error dialog). In WINDOWED
# mode DDrawCompat works fine, and the builder only needs DDraw to init -- it never renders
# a frame with -norun. So: keep ddraw.dll in place and use -window. This also works on VMs
# with generic display adapters that have no hardware DirectDraw at all.
$ddrawPresent = Test-Path (Join-Path $Runtime "ddraw.dll")
if ($ddrawPresent) {
Write-Host " (ddraw.dll present -- running windowed so DDrawCompat/dgVoodoo2 init succeeds)"
} else {
Write-Host " (no ddraw.dll -- running fullscreen with native DirectDraw)"
}
# Native DirectDraw on Win10/11 cannot create a 16-bit fullscreen surface without the
# DWM8And16BitMitigation shim, which is unreliable on some machine configs.
# Temporarily force 32-bit colour in options.ini so native DDraw always succeeds;
# restored in the finally block regardless of how the build ends.
$optionsIni = Join-Path $Runtime "options.ini"
$bitdepthOrig = $null
if (-not $ddrawPresent -and (Test-Path $optionsIni)) {
$content = Get-Content $optionsIni -Raw
if ($content -match '(?m)^bitdepth=(\d+)') {
$bitdepthOrig = $Matches[1]
if ($bitdepthOrig -ne '32') {
($content -replace '(?m)^bitdepth=\d+', 'bitdepth=32') | Set-Content $optionsIni -NoNewline
Write-Host " (temporarily set options.ini bitdepth=32 for build, was $bitdepthOrig)"
} else { $bitdepthOrig = $null }
}
}
$code = $null
try {
$windowFlag = if ($ddrawPresent) { "-window" } else { "" }
$argList = "/gosnodialogs -armorlevel 3 -build -norun -nosound -nocd -noeula $windowFlag".Trim()
$p = Start-Process -FilePath $builder -ArgumentList $argList -WorkingDirectory $Runtime -PassThru
$timedOut = $false
try { Wait-Process -Id $p.Id -Timeout $TimeoutSec -ErrorAction Stop }
catch { $timedOut = $true }
if ($timedOut) {
try { Stop-Process -Id $p.Id -Force -ErrorAction SilentlyContinue } catch {}
throw ("Resource build did not finish within $TimeoutSec s. The LAB_ONLY exe most likely hit a " +
"modal content STOP (a missing/inconsistent source asset in the WIP Content\ tree). " +
"Run the builder interactively to see which asset, fix the content, then re-deploy:`n" +
" cd `"$Runtime`"; .\MW4pro.exe -armorlevel 3 -build -norun -window -nosound -nocd -noeula")
}
$p.Refresh()
$code = $p.ExitCode
if ($code -ne 0) {
$log = Join-Path $Runtime "debuglog.txt"
$tail = if (Test-Path $log) { (Get-Content $log -Tail 25 -EA SilentlyContinue) -join "`n" } else { "(no debuglog.txt)" }
throw ("Resource build exited with code $code -- likely a fatal content STOP on a missing/" +
"inconsistent source asset in the WIP Content\ tree (/gosnodialogs turns STOPs into a " +
"clean exit). Deploy aborted so partial packages are NOT shipped. Last debuglog.txt:`n" +
"$tail`n`nFix the asset and re-run, or run deploy-mw4.ps1 -SkipResourceBuild to ship existing packages.")
}
} finally {
if ($bitdepthOrig -and (Test-Path $optionsIni)) {
$content = Get-Content $optionsIni -Raw
($content -replace '(?m)^bitdepth=\d+', "bitdepth=$bitdepthOrig") | Set-Content $optionsIni -NoNewline
Write-Host " (restored options.ini bitdepth=$bitdepthOrig)"
}
}
# 4) Report what changed.
Write-Host "[pack 3/3] resource build complete (exit $code)." -ForegroundColor Yellow
$changed = @()
if (Test-Path $resDir) {
Get-ChildItem $resDir -Recurse -Filter *.mw4 -EA SilentlyContinue | ForEach-Object {
if (-not $before.ContainsKey($_.FullName) -or $_.LastWriteTimeUtc -gt $startUtc) {
$changed += $_.FullName.Substring($Runtime.Length).TrimStart('\')
}
}
}
if ($changed.Count) {
Write-Host (" rebuilt {0} package(s):" -f $changed.Count) -ForegroundColor Green
$changed | Sort-Object | ForEach-Object { " $_" }
} else {
Write-Host " all packages already up to date (nothing rebuilt)." -ForegroundColor Green
}