From 7b7cc56bc1a4c0ce48ef3ab0a59a9b6a487a288e Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Tue, 2 Jun 2026 16:11:24 +0200 Subject: [PATCH] feat: keep and auto-mount CD images via imgmount instead of stripping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Removed .iso, .cue, .img, .ccd from SKIP_EXT (they're now kept in bundles) - Added CD_EXT set and findCdImages() method to detect mountable images - buildDosboxConf() now generates imgmount D:/E:/… commands for each CD image - Only .nrg, .mdf, .mds, .sub, .dmg are still stripped (unsupported formats) Games with CD images will now work out of the box — DOSBox presents them as CD-ROM drives and the game can find its disc. --- .../java/com/dostalgia/UploadResource.java | 46 ++++++++++++++++--- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/dostalgia/UploadResource.java b/src/main/java/com/dostalgia/UploadResource.java index 6660f4c..c170c36 100644 --- a/src/main/java/com/dostalgia/UploadResource.java +++ b/src/main/java/com/dostalgia/UploadResource.java @@ -380,13 +380,37 @@ public class UploadResource { // ─── Bundle Creation ───────────────────────────────────────── - /** File extensions that are never game data and should be excluded from .jsdos bundles. */ + /** File extensions that are never game data and should be excluded from .jsdos bundles. + * Only formats DOSBox can't mount natively are stripped. + * Mountable formats (.iso, .cue, .img, .ccd) are kept and auto-mounted via imgmount. */ private static final java.util.Set SKIP_EXT = java.util.Set.of( - ".img", ".iso", ".nrg", ".mdf", ".mds", // disk images - ".ccd", ".sub", ".cue", // CloneCD / CUE sheets - ".dmg" // Mac disk images + ".nrg", ".mdf", ".mds", // disk images DOSBox can't mount natively + ".sub", // subchannel data (accompanies .ccd — CCD itself is kept) + ".dmg" // Mac disk images ); + /** File extensions that DOSBox can mount as CD-ROM via imgmount. */ + private static final java.util.Set CD_EXT = java.util.Set.of( + ".iso", ".cue", ".img", ".ccd" + ); + + /** Find mountable CD image files in the extracted game directory. + * Returns relative paths (with forward slashes) sorted alphabetically. */ + private List findCdImages(Path dir) throws IOException { + List cds = new ArrayList<>(); + try (var walk = Files.walk(dir)) { + walk.filter(Files::isRegularFile).forEach(f -> { + String name = f.getFileName().toString().toLowerCase(); + int dot = name.lastIndexOf('.'); + if (dot >= 0 && CD_EXT.contains(name.substring(dot))) { + cds.add(dir.relativize(f).toString().replace('\\', '/')); + } + }); + } + cds.sort(String::compareTo); + return cds; + } + /** * Executable filenames (lowercase, stem only, no extension) that should NEVER * be selected as the main game executable. These are DOS extenders, DPMI hosts, @@ -415,7 +439,9 @@ public class UploadResource { Path jsdos = extractDir.resolve(".jsdos"); Files.createDirectories(jsdos); String relExe = extractDir.relativize(Path.of(exePath)).toString(); - Files.writeString(jsdos.resolve("dosbox.conf"), buildDosboxConf(relExe)); + // Find CD images for DOSBox imgmount (mountable via D:, E:, …) + List cdImages = findCdImages(extractDir); + Files.writeString(jsdos.resolve("dosbox.conf"), buildDosboxConf(relExe, cdImages)); Files.write(jsdos.resolve("jsdos.json"), buildJsdosJson(relExe)); // ZIP it up directly from extractDir (no temp copy) @@ -524,8 +550,8 @@ public class UploadResource { return json.getBytes(java.nio.charset.StandardCharsets.UTF_8); } - private String buildDosboxConf(String relExe) { - // DOS uses \ as path separator; / is a switch character. + private String buildDosboxConf(String relExe, List cdImages) { + // DOS uses \\ as path separator; / is a switch character. // If the executable is in a subdirectory, cd into it first. var parts = splitDirExe(relExe); String dir = parts[0]; @@ -558,6 +584,12 @@ public class UploadResource { sb.append("[autoexec]\n"); sb.append("@echo off\n"); sb.append("mount c .\n"); + // Mount CD images as D:, E:, … so games can find their CD + char driveLetter = 'D'; + for (String img : cdImages) { + sb.append("imgmount ").append(driveLetter).append(" \"").append(img).append("\" -t cdrom\n"); + driveLetter++; + } sb.append("c:\n"); if (dir != null) { sb.append("path=c:\\\n");