Releases: Patrickjaillet/retrotools26
Releases · Patrickjaillet/retrotools26
Release list
Retro Tools 2026 v0.1.7
[0.1.7] - 2026-08-14
Fixed
- Games tab Grid view still overlapped the details panel with a large game list after the v0.1.6 fix: the per-row card count calculation counted only each card's content width (180px), not its rendered width including the card frame's inner margin (10px each side) — one card too many fit in the calculation and still overflowed the column. Now uses the full rendered card width and the real item spacing read from
ui.spacing()instead of a guessed constant; verified with a 200-game scrollable list.
Retro Tools 2026 v0.1.6
[0.1.6] - 2026-08-14
Fixed
- Games tab Grid view: two rendering bugs found via a real user report (34410 games, TOSEC Amiga DAT). The status tile on each card used
Frame+centered_and_justified(same bug asplatform_badge::draw, fixed the same way — exact-sizePainterallocation). Separately,horizontal_wrappedinside theScrollAreanested in the grid's half-width column was wrapping against the whole window's width instead of the constrained column width, so cards kept flowing past the column boundary and under the details panel instead of wrapping; replaced with explicit row-chunking based on a freshly measuredui.available_width(). - Landing page download buttons pointed at the old v0.1.0 release assets — never updated across the v0.1.1-v0.1.4 releases. Now point at the current release.
Retro Tools 2026 v0.1.5
[0.1.5] - 2026-08-14
Fixed
platform_badge::drawusedcentered_and_justified, which claims all available space in its parentUi— harmless in a plain vertical layout, but it stretched the badge into a full-width colored bar wherever it sat inside anegui::Gridcell (Platforms tab) or next to a heading (Dashboard, Games), discovered while taking real screenshots for the README. Now allocates its exact size via thePainter, same approach asshader_preview::draw.
Changed
README.mdrewritten as a pure end-user showcase (what the app does, not how to build it) with 4 real screenshots (Dashboard, Games, Platforms, 1G1R Builder), replacing the previous 2-screenshot version with build-instructions front and center.
Retro Tools 2026 v0.1.4
[0.1.4] - 2026-08-14
Fixed
- CI was red on every commit since early in the project and had gone unnoticed because local checks never ran with the same strict flags:
cargo clippy --workspace --all-targets -- -D warningsfailed on two long-standing warnings (ThemePreference's andToastManager's manualDefaultimpls, both now#[derive(Default)];ToastManager::reportwas genuinely unused code and removed), andcargo fmt --all -- --checkfailed across most of the codebase (now reformatted to rustfmt defaults, no behavior change)
Retro Tools 2026 v0.1.3
[0.1.3] - 2026-08-14
Fixed
- Dashboard, Platforms, Plugins, Settings, Download and About tabs now scroll (each wrapped in its own
egui::ScrollArea::vertical()) — on a small or restored-from-minimized window, content past the bottom of the visible area was previously unreachable with no scrollbar; the Games and 1G1R tabs already had their own internal scrolling and are unaffected
Added
- New "Download" tab (
crates/ui/src/views/download.rs): official/community links for everything this app works with but doesn't bundle — DAT sources (No-Intro, Redump, TOSEC), frontends/distributions (Batocera, Recalbox, Lakka, EmulationStation-DE), RetroArch cores and shaders, RetroAchievements account creation, and the third-party RVZ/CSO conversion tools; deliberately excludes ROM download sites, with a visible note explaining why — this app manages ROMs you already own, it doesn't point at copyright-infringing sources
Retro Tools 2026 v0.1.2
[0.1.2] - 2026-08-14
Adds the "Modules Futurs Retrogaming" batch (Phases 11-20): Batocera/
Recalbox/Lakka export, ScreenScraper metadata scraping, ES-DE smart
collections, save backup/restore, controller profile library, shader
overrides, a core-compatibility advisor, RVZ/CSO conversion, SD/USB card
imaging, and RetroAchievements integration — plus generated platform
badges and shader preset previews in the UI.
Added
- Static shader preset previews (
crates/ui/src/shader_preview.rs): a small synthetic reference image shown next to each shader association and in the preset picker in Settings, illustrating the preset's category (CRT/scanline/pixel-art upscaler) with scanline overlays, a vignette, or a blocky-vs-smooth split — not a real screenshot, since this project doesn't bundle third-party shader/game screenshots; the file-name classification is a pure, unit-tested function kept separate from the drawing code - Procedurally generated platform badges (
crates/ui/src/platform_badge.rs): a deterministic colored circle with 2-4 letter initials derived from the platform's name, shown in the Platforms, Dashboard and Games tabs — real console/company logos are trademarks and can't legally be bundled in this public repository under any license this project could choose, so this sidesteps that entirely while still giving every platform a distinct visual identity - RetroAchievements integration (
retrotools-plugin-retroachievements): syncs and locally caches known RetroAchievements-compatible ROM hashes per platform (via an editable platform → console-id table) using your own username/API key (encrypted, Settings), then cross-references the current 1G1R selection and reports any kept game with no known hash; a new opt-in tie-breaker,RulePriority::prefer_retroachievements_compatible(off by default, changes nothing unless enabled), lets 1G1R selection itself prefer an RA-compatible alternate when otherwise tied — both read the same on-disk hash cache without sharing Rust state; RetroAchievements compatibility now also shows in the Games tab's detail panel - SD/USB card imaging (
retrotools-plugin-sdcard-imager): checksum verification of a downloaded Batocera/Recalbox/Lakka base image (sdcard verify), removable-USB-disk detection (sdcard list-devices), and raw image writing (sdcard write) gated by a typed double confirmation of the exact device id (nothing is written if--device/--confirmdon't match) — the destructive write path is deliberately plain CLI-invoked functions rather than the generic plugin contract, sincePluginContexthas no room for that confirmation;sdcard-inject(a normal plugin) then mirrors a staging folder (built 1G1R set plus any Export/Controllers/Shaders output) onto the freshly-imaged, already-mounted partition; a manual real-hardware validation procedure is documented indocs/PLUGIN_DEV.mdsince writing to a real device is intentionally not automated in tests - RVZ (GameCube/Wii) and CSO (PSP) conversion:
convert to-rvz/from-rvz(via a third-partyDolphinTool) andconvert to-cso/from-cso(via a third-partymaxcso), symmetric to the existing CHD conversion commands; neither tool is bundled with this app (unlike UnRAR/chdman/7za) —docs/COMPILATION.mdexplains how to obtain and point the app at them (RETROTOOLS_DOLPHINTOOL_PATH/RETROTOOLS_MAXCSO_PATH, aresources/folder, orPATH), and each command fails with a clear message rather than silently if the tool isn't found - Core compatibility advisor (
retrotools-plugin-core-advisor): a local, user-imported JSON database mapping platform/game → recommended libretro core (with a confidence level, a free-text note, and a "known problematic" flag), edited from a new Settings section;core-advisor-reportcross-references the games the last scan actually matched (via the newPluginContext::match_report, no re-scanning) against that database, writes a plain-text report, and generates a per-game.optcore-options override at RetroArch's exact expected path for any entry with specific options; the recommended core and its note now also show in the Games tab's detail panel - RetroArch shader override generation (
retrotools-plugin-shaders): a library of.glslp/.slangppresets (3 realistic starters — CRT geom, scanlines, scale2x — whose shader paths were verified against the reallibretro/slang-shadersfolder layout so they actually resolve on a standard RetroArch install, though nothing is copied from that repository itself, plus import of externally-supplied preset files), a saved shader → core / shader → game association list edited from a new Settings section, andshaders-exportwhich writes RetroArch override files at the exact path RetroArch itself expects (<core>/<core>.cfgfor a whole core,<core>/<content dir>/<game>.cfgfor one game); every generated file is recorded in a manifest soshaders-cleancan remove exactly what this tool produced without ever touching a hand-written override PluginContextgained amatch_report: Option<&MatchReport>field so a plugin can cross-reference per-ROM scan status (matched/corrupt/unknown/missing) without re-scanning — needed by the upcoming core-compatibility and RetroAchievements modules; the UI now threads its liveMatchReportthrough, the CLI passesNone(it doesn't currently keep one around between commands)
Retro Tools 2026 v0.1.0
Retro Tools 2026 v0.1.0
First release: DAT parsing (No-Intro/Redump/TOSEC/MAME), ROM scanning and
hashing (incl. ZIP/7Z/RAR/CHD), 1G1R selection with configurable
region/language rules, file-build operations with undo, a static plugin
system, a full CLI, an egui desktop UI, and Windows packaging
(installer + portable build).
Added
- Replaced the two literal "Placeholder preview" mockups in
docs/screenshot1.png/screenshot2.pngwith real captures of the running app (Dashboard and 1G1R Builder, with an actual DAT imported); corrected a stale claim indocs/PLUGIN_DEV.mdthat CHD conversion was unimplemented (it was added in Phase 7,retrotools_core::convert) - Real GitHub-Releases-backed auto-updater (
retrotools_common::updater::GitHubReleaseSource): checks the public Releases API (no auth token needed) and compares versions; wired into the UI (startup check whencheck_updates_on_startupis on and a repository is configured in Settings, with a toast when an update is available) and the CLI (check-update [--repository owner/repo]); no repository is guessed by default (AppConfig::update_repositorystartsNone) - Windows installer (
packaging/installer.iss, Inno Setup 7): per-user install (no admin rights), bundlesresources/*.exeand docs, Start Menu/desktop shortcuts; unsigned (no code-signing certificate available) - Portable build (
packaging/make_portable.ps1+retrotools_common::config::is_portable_mode()): dropping aportable.txtmarker next to the exe switches every config/cache/log/DAT path to<exe_dir>/data/instead of the per-user profile - Multi-resolution app icon (
crates/ui/assets/icon.ico, 16/32/48/256), procedurally generated (no source logo existed), embedded into the exe (crates/ui/build.rsviawinresource) and set as the runtime window icon - Full-pipeline integration test (
crates/core/tests/integration_pipeline.rs): scan → match → 1G1R preview/selection → filter → plan → execute against real files on disk, plus post-transfer verification and undo, using only the public API — the previous test suite only ever covered one module at a time - Large-scale synthetic-DAT non-regression test (
crates/core/tests/synthetic_no_intro_regression.rs): a generated ~750-game, ~150-family DAT modeled on real No-Intro naming conventions (region/revision/beta tags), checked for zero lost or duplicated families after 1G1R selection, with a runtime ceiling to catch algorithmic regressions; real No-Intro/Redump sample DATs aren't bundled (third-party copyright, no network access here to fetch them) criterionbenchmarks for hashing (crates/core/benches/hashing.rs, 1/8/32 MB buffers) and DAT parsing (crates/core/benches/dat_parsing.rs, 500/3000-game synthetic DATs), runnable viacargo bench -p retrotools-core- Headless automated UI smoke tests (
crates/ui/src/main.rs::ui_smoke_tests): drive every tab'sshow()against a realegui::Contextwith no window/event loop, across several frames, with and without an imported DAT, both in Expert and Wizard 1G1R modes;egui_kittestisn't published for the pinned egui/eframe 0.28, so this is a small hand-rolled harness instead - Security review of archive extraction and file-build path construction: confirmed no zip-slip vector (entries are always streamed to a caller-supplied writer, never used to build a filesystem path) and added adversarial tests proving a malicious DAT-supplied game/rom name (
../../../../etc/evil, backslash traversal) can never escape the configured destination root - Test proving a build batch degrades gracefully when one transfer fails (destination blocked by a pre-existing file, the same failure class as a full disk or a permissions error): the failing item is reported per-item, the rest of the batch still completes
- ROM/ISO format converter (
retrotools_core::convert):convert_to_chd/convert_from_chd, reusing the already-bundledchdman.exe(the same tool used for CHD extraction since Phase 2); new CLIconvert to-chd <source> <dest.chd>andconvert from-chd <source.chd> <dest_dir>; verified with a real round trip (raw image → CHD → extracted back → byte-for-byte identical). CSO (PSP) and RVZ (Dolphin) are still out of scope — each needs its own dedicated codec (maxcso,DolphinTool) that isn't bundled and isn't a byproduct of any other feature - Missing-DAT detection and assisted download (
retrotools_core::dat_library::platforms_missing_dat): flags ROM subfolders with no matching DAT imported yet; new CLIdat detect-missing <roms_root> <dat_dir> [--assist]and a new "Missing DATs" section in the UI's Platforms tab (Detect missing DATs...button, then a per-platformDownload & importbutton when a same-named DAT source is already tracked) — reuses the existing tracked-source infrastructure rather than attempting real DAT discovery, since no unauthenticated No-Intro/Redump/TOSEC API exists for that; verified end-to-end (CLI and UI) against a real local HTTP server - Games grid view (
views/games.rs::show_grid), selectable alongside the existing list view via a List/Grid toggle; card-based layout with a status-colored placeholder tile (no real artwork yet — no scraper until Phase 7) - Wizard mode for the 1G1R tab (
views/onegameonerom.rs::wizard, driven by the newAppState::wizard_step/WizardStep): a step-by-step Platform → Scan → Rules → Preview → Build flow with a clickable breadcrumb and Back/Next navigation, reusing the same section-rendering functions as the existing single-page layout - Expert mode toggle in the 1G1R tab (
AppState::expert_mode, on by default): switches between the wizard and the original all-on-one-page layout - Command palette (
Ctrl+Shift+Por the new 🔍 button): fuzzy-filtered command list with arrow-key navigation and Enter/click execution — jump to any tab, import a DAT, toggle expert mode, toggle light/dark theme - Additional keyboard shortcuts:
Alt+1throughAlt+7jump directly to each tab - Minimal i18n layer (
crates/ui/src/i18n.rs):Language/Key/t(), with a language selector in Settings that switches the UI immediately; covers tabs, the dashboard and a handful of key buttons/labels rather than every string, matching the roadmap's "structure ready" goal - Adjustable UI scale for accessibility (
AppConfig::ui_scale, a Settings slider applied viaegui::Context::set_pixels_per_pointand persisted across restarts) - Light fade-in transition when switching tabs (
egui::Context::animate_bool_with_timeinapp.rs::central_content), as lightweight visual feedback without pulling in a tweening library - Duplicate ROM detection (
retrotools-core::matcher::find_duplicate_matches): identifies extra copies of a ROM that already matched a DAT entry elsewhere (as opposed tounknown, which is content the DAT doesn't recognize at all) and picks a deterministic file to keep; the CLIcleancommand gained--duplicates(opt-in, off by default to stay backward-compatible) and--no-unknown, trashing both categories through the same undo-able safe-delete path with the reason labeled in its output - PDF export for scan reports (
ScanReport::to_pdf, viaprintpdf's HTML-to-PDF renderer, reusing the existingto_htmllayout instead of a separate PDF-specific one); new CLIscan --pdf <path>option - RAR and CHD archive support (
retrotools-core::external_tools, extendingarchive.rs): shells out to bundled third-party CLI tools underresources/(UnRAR.exefor read-only RAR extraction,chdman.exefor CHD disk images — seedocs/COMPILATION.mdfor licensing notes and packaging instructions) since neither format has a maintained pure-Rust decoder; tool resolution checks an env var override, aresources/folder near the executable, thenPATH; verified with a real create→scan→hash→extract→compare round trip against a CHD built bychdmanitself - Real-time scan throughput (files/s, MB/s) in the 1G1R tab's progress indicator (
AppState::scan_speed) - DAT auto-update from a tracked download URL (
retrotools-core::dat_update): register a name + direct DAT/ZIP URL once, then re-fetch it on demand and compare its version against the localDatCacheto report whether anything actually changed, without ever re-importing an unchanged DAT; new CLI commandsdat source-add/dat source-list/dat source-remove/dat update/dat update-all, and a matching "DAT update sources" section in the Settings tab (background thread, doesn't block the UI) - Internal plugin architecture (
retrotools-plugin-api): aPlugintrait,PluginContextandPluginRegistrylet optional modules extend the app without modifyingretrotools-coreorretrotools-ui; plugins are statically-linked crates registered at startup rather than dynamically loaded.dlls (seedocs/PLUGIN_DEV.mdfor the rationale and a step-by-step guide) - Playlist Generator plugin (
retrotools-plugin-playlists): generates RetroArch.lpl, LaunchBox XML and ES-DEgamelist.xmlplaylists from the current 1G1R selection - BIOS Manager plugin (
retrotools-plugin-bios): verifies a folder of BIOS files against a BIOS DAT (the same Logiqx/XML format No-Intro publishes for BIOS packs) by reusing the core scan/match engine, so no BIOS checksum is ever hardcoded - New CLI commands
plugin listandplugin run <id> <dat> --output <dir> [--source <dir>] [--profile <name>] - New Plugins tab in the UI, listing every registered plugin with a
Runbutton; validated end-to-end (source/output folder pickers, real files written to disk, live "last run" status per plugin) - "Fix report" (
retrotools-core::fix): turns a scan/match result into a precise, actionable list of what's needed to complete a set — ROMs to obtain (missing) and files to replace (present but not matching the DAT) — exportable as text/CSV, shown in the 1G1R tab and via the new CLIfixcommand - Set comparator (
retrotools-core::compare): diffs two ROM scans by conte...