From 8fe32103e68ecae3dd43362fc5f0a64ac90e88b9 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sat, 28 Mar 2026 18:09:13 +0100 Subject: [PATCH] feat: add install.ps1 powershell installer --- install.ps1 | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 install.ps1 diff --git a/install.ps1 b/install.ps1 new file mode 100644 index 00000000..17373e83 --- /dev/null +++ b/install.ps1 @@ -0,0 +1,104 @@ +# RetroBIOS installer for Windows (PowerShell 5+, no Python required) +$ErrorActionPreference = "Stop" +$baseUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main" +$releaseUrl = "https://github.com/Abdess/retrobios/releases/download/large-files" + +$platform = $null +$biosPath = $null + +# Detect EmuDeck +$emudeckSettings = Join-Path $env:APPDATA "EmuDeck\settings.ps1" +if (Test-Path $emudeckSettings) { + $content = Get-Content $emudeckSettings -Raw + if ($content -match '\$emulationPath\s*=\s*"([^"]+)"') { + $platform = "emudeck" + $biosPath = Join-Path $Matches[1] "bios" + Write-Host "Found EmuDeck at $biosPath" + } +} + +# Detect RetroArch +if (-not $platform) { + $raCfg = Join-Path $env:APPDATA "RetroArch\retroarch.cfg" + if (Test-Path $raCfg) { + $platform = "retroarch" + $biosPath = Join-Path $env:APPDATA "RetroArch\system" + foreach ($line in Get-Content $raCfg) { + if ($line -match '^\s*system_directory\s*=\s*"?([^"]+)"?') { + $val = $Matches[1].Trim() + if ($val -and $val -ne "default") { + $biosPath = $val + } + break + } + } + Write-Host "Found RetroArch at $biosPath" + } +} + +# Fallback +if (-not $platform) { + $platform = Read-Host "Platform (retroarch, batocera, emudeck, ...)" + $biosPath = Read-Host "BIOS directory path" + if (-not $platform -or -not $biosPath) { + Write-Host "Aborted." -ForegroundColor Red; exit 1 + } +} + +Write-Host "`nFetching file index for $platform..." +$manifest = Invoke-RestMethod "$baseUrl/install/$platform.json" +$files = $manifest.files +Write-Host " $($files.Count) files" + +Write-Host "`nChecking existing files..." +$toDownload = @() +$upToDate = 0 + +foreach ($f in $files) { + $dest = Join-Path $biosPath $f.dest + if (Test-Path $dest) { + if ($f.sha1) { + $actual = (Get-FileHash $dest -Algorithm SHA1).Hash.ToLower() + if ($actual -eq $f.sha1) { $upToDate++; continue } + } else { + $upToDate++; continue + } + } + $toDownload += $f +} + +Write-Host " $upToDate/$($files.Count) up to date, $($toDownload.Count) to download" + +if ($toDownload.Count -eq 0) { + Write-Host "`nDone. 0 downloaded, $upToDate already up to date." + exit 0 +} + +$downloaded = 0 +$errors = 0 +$total = $toDownload.Count + +foreach ($f in $toDownload) { + $dest = Join-Path $biosPath $f.dest + $dir = Split-Path $dest -Parent + if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } + + if ($f.release_asset) { + $url = "$releaseUrl/$($f.release_asset)" + } else { + $url = "$baseUrl/$($f.repo_path)" + } + + try { + Invoke-WebRequest -Uri $url -OutFile $dest -UseBasicParsing + $downloaded++ + $i = $downloaded + $errors + Write-Host " [$i/$total] $($f.dest) ok" + } catch { + $errors++ + $i = $downloaded + $errors + Write-Host " [$i/$total] $($f.dest) FAILED" -ForegroundColor Red + } +} + +Write-Host "`nDone. $downloaded downloaded, $upToDate already up to date."