Skip to content

Releases: Patrickjaillet/retrotools26

Retro Tools 2026 v0.1.7

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 14 Aug 13:33

[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

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 14 Aug 13:08

[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 as platform_badge::draw, fixed the same way — exact-size Painter allocation). Separately, horizontal_wrapped inside the ScrollArea nested 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 measured ui.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

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 14 Aug 09:57

[0.1.5] - 2026-08-14

Fixed

  • platform_badge::draw used centered_and_justified, which claims all available space in its parent Ui — harmless in a plain vertical layout, but it stretched the badge into a full-width colored bar wherever it sat inside an egui::Grid cell (Platforms tab) or next to a heading (Dashboard, Games), discovered while taking real screenshots for the README. Now allocates its exact size via the Painter, same approach as shader_preview::draw.

Changed

  • README.md rewritten 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

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 14 Aug 08:51

[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 warnings failed on two long-standing warnings (ThemePreference's and ToastManager's manual Default impls, both now #[derive(Default)]; ToastManager::report was genuinely unused code and removed), and cargo fmt --all -- --check failed across most of the codebase (now reformatted to rustfmt defaults, no behavior change)

Retro Tools 2026 v0.1.3

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 14 Aug 08:18

[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

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 13 Aug 23:06

[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/--confirm don't match) — the destructive write path is deliberately plain CLI-invoked functions rather than the generic plugin contract, since PluginContext has 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 in docs/PLUGIN_DEV.md since 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-party DolphinTool) and convert to-cso/from-cso (via a third-party maxcso), symmetric to the existing CHD conversion commands; neither tool is bundled with this app (unlike UnRAR/chdman/7za) — docs/COMPILATION.md explains how to obtain and point the app at them (RETROTOOLS_DOLPHINTOOL_PATH/RETROTOOLS_MAXCSO_PATH, a resources/ folder, or PATH), 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-report cross-references the games the last scan actually matched (via the new PluginContext::match_report, no re-scanning) against that database, writes a plain-text report, and generates a per-game .opt core-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/.slangp presets (3 realistic starters — CRT geom, scanlines, scale2x — whose shader paths were verified against the real libretro/slang-shaders folder 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, and shaders-export which writes RetroArch override files at the exact path RetroArch itself expects (<core>/<core>.cfg for a whole core, <core>/<content dir>/<game>.cfg for one game); every generated file is recorded in a manifest so shaders-clean can remove exactly what this tool produced without ever touching a hand-written override
  • PluginContext gained a match_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 live MatchReport through, the CLI passes None (it doesn't currently keep one around between commands)

Retro Tools 2026 v0.1.0

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 13 Aug 18:57

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.png with real captures of the running app (Dashboard and 1G1R Builder, with an actual DAT imported); corrected a stale claim in docs/PLUGIN_DEV.md that 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 when check_updates_on_startup is 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_repository starts None)
  • Windows installer (packaging/installer.iss, Inno Setup 7): per-user install (no admin rights), bundles resources/*.exe and docs, Start Menu/desktop shortcuts; unsigned (no code-signing certificate available)
  • Portable build (packaging/make_portable.ps1 + retrotools_common::config::is_portable_mode()): dropping a portable.txt marker 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.rs via winresource) 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)
  • criterion benchmarks 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 via cargo bench -p retrotools-core
  • Headless automated UI smoke tests (crates/ui/src/main.rs::ui_smoke_tests): drive every tab's show() against a real egui::Context with no window/event loop, across several frames, with and without an imported DAT, both in Expert and Wizard 1G1R modes; egui_kittest isn'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-bundled chdman.exe (the same tool used for CHD extraction since Phase 2); new CLI convert to-chd <source> <dest.chd> and convert 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 CLI dat 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-platform Download & import button 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 new AppState::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+P or 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+1 through Alt+7 jump 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 via egui::Context::set_pixels_per_point and persisted across restarts)
  • Light fade-in transition when switching tabs (egui::Context::animate_bool_with_time in app.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 to unknown, which is content the DAT doesn't recognize at all) and picks a deterministic file to keep; the CLI clean command 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, via printpdf's HTML-to-PDF renderer, reusing the existing to_html layout instead of a separate PDF-specific one); new CLI scan --pdf <path> option
  • RAR and CHD archive support (retrotools-core::external_tools, extending archive.rs): shells out to bundled third-party CLI tools under resources/ (UnRAR.exe for read-only RAR extraction, chdman.exe for CHD disk images — see docs/COMPILATION.md for licensing notes and packaging instructions) since neither format has a maintained pure-Rust decoder; tool resolution checks an env var override, a resources/ folder near the executable, then PATH; verified with a real create→scan→hash→extract→compare round trip against a CHD built by chdman itself
  • 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 local DatCache to report whether anything actually changed, without ever re-importing an unchanged DAT; new CLI commands dat 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): a Plugin trait, PluginContext and PluginRegistry let optional modules extend the app without modifying retrotools-core or retrotools-ui; plugins are statically-linked crates registered at startup rather than dynamically loaded .dlls (see docs/PLUGIN_DEV.md for the rationale and a step-by-step guide)
  • Playlist Generator plugin (retrotools-plugin-playlists): generates RetroArch .lpl, LaunchBox XML and ES-DE gamelist.xml playlists 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 list and plugin run <id> <dat> --output <dir> [--source <dir>] [--profile <name>]
  • New Plugins tab in the UI, listing every registered plugin with a Run button; 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 CLI fix command
  • Set comparator (retrotools-core::compare): diffs two ROM scans by conte...
Read more