Skip to content

Instantly share code, notes, and snippets.

@kalbasit
Last active July 12, 2026 19:23
Show Gist options
  • Select an option

  • Save kalbasit/c7fce3a10dfc23d8df378f249cca1092 to your computer and use it in GitHub Desktop.

Select an option

Save kalbasit/c7fce3a10dfc23d8df378f249cca1092 to your computer and use it in GitHub Desktop.
RomM sync tool — click-to-run 'pull anything new from this device into RomM' (robocopy, idempotent/resumable, ps4=zip-only, switch=base-nsp; -Inspect dumps switch update/DLC layout)

RomM sync tool (Windows / EmuDeck → RomM)

Click-to-run: pulls any new games from this device into the RomM library on TrueNAS (mounted as Z:). Uses robocopy — idempotent, resumable across hibernate/disconnect, and it never deletes. Safe to run any time (e.g. after WiiUDownloader drops a game into roms\wiiu).

1. Install — paste into PowerShell

mkdir C:\Emulation\tools\romm-sync 2>$null
cd C:\Emulation\tools\romm-sync
irm https://gist.githubusercontent.com/kalbasit/c7fce3a10dfc23d8df378f249cca1092/raw/sync-roms-to-romm.ps1            -OutFile sync-roms-to-romm.ps1
irm https://gist.githubusercontent.com/kalbasit/c7fce3a10dfc23d8df378f249cca1092/raw/restructure-switch-for-romm.ps1 -OutFile restructure-switch-for-romm.ps1
irm https://gist.githubusercontent.com/kalbasit/c7fce3a10dfc23d8df378f249cca1092/raw/sync-bios-for-romm.ps1           -OutFile sync-bios-for-romm.ps1
irm https://gist.githubusercontent.com/kalbasit/c7fce3a10dfc23d8df378f249cca1092/raw/Sync-RomM.cmd                    -OutFile Sync-RomM.cmd

2. Make the desktop button — paste into PowerShell

$ws  = New-Object -ComObject WScript.Shell
$lnk = $ws.CreateShortcut("$([Environment]::GetFolderPath('Desktop'))\Sync RomM.lnk")
$lnk.TargetPath       = "C:\Emulation\tools\romm-sync\Sync-RomM.cmd"
$lnk.WorkingDirectory = "C:\Emulation\tools\romm-sync"
$lnk.IconLocation     = "shell32.dll,45"
$lnk.Save()

Now double-click Sync RomM on your desktop whenever you want to push new games. (Or just: right-click Sync-RomM.cmd → Send to → Desktop (create shortcut).)

3. Usage

What Command
Normal sync double-click the desktop button
Preview only (copies nothing) powershell -ExecutionPolicy Bypass -File .\sync-roms-to-romm.ps1 -DryRun
Inspect Switch update/DLC layout powershell -ExecutionPolicy Bypass -File .\sync-roms-to-romm.ps1 -Inspect

What it does

  • Copies every used platform folder under C:\Emulation\romsZ:\emulation\roms.
  • Rules: ps4 → packaged *.zip only · switch → base *.nsp only · everything else → full recursive.
  • Skips ES-DE cruft (metadata.txt, systeminfo.txt, gamelist.xml, media\).
  • Writes a timestamped romm-sync-*.log and prints a per-platform summary.

Switch updates / DLC

The desktop button handles Switch specially via restructure-switch-for-romm.ps1: it matches base games in roms\switch to the updates/DLC in storage\ryujinx\patchesAndDlc (by game name) and builds RomM's per-game layout on Z:roms\switch\<Game>\{base.nsp, update\, dlc\} — then removes the old flat .nsp. Your device's C:\Emulation is never modified.

Preview the Switch mapping before it runs anything:

powershell -ExecutionPolicy Bypass -File .\restructure-switch-for-romm.ps1 -DryRun

BIOS / firmware

The desktop button also runs sync-bios-for-romm.ps1, which copies BIOS from C:\Emulation\bios into Z:\emulation\bios\<slug>\. Matching is by MD5/SHA1 against RomM's own known-BIOS list (not by filename), so a file named scph-5501.bin still matches and is written under RomM's canonical name. Files RomM doesn't track (PCSX2 .mec/.nvm, Switch keys/firmware, placeholders) are reported and skipped — never guessed.

Preview it on its own:

powershell -ExecutionPolicy Bypass -File .\sync-bios-for-romm.ps1 -DryRun

Update later

Re-run the irm commands in step 1 to pull the newest version of the scripts.

<#
restructure-switch-for-romm.ps1
Builds RomM's multi-file Switch layout on the TrueNAS share (Z:) so updates
and DLC associate with their base game. RomM treats a FOLDER-per-game as one
game and tags special subfolders (update/ dlc/). It matches base .nsp in
C:\Emulation\roms\switch to the extras in
C:\Emulation\storage\ryujinx\patchesAndDlc by GAME NAME, and writes:
Z:\emulation\roms\switch\<Game>\<base>.nsp
Z:\emulation\roms\switch\<Game>\update\<update .nsp>
Z:\emulation\roms\switch\<Game>\dlc\<dlc .nsp>
Your device's C:\Emulation structure is NOT modified. Only Z: is written.
It also removes the old FLAT *.nsp that the first copy left directly under
Z:\...\switch (now superseded by the per-game folders).
Classification: filename containing "DLC" -> dlc; otherwise -> update.
Extras with no matching base game (e.g. Cuphead) are reported and skipped.
Idempotent + resumable (robocopy /Z). ALWAYS preview first:
powershell -ExecutionPolicy Bypass -File .\restructure-switch-for-romm.ps1 -DryRun
Then apply:
powershell -ExecutionPolicy Bypass -File .\restructure-switch-for-romm.ps1
#>
param(
[string]$Src = "C:\Emulation",
[string]$Dst = "Z:\emulation",
[switch]$DryRun
)
$ErrorActionPreference = "Stop"
$PSNativeCommandUseErrorActionPreference = $false
$swSrc = Join-Path $Src 'roms\switch'
$swDst = Join-Path $Dst 'roms\switch'
if (-not (Test-Path $swSrc)) { throw "Switch source not found: $swSrc" }
# extras: known path, else recursive search for a patchesAndDlc folder under ryujinx
$dlcSrc = Join-Path $Src 'storage\ryujinx\patchesAndDlc'
if (-not (Test-Path $dlcSrc)) {
$found = Get-ChildItem (Join-Path $Src 'storage\ryujinx') -Recurse -Directory -Filter 'patchesAndDlc' -ErrorAction SilentlyContinue | Select-Object -First 1
if ($found) { $dlcSrc = $found.FullName }
}
function Normalize-Name([string]$fileName) {
$n = [IO.Path]::GetFileNameWithoutExtension($fileName)
$n = $n -replace '\[[^\]]*\]', '' # drop [titleid] / [v..] / [DLC ..]
$n = $n -replace '\([^\)]*\)', '' # drop (1.2.0) etc.
$n = $n -replace '(?i)\bv\d+(\.\d+)*\b', '' # drop trailing v1.0.1 / v0
($n -replace '\s+', ' ').Trim()
}
$skip = '(?i)^(metadata\.txt|systeminfo\.txt|gamelist\.xml|desktop\.ini)$'
# --- gather base games ---
$bases = @{}
Get-ChildItem -LiteralPath $swSrc -File -ErrorAction SilentlyContinue |
Where-Object { $_.Extension -ieq '.nsp' -and $_.Name -notmatch $skip } |
ForEach-Object {
$key = Normalize-Name $_.Name
$bases[$key] = [pscustomobject]@{ Name = $key; File = $_; Updates = @(); Dlc = @() }
}
# --- gather + match extras ---
$unmatched = @()
if ($dlcSrc -and (Test-Path $dlcSrc)) {
Get-ChildItem -LiteralPath $dlcSrc -File -ErrorAction SilentlyContinue |
Where-Object { $_.Extension -ieq '.nsp' } |
ForEach-Object {
$key = Normalize-Name $_.Name
$isDlc = $_.Name -match '(?i)\bDLC\b'
if ($bases.ContainsKey($key)) {
if ($isDlc) { $bases[$key].Dlc += $_ }
else { $bases[$key].Updates += $_ }
} else {
$unmatched += $_
}
}
} else {
Write-Host "WARNING: patchesAndDlc folder not found under $Src\storage\ryujinx" -ForegroundColor Yellow
}
Write-Host "=== Switch restructure plan ($(if($DryRun){'DRY RUN'}else{'APPLY'})) ===" -ForegroundColor Cyan
Write-Host " base src : $swSrc"
Write-Host " extras : $dlcSrc"
Write-Host " dest : $swDst"
Write-Host ""
function Copy-One($file, $dstDir) {
# use FileInfo members (NOT Get-Item/Split-Path) so names with [ ] aren't treated as wildcards
$a = @($file.DirectoryName, $dstDir, $file.Name, '/Z', '/R:3', '/W:5', '/NP', '/NJH', '/NJS')
if ($DryRun) { $a += '/L' }
& robocopy @a | Out-Null
return $LASTEXITCODE
}
foreach ($b in ($bases.Values | Sort-Object Name)) {
$gameDir = Join-Path $swDst $b.Name
Write-Host ("* {0}" -f $b.Name) -ForegroundColor Green
if (-not $DryRun) { $null = New-Item -ItemType Directory -Force -Path $gameDir }
$dstBase = Join-Path $gameDir $b.File.Name # target inside the game folder
$flatBase = Join-Path $swDst $b.File.Name # where the first bulk copy left it on Z:
$srcLen = $b.File.Length
# "complete" = exists AND byte size matches the source (guards against half-copied files)
$dstOk = (Test-Path -LiteralPath $dstBase) -and ((Get-Item -LiteralPath $dstBase -ErrorAction SilentlyContinue).Length -eq $srcLen)
$flatOk = (Test-Path -LiteralPath $flatBase) -and ((Get-Item -LiteralPath $flatBase -ErrorAction SilentlyContinue).Length -eq $srcLen)
if ($dstOk) {
Write-Host (" base : {0} (already complete in folder - skip)" -f $b.File.Name)
} elseif ($flatOk) {
# server-side rename within the same TrueNAS share -- instant, no network re-copy
Write-Host (" base : {0} (MOVE existing copy on Z: into folder - no re-copy)" -f $b.File.Name) -ForegroundColor DarkGreen
if (-not $DryRun) { Move-Item -LiteralPath $flatBase -Destination $dstBase -Force }
} else {
Write-Host (" base : {0} (copy from source - not on Z: or incomplete)" -f $b.File.Name)
[void](Copy-One $b.File $gameDir)
}
foreach ($u in $b.Updates) {
$sz = "{0:N0} MB" -f ($u.Length/1MB)
Write-Host (" upd : {0} ({1})" -f $u.Name, $sz)
[void](Copy-One $u (Join-Path $gameDir 'update'))
}
foreach ($d in $b.Dlc) {
$sz = if ($d.Length -ge 1MB) { "{0:N0} MB" -f ($d.Length/1MB) } else { "{0:N0} KB" -f ($d.Length/1KB) }
# tiny DLC nsp is usually a licence/unlock ticket (normal for e.g. BotW - content ships in the update), NOT broken.
$warn = if ($d.Length -lt 1MB) { " <-- tiny (licence/unlock nsp; normal for BotW - needs the update applied)" } else { "" }
Write-Host (" dlc : {0} ({1}){2}" -f $d.Name, $sz, $warn) -ForegroundColor $(if($warn){'Yellow'}else{'Gray'})
[void](Copy-One $d (Join-Path $gameDir 'dlc'))
}
Write-Host ""
}
if ($unmatched.Count) {
Write-Host "--- extras with NO base game (skipped) ---" -ForegroundColor Yellow
$unmatched | ForEach-Object { Write-Host (" {0}" -f $_.Name) }
Write-Host " (add the matching base .nsp to roms\switch and re-run to include these)"
Write-Host ""
}
# --- remove old flat base .nsp left directly under Z:\...\switch ---
$flat = @(Get-ChildItem -LiteralPath $swDst -File -Filter *.nsp -ErrorAction SilentlyContinue)
$subdirs = @(Get-ChildItem -LiteralPath $swDst -Directory -ErrorAction SilentlyContinue)
if ($flat) {
Write-Host "--- leftover flat *.nsp directly under $swDst ---" -ForegroundColor Yellow
foreach ($f in $flat) {
# only delete a flat file if the same file now exists inside a game folder (a true duplicate)
$inFolder = $subdirs | ForEach-Object { Join-Path $_.FullName $f.Name } | Where-Object { Test-Path -LiteralPath $_ }
if ($inFolder) {
if ($DryRun) { Write-Host (" would remove (now in folder): {0}" -f $f.Name) }
else { Remove-Item -LiteralPath $f.FullName -Force; Write-Host (" removed (now in folder): {0}" -f $f.Name) }
} else {
Write-Host (" kept (not placed in any folder): {0}" -f $f.Name) -ForegroundColor DarkYellow
}
}
Write-Host ""
}
Write-Host ("Done ({0}). {1} base games, {2} extras matched, {3} unmatched." -f `
$(if($DryRun){'preview'}else{'applied'}), $bases.Count,
(($bases.Values | ForEach-Object { $_.Updates.Count + $_.Dlc.Count }) | Measure-Object -Sum).Sum,
$unmatched.Count) -ForegroundColor Cyan
if ($DryRun) { Write-Host "Re-run without -DryRun to apply." -ForegroundColor Cyan }
<#
sync-bios-for-romm.ps1
Copies BIOS that RomM recognizes from your device's bios\ folder into the RomM
library at Z:\emulation\bios\<slug>\ .
Matching is by HASH (md5/sha1) against RomM's OWN known-BIOS list
(backend/models/fixtures/known_bios_files.json), so it is FILENAME-AGNOSTIC:
a file named "scph-5501.bin" still matches by MD5 and is written under RomM's
canonical name ("scph5501.bin") so RomM shows it verified. No hand-built table.
Files whose hash isn't in RomM's list (PCSX2 .mec/.nvm, Switch keys/firmware,
txt placeholders, etc.) are REPORTED and skipped -- RomM doesn't track those.
(Switch firmware/keys are handled as a separate BACKUP, not via RomM -- they are
version-locked and belong in a backup location, not the web-exposed library.)
Only bios\ is hashed (not roms\ -- that would mean hashing 170 GB).
If you keep BIOS elsewhere, point -BiosSrc at it.
Preview first (hashes + plans, copies nothing):
powershell -ExecutionPolicy Bypass -File .\sync-bios-for-romm.ps1 -DryRun
Apply:
powershell -ExecutionPolicy Bypass -File .\sync-bios-for-romm.ps1
#>
param(
[string]$BiosSrc = "C:\Emulation\bios",
[string]$Dst = "Z:\emulation",
[string]$FixtureUrl = "https://raw.githubusercontent.com/rommapp/romm/4.9.2/backend/models/fixtures/known_bios_files.json",
[switch]$DryRun
)
$ErrorActionPreference = "Stop"
if (-not (Test-Path $BiosSrc)) { throw "BIOS source not found: $BiosSrc" }
$biosDst = Join-Path $Dst 'bios'
Write-Host "Fetching RomM known-BIOS list..." -ForegroundColor Cyan
$fixture = Invoke-RestMethod -Uri $FixtureUrl
# key = "<slug>:<filename>", value = { size, crc, md5, sha1 } -> hash -> @{Slug;Name}
$byMd5 = @{}
$bySha1 = @{}
foreach ($p in $fixture.PSObject.Properties) {
$i = $p.Name.IndexOf(':'); if ($i -lt 0) { continue }
$entry = [pscustomobject]@{ Slug = $p.Name.Substring(0,$i); Name = $p.Name.Substring($i+1) }
$md5 = ("" + $p.Value.md5).ToLower()
$sha1 = ("" + $p.Value.sha1).ToLower()
if ($md5) { if (-not $byMd5.ContainsKey($md5)) { $byMd5[$md5] = $entry } }
if ($sha1) { if (-not $bySha1.ContainsKey($sha1)) { $bySha1[$sha1] = $entry } }
}
Write-Host (" {0} md5 / {1} sha1 known-BIOS hashes loaded." -f $byMd5.Count, $bySha1.Count)
$files = @(Get-ChildItem -LiteralPath $BiosSrc -File -Recurse)
Write-Host ("Hashing {0} files under {1} ..." -f $files.Count, $BiosSrc)
$matched = @(); $unmatched = @()
foreach ($f in $files) {
$md5 = (Get-FileHash -LiteralPath $f.FullName -Algorithm MD5).Hash.ToLower()
$hit = $byMd5[$md5]
if (-not $hit) {
$sha1 = (Get-FileHash -LiteralPath $f.FullName -Algorithm SHA1).Hash.ToLower()
$hit = $bySha1[$sha1]
}
if ($hit) { $matched += [pscustomobject]@{ Src = $f.FullName; Slug = $hit.Slug; Name = $hit.Name } }
else { $unmatched += $f }
}
Write-Host ""
Write-Host ("=== Recognized BIOS ({0}) -> {1} ===" -f $matched.Count, $biosDst) -ForegroundColor Green
foreach ($m in ($matched | Sort-Object Slug, Name)) {
$ddir = Join-Path $biosDst $m.Slug
$dfile = Join-Path $ddir $m.Name
$orig = Split-Path $m.Src -Leaf
$ren = if ($orig -ine $m.Name) { " (from $orig)" } else { "" }
Write-Host (" {0}\{1}{2}" -f $m.Slug, $m.Name, $ren)
if (-not $DryRun) {
New-Item -ItemType Directory -Force -Path $ddir | Out-Null
Copy-Item -LiteralPath $m.Src -Destination $dfile -Force
}
}
if ($unmatched.Count) {
Write-Host ""
Write-Host ("=== Not in RomM's list -- skipped ({0}) ===" -f $unmatched.Count) -ForegroundColor Yellow
foreach ($u in ($unmatched | Sort-Object FullName)) {
Write-Host (" {0} ({1:N0} KB)" -f $u.FullName.Substring($BiosSrc.Length).TrimStart('\'), ($u.Length/1KB))
}
Write-Host " (emulator-generated files, Switch keys/firmware, or placeholders -- RomM doesn't verify these)"
}
Write-Host ""
Write-Host ("Done ({0}). {1} recognized, {2} skipped." -f $(if($DryRun){'preview'}else{'copied'}), $matched.Count, $unmatched.Count) -ForegroundColor Cyan
if ($DryRun) { Write-Host "Re-run without -DryRun to copy." -ForegroundColor Cyan }
@echo off
REM Double-click this to sync any new games from this device into RomM.
REM Keep it in the same folder as sync-roms-to-romm.ps1.
cd /d "%~dp0"
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0sync-roms-to-romm.ps1" %*
echo.
pause
<#
sync-roms-to-romm.ps1
Click-to-run "pull anything NEW from this device into RomM".
Mirrors every USED platform folder under <Src>\roms into <Dst>\roms with
robocopy: idempotent + resumable, copies only new/changed files, NEVER
deletes. Safe to run any time -- e.g. after WiiUDownloader drops a game into
roms\wiiu, or you add anything to any platform folder.
Per-platform rules (kept from the initial import):
ps4 -> only the packaged *.zip (recurse to find it; skips .lnk + the
extracted storage\shadps4 tree)
switch -> only base *.nsp at the top level (updates/DLC are a separate step)
everything else -> full recursive copy
ES-DE cruft (metadata.txt / systeminfo.txt / gamelist.xml / media\) is skipped.
Usage:
double-click Sync-RomM.cmd (runs a normal sync, then pauses)
or from PowerShell:
powershell -ExecutionPolicy Bypass -File .\sync-roms-to-romm.ps1
... -DryRun # preview only, copies nothing
... -Inspect # dump switch base + storage\ryujinx tree (for DLC planning), then exit
#>
param(
[string]$Src = "C:\Emulation",
[string]$Dst = "Z:\emulation",
[switch]$DryRun,
[switch]$Inspect
)
$ErrorActionPreference = "Stop"
# PS 7.4+ would throw on robocopy's success codes (1..7); interpret them ourselves.
$PSNativeCommandUseErrorActionPreference = $false
$SrcRoms = Join-Path $Src "roms"
$DstRoms = Join-Path $Dst "roms"
if (-not (Test-Path $SrcRoms)) { throw "Source roms not found: $SrcRoms" }
$skipNames = '(?i)^(gamelist\.xml|systeminfo\.txt|\.gitkeep|desktop\.ini|metadata\.txt|neogeo\.zip)$'
$skipExts = @('.txt', '.xml', '.jpg', '.png', '.md')
function Get-RealFiles($dir) {
Get-ChildItem -LiteralPath $dir -File -Recurse |
Where-Object { $_.Name -notmatch $skipNames -and $_.Extension -notin $skipExts }
}
function HumanSize([Nullable[long]]$b) {
if ($null -eq $b) { $b = 0 }
if ($b -ge 1GB) { "{0:N1} GB" -f ($b/1GB) }
elseif ($b -ge 1MB) { "{0:N1} MB" -f ($b/1MB) }
elseif ($b -ge 1KB) { "{0:N1} KB" -f ($b/1KB) }
else { "$b B" }
}
# ---------------- Inspect mode: gather Switch update/DLC layout ----------------
if ($Inspect) {
Write-Host "=== switch base games ($SrcRoms\switch) ==="
Get-ChildItem -LiteralPath (Join-Path $SrcRoms 'switch') -File -ErrorAction SilentlyContinue |
Sort-Object Name | ForEach-Object { Write-Host (" {0} ({1})" -f $_.Name, (HumanSize $_.Length)) }
$ry = Join-Path $Src 'storage\ryujinx'
Write-Host ""
Write-Host "=== ryujinx extras tree ($ry, recursive) ==="
if (Test-Path $ry) {
Get-ChildItem -LiteralPath $ry -File -Recurse -ErrorAction SilentlyContinue | Sort-Object FullName |
ForEach-Object { Write-Host (" {0} ({1})" -f $_.FullName.Substring($Src.Length).TrimStart('\'), (HumanSize $_.Length)) }
} else { Write-Host " (not found)" }
Write-Host ""
Write-Host "Paste this back to Claude to design the Switch update/DLC restructuring."
return
}
# ---------------- Sync mode ----------------
# switch is NOT flat-copied here - it's handled by restructure-switch-for-romm.ps1
# (base + update/ + dlc/ folders) after the loop, so the two don't fight.
$overrides = @{
ps4 = @{ filter = '*.zip'; recurse = $true }
}
$dstDrive = Split-Path $Dst -Qualifier
if (-not (Test-Path "$dstDrive\")) {
throw "Destination drive $dstDrive not available. Is the TrueNAS games dataset mounted as $dstDrive ?"
}
$stamp = Get-Date -Format "yyyyMMdd-HHmmss"
$logFile = Join-Path (Get-Location) "romm-sync-$stamp.log"
Write-Host "=== Sync device ROMs -> RomM ==="
Write-Host " $SrcRoms -> $DstRoms"
Write-Host " Log: $logFile"
if ($DryRun) { Write-Host " DRY RUN (nothing copied)" -ForegroundColor Yellow }
$common = @('/Z','/R:3','/W:5','/NP','/TEE',"/LOG+:$logFile",
'/XF','metadata.txt','systeminfo.txt','gamelist.xml','desktop.ini')
if ($DryRun) { $common += '/L' }
# used platforms = subfolders of roms\ with >=1 real ROM file (auto-includes new ones)
$platforms = Get-ChildItem -LiteralPath $SrcRoms -Directory | Sort-Object Name |
Where-Object { @(Get-RealFiles $_.FullName).Count -gt 0 }
$results = @()
foreach ($pf in $platforms) {
$p = $pf.Name
if ($p -ieq 'switch') { continue } # handled by the restructure step below
$sdir = $pf.FullName
$ddir = Join-Path $DstRoms $p
$ov = $overrides[$p]
$roboArgs = @($sdir, $ddir)
if ($ov -and $ov.filter) {
$roboArgs += $ov.filter
if ($ov.recurse) { $roboArgs += '/S' }
} else {
$roboArgs += '/E'
}
$roboArgs += $common
$roboArgs += @('/XD', (Join-Path $sdir 'media'))
$tag = if ($ov -and $ov.filter) { "[$($ov.filter)]" } else { "[full]" }
Write-Host ""
Write-Host ("-- {0} {1}" -f $p, $tag) -ForegroundColor Cyan
& robocopy @roboArgs
$code = $LASTEXITCODE
$copied = ($code -band 1) -eq 1 # bit 0 => files copied
$status = if ($code -ge 8) { "FAILED ($code)" } elseif ($copied) { "NEW files copied" } else { "up to date" }
$results += [pscustomobject]@{ Platform = $p; Code = $code; Status = $status }
}
# --- switch: build the update/DLC folder layout via the companion script ---
$restruct = Join-Path $PSScriptRoot 'restructure-switch-for-romm.ps1'
if (Test-Path (Join-Path $SrcRoms 'switch')) {
Write-Host ""
Write-Host "-- switch [base + update/ + dlc/ layout]" -ForegroundColor Cyan
if (Test-Path $restruct) {
if ($DryRun) { & $restruct -Src $Src -Dst $Dst -DryRun } else { & $restruct -Src $Src -Dst $Dst }
} else {
Write-Host " restructure-switch-for-romm.ps1 not found next to this script - skipping switch." -ForegroundColor Yellow
}
}
# --- bios: copy RomM-recognized BIOS (md5-matched) via the companion script ---
$biosScript = Join-Path $PSScriptRoot 'sync-bios-for-romm.ps1'
if ((Test-Path $biosScript) -and (Test-Path (Join-Path $Src 'bios'))) {
Write-Host ""
Write-Host "-- bios [md5-matched against RomM's known list]" -ForegroundColor Cyan
if ($DryRun) { & $biosScript -BiosSrc (Join-Path $Src 'bios') -Dst $Dst -DryRun }
else { & $biosScript -BiosSrc (Join-Path $Src 'bios') -Dst $Dst }
}
Write-Host ""
Write-Host "==================== SUMMARY ===================="
$results | Format-Table -AutoSize | Out-String | Write-Host
$new = @($results | Where-Object { ($_.Code -band 1) -eq 1 -and $_.Code -lt 8 })
$fail = @($results | Where-Object { $_.Code -ge 8 })
if ($fail.Count) { Write-Host ("{0} platform(s) FAILED -- see the log." -f $fail.Count) -ForegroundColor Red }
Write-Host ("{0} platform(s) had new files this run." -f $new.Count) -ForegroundColor Green
if ($new.Count -and -not $DryRun) {
Write-Host "New games synced. Trigger a RomM scan (or wait for the nightly rescan) to import them." -ForegroundColor Green
}
Write-Host "Log: $logFile"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment