diff --git a/Platform/Apple/tools/jace/src/main/java/jace/EmulatorUILogic.java b/Platform/Apple/tools/jace/src/main/java/jace/EmulatorUILogic.java index 8e959af1..7872f39b 100644 --- a/Platform/Apple/tools/jace/src/main/java/jace/EmulatorUILogic.java +++ b/Platform/Apple/tools/jace/src/main/java/jace/EmulatorUILogic.java @@ -18,10 +18,10 @@ */ package jace; -import com.sun.javafx.tk.quantum.OverlayWarning; import jace.apple2e.MOS65C02; import jace.apple2e.RAM128k; import jace.apple2e.SoftSwitches; +import jace.config.ConfigurableField; import jace.config.ConfigurationUIController; import jace.config.InvokableAction; import jace.config.Reconfigurable; @@ -82,6 +82,12 @@ public class EmulatorUILogic implements Reconfigurable { }; } + @ConfigurableField( + category = "General", + name = "Show Drives" + ) + public boolean showDrives = false; + public static void updateCPURegisters(MOS65C02 cpu) { // DebuggerPanel debuggerPanel = Emulator.getFrame().getDebuggerPanel(); // debuggerPanel.valueA.setText(Integer.toHexString(cpu.A)); diff --git a/Platform/Apple/tools/jace/src/main/java/jace/JaceUIController.java b/Platform/Apple/tools/jace/src/main/java/jace/JaceUIController.java index eb381ea6..812e6979 100644 --- a/Platform/Apple/tools/jace/src/main/java/jace/JaceUIController.java +++ b/Platform/Apple/tools/jace/src/main/java/jace/JaceUIController.java @@ -191,10 +191,13 @@ public class JaceUIController { private List getMediaConsumers() { List consumers = new ArrayList<>(); - for (Optional card : computer.memory.getAllCards()) { - card.filter(c -> c instanceof MediaConsumerParent).ifPresent(parent -> { - consumers.addAll(Arrays.asList(((MediaConsumerParent) parent).getConsumers())); - }); + consumers.add(Emulator.computer.getUpgradeHandler()); + if (Emulator.logic.showDrives) { + for (Optional card : computer.memory.getAllCards()) { + card.filter(c -> c instanceof MediaConsumerParent).ifPresent(parent -> { + consumers.addAll(Arrays.asList(((MediaConsumerParent) parent).getConsumers())); + }); + } } return consumers; } @@ -254,24 +257,25 @@ public class JaceUIController { public void removeMouseListener(EventHandler handler) { appleScreen.removeEventHandler(MouseEvent.ANY, handler); } - + Label currentNotification = null; + public void displayNotification(String message) { Label oldNotification = currentNotification; Label notification = new Label(message); currentNotification = notification; notification.setEffect(new DropShadow(2.0, Color.BLACK)); notification.setTextFill(Color.WHITE); - notification.setBackground(new Background(new BackgroundFill(Color.rgb(0,0,80, 0.7), new CornerRadii(5.0), new Insets(-5.0)))); - Application.invokeLater(() -> { + notification.setBackground(new Background(new BackgroundFill(Color.rgb(0, 0, 80, 0.7), new CornerRadii(5.0), new Insets(-5.0)))); + Application.invokeLater(() -> { stackPane.getChildren().remove(oldNotification); stackPane.getChildren().add(notification); }); - - notificationExecutor.schedule(()->{ - Application.invokeLater(() -> { + + notificationExecutor.schedule(() -> { + Application.invokeLater(() -> { stackPane.getChildren().remove(notification); - }); + }); }, 4, TimeUnit.SECONDS); } } diff --git a/Platform/Apple/tools/jace/src/main/java/jace/LawlessLegends.java b/Platform/Apple/tools/jace/src/main/java/jace/LawlessLegends.java index 23432118..d496a234 100644 --- a/Platform/Apple/tools/jace/src/main/java/jace/LawlessLegends.java +++ b/Platform/Apple/tools/jace/src/main/java/jace/LawlessLegends.java @@ -6,7 +6,6 @@ package jace; import jace.config.Configuration; -import jace.core.RAM; import jace.core.RAMEvent; import jace.core.RAMListener; import jace.core.Utility; @@ -17,17 +16,10 @@ import jace.hardware.CardRamworks; import jace.hardware.PassportMidiInterface; import jace.hardware.massStorage.CardMassStorage; import jace.lawless.LawlessHacks; +import jace.lawless.LawlessImageTool; import jace.lawless.LawlessVideo; -import jace.library.DiskType; -import jace.library.MediaEntry; -import jace.library.MediaEntry.MediaFile; import jace.ui.MetacheatUI; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; -import java.nio.file.StandardCopyOption; import java.util.logging.Level; import java.util.logging.Logger; import javafx.application.Application; @@ -168,87 +160,6 @@ public class LawlessLegends extends Application { Emulator.computer.cheatEngine.setValue(LawlessHacks.class); Configuration.buildTree(); Emulator.computer.reconfigure(); - RAM memory = Emulator.computer.memory; - - // Insert game disk image - MediaEntry e1 = new MediaEntry(); - e1.author = "8 Bit Bunch"; - e1.name = "Lawless Legends"; - e1.type = DiskType.LARGE; - MediaFile f1 = new MediaEntry.MediaFile(); - f1.path = getGamePath("game.2mg"); - - if (f1.path != null && f1.path.exists()) { - memory.getCard(7).ifPresent(card -> { - try { - ((CardMassStorage) card).currentDrive.insertMedia(e1, f1); - } catch (IOException ex) { - Logger.getLogger(LawlessLegends.class.getName()).log(Level.SEVERE, null, ex); - } - }); - } - - // Insert utility disk image - MediaEntry e2 = new MediaEntry(); - e2.author = "8 Bit Bunch"; - e2.name = "Lawless Legends Utilities"; - e2.type = DiskType.FLOPPY140_DO; - MediaFile f2 = new MediaEntry.MediaFile(); - f2.path = getGamePath("utilities.dsk"); - if (f2.path != null && f2.path.exists()) { - memory.getCard(6).ifPresent(card -> { - try { - ((CardDiskII) card).getConsumers()[0].insertMedia(e2, f2); - } catch (IOException ex) { - Logger.getLogger(LawlessLegends.class.getName()).log(Level.SEVERE, null, ex); - } - }); - } - } - - private File getGamePath(String filename) { - File base = getApplicationStoragePath(); - File target = new File(base, filename); - if (!target.exists()) { - copyResource(filename, target); - } - return target; - } - - private File getApplicationStoragePath() { - String path = System.getenv("APPDATA"); - if (path == null) { - path = System.getProperty("user.home"); - } - if (path == null) { - path = "."; - } - File base = new File(path); - File appPath = new File(base, "lawless-legends"); - appPath.mkdirs(); - return appPath; - } - - private void copyResource(String filename, File target) { - File localResource = new File(".", filename); - InputStream in = null; - if (localResource.exists()) { - try { - in = new FileInputStream(localResource); - } catch (FileNotFoundException ex) { - Logger.getLogger(LawlessLegends.class.getName()).log(Level.SEVERE, null, ex); - } - } else { - in = getClass().getClassLoader().getResourceAsStream("jace/data/" + filename); - } - if (in != null) { - try { - java.nio.file.Files.copy(in, target.toPath(), StandardCopyOption.REPLACE_EXISTING); - } catch (IOException ex) { - Logger.getLogger(LawlessLegends.class.getName()).log(Level.SEVERE, null, ex); - } - } else { - Logger.getLogger(LawlessLegends.class.getName()).log(Level.SEVERE, "Unable to find resource {0}", filename); - } + ((LawlessImageTool) Emulator.computer.getUpgradeHandler()).loadGame(); } } diff --git a/Platform/Apple/tools/jace/src/main/java/jace/core/Keyboard.java b/Platform/Apple/tools/jace/src/main/java/jace/core/Keyboard.java index e8c8fa51..e7cfb5ce 100644 --- a/Platform/Apple/tools/jace/src/main/java/jace/core/Keyboard.java +++ b/Platform/Apple/tools/jace/src/main/java/jace/core/Keyboard.java @@ -18,6 +18,7 @@ */ package jace.core; +import jace.Emulator; import jace.apple2e.SoftSwitches; import jace.config.InvokableAction; import jace.config.Reconfigurable; @@ -68,6 +69,7 @@ public class Keyboard implements Reconfigurable { return "kbd"; } static byte currentKey = 0; + public boolean shiftPressed = false; public static void clearStrobe() { currentKey = (byte) (currentKey & 0x07f); @@ -102,6 +104,7 @@ public class Keyboard implements Reconfigurable { registerKeyHandler(new KeyHandler(code) { @Override public boolean handleKeyUp(KeyEvent e) { + Emulator.computer.getKeyboard().shiftPressed = e.isShiftDown(); if (action == null || !action.notifyOnRelease()) { return false; } @@ -125,6 +128,7 @@ public class Keyboard implements Reconfigurable { @Override public boolean handleKeyDown(KeyEvent e) { // System.out.println("Key down: "+method.toString()); + Emulator.computer.getKeyboard().shiftPressed = e.isShiftDown(); Object returnValue = null; try { if (method.getParameterCount() > 0) { @@ -248,6 +252,7 @@ public class Keyboard implements Reconfigurable { default: } + Emulator.computer.getKeyboard().shiftPressed = e.isShiftDown(); if (e.isShiftDown()) { c = fixShiftedChar(c); } diff --git a/Platform/Apple/tools/jace/src/main/java/jace/core/Utility.java b/Platform/Apple/tools/jace/src/main/java/jace/core/Utility.java index e9335427..1e4c0c4a 100644 --- a/Platform/Apple/tools/jace/src/main/java/jace/core/Utility.java +++ b/Platform/Apple/tools/jace/src/main/java/jace/core/Utility.java @@ -33,18 +33,24 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; +import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicBoolean; 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; +import javafx.scene.control.ButtonType; import javafx.scene.control.ContentDisplay; import javafx.scene.control.Label; import javafx.scene.effect.DropShadow; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.paint.Color; + /** * This is a set of helper functions which do not belong anywhere else. * Functions vary from introspection, discovery, and string/pattern matching. @@ -52,7 +58,9 @@ import javafx.scene.paint.Color; * @author Brendan Robert (BLuRry) brendan.robert@gmail.com */ public class Utility { + static Reflections reflections = new Reflections("jace"); + public static Set findAllSubclasses(Class clazz) { return reflections.getSubTypesOf(clazz); } @@ -135,6 +143,7 @@ public class Utility { } private static boolean isHeadless = false; + public static void setHeadlessMode(boolean headless) { isHeadless = headless; } @@ -142,7 +151,7 @@ public class Utility { public static boolean isHeadlessMode() { return isHeadless; } - + public static Optional loadIcon(String filename) { if (isHeadless) { return Optional.empty(); @@ -181,6 +190,20 @@ public class Utility { return Optional.of(label); } + public static void confirm(String title, String message, Runnable accept) { + Platform.runLater(() -> { + Alert confirm = new Alert(Alert.AlertType.CONFIRMATION); + confirm.setContentText(message); + confirm.setTitle(title); + Optional response = confirm.showAndWait(); + response.ifPresent(b -> { + if (b.getButtonData().isDefaultButton()) { + (new Thread(accept)).start(); + } + }); + }); + } + // public static void runModalProcess(String title, final Runnable runnable) { //// final JDialog frame = new JDialog(Emulator.getFrame()); // final JProgressBar progressBar = new JProgressBar(); @@ -201,7 +224,6 @@ public class Utility { // frame.dispose(); // }).start(); // } - public static class RankingComparator implements Comparator { String match; diff --git a/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessComputer.java b/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessComputer.java index 6fa62250..3ff68437 100644 --- a/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessComputer.java +++ b/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessComputer.java @@ -1,11 +1,14 @@ package jace.lawless; +import jace.Emulator; import jace.apple2e.Apple2e; import jace.apple2e.RAM128k; import jace.apple2e.SoftSwitches; import jace.apple2e.VideoNTSC; +import jace.config.ConfigurableField; import jace.core.Card; import jace.core.Video; +import jace.library.MediaConsumer; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -23,7 +26,8 @@ public class LawlessComputer extends Apple2e { byte[] bootScreen = null; boolean performedBootAnimation = false; - + LawlessImageTool gameDiskHandler = new LawlessImageTool(); + public LawlessComputer() { super(); // Fill text page 1 with spaces @@ -118,7 +122,7 @@ public class LawlessComputer extends Apple2e { } } - List vblCallbacks = Collections.synchronizedList(new ArrayList()); + List vblCallbacks = Collections.synchronizedList(new ArrayList<>()); public void waitForVBL() throws InterruptedException { waitForVBL(0); @@ -141,8 +145,7 @@ public class LawlessComputer extends Apple2e { public void notifyVBLStateChanged(boolean state) { super.notifyVBLStateChanged(state); if (state) { - Runnable r; - while (!vblCallbacks.isEmpty()) { + while (vblCallbacks != null && !vblCallbacks.isEmpty()) { vblCallbacks.remove(0).run(); } } @@ -178,4 +181,7 @@ public class LawlessComputer extends Apple2e { return bootScreen; } + public MediaConsumer getUpgradeHandler() { + return gameDiskHandler; + } } diff --git a/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessImageTool.java b/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessImageTool.java new file mode 100644 index 00000000..b4f53ac8 --- /dev/null +++ b/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessImageTool.java @@ -0,0 +1,223 @@ +package jace.lawless; + +import jace.Emulator; +import jace.LawlessLegends; +import jace.apple2e.RAM128k; +import jace.core.Keyboard; +import jace.core.RAM; +import jace.core.Utility; +import jace.hardware.massStorage.CardMassStorage; +import jace.library.DiskType; +import jace.library.MediaConsumer; +import jace.library.MediaEntry; +import jace.library.MediaEntry.MediaFile; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.StandardCopyOption; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.logging.Level; +import java.util.logging.Logger; +import javafx.scene.control.Label; + +/** + * + * @author brobert + */ +public class LawlessImageTool implements MediaConsumer { + + Optional