Files

96 lines
5.2 KiB
PowerShell

<#
play-mr.ps1 - replay a MechWarrior4 / FireStorm mission-review (.mr) file IN-ENGINE,
using the game's built-in -mrtest developer hook.
How the game's replay works (reverse-engineered from MW4Application.cpp / mreplay2.cpp):
* MW4.exe parses "-mrtest" -> g_bMRTest = true.
* With -mrtest set, when you START A SINGLE-PLAYER (Instant Action) game from the menu,
the app does NOT start a live match -- it calls CMRPFull::LoadDefaultMR() then DoReplay(),
which spins up a local loopback "server", feeds the recorded packets back through the
net-message handlers, and reconstructs the whole match in full 3D.
* LoadDefaultMR() opens a HARD-CODED path (drive "c:" is baked in):
C:\mw4files\00000000-0000-0000-0000-000000000000.mr (the GUID_NULL name)
So to replay any .mr we just stage it there, then launch with -mrtest.
This launcher: validates the .mr, stages it to that path (backing up any existing one),
applies the Win11 DirectDraw compat shim to the exe, and launches MW4.exe -mrtest.
REQUIREMENTS / CAVEATS
* Use a game build whose MW4.exe supports -mrtest (our rebuilt rel.bin\MW4.exe does;
the string "-mrtest" + g_bMRTest are present in MW4.map). Retail Mektek builds may not.
* CONTENT MUST MATCH THE RECORDING. DoReplay rebuilds the match from create-messages that
reference content by resource id + content version (63). Replay a FireStorm .mr only on
the same FireStorm build/content it was recorded on, or it will desync / STOP.
* The .mr default path is on C: regardless of where the game is installed (drive is hard-coded).
USAGE
powershell -ExecutionPolicy Bypass -File play-mr.ps1 -MrFile "match.mr"
powershell -ExecutionPolicy Bypass -File play-mr.ps1 -MrFile "match.mr" -GameDir "D:\Games\FireStorm"
Then in the game: Main Menu -> Instant Action -> configure -> Launch. The replay starts
instead of a live match. (No auto-start switch exists, so that one click is required.)
-window -dragon -nomovie
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)] [string]$MrFile,
[string]$GameDir = "C:\VWE\firestorm\MW4", # point this at your game install on another system
[string]$Exe = "MW4.exe",
[string]$ExtraArgs = "-window -dragon -nomovie", # e.g. "-window -nomovie"
[switch]$NoShim, # skip the DirectDraw AppCompat shim
[switch]$KeepStaged # don't restore the previous default .mr afterwards
)
$ErrorActionPreference = "Stop"
# --- validate inputs ---------------------------------------------------------
if (-not (Test-Path -LiteralPath $MrFile)) { throw "Mission-review file not found: $MrFile" }
$MrFile = (Resolve-Path -LiteralPath $MrFile).Path
$exePath = Join-Path $GameDir $Exe
if (-not (Test-Path -LiteralPath $exePath)) { throw "Game exe not found: $exePath (pass -GameDir <install folder>)" }
# magic check: mreplay2 .mr starts with DWORD 0xAB9A655F (LE: 5F 65 9A AB); also accept old variants
$sig = [System.IO.File]::ReadAllBytes($MrFile)[0..3]
$magic = '{0:X2}{1:X2}{2:X2}{3:X2}' -f $sig[3],$sig[2],$sig[1],$sig[0]
if ($magic -notin @('AB9A655F','AB9A654F','AB9A655E')) {
Write-Host "WARNING: '$MrFile' doesn't start with the mreplay2 magic (got 0x$magic)." -ForegroundColor Yellow
Write-Host " It may be a top-down 'lastgame.mr' MissionReview log, not a DoReplay file." -ForegroundColor Yellow
}
# --- stage to the hard-coded default path ------------------------------------
$mrDir = "C:\mw4files"
$target = Join-Path $mrDir "00000000-0000-0000-0000-000000000000.mr"
if (-not (Test-Path $mrDir)) { New-Item -ItemType Directory -Path $mrDir -Force | Out-Null }
$backup = $null
if ((Test-Path -LiteralPath $target) -and -not $KeepStaged) {
$backup = "$target.prev"
Move-Item -LiteralPath $target -Destination $backup -Force
Write-Host " (backed up existing default .mr -> $backup)"
}
Copy-Item -LiteralPath $MrFile -Destination $target -Force
Write-Host "Staged replay:" -ForegroundColor Cyan
Write-Host " source : $MrFile"
Write-Host " -> $target"
# --- Win11 DirectDraw 16-bit compat shim on the exe path ---------------------
if (-not $NoShim) {
$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 $exePath -Value "DWM8And16BitMitigation HIGHDPIAWARE" -Type String
Write-Host " (applied DirectDraw compat shim to $exePath)"
}
# --- launch ------------------------------------------------------------------
$argList = "-mrtest"
if ($ExtraArgs.Trim()) { $argList = "$argList $($ExtraArgs.Trim())" }
Write-Host "`nLaunching: $Exe $argList (cwd: $GameDir)" -ForegroundColor Green
Write-Host "==> In the game: Main Menu -> INSTANT ACTION -> Launch. The replay starts instead of a live match." -ForegroundColor Green
Write-Host " (ESC / quit the match to end the replay.)`n"
$proc = Start-Process -FilePath $exePath -ArgumentList $argList -WorkingDirectory $GameDir -PassThru
Write-Host "MW4.exe started (PID $($proc.Id))."
if ($backup -and -not $KeepStaged) {
Write-Host "`nWhen you're done, restore the previous default .mr with:"
Write-Host " Move-Item -Force '$backup' '$target'"
}