# stage-saves.ps1 # PowerShell script to collect and structure emulation saves on Z:\tmp\saves_staging\ $stagingDir = "Z:\Emulation\tmp\saves_staging" if (-not (Test-Path $stagingDir)) { New-Item -ItemType Directory -Path $stagingDir -Force | Out-Null } Write-Host "Staging saves to: $stagingDir" -ForegroundColor Cyan # Helper to copy single save files function Stage-SingleSave($platform, $srcPath) { if (Test-Path $srcPath) { $destPlatformDir = Join-Path $stagingDir $platform if (-not (Test-Path $destPlatformDir)) { New-Item -ItemType Directory -Path $destPlatformDir -Force | Out-Null } $fileName = Split-Path $srcPath -Leaf $destPath = Join-Path $destPlatformDir $fileName Copy-Item -Path $srcPath -Destination $destPath -Force Write-Host " [+] Staged $platform save: $fileName" -ForegroundColor Green } else { Write-Warning " [-] Source save not found: $srcPath" } } # Helper to zip a directory of Switch files function Stage-SwitchSave($name, $folderPath) { if (Test-Path $folderPath) { $destPlatformDir = Join-Path $stagingDir "switch" if (-not (Test-Path $destPlatformDir)) { New-Item -ItemType Directory -Path $destPlatformDir -Force | Out-Null } # Normalize name to lowercase alphanumeric $cleanName = ($name -replace '[^a-zA-Z0-9]', '').ToLower() $zipPath = Join-Path $destPlatformDir "$cleanName.zip" # Remove old zip if exists if (Test-Path $zipPath) { Remove-Item $zipPath -Force } # Compress folder contents (so files are at root of zip) $filesPath = Join-Path $folderPath "*" Compress-Archive -Path $filesPath -DestinationPath $zipPath -Force Write-Host " [+] Zipped & Staged Switch save: $name ($cleanName.zip)" -ForegroundColor Green } else { Write-Warning " [-] Source Switch save folder not found: $folderPath" } } # --- 1. Stage GBA (mGBA) --- Write-Host "`nStaging GBA saves..." -ForegroundColor Yellow Stage-SingleSave "gba" "Z:\Emulation\saves\mgba\Pokemon FireRed Rocket Edition.sav" # --- 2. Stage NDS (melonDS) --- Write-Host "`nStaging NDS saves..." -ForegroundColor Yellow $ndsSaves = @( "Ace Attorney Investigations - Miles Edgeworth.sav", "Heartgold QoL.sav", "Nine Hours, Nine Persons, Nine Doors.sav", "Pokemon Definitive HeartGold Version.sav", "Pokemon Definitive HeartGold.sav", "Pokemon HeartGold Generations 2.0.sav" ) foreach ($save in $ndsSaves) { Stage-SingleSave "nds" "Z:\Emulation\saves\melonds\saves\$save" } # --- 3. Stage N64 (RetroArch) --- Write-Host "`nStaging N64 saves..." -ForegroundColor Yellow Stage-SingleSave "n64" "Z:\Emulation\saves\retroarch\saves\007 - The World Is Not Enough (USA).srm" Stage-SingleSave "n64" "Z:\Emulation\saves\retroarch\saves\Chameleon Twist 2 (USA).srm" # --- 4. Stage PSX (RetroArch) --- Write-Host "`nStaging PS1 saves..." -ForegroundColor Yellow Stage-SingleSave "psx" "Z:\Emulation\saves\retroarch\saves\Tomba! 2 - The Evil Swine Return (USA).srm" # --- 5. Stage Switch JKSV Saves --- Write-Host "`nStaging Switch JKSV saves..." -ForegroundColor Yellow $jksvDir = "Z:\Emulation\JKSV" if (Test-Path $jksvDir) { $gameDirs = Get-ChildItem -Path $jksvDir -Directory foreach ($gameDir in $gameDirs) { $gameName = $gameDir.Name # Get all subdirectories (backups) inside this game folder $backups = Get-ChildItem -Path $gameDir.FullName -Directory | Sort-Object Name -Descending if ($backups.Count -gt 0) { # Pick the most recent backup $recentBackup = $backups[0] Stage-SwitchSave $gameName $recentBackup.FullName } } } else { Write-Warning "JKSV directory not found!" } # --- 6. Stage Switch Yuzu Local Roaming Saves --- Write-Host "`nStaging Switch Yuzu local saves..." -ForegroundColor Yellow $yuzuUserSaveBase = "C:\Users\MattC\AppData\Roaming\yuzu\nand\user\save\0000000000000000" if (Test-Path $yuzuUserSaveBase) { # 01008DB008C2C000: Pokemon Let's Go Pikachu # Yuzu uses profile folders inside yuzu\nand\user\save\0000000000000000\\ # We will search for title IDs recursively under the base folder # 01008DB008C2C000 -> Let's Go Pikachu $pikachuFolders = Get-ChildItem -Path $yuzuUserSaveBase -Directory -Filter "01008DB008C2C000" -Recurse # Pick the one with the latest write time if ($pikachuFolders.Count -gt 0) { $latestPikachu = $pikachuFolders | Sort-Object LastWriteTime -Descending | Select-Object -First 1 Stage-SwitchSave "01008db008c2c000" $latestPikachu.FullName } else { Write-Warning "Pokemon Let's Go Pikachu save folder not found in Yuzu AppData!" } # 0100453019AA8000 -> Xenoblade Chronicles X: Definitive Edition $xenoFolders = Get-ChildItem -Path $yuzuUserSaveBase -Directory -Filter "0100453019AA8000" -Recurse if ($xenoFolders.Count -gt 0) { $latestXeno = $xenoFolders | Sort-Object LastWriteTime -Descending | Select-Object -First 1 Stage-SwitchSave "0100453019aa8000" $latestXeno.FullName } else { Write-Warning "Xenoblade X save folder not found in Yuzu AppData!" } } else { Write-Warning "Yuzu user save base path not found!" } Write-Host "`nStaging complete!" -ForegroundColor Cyan