Last active
November 22, 2023 18:19
-
-
Save milnak/deb3f4e81b40c5489dda2feb88a58972 to your computer and use it in GitHub Desktop.
PinHP Rom Organizer #pinhp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Place this file in root of USB, i.e. parent of the "rpi2jamma" folder. | |
# Prerequisite: | |
# category.ini and version.ini from https://www.progettosnaps.net/index.php | |
# Place these files into "folders" folder off USB root. | |
# When run, this will: | |
# 1. Move unsupported ROMS to "roms_unused" | |
# 2. Organize roms into folders under "roms_advmame" | |
# 3. Add a ".title" file in each rom folder, describing the content. | |
# 4. Ensure that all extras (button, marquee, etc.) exist for each ROM file. | |
# 5. Check that custom_folders=Y is set in "config.ini" file. | |
function Create-LegalFilename { | |
Param( | |
[Parameter(Mandatory)][string]$Filename | |
) | |
# This won't work, as characters need regex escaping. | |
# $group = '[{0}]' -f [System.IO.Path]::GetInvalidFileNameChars() -join '' | |
$group = '[' | |
foreach ($c in [IO.Path]::GetInvalidFileNameChars()) { | |
$group += [regex]::escape($c) | |
} | |
$group += ']' | |
$Filename -replace $group, '-' | |
} | |
function Read-MameIni { | |
Param( | |
[Parameter(Mandatory)][string]$Filename, | |
[switch]$IsVersion = $False | |
) | |
$hash = @{} | |
$section = $null | |
Get-Content $Filename -ErrorAction Stop | ForEach-Object { | |
$line = $_.ToString() | |
# '[' indicates a section marker | |
if ($line.length -ge 3 -and $line.Substring(0, 1) -eq '[') { | |
if ($line -eq '[FOLDER_SETTINGS]') { | |
$section = $null | |
} | |
else { | |
if ($IsVersion) { | |
if ($line -ne '[ROOT_FOLDER]') { | |
# versions can include 'a', 'b', 'u', 'rc', e.g. '0.106u1' or b, e.g. '0.34b5' | |
$line = ($line -split 'a' -split 'b' -split 'u' -split 'r' -split ']')[0] | |
$section = [Version]$line.Substring(1) | |
} | |
} | |
else { | |
$section = $line.Substring(1, $line.Length - 2) | |
} | |
} | |
} | |
elseif ($section -and $line -match '^[a-z0-9]') { | |
# Return as a hash rather than a PSCustomObject as hash lookup is much faster. | |
# [PSCustomObject]@{ rom=$line; value=$section } | |
$hash[$line] = $section | |
} | |
} | |
$hash | |
} | |
function Move-UnsupportedRoms { | |
Param( | |
[Parameter(Mandatory)][string]$Folder, | |
[Parameter(Mandatory)][string]$BackupFolder | |
) | |
if (-not (Test-Path $BackupFolder -PathType Container)) { | |
New-Item -ItemType Directory -Name $BackupFolder -ErrorAction Stop | Out-Null | |
} | |
# map of romname to version where rom was introduced. | |
$version = Read-MameIni -Filename 'folders\version.ini' -IsVersion | |
# AdvanceMAME 1.4 Reference Collection (Complete MAME 0.106) | |
$supportedRoms = $version | Where-Object value -le '0.106' | |
Get-ChildItem $Folder -Recurse -Filter '*.zip' | ForEach-Object { | |
$romName = $_.BaseName | |
if (-not ($supportedRoms.ContainsKey($romName))) { | |
# ROM not supported in this MAME version, move to backup folder. | |
'Unsupported ROM: {0}' -f $romName | |
Move-Item -LiteralPath $_.FullName -Destination $BackupFolder -ErrorAction Stop -Force | |
} | |
} | |
} | |
function Categorize-Roms { | |
Param( | |
[Parameter(Mandatory)][string]$Folder, | |
[Parameter(Mandatory)][string]$BackupFolder | |
) | |
# map of romname to category description, e.g. 'Casino / Cards' | |
$categories = Read-MameIni -Filename 'folders\category.ini' | |
Get-ChildItem $Folder -Recurse -Filter '*.zip' | ForEach-Object { | |
$romName = $_.BaseName | |
$category = $categories[$romName] | |
if (-not $category) { | |
# Can't find category, move to backup folder. | |
'Unknown category: {0}' -f $romName | |
Move-Item -LiteralPath $_.FullName -Destination $BackupFolder -ErrorAction Stop -Force | |
} | |
else { | |
# pinHP crashes if a folder contains an '&' | |
$category = $category -replace '&', '-' | |
$split = ($category -split '/').Trim() | |
if ($split.Length -eq 2) { | |
# For some categories, use the primary. | |
if ($split[0] -in @('Driving', 'Fighter', 'Maze', 'Shooter', 'Sports', 'System')) { | |
$category = $split[0] | |
} | |
else { | |
$category = $split[1] | |
} | |
} | |
else { | |
$category = $split[0] | |
} | |
if ($category -eq 'System') { | |
# 'System' is a BIOS. Move it to the backup folder. | |
'System file: {0}' -f $romName | |
$targetFolder = $BackupFolder | |
} | |
else { | |
$targetFolder = Join-Path $Folder (Create-LegalFilename -Filename $category) | |
if (-not (Test-Path $targetFolder -PathType Container)) { | |
New-Item -ItemType Directory -Name $targetFolder -ErrorAction Stop | Out-Null | |
# Each folder needs a '.title' file containing folder description. | |
$category | Out-File -Encoding ascii -FilePath (Join-Path $targetFolder '.title') | |
} | |
} | |
Move-Item -LiteralPath $_.FullName -Destination $targetFolder -ErrorAction Stop -Force | |
} | |
} | |
} | |
function Cleanup-Folders { | |
Param( | |
[Parameter(Mandatory)][string]$Folder | |
) | |
# Find empty folders or folders with only a '.title' file in it, and remove the folder. | |
Get-ChildItem -LiteralPath $Folder -Directory | ForEach-Object { | |
$files = Get-ChildItem -LiteralPath $_.FullName | |
if ($files.Count -eq 0 -or ($files.Count -eq 1 -and $files[0].Name -eq '.title')) { | |
Remove-Item -LiteralPath $_.FullName -Recurse -Force | |
} | |
} | |
} | |
# Look for any "extras" (marquee, button, etc.) that are missing for a rom. | |
function Check-Extras { | |
Param( | |
[Parameter(Mandatory)][string]$Folder | |
) | |
$buttons = Get-ChildItem (Join-Path $Folder 'buttons') -Filter '*.png' | Select-Object -ExpandProperty BaseName | |
$logos = Get-ChildItem (Join-Path $Folder 'logos') -Filter '*.png' | Select-Object -ExpandProperty BaseName | |
$marquees = Get-ChildItem (Join-Path $Folder 'marquees') -Filter '*.png' | Select-Object -ExpandProperty BaseName | |
$snaps = Get-ChildItem (Join-Path $Folder 'snaps') -Filter '*.png' | Select-Object -ExpandProperty BaseName | |
$titles = Get-ChildItem (Join-Path $Folder 'titles') -Filter '*.png' | Select-Object -ExpandProperty BaseName | |
$videos = Get-ChildItem (Join-Path $Folder 'videos') -Filter '*.mp4' | Select-Object -ExpandProperty BaseName | |
Get-ChildItem (Join-Path $Folder 'roms_advmame') -Recurse -Filter '*.zip' | Select-Object BaseName | Sort-Object BaseName | ForEach-Object { | |
$romName = $_.BaseName | |
$missing = $null | |
if (-not ($buttons -contains $romName)) { $missing += 'button ' } | |
if (-not ($logos -contains $romName)) { $missing += 'logo ' } | |
if (-not ($marquees -contains $romName)) { $missing += 'marquee ' } | |
if (-not ($snaps -contains $romName)) { $missing += 'snap ' } | |
if (-not ($titles -contains $romName)) { $missing += 'title ' } | |
if (-not ($videos -contains $romName)) { $missing += 'video ' } | |
if ($missing) { | |
'{0}: {1}' -f $romName, $missing | |
} | |
} | |
} | |
# Ensure custom_folders=Y in config.ini | |
function Check-CustomFolders { | |
Param( | |
[Parameter(Mandatory)][string]$Folder | |
) | |
$configPath = (Join-Path $Folder 'config.ini') | |
$data = Get-Content $configPath ` | |
| Select-String 'custom_folders' ` | |
| ConvertFrom-StringData | |
if ($data['custom_folders'] -ne 'Y') { | |
Write-Warning ('Set custom_folders=Y in {0}' -f $configPath) | |
} | |
} | |
# | |
# main | |
# | |
if (-not (Test-Path './rpi2jamma' -PathType Container)) { | |
Write-Warning 'rpi2jamma folder not found' | |
Exit | |
} | |
Move-UnsupportedRoms -Folder 'rpi2jamma\roms_advmame' -BackupFolder 'rpi2jamma\roms_unused' | |
Categorize-Roms -Folder 'rpi2jamma\roms_advmame' -BackupFolder 'rpi2jamma\roms_unused' | |
Cleanup-Folders -Folder 'rpi2jamma\roms_advmame' | |
Check-Extras -Folder 'rpi2jamma' | |
Check-CustomFolders -Folder 'rpi2jamma' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment