From 7668e723ec3f1065a8385a24c0190373c49e9848 Mon Sep 17 00:00:00 2001 From: Brendan Robert Date: Fri, 20 May 2016 23:50:38 -0500 Subject: [PATCH] Mass storage supports command-line settings now. For example -s7.d1 myDisk.2mg will insert the 800k or hard drive image into Slot 7, Drive 1. --- src/main/java/jace/config/Configuration.java | 2 +- src/main/java/jace/core/Utility.java | 153 +----------------- .../hardware/massStorage/CardMassStorage.java | 32 +++- 3 files changed, 33 insertions(+), 154 deletions(-) diff --git a/src/main/java/jace/config/Configuration.java b/src/main/java/jace/config/Configuration.java index ee4de17..16fd22e 100644 --- a/src/main/java/jace/config/Configuration.java +++ b/src/main/java/jace/config/Configuration.java @@ -598,7 +598,7 @@ public class Configuration implements Reconfigurable { } } if (!found) { - System.err.println("Unable to find property " + fieldName + " for device " + deviceName + ". Try one of these :" + Utility.join(shortFieldNames, ", ")); + System.err.println("Unable to find property " + fieldName + " for device " + deviceName + ". Try one of these: " + Utility.join(shortFieldNames, ", ")); } } } diff --git a/src/main/java/jace/core/Utility.java b/src/main/java/jace/core/Utility.java index 280102f..e933542 100644 --- a/src/main/java/jace/core/Utility.java +++ b/src/main/java/jace/core/Utility.java @@ -35,6 +35,7 @@ import java.util.Optional; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Collectors; import javafx.application.Platform; import javafx.geometry.Pos; import javafx.scene.control.Alert; @@ -51,152 +52,10 @@ import javafx.scene.paint.Color; * @author Brendan Robert (BLuRry) brendan.robert@gmail.com */ public class Utility { - - //--------------- Introspection utilities - /* - private static Set findClasses(String pckgname, Class clazz) { - Set output = new HashSet<>(); - // Code from JWhich - // ====== - // Translate the package name into an absolute path - String name = pckgname; - if (!name.startsWith("/")) { - name = "/" + name; - } - name = name.replace('.', '/'); - - // Get a File object for the package - URL url = Utility.class.getResource(name); - if (url == null || url.getFile().contains("jre/lib")) { - return output; - } - if (url.getProtocol().equalsIgnoreCase("jar")) { - return findClassesInJar(url, clazz); - } - - File directory = new File(url.getFile()); - // New code - // ====== - if (directory.exists()) { - // Get the list of the files contained in the package - for (String filename : directory.list()) { - char firstLetter = filename.charAt(0); - if (firstLetter < 'A' || (firstLetter > 'Z' && firstLetter < 'a') || firstLetter > 'z') { - continue; - } - // we are only interested in .class files - if (filename.endsWith(".class")) { - // removes the .class extension - String classname = filename.substring(0, filename.length() - 6); - try { - // Try to create an instance of the object - String className = pckgname + "." + classname; - Class c = Class.forName(className); - if (clazz.isAssignableFrom(c)) { - output.add(c); - } - } catch (Throwable ex) { - System.err.println(ex); - } - } else { -// System.out.println("Skipping non class: " + filename); - } - } - } - return output; - } - - private static Set findClassesInJar(URL jarLocation, Class clazz) { - Set output = new HashSet<>(); - JarFile jarFile = null; - try { - JarURLConnection conn = (JarURLConnection) jarLocation.openConnection(); - jarFile = conn.getJarFile(); - Enumeration entries = jarFile.entries(); - String last = ""; - while (entries.hasMoreElements()) { - JarEntry jarEntry = entries.nextElement(); - if (jarEntry.getName().equals(last)) { - return output; - } - last = jarEntry.getName(); - if (jarEntry.getName().endsWith(".class")) { - String className = jarEntry.getName(); - className = className.substring(0, className.length() - 6); - className = className.replaceAll("/", "\\."); - if (className.startsWith("com.sun")) { - continue; - } - if (className.startsWith("java")) { - continue; - } - if (className.startsWith("javax")) { - continue; - } - if (className.startsWith("com.oracle")) { - continue; - } - // removes the .class extension - try { - // Try to create an instance of the object -// System.out.println("Class: " + className); - Class c = Class.forName(className); - if (clazz.isAssignableFrom(c)) { - output.add(c); - } - } catch (ClassNotFoundException cnfex) { - System.err.println(cnfex); - } catch (Throwable cnfex) { -// System.err.println(cnfex); - } - } else { -// System.out.println("Skipping non class: " + jarEntry.getName()); - } - } - } catch (IOException ex) { - Logger.getLogger(Utility.class.getName()).log(Level.SEVERE, null, ex); - } finally { - try { - if (jarFile != null) { - jarFile.close(); - } - } catch (IOException ex) { - Logger.getLogger(Utility.class.getName()).log(Level.SEVERE, null, ex); - } - } - return output; - } - private static final Map> classCache = new HashMap<>(); -*/ static Reflections reflections = new Reflections("jace"); public static Set findAllSubclasses(Class clazz) { return reflections.getSubTypesOf(clazz); } - /* - public static List findAllSubclasses(Class clazz) { - if (classCache.containsKey(clazz)) { - return (List) classCache.get(clazz); - } - TreeMap allClasses = new TreeMap<>(); - List values = new ArrayList(allClasses.values()); - classCache.put(clazz, values); - for (Package p : Package.getPackages()) { - if (p.getName().startsWith("java") - || p.getName().startsWith("com.sun") - || p.getName().startsWith("sun") - || p.getName().startsWith("com.oracle")) { - continue; - } - findClasses(p.getName(), clazz) - .stream() - .filter((c) -> !(Modifier.isAbstract(c.getModifiers()))) - .forEach((c) -> { - allClasses.put(c.getSimpleName(), c); - }); - } - return values; - } - */ //------------------------------ String comparators /** @@ -271,14 +130,8 @@ public class Utility { return score * adjustment * adjustment; } - public static String join(Collection c, String d) { - String result = ""; - boolean isFirst = true; - for (Object o : c) { - result += (isFirst ? "" : d) + o.toString(); - isFirst = false; - } - return result; + public static String join(Collection c, String d) { + return c.stream().collect(Collectors.joining(d)); } private static boolean isHeadless = false; diff --git a/src/main/java/jace/hardware/massStorage/CardMassStorage.java b/src/main/java/jace/hardware/massStorage/CardMassStorage.java index 20beab2..da8a196 100644 --- a/src/main/java/jace/hardware/massStorage/CardMassStorage.java +++ b/src/main/java/jace/hardware/massStorage/CardMassStorage.java @@ -20,6 +20,7 @@ package jace.hardware.massStorage; import jace.EmulatorUILogic; import jace.apple2e.MOS65C02; +import jace.config.ConfigurableField; import jace.config.Name; import jace.core.Card; import jace.core.Computer; @@ -28,8 +29,11 @@ import jace.core.RAMEvent.TYPE; import jace.core.Utility; import jace.hardware.ProdosDriver; import jace.hardware.SmartportDriver; +import jace.library.MediaCache; import jace.library.MediaConsumer; import jace.library.MediaConsumerParent; +import jace.library.MediaEntry; +import java.io.File; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; @@ -43,6 +47,10 @@ import java.util.logging.Logger; @Name("Mass Storage Device") public class CardMassStorage extends Card implements MediaConsumerParent { + @ConfigurableField(category = "Disk", defaultValue = "", shortName = "d1", name = "Drive 1 disk image", description = "Path of disk 1") + public String disk1; + @ConfigurableField(category = "Disk", defaultValue = "", shortName = "d2", name = "Drive 2 disk image", description = "Path of disk 2") + public String disk2; MassStorageDrive drive1; MassStorageDrive drive2; @@ -59,8 +67,8 @@ public class CardMassStorage extends Card implements MediaConsumerParent { @Override public void setSlot(int slot) { super.setSlot(slot); - drive1.getIcon().ifPresent(icon->icon.setText("S" + getSlot() + "D1")); - drive2.getIcon().ifPresent(icon->icon.setText("S" + getSlot() + "D2")); + drive1.getIcon().ifPresent(icon -> icon.setText("S" + getSlot() + "D1")); + drive2.getIcon().ifPresent(icon -> icon.setText("S" + getSlot() + "D2")); } @Override @@ -128,10 +136,28 @@ public class CardMassStorage extends Card implements MediaConsumerParent { @Override public void reconfigure() { unregisterListeners(); + if (disk1 != null && !disk1.isEmpty()) { + try { + MediaEntry entry = MediaCache.getMediaFromFile(new File(disk1)); + drive1.insertMedia(entry, entry.files.get(0)); + disk1 = null; + } catch (IOException ex) { + Logger.getLogger(CardMassStorage.class.getName()).log(Level.SEVERE, null, ex); + } + } + if (disk2 != null && !disk2.isEmpty()) { + try { + MediaEntry entry = MediaCache.getMediaFromFile(new File(disk2)); + drive2.insertMedia(entry, entry.files.get(0)); + disk2 = null; + } catch (IOException ex) { + Logger.getLogger(CardMassStorage.class.getName()).log(Level.SEVERE, null, ex); + } + } if (computer.getCpu() != null) { int pc = computer.getCpu().getProgramCounter(); if (drive1.getCurrentDisk() != null && getSlot() == 7 && (pc >= 0x0c65e && pc <= 0x0c66F)) { - // If the computer is in a loop trying to boot from cards 6, fast-boot from here instead + // If the computer is in a loop trying to boot from cards 6, fast-boot from here instead // This is a convenience to boot a hard-drive if the emulator has started waiting for a currentDisk currentDrive = drive1; EmulatorUILogic.simulateCtrlAppleReset();