diff --git a/src/main/java/com/dostalgia/GameService.java b/src/main/java/com/dostalgia/GameService.java index 0c34d1b..8ab3ca4 100644 --- a/src/main/java/com/dostalgia/GameService.java +++ b/src/main/java/com/dostalgia/GameService.java @@ -166,8 +166,9 @@ public class GameService { throw new NoSuchFileException("Bundle not found: " + bundleFile); } - // Build new config entries - byte[] newDosboxConf = buildDosboxConfBytes(executable); + // Build new config entries — preserve any CD images in the bundle + List cdImages = findCdImagesInBundle(bundlePath); + byte[] newDosboxConf = buildDosboxConfBytes(executable, cdImages); byte[] newJsdosJson = buildJsdosJsonBytes(executable); // Patch the ZIP: read old, write new with modified config entries @@ -203,8 +204,28 @@ public class GameService { save(game); } - /** Build a dosbox.conf for a given executable path. */ - private byte[] buildDosboxConfBytes(String relExe) { + /** Scan a .jsdos bundle for CD image files (preserves the case from the ZIP entry). */ + private List findCdImagesInBundle(Path bundlePath) throws IOException { + Set cdExt = Set.of(".iso", ".cue", ".img", ".ccd", ".bin"); + List cds = new ArrayList<>(); + try (var zis = new java.util.zip.ZipInputStream(Files.newInputStream(bundlePath))) { + java.util.zip.ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (entry.isDirectory()) continue; + String name = entry.getName().toLowerCase(); + int dot = name.lastIndexOf('.'); + if (dot >= 0 && cdExt.contains(name.substring(dot))) { + cds.add(entry.getName()); // preserve original filename casing + } + zis.closeEntry(); + } + } + cds.sort(String::compareTo); + return cds; + } + + /** Build a dosbox.conf for a given executable path and optional CD images. */ + private byte[] buildDosboxConfBytes(String relExe, List cdImages) { var parts = splitExePath(relExe); String dir = parts[0]; String exe = parts[1]; @@ -214,7 +235,16 @@ public class GameService { sb.append("[mixer]\nnosound=false\nrate=44100\n\n"); sb.append("[sblaster]\nsbtype=sb16\nirq=7\ndma=1\nhdma=5\n\n"); sb.append("[dos]\nxms=true\nems=true\numb=true\n\n"); - sb.append("[autoexec]\n@echo off\nmount c .\nc:\n"); + sb.append("[autoexec]\n@echo off\nmount c .\n"); + // Mount CD images as D:, E:, … so games can find their CD + char driveLetter = 'D'; + for (String img : cdImages) { + String imgLower = img.toLowerCase(); + String flags = imgLower.endsWith(".bin") ? " -t cdrom -fs iso" : " -t cdrom"; + sb.append("imgmount ").append(driveLetter).append(" \"").append(img).append("\"").append(flags).append("\n"); + driveLetter++; + } + sb.append("c:\n"); if (dir != null) { sb.append("path=c:\\\n"); sb.append("cd ").append(dir).append("\n"); @@ -299,7 +329,9 @@ public class GameService { throw new NoSuchFileException("Bundle not found: " + game.getBundleFile()); } - byte[] newDosboxConf = buildDosboxConfBytes(setupExe); + // Build new config entries — preserve any CD images in the bundle + List cdImages = findCdImagesInBundle(bundlePath); + byte[] newDosboxConf = buildDosboxConfBytes(setupExe, cdImages); byte[] newJsdosJson = buildJsdosJsonBytes(setupExe); try (var zis = new java.util.zip.ZipInputStream(Files.newInputStream(bundlePath));