From 0ccb63558f0f01c2086d9b57d61dd56af1abb162 Mon Sep 17 00:00:00 2001 From: Brendan Robert Date: Tue, 3 Feb 2015 00:55:25 -0600 Subject: [PATCH] A lot of things have been deactivated to sever the link to the old Swing UI. Indicators, namely, have been commented out in many places. Ultimately the emulator is wholly unusable in this state. The video rendering was re-written to use writableImages and is displaying (something) but keyboard input and configurations are broken so nothing much happens after the inital boot. Basically the underlying part to make this show up in JavaFX is starting to take shape. --- .gitignore | 3 +- src/main/java/jace/Emulator.java | 160 +++++++------- src/main/java/jace/EmulatorUILogic.java | 156 +++++++------- src/main/java/jace/JaceApplication.java | 8 + src/main/java/jace/JaceUIController.java | 16 +- src/main/java/jace/apple2e/Apple2e.java | 2 - src/main/java/jace/apple2e/VideoDHGR.java | 198 +++++++++--------- src/main/java/jace/apple2e/VideoNTSC.java | 58 ++--- src/main/java/jace/core/Palette.java | 34 +-- src/main/java/jace/core/Utility.java | 30 +-- src/main/java/jace/core/Video.java | 40 ++-- src/main/java/jace/core/VideoWriter.java | 4 +- .../java/jace/hardware/CardAppleMouse.java | 34 +-- src/main/java/jace/hardware/CardDiskII.java | 8 +- .../java/jace/hardware/CardRamFactor.java | 2 +- src/main/java/jace/hardware/CardSSC.java | 4 +- .../java/jace/hardware/CardThunderclock.java | 4 +- .../hardware/massStorage/CardMassStorage.java | 2 +- src/main/java/jace/library/MediaEditUI.java | 4 +- .../java/jace/library/MediaLibraryUI.form | 2 +- .../java/jace/library/MediaLibraryUI.java | 20 +- src/main/java/jace/state/State.java | 4 +- src/main/java/jace/state/StateManager.java | 11 +- .../java/jace/ui/AbstractEmulatorFrame.java | 4 +- src/main/resources/fxml/JaceUI.fxml | 5 +- target/classes/fxml/JaceUI.fxml | 5 +- target/maven-archiver/pom.properties | 2 +- .../compile/default-compile/createdFiles.lst | 2 - 28 files changed, 416 insertions(+), 406 deletions(-) diff --git a/.gitignore b/.gitignore index 1213193..7f30f15 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* /jace/nbproject/private/ -/jace/target/ \ No newline at end of file +/jace/target/ +*.jace.conf diff --git a/src/main/java/jace/Emulator.java b/src/main/java/jace/Emulator.java index ddff938..fb1209b 100644 --- a/src/main/java/jace/Emulator.java +++ b/src/main/java/jace/Emulator.java @@ -49,13 +49,6 @@ public class Emulator { instance = new Emulator(args); } - public static AbstractEmulatorFrame getFrame() { - if (instance != null) { - return instance.theApp; - } else { - return null; - } - } public static Apple2e computer; public AbstractEmulatorFrame theApp; @@ -90,90 +83,91 @@ public class Emulator { Configuration.applySettings(settings); // theApp = new MainFrame(); - theApp = new EmulatorFrame(computer); - try { - theApp.setIconImage(ImageIO.read(Emulator.class.getClassLoader().getResourceAsStream("jace/data/woz_figure.gif"))); - } catch (IOException ex) { - Logger.getLogger(Emulator.class.getName()).log(Level.SEVERE, null, ex); - } - //theApp.setBounds(new Rectangle((140*6),(192*3))); - theApp.setVisible(true); - theApp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - theApp.setFocusTraversalKeysEnabled(false); - theApp.setTitle("Java Apple Computer Emulator"); - theApp.addKeyListener(computer.getKeyboard().getListener()); - theApp.addComponentListener(new ComponentListener() { - // theApp.screen.addComponentListener(new ComponentListener() { - @Override - public void componentResized(ComponentEvent e) { -// System.out.println("Screen resized"); - resizeVideo(); - } - - @Override - public void componentMoved(ComponentEvent e) { - resizeVideo(); - } - - @Override - public void componentShown(ComponentEvent e) { - } - - @Override - public void componentHidden(ComponentEvent e) { - } - }); - theApp.addWindowListener(new WindowListener() { - @Override - public void windowOpened(WindowEvent e) { - } - - @Override - public void windowClosing(WindowEvent e) { - } - - @Override - public void windowClosed(WindowEvent e) { - } - - @Override - public void windowIconified(WindowEvent e) { - computer.getVideo().suspend(); - } - - @Override - public void windowDeiconified(WindowEvent e) { - computer.getVideo().resume(); - resizeVideo(); - } - - @Override - public void windowActivated(WindowEvent e) { - resizeVideo(); - } - - @Override - public void windowDeactivated(WindowEvent e) { - resizeVideo(); - } - }); +// theApp = new EmulatorFrame(computer); +// try { +// theApp.setIconImage(ImageIO.read(Emulator.class.getClassLoader().getResourceAsStream("jace/data/woz_figure.gif"))); +// } catch (IOException ex) { +// Logger.getLogger(Emulator.class.getName()).log(Level.SEVERE, null, ex); +// } +// //theApp.setBounds(new Rectangle((140*6),(192*3))); +// theApp.setVisible(true); +// theApp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); +// theApp.setFocusTraversalKeysEnabled(false); +// theApp.setTitle("Java Apple Computer Emulator"); +// theApp.addKeyListener(computer.getKeyboard().getListener()); +// theApp.addComponentListener(new ComponentListener() { +// // theApp.screen.addComponentListener(new ComponentListener() { +// @Override +// public void componentResized(ComponentEvent e) { +//// System.out.println("Screen resized"); +// resizeVideo(); +// } +// +// @Override +// public void componentMoved(ComponentEvent e) { +// resizeVideo(); +// } +// +// @Override +// public void componentShown(ComponentEvent e) { +// } +// +// @Override +// public void componentHidden(ComponentEvent e) { +// } +// }); +// theApp.addWindowListener(new WindowListener() { +// @Override +// public void windowOpened(WindowEvent e) { +// } +// +// @Override +// public void windowClosing(WindowEvent e) { +// } +// +// @Override +// public void windowClosed(WindowEvent e) { +// } +// +// @Override +// public void windowIconified(WindowEvent e) { +// computer.getVideo().suspend(); +// } +// +// @Override +// public void windowDeiconified(WindowEvent e) { +// computer.getVideo().resume(); +// resizeVideo(); +// } +// +// @Override +// public void windowActivated(WindowEvent e) { +// resizeVideo(); +// } +// +// @Override +// public void windowDeactivated(WindowEvent e) { +// resizeVideo(); +// } +// }); EmulatorUILogic.registerDebugger(); - computer.getVideo().setScreen(theApp.getScreenGraphics()); +// computer.getVideo().setScreen(theApp.getScreenGraphics()); computer.coldStart(); } public static void resizeVideo() { - AbstractEmulatorFrame window = getFrame(); - if (window != null) { - window.resizeVideo(); - } +// AbstractEmulatorFrame window = getFrame(); +// if (window != null) { +// window.resizeVideo(); +// } } public static Component getScreen() { - AbstractEmulatorFrame window = getFrame(); - if (window != null) { - return window.getScreen(); - } return null; +// AbstractEmulatorFrame window = getFrame(); +// if (window != null) { +// return window.getScreen(); +// } +// return null; } } \ No newline at end of file diff --git a/src/main/java/jace/EmulatorUILogic.java b/src/main/java/jace/EmulatorUILogic.java index 4df837d..be1fc13 100644 --- a/src/main/java/jace/EmulatorUILogic.java +++ b/src/main/java/jace/EmulatorUILogic.java @@ -33,6 +33,7 @@ import jace.library.MediaLibrary; import jace.ui.AbstractEmulatorFrame; import jace.ui.DebuggerPanel; import java.awt.Color; +import java.awt.Graphics2D; import java.awt.HeadlessException; import java.awt.image.BufferedImage; import java.io.File; @@ -44,6 +45,9 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; +import javafx.scene.image.WritableImage; import javax.imageio.ImageIO; import javax.swing.JFileChooser; import javax.swing.JLabel; @@ -75,22 +79,22 @@ public class EmulatorUILogic { } public static void updateCPURegisters(MOS65C02 cpu) { - DebuggerPanel debuggerPanel = Emulator.getFrame().getDebuggerPanel(); - debuggerPanel.valueA.setText(Integer.toHexString(cpu.A)); - debuggerPanel.valueX.setText(Integer.toHexString(cpu.X)); - debuggerPanel.valueY.setText(Integer.toHexString(cpu.Y)); - debuggerPanel.valuePC.setText(Integer.toHexString(cpu.getProgramCounter())); - debuggerPanel.valueSP.setText(Integer.toHexString(cpu.getSTACK())); - debuggerPanel.valuePC2.setText(cpu.getFlags()); - debuggerPanel.valueINST.setText(cpu.disassemble()); +// DebuggerPanel debuggerPanel = Emulator.getFrame().getDebuggerPanel(); +// debuggerPanel.valueA.setText(Integer.toHexString(cpu.A)); +// debuggerPanel.valueX.setText(Integer.toHexString(cpu.X)); +// debuggerPanel.valueY.setText(Integer.toHexString(cpu.Y)); +// debuggerPanel.valuePC.setText(Integer.toHexString(cpu.getProgramCounter())); +// debuggerPanel.valueSP.setText(Integer.toHexString(cpu.getSTACK())); +// debuggerPanel.valuePC2.setText(cpu.getFlags()); +// debuggerPanel.valueINST.setText(cpu.disassemble()); } public static void enableDebug(boolean b) { - DebuggerPanel debuggerPanel = Emulator.getFrame().getDebuggerPanel(); - debugger.setActive(b); - debuggerPanel.enableDebug.setSelected(b); - debuggerPanel.setBackground( - b ? Color.RED : new Color(0, 0, 0x040)); +// DebuggerPanel debuggerPanel = Emulator.getFrame().getDebuggerPanel(); +// debugger.setActive(b); +// debuggerPanel.enableDebug.setSelected(b); +// debuggerPanel.setBackground( +// b ? Color.RED : new Color(0, 0, 0x040)); } public static void enableTrace(boolean b) { @@ -187,13 +191,13 @@ public class EmulatorUILogic { @InvokableAction( name = "BRUN file", - category = "file", - description = "Loads a binary file in memory and executes it. File should end with #06xxxx, where xxxx is the start address in hex", - alternatives = "Execute program;Load binary;Load program;Load rom;Play single-load game") + category = "file", + description = "Loads a binary file in memory and executes it. File should end with #06xxxx, where xxxx is the start address in hex", + alternatives = "Execute program;Load binary;Load program;Load rom;Play single-load game") public static void runFile() { Emulator.computer.pause(); JFileChooser select = new JFileChooser(); - select.showDialog(Emulator.getFrame(), "Execute binary file"); +// select.showDialog(Emulator.getFrame(), "Execute binary file"); File binary = select.getSelectedFile(); if (binary == null) { Emulator.computer.resume(); @@ -237,49 +241,49 @@ public class EmulatorUILogic { @InvokableAction( name = "Adjust display", - category = "display", - description = "Adjusts window size to 1:1 aspect ratio for optimal viewing.", - alternatives = "Adjust screen;Adjust window size;Adjust aspect ratio;Fix screen;Fix window size;Fix aspect ratio;Correct aspect ratio;") + category = "display", + description = "Adjusts window size to 1:1 aspect ratio for optimal viewing.", + alternatives = "Adjust screen;Adjust window size;Adjust aspect ratio;Fix screen;Fix window size;Fix aspect ratio;Correct aspect ratio;") static public void scaleIntegerRatio() { - AbstractEmulatorFrame frame = Emulator.getFrame(); - if (frame == null) { - return; - } - Emulator.computer.pause(); - frame.enforceIntegerRatio(); - Emulator.computer.resume(); +// AbstractEmulatorFrame frame = Emulator.getFrame(); +// if (frame == null) { +// return; +// } +// Emulator.computer.pause(); +// frame.enforceIntegerRatio(); +// Emulator.computer.resume(); } @InvokableAction( name = "Toggle Debug", - category = "debug", - description = "Show/hide the debug panel", - alternatives = "Show Debug;Hide Debug") + category = "debug", + description = "Show/hide the debug panel", + alternatives = "Show Debug;Hide Debug") public static void toggleDebugPanel() { - AbstractEmulatorFrame frame = Emulator.getFrame(); - if (frame == null) { - return; - } - frame.setShowDebug(!frame.isShowDebug()); - frame.reconfigure(); - Emulator.resizeVideo(); +// AbstractEmulatorFrame frame = Emulator.getFrame(); +// if (frame == null) { +// return; +// } +// frame.setShowDebug(!frame.isShowDebug()); +// frame.reconfigure(); +// Emulator.resizeVideo(); } public static void toggleFullscreen() { - AbstractEmulatorFrame frame = Emulator.getFrame(); - if (frame == null) { - return; - } - Emulator.computer.pause(); - frame.toggleFullscreen(); - Emulator.computer.resume(); +// AbstractEmulatorFrame frame = Emulator.getFrame(); +// if (frame == null) { +// return; +// } +// Emulator.computer.pause(); +// frame.toggleFullscreen(); +// Emulator.computer.resume(); } @InvokableAction( name = "Save Raw Screenshot", - category = "general", - description = "Save raw (RAM) format of visible screen", - alternatives = "screendump, raw screenshot") + category = "general", + description = "Save raw (RAM) format of visible screen", + alternatives = "screendump, raw screenshot") public static void saveScreenshotRaw() throws FileNotFoundException, IOException { SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss"); String timestamp = df.format(new Date()); @@ -317,16 +321,15 @@ public class EmulatorUILogic { @InvokableAction( name = "Save Screenshot", - category = "general", - description = "Save image of visible screen", - alternatives = "Save image,save framebuffer,screenshot") + category = "general", + description = "Save image of visible screen", + alternatives = "Save image,save framebuffer,screenshot") public static void saveScreenshot() throws HeadlessException, IOException { JFileChooser select = new JFileChooser(); Emulator.computer.pause(); - BufferedImage i = Emulator.computer.getVideo().getFrameBuffer(); - BufferedImage j = new BufferedImage(i.getWidth(), i.getHeight(), i.getType()); - j.getGraphics().drawImage(i, 0, 0, null); - select.showSaveDialog(Emulator.getFrame()); + Image i = Emulator.computer.getVideo().getFrameBuffer(); + BufferedImage bufImageARGB = SwingFXUtils.fromFXImage(i, null); +// select.showSaveDialog(Emulator.getFrame()); File targetFile = select.getSelectedFile(); if (targetFile == null) { return; @@ -334,38 +337,47 @@ public class EmulatorUILogic { String filename = targetFile.getName(); System.out.println("Writing screenshot to " + filename); String extension = filename.substring(filename.lastIndexOf(".") + 1); - ImageIO.write(j, extension, targetFile); + BufferedImage bufImageRGB = new BufferedImage(bufImageARGB.getWidth(), bufImageARGB.getHeight(), BufferedImage.OPAQUE); + + Graphics2D graphics = bufImageRGB.createGraphics(); + graphics.drawImage(bufImageARGB, 0, 0, null); + + ImageIO.write(bufImageRGB, extension, targetFile); + graphics.dispose(); } public static final String CONFIGURATION_DIALOG_NAME = "Configuration"; + @InvokableAction( name = "Configuration", - category = "general", - description = "Edit emulator configuraion", - alternatives = "Reconfigure,Preferences,Settings") + category = "general", + description = "Edit emulator configuraion", + alternatives = "Reconfigure,Preferences,Settings") public static void showConfig() { - if (Emulator.getFrame().getModalDialogUI(CONFIGURATION_DIALOG_NAME) == null) { - JPanel ui = new ConfigurationPanel(); - Emulator.getFrame().registerModalDialog(ui, CONFIGURATION_DIALOG_NAME, null, false); - } - Emulator.getFrame().showDialog(CONFIGURATION_DIALOG_NAME); +// if (Emulator.getFrame().getModalDialogUI(CONFIGURATION_DIALOG_NAME) == null) { +// JPanel ui = new ConfigurationPanel(); +// Emulator.getFrame().registerModalDialog(ui, CONFIGURATION_DIALOG_NAME, null, false); +// } +// Emulator.getFrame().showDialog(CONFIGURATION_DIALOG_NAME); } public static final String MEDIA_MANAGER_DIALOG_NAME = "Media Manager"; public static final String MEDIA_MANAGER_EDIT_DIALOG_NAME = "Media Details"; + @InvokableAction( name = "Media Manager", - category = "general", - description = "Show the media manager", - alternatives = "Insert disk;Eject disk;Browse;Download;Select") + category = "general", + description = "Show the media manager", + alternatives = "Insert disk;Eject disk;Browse;Download;Select") public static void showMediaManager() { - if (Emulator.getFrame().getModalDialogUI(MEDIA_MANAGER_DIALOG_NAME) == null) { - Emulator.getFrame().registerModalDialog(MediaLibrary.getInstance().buildUserInterface(), MEDIA_MANAGER_DIALOG_NAME, null, false); - } - Emulator.getFrame().showDialog(MEDIA_MANAGER_DIALOG_NAME); +// if (Emulator.getFrame().getModalDialogUI(MEDIA_MANAGER_DIALOG_NAME) == null) { +// Emulator.getFrame().registerModalDialog(MediaLibrary.getInstance().buildUserInterface(), MEDIA_MANAGER_DIALOG_NAME, null, false); +// } +// Emulator.getFrame().showDialog(MEDIA_MANAGER_DIALOG_NAME); } public static boolean confirm(String message) { - return JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(Emulator.getFrame(), message); +// return JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(Emulator.getFrame(), message); + return false; } -} \ No newline at end of file +} diff --git a/src/main/java/jace/JaceApplication.java b/src/main/java/jace/JaceApplication.java index 2185e23..9503687 100644 --- a/src/main/java/jace/JaceApplication.java +++ b/src/main/java/jace/JaceApplication.java @@ -31,6 +31,7 @@ public class JaceApplication extends Application { try { AnchorPane node = (AnchorPane) fxmlLoader.load(); controller = fxmlLoader.getController(); + controller.initialize(); Scene s = new Scene(node); primaryStage.setScene(s); } catch (IOException exception) { @@ -38,6 +39,13 @@ public class JaceApplication extends Application { } primaryStage.show(); + Emulator e = new Emulator(); + javafx.application.Platform.runLater(() -> { + while (Emulator.computer.getVideo() == null || Emulator.computer.getVideo().getFrameBuffer() == null) { + Thread.yield(); + } + controller.connectScreen(Emulator.computer.getVideo()); + }); } /** diff --git a/src/main/java/jace/JaceUIController.java b/src/main/java/jace/JaceUIController.java index 1cc3407..b21413b 100644 --- a/src/main/java/jace/JaceUIController.java +++ b/src/main/java/jace/JaceUIController.java @@ -6,11 +6,11 @@ package jace; +import jace.core.Video; import javafx.scene.canvas.Canvas; -import java.net.URL; import java.util.ResourceBundle; import javafx.fxml.FXML; -import javafx.fxml.Initializable; +import javafx.scene.image.ImageView; import javafx.scene.layout.Region; /** @@ -21,18 +21,20 @@ public class JaceUIController { @FXML private ResourceBundle resources; - @FXML - private Canvas displayCanvas; - @FXML private Region notificationRegion; + + @FXML + private ImageView appleScreen; @FXML public void initialize() { - assert displayCanvas != null : "fx:id=\"displayCanvas\" was not injected: check your FXML file 'JaceUI.fxml'."; assert notificationRegion != null : "fx:id=\"notificationRegion\" was not injected: check your FXML file 'JaceUI.fxml'."; + assert appleScreen != null : "fx:id=\"appleScreen\" was not injected: check your FXML file 'JaceUI.fxml'."; } - + public void connectScreen(Video video) { + appleScreen.setImage(video.getFrameBuffer()); + } } diff --git a/src/main/java/jace/apple2e/Apple2e.java b/src/main/java/jace/apple2e/Apple2e.java index 35d1e21..b828d71 100644 --- a/src/main/java/jace/apple2e/Apple2e.java +++ b/src/main/java/jace/apple2e/Apple2e.java @@ -237,13 +237,11 @@ public class Apple2e extends Computer { Graphics g = null; if (getVideo() != null) { getVideo().suspend(); - g = getVideo().getScreen(); } try { setVideo((Video) videoRenderer.getValue().getConstructor(Computer.class).newInstance(this)); getVideo().configureVideoMode(); getVideo().reconfigure(); - getVideo().setScreen(g); Emulator.resizeVideo(); getVideo().resume(); } catch (InstantiationException | IllegalAccessException ex) { diff --git a/src/main/java/jace/apple2e/VideoDHGR.java b/src/main/java/jace/apple2e/VideoDHGR.java index a0c3ea4..3e76829 100644 --- a/src/main/java/jace/apple2e/VideoDHGR.java +++ b/src/main/java/jace/apple2e/VideoDHGR.java @@ -25,10 +25,10 @@ import jace.core.RAMEvent; import jace.core.RAMListener; import jace.core.Video; import jace.core.VideoWriter; -import java.awt.Color; -import java.awt.image.BufferedImage; -import java.awt.image.DataBuffer; import java.util.logging.Logger; +import javafx.scene.image.PixelWriter; +import javafx.scene.image.WritableImage; +import javafx.scene.paint.Color; /** * This is the primary video rendering class, which provides all necessary video @@ -36,7 +36,7 @@ import java.util.logging.Logger; * configureVideoMode). The quality of the color rendering is sub-par compared * to VideoNTSC. * - * @author Brendan Robert (BLuRry) brendan.robert@gmail.com + * @author Brendan Robert (BLuRry) brendan.robert@gmail.com */ public class VideoDHGR extends Video { // Reorder bits 3,2,1,0 -> 0,3,2,1 @@ -79,7 +79,7 @@ public class VideoDHGR extends Video { } @Override - public void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { + public void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { displayHires(screen, xOffset, y, yGraphicsOffset + 0x02000); } }; @@ -90,7 +90,7 @@ public class VideoDHGR extends Video { } @Override - public void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { + public void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { displayHires(screen, xOffset, y, yGraphicsOffset + 0x04000); } }; @@ -101,7 +101,7 @@ public class VideoDHGR extends Video { } @Override - public void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { + public void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { displayDoubleHires(screen, xOffset, y, yGraphicsOffset + 0x02000); } @@ -117,7 +117,7 @@ public class VideoDHGR extends Video { } @Override - public void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { + public void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { displayDoubleHires(screen, xOffset, y, yGraphicsOffset + 0x04000); } @@ -133,7 +133,7 @@ public class VideoDHGR extends Video { } @Override - public void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { + public void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { displayText(screen, xOffset, y, yTextOffset + 0x0400); } }; @@ -144,7 +144,7 @@ public class VideoDHGR extends Video { } @Override - public void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { + public void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { displayText(screen, xOffset, y, yTextOffset + 0x0800); } }; @@ -155,7 +155,7 @@ public class VideoDHGR extends Video { } @Override - public void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { + public void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { displayText80(screen, xOffset, y, yTextOffset + 0x0400); } @@ -171,7 +171,7 @@ public class VideoDHGR extends Video { } @Override - public void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { + public void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { displayText80(screen, xOffset, y, yTextOffset + 0x0800); } @@ -187,7 +187,7 @@ public class VideoDHGR extends Video { } @Override - public void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { + public void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { displayLores(screen, xOffset, y, yTextOffset + 0x0400); } @@ -203,7 +203,7 @@ public class VideoDHGR extends Video { } @Override - public void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { + public void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { displayLores(screen, xOffset, y, yTextOffset + 0x0800); } @@ -219,7 +219,7 @@ public class VideoDHGR extends Video { } @Override - public void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { + public void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { displayDoubleLores(screen, xOffset, y, yTextOffset + 0x0400); } @@ -235,7 +235,7 @@ public class VideoDHGR extends Video { } @Override - public void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { + public void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { displayDoubleLores(screen, xOffset, y, yTextOffset + 0x0800); } @@ -251,7 +251,7 @@ public class VideoDHGR extends Video { } @Override - public void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { + public void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset) { displayMixed(screen, xOffset, y, yTextOffset, yGraphicsOffset); } @@ -288,7 +288,7 @@ public class VideoDHGR extends Video { // color burst per byte (chat mauve compatibility) boolean[] useColor = new boolean[80]; - protected void displayDoubleHires(BufferedImage screen, int xOffset, int y, int rowAddress) { + protected void displayDoubleHires(WritableImage screen, int xOffset, int y, int rowAddress) { // Skip odd columns since this does two at once if ((xOffset & 0x01) == 1) { return; @@ -314,7 +314,7 @@ public class VideoDHGR extends Video { } boolean extraHalfBit = false; - protected void displayHires(BufferedImage screen, int xOffset, int y, int rowAddress) { + protected void displayHires(WritableImage screen, int xOffset, int y, int rowAddress) { // Skip odd columns since this does two at once if ((xOffset & 0x01) == 1) { return; @@ -369,40 +369,40 @@ public class VideoDHGR extends Video { value |= 0x10000000; } hgrToDhgr[bb1][bb2] = value; - hgrToDhgrBW[bb1 & 0x0ff][bb2] = - byteDoubler((byte) bb1) | (byteDoubler((byte) bb2) << 14); + hgrToDhgrBW[bb1 & 0x0ff][bb2] + = byteDoubler((byte) bb1) | (byteDoubler((byte) bb2) << 14); } } } - protected void displayLores(BufferedImage screen, int xOffset, int y, int rowAddress) { + protected void displayLores(WritableImage screen, int xOffset, int y, int rowAddress) { int c1 = ((RAM128k) computer.getMemory()).getMainMemory().readByte(rowAddress + xOffset) & 0x0FF; if ((y & 7) < 4) { c1 &= 15; } else { c1 >>= 4; } - DataBuffer b = screen.getRaster().getDataBuffer(); - int yOffset = xyOffset[y][times14[xOffset]]; - int color = Palette.color[c1].getRGB(); + Color color = Palette.color[c1]; // Unrolled loop, faster - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); + PixelWriter writer = screen.getPixelWriter(); + int x = xOffset * 7; + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); } - private void displayDoubleLores(BufferedImage screen, int xOffset, int y, int rowAddress) { + private void displayDoubleLores(WritableImage screen, int xOffset, int y, int rowAddress) { int c1 = ((RAM128k) computer.getMemory()).getAuxVideoMemory().readByte(rowAddress + xOffset) & 0x0FF; int c2 = ((RAM128k) computer.getMemory()).getMainMemory().readByte(rowAddress + xOffset) & 0x0FF; if ((y & 7) < 4) { @@ -412,25 +412,26 @@ public class VideoDHGR extends Video { c1 >>= 4; c2 >>= 4; } - DataBuffer b = screen.getRaster().getDataBuffer(); - int yOffset = xyOffset[y][times14[xOffset]]; - int color = Palette.color[c1].getRGB(); - int color2 = Palette.color[c2].getRGB(); + PixelWriter writer = screen.getPixelWriter(); +// int yOffset = xyOffset[y][times14[xOffset]]; + Color color = Palette.color[c1]; // Unrolled loop, faster - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color2); - b.setElem(yOffset++, color2); - b.setElem(yOffset++, color2); - b.setElem(yOffset++, color2); - b.setElem(yOffset++, color2); - b.setElem(yOffset++, color2); - b.setElem(yOffset++, color2); + int x = xOffset * 7; + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + color = Palette.color[c2]; + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); } boolean flashInverse = false; int flashTimer = 0; @@ -456,8 +457,6 @@ public class VideoDHGR extends Video { // 80-BF - Normal characters (uppercase only) // C0-DF - Normal characters (repeat 80-9F) // E0-FF - Normal characters (lowercase) - - // MAP1: Normal map, flash inverse = false CHAR_MAP1 = new int[256]; // MAP2: Normal map, flash inverse = true @@ -544,7 +543,7 @@ public class VideoDHGR extends Video { return currentCharMap[b & 0x0ff]; } - protected void displayText(BufferedImage screen, int xOffset, int y, int rowAddress) { + protected void displayText(WritableImage screen, int xOffset, int y, int rowAddress) { // Skip odd columns since this does two at once if ((xOffset & 0x01) == 1) { return; @@ -561,7 +560,7 @@ public class VideoDHGR extends Video { showBW(screen, times14[xOffset], y, out); } - protected void displayText80(BufferedImage screen, int xOffset, int y, int rowAddress) { + protected void displayText80(WritableImage screen, int xOffset, int y, int rowAddress) { // Skip odd columns since this does two at once if ((xOffset & 0x01) == 1) { return; @@ -576,7 +575,7 @@ public class VideoDHGR extends Video { showBW(screen, times14[xOffset], y, bits); } - private void displayMixed(BufferedImage screen, int xOffset, int y, int textOffset, int graphicsOffset) { + private void displayMixed(WritableImage screen, int xOffset, int y, int textOffset, int graphicsOffset) { mixed.actualWriter().displayByte(screen, xOffset, y, textOffset, graphicsOffset); } protected boolean hiresMode = false; @@ -586,50 +585,50 @@ public class VideoDHGR extends Video { public void configureVideoMode() { boolean page2 = SoftSwitches.PAGE2.isOn() && SoftSwitches._80STORE.isOff(); dhgrMode = SoftSwitches._80COL.getState() && SoftSwitches.DHIRES.getState() && SoftSwitches.HIRES.getState(); - currentTextWriter = - SoftSwitches._80COL.getState() - ? page2 - ? text80Page2 : text80Page1 - : page2 - ? textPage2 : textPage1; - currentGraphicsWriter = - SoftSwitches._80COL.getState() && SoftSwitches.DHIRES.getState() - ? SoftSwitches.HIRES.getState() - ? page2 - ? dhiresPage2 : dhiresPage1 - : page2 - ? dloresPage2 : dloresPage1 - : SoftSwitches.HIRES.getState() - ? page2 - ? hiresPage2 : hiresPage1 - : page2 - ? loresPage2 : loresPage1; + currentTextWriter + = SoftSwitches._80COL.getState() + ? page2 + ? text80Page2 : text80Page1 + : page2 + ? textPage2 : textPage1; + currentGraphicsWriter + = SoftSwitches._80COL.getState() && SoftSwitches.DHIRES.getState() + ? SoftSwitches.HIRES.getState() + ? page2 + ? dhiresPage2 : dhiresPage1 + : page2 + ? dloresPage2 : dloresPage1 + : SoftSwitches.HIRES.getState() + ? page2 + ? hiresPage2 : hiresPage1 + : page2 + ? loresPage2 : loresPage1; setCurrentWriter( SoftSwitches.TEXT.getState() ? currentTextWriter - : SoftSwitches.MIXED.getState() ? mixed - : currentGraphicsWriter); + : SoftSwitches.MIXED.getState() ? mixed + : currentGraphicsWriter); hiresMode = !SoftSwitches.DHIRES.getState(); } - protected void showDhgr(BufferedImage screen, int xOffset, int y, int dhgrWord) { + protected void showDhgr(WritableImage screen, int xOffset, int y, int dhgrWord) { //Graphics2D g = (Graphics2D) screen.getGraphics(); - DataBuffer b = screen.getRaster().getDataBuffer(); - int yOffset = xyOffset[y][xOffset]; + int x = xOffset * 7; + PixelWriter writer = screen.getPixelWriter(); try { for (int i = 0; i < 7; i++) { - int color = Palette.color[flipNybble[dhgrWord & 15]].getRGB(); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); - b.setElem(yOffset++, color); + Color color = Palette.color[flipNybble[dhgrWord & 15]]; + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); + writer.setColor(x++, y, color); dhgrWord >>= 4; } } catch (ArrayIndexOutOfBoundsException ex) { Logger.getLogger(getClass().getName()).warning("Went out of bounds in video display"); } } - static final int BLACK = Color.BLACK.getRGB(); - static final int WHITE = Color.WHITE.getRGB(); + static final Color BLACK = Color.BLACK; + static final Color WHITE = Color.WHITE; static final int[][] xyOffset; static { @@ -641,21 +640,20 @@ public class VideoDHGR extends Video { } } - protected void showBW(BufferedImage screen, int xOffset, int y, int dhgrWord) { + protected void showBW(WritableImage screen, int xOffset, int y, int dhgrWord) { int color = 0; // Using the data buffer directly is about 15 times faster than setRGB // This is because setRGB does extra (useless) color model logic // For that matter even Graphics.drawLine is faster than setRGB! - DataBuffer b = screen.getRaster().getDataBuffer(); // This is equivilant to y*560 but is 5% faster // Also, adding xOffset now makes it additionally 5% faster //int yOffset = ((y << 4) + (y << 5) + (y << 9))+xOffset; - //is this lookup faster? - int yOffset = xyOffset[y][xOffset]; + int x = xOffset * 7; + PixelWriter writer = screen.getPixelWriter(); for (int i = 0; i < 28; i++) { // yOffset++ is used instead of yOffset+i, because it is faster - b.setElem(yOffset++, (dhgrWord & 1) == 1 ? WHITE : BLACK); + writer.setColor(x++, y, (dhgrWord & 1) == 1 ? WHITE : BLACK); dhgrWord >>= 1; } } @@ -742,7 +740,7 @@ public class VideoDHGR extends Video { } @Override - public void hblankStart(BufferedImage screen, int y, boolean isDirty) { + public void hblankStart(WritableImage screen, int y, boolean isDirty) { // Do nothing } -} \ No newline at end of file +} diff --git a/src/main/java/jace/apple2e/VideoNTSC.java b/src/main/java/jace/apple2e/VideoNTSC.java index db73211..37f7fe1 100644 --- a/src/main/java/jace/apple2e/VideoNTSC.java +++ b/src/main/java/jace/apple2e/VideoNTSC.java @@ -23,24 +23,24 @@ import jace.core.Computer; import jace.core.RAMEvent; import jace.core.RAMListener; import jace.core.Video; -import java.awt.image.BufferedImage; -import java.awt.image.DataBuffer; import java.util.HashSet; import java.util.Set; +import javafx.scene.image.PixelWriter; +import javafx.scene.image.WritableImage; /** * Provides a clean color monitor simulation, complete with text-friendly * palette and mixed color/bw (mode 7) rendering. This class extends the * VideoDHGR class to provide all necessary video writers and other rendering - * mechanics, and then overrides the actual output routines (showBW, showDhgr) with more suitable - * (and much prettier) alternatives. Rather than draw to the video buffer every - * cycle, rendered screen info is pushed into a buffer with mask bits (to - * indicate B&W vs color) And the actual conversion happens at the end of the - * scanline during the HBLANK period. This video rendering was inspired by - * Blargg but was ultimately rewritten from scratch once the color palette was - * implemented. + * mechanics, and then overrides the actual output routines (showBW, showDhgr) + * with more suitable (and much prettier) alternatives. Rather than draw to the + * video buffer every cycle, rendered screen info is pushed into a buffer with + * mask bits (to indicate B&W vs color) And the actual conversion happens at the + * end of the scanline during the HBLANK period. This video rendering was + * inspired by Blargg but was ultimately rewritten from scratch once the color + * palette was implemented. * - * @author Brendan Robert (BLuRry) brendan.robert@gmail.com + * @author Brendan Robert (BLuRry) brendan.robert@gmail.com */ public class VideoNTSC extends VideoDHGR { @@ -69,19 +69,21 @@ public class VideoNTSC extends VideoDHGR { } @Override - protected void showBW(BufferedImage screen, int xOffset, int y, int dhgrWord) { + protected void showBW(WritableImage screen, int xOffset, int y, int dhgrWord) { if (lastKnownY != y) { lastKnownY = y; pos = rowStart = divBy28[xOffset]; colorActive = false; } else { - if (pos > 20) pos-=20; + if (pos > 20) { + pos -= 20; + } } doDisplay(screen, xOffset, y, dhgrWord); } @Override - protected void showDhgr(BufferedImage screen, int xOffset, int y, int dhgrWord) { + protected void showDhgr(WritableImage screen, int xOffset, int y, int dhgrWord) { if (lastKnownY != y) { lastKnownY = y; pos = rowStart = divBy28[xOffset]; @@ -91,7 +93,7 @@ public class VideoNTSC extends VideoDHGR { } @Override - protected void displayLores(BufferedImage screen, int xOffset, int y, int rowAddress) { + protected void displayLores(WritableImage screen, int xOffset, int y, int rowAddress) { // Skip odd columns since this does two at once if ((xOffset & 0x01) == 1) { return; @@ -119,14 +121,16 @@ public class VideoNTSC extends VideoDHGR { scanline[pos++] = pat; } - private void doDisplay(BufferedImage screen, int xOffset, int y, int dhgrWord) { - if (pos >= 20) pos -= 20; + private void doDisplay(WritableImage screen, int xOffset, int y, int dhgrWord) { + if (pos >= 20) { + pos -= 20; + } scanline[pos] = dhgrWord; pos++; } @Override - public void hblankStart(BufferedImage screen, int y, boolean isDirty) { + public void hblankStart(WritableImage screen, int y, boolean isDirty) { if (isDirty) { renderScanline(screen, y); } @@ -146,14 +150,14 @@ public class VideoNTSC extends VideoDHGR { } } - private void renderScanline(BufferedImage screen, int y) { - DataBuffer b = screen.getRaster().getDataBuffer(); + private void renderScanline(WritableImage screen, int y) { + PixelWriter writer = screen.getPixelWriter(); try { // This is equivilant to y*560 but is 5% faster //int yOffset = ((y << 4) + (y << 5) + (y << 9))+xOffset; // For some reason this jumps up to 40 in the wayout title screen (?) - int p = pyOffset[y][rowStart]; + int p = 0; if (rowStart > 0) { getCurrentWriter().markDirty(y); } @@ -185,9 +189,9 @@ public class VideoNTSC extends VideoDHGR { byteCounter++; } if (isBW) { - b.setElem(p++, ((bits & 0x8) == 0) ? BLACK : WHITE); + writer.setColor(p++, y, ((bits & 0x8) == 0) ? BLACK : WHITE); } else { - b.setElem(p++, activePalette[i % 4][bits & 0x07f]); + writer.setArgb(p++, y, activePalette[i % 4][bits & 0x07f]); } bits >>= 1; if (i == 20) { @@ -196,7 +200,7 @@ public class VideoNTSC extends VideoDHGR { } } else { for (int i = 0; i < 28; i++) { - b.setElem(p++, activePalette[i % 4][bits & 0x07f]); + writer.setArgb(p++, y, activePalette[i % 4][bits & 0x07f]); bits >>= 1; if (i == 20) { bits |= add << (hiresMode ? 9 : 10); @@ -208,7 +212,7 @@ public class VideoNTSC extends VideoDHGR { for (int s = rowStart; s < 20; s++) { int bits = scanline[s]; for (int i = 0; i < 28; i++) { - b.setElem(p++, ((bits & 1) == 0) ? BLACK : WHITE); + writer.setColor(p++, y, ((bits & 1) == 0) ? BLACK : WHITE); bits >>= 1; } } @@ -265,8 +269,8 @@ public class VideoNTSC extends VideoDHGR { } double y1 = yiq[col][0]; double y2 = ((double) level / (double) maxLevel); - solidPalette[offset][pattern] = (255 << 24) | yiqToRgb(y1, yiq[col][1] * MAX_I, yiq[col][2] * MAX_Q); - textPalette[offset][pattern] = (255 << 24) | yiqToRgb(y2, yiq[col][1] * MAX_I, yiq[col][2] * MAX_Q); + solidPalette[offset][pattern] = yiqToRgb(y1, yiq[col][1] * MAX_I, yiq[col][2] * MAX_Q); + textPalette[offset][pattern] = yiqToRgb(y2, yiq[col][1] * MAX_I, yiq[col][2] * MAX_Q); } } // Avoid NPE just in case. @@ -277,7 +281,7 @@ public class VideoNTSC extends VideoDHGR { int r = (int) (normalize((y + 0.956 * i + 0.621 * q), 0, 1) * 255); int g = (int) (normalize((y - 0.272 * i - 0.647 * q), 0, 1) * 255); int b = (int) (normalize((y - 1.105 * i + 1.702 * q), 0, 1) * 255); - return (r << 16) | (g << 8) | b; + return (255 << 24) | (r << 16) | (g << 8) | b; } public static double normalize(double x, double minX, double maxX) { diff --git a/src/main/java/jace/core/Palette.java b/src/main/java/jace/core/Palette.java index 43f820f..80a55e6 100644 --- a/src/main/java/jace/core/Palette.java +++ b/src/main/java/jace/core/Palette.java @@ -18,7 +18,7 @@ */ package jace.core; -import java.awt.Color; +import javafx.scene.paint.Color; /** * Fixed color palette -- only used for the older DHGR renderer (the new NTSC renderer uses its own YUV conversion and builds its own palettes) @@ -37,21 +37,21 @@ public class Palette { static public Color[] color; static { color = new Color[16]; - color[ 0] = new Color( 0, 0, 0); - color[ 1] = new Color(208, 0, 48); - color[ 2] = new Color( 0, 0,128); - color[ 3] = new Color(255, 0,255); - color[ 4] = new Color( 0,128, 0); - color[ 5] = new Color(128,128,128); - color[ 6] = new Color( 0, 0,255); - color[ 7] = new Color( 96,160,255); - color[ 8] = new Color(128, 80, 0); - color[ 9] = new Color(255,128, 0); - color[10] = new Color(192,192,192); - color[11] = new Color(255,144,128); - color[12] = new Color( 0,255, 0); - color[13] = new Color(255,255, 0); - color[14] = new Color( 64,255,144); - color[15] = new Color(255,255,255); + color[ 0] = new Color( 0, 0, 0, 1); + color[ 1] = new Color(208, 0, 48, 1); + color[ 2] = new Color( 0, 0,128, 1); + color[ 3] = new Color(255, 0,255, 1); + color[ 4] = new Color( 0,128, 0, 1); + color[ 5] = new Color(128,128,128, 1); + color[ 6] = new Color( 0, 0,255, 1); + color[ 7] = new Color( 96,160,255, 1); + color[ 8] = new Color(128, 80, 0, 1); + color[ 9] = new Color(255,128, 0, 1); + color[10] = new Color(192,192,192, 1); + color[11] = new Color(255,144,128, 1); + color[12] = new Color( 0,255, 0, 1); + color[13] = new Color(255,255, 0, 1); + color[14] = new Color( 64,255,144, 1); + color[15] = new Color(255,255,255, 1); } } \ No newline at end of file diff --git a/src/main/java/jace/core/Utility.java b/src/main/java/jace/core/Utility.java index 806d8d1..38cb31e 100644 --- a/src/main/java/jace/core/Utility.java +++ b/src/main/java/jace/core/Utility.java @@ -96,13 +96,13 @@ public class Utility { try { // Try to create an instance of the object String className = pckgname + "." + classname; -// System.out.println("Class: " + className); + 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 ex) { + System.err.println(ex); } } else { // System.out.println("Skipping non class: " + filename); @@ -284,7 +284,7 @@ public class Utility { } public static void runModalProcess(String title, final Runnable runnable) { - final JDialog frame = new JDialog(Emulator.getFrame()); +// final JDialog frame = new JDialog(Emulator.getFrame()); final JProgressBar progressBar = new JProgressBar(); progressBar.setIndeterminate(true); final JPanel contentPane = new JPanel(); @@ -292,16 +292,16 @@ public class Utility { contentPane.setLayout(new BorderLayout()); contentPane.add(new JLabel(title), BorderLayout.NORTH); contentPane.add(progressBar, BorderLayout.CENTER); - frame.setContentPane(contentPane); - frame.pack(); - frame.setLocationRelativeTo(null); - frame.setVisible(true); - - new Thread(() -> { - runnable.run(); - frame.setVisible(false); - frame.dispose(); - }).start(); +// frame.setContentPane(contentPane); +// frame.pack(); +// frame.setLocationRelativeTo(null); +// frame.setVisible(true); +// +// new Thread(() -> { +// runnable.run(); +// frame.setVisible(false); +// frame.dispose(); +// }).start(); } public static class RankingComparator implements Comparator { @@ -399,7 +399,7 @@ public class Utility { public static void gripe(final String message) { EventQueue.invokeLater(() -> { - JOptionPane.showMessageDialog(Emulator.getFrame(), message, "Error", JOptionPane.ERROR_MESSAGE); +// JOptionPane.showMessageDialog(Emulator.getFrame(), message, "Error", JOptionPane.ERROR_MESSAGE); }); } diff --git a/src/main/java/jace/core/Video.java b/src/main/java/jace/core/Video.java index 1c8d34e..5f0057e 100644 --- a/src/main/java/jace/core/Video.java +++ b/src/main/java/jace/core/Video.java @@ -22,8 +22,8 @@ import jace.state.Stateful; import jace.Emulator; import jace.config.ConfigurableField; import jace.config.InvokableAction; -import java.awt.Graphics; -import java.awt.image.BufferedImage; +import javafx.scene.image.Image; +import javafx.scene.image.WritableImage; /** * Generic abstraction of a 560x192 video output device which renders 40 columns @@ -38,9 +38,9 @@ import java.awt.image.BufferedImage; public abstract class Video extends Device { @Stateful - BufferedImage video; + WritableImage video; + WritableImage visible; VideoWriter currentWriter; - Graphics screen; private byte floatingBus = 0; private int width = 560; private int height = 192; @@ -94,7 +94,8 @@ public abstract class Video extends Device { public Video(Computer computer) { super(computer); suspend(); - video = new BufferedImage(560, 192, BufferedImage.TYPE_INT_RGB); + video = new WritableImage(560, 192); + visible = new WritableImage(560, 192); vPeriod = 0; hPeriod = 0; forceRefresh(); @@ -116,15 +117,6 @@ public abstract class Video extends Device { return height; } - public void setScreen(Graphics g) { - screen = g; - - } - - public Graphics getScreen() { - return screen; - } - public VideoWriter getCurrentWriter() { return currentWriter; } @@ -139,14 +131,14 @@ public abstract class Video extends Device { public static int MIN_SCREEN_REFRESH = 15; public void redraw() { - if (screen == null || video == null) { - return; - } screenDirty = false; - screen.drawImage(video, 0, 0, width, height, null); - if (Emulator.getFrame() != null) { - Emulator.getFrame().repaintIndicators(); - } + javafx.application.Platform.runLater(() -> { + visible.getPixelWriter().setPixels(0, 0, 560, 192, video.getPixelReader(), 0, 0); + }); +// screen.drawImage(video, 0, 0, width, height, null); +// if (Emulator.getFrame() != null) { +// Emulator.getFrame().repaintIndicators(); +// } } public void vblankStart() { @@ -157,7 +149,7 @@ public abstract class Video extends Device { abstract public void vblankEnd(); - abstract public void hblankStart(BufferedImage screen, int y, boolean isDirty); + abstract public void hblankStart(WritableImage screen, int y, boolean isDirty); public void setScannerLocation(int loc) { scannerAddress = loc; @@ -294,7 +286,7 @@ public abstract class Video extends Device { return "vid"; } - public BufferedImage getFrameBuffer() { - return video; + public Image getFrameBuffer() { + return visible; } } diff --git a/src/main/java/jace/core/VideoWriter.java b/src/main/java/jace/core/VideoWriter.java index 20de46f..7213ea6 100644 --- a/src/main/java/jace/core/VideoWriter.java +++ b/src/main/java/jace/core/VideoWriter.java @@ -18,7 +18,7 @@ */ package jace.core; -import java.awt.image.BufferedImage; +import javafx.scene.image.WritableImage; /** * VideoWriter is an abstraction of a graphics display mode that knows how to @@ -32,7 +32,7 @@ import java.awt.image.BufferedImage; */ public abstract class VideoWriter { - public abstract void displayByte(BufferedImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset); + public abstract void displayByte(WritableImage screen, int xOffset, int y, int yTextOffset, int yGraphicsOffset); // This is used to support composite mixed-mode writers so that we can talk to the writer being used for a scanline public VideoWriter actualWriter() { diff --git a/src/main/java/jace/hardware/CardAppleMouse.java b/src/main/java/jace/hardware/CardAppleMouse.java index d0d8bbd..5404091 100644 --- a/src/main/java/jace/hardware/CardAppleMouse.java +++ b/src/main/java/jace/hardware/CardAppleMouse.java @@ -349,7 +349,7 @@ public class CardAppleMouse extends Card implements MouseListener { */ private void initMouse() { mouseActive.setDescription("Active"); - Emulator.getFrame().addIndicator(this, mouseActive, 2000); +// Emulator.getFrame().addIndicator(this, mouseActive, 2000); setClampWindowX(0, 0x3ff); setClampWindowY(0, 0x3ff); clearMouse(); @@ -463,31 +463,32 @@ public class CardAppleMouse extends Card implements MouseListener { if (drawingArea == null) { return; } - Graphics2D screen = (Graphics2D) computer.getVideo().getScreen(); +// Graphics2D screen = (Graphics2D) computer.getVideo().getScreen(); // Point currentMouseLocation = MouseInfo.getPointerInfo().getLocation(); // Point topLeft = drawingArea.getLocationOnScreen(); - Point currentMouseLocation = Emulator.getFrame().getContentPane().getMousePosition(); - if (currentMouseLocation == null) return; + Point currentMouseLocation = null; // = Emulator.getFrame().getContentPane().getMousePosition(); +// if (currentMouseLocation == null) return; // Point topLeft = drawingArea.getLocationOnScreen(); Point topLeft = new Point(0,0); Dimension d = drawingArea.getBounds().getSize(); - if (screen.getTransform() != null) { - d = new Dimension((int) (screen.getTransform().getScaleX() * d.width), - (int) (screen.getTransform().getScaleY() * d.height)); - topLeft.x += screen.getTransform().getTranslateX(); - topLeft.y += screen.getTransform().getTranslateY(); - } +// if (screen.getTransform() != null) { +// d = new Dimension((int) (screen.getTransform().getScaleX() * d.width), +// (int) (screen.getTransform().getScaleY() * d.height)); +// topLeft.x += screen.getTransform().getTranslateX(); +// topLeft.y += screen.getTransform().getTranslateY(); +// } if (fullscreenFix) { - if (Emulator.getFrame().isFullscreenActive()) { - Toolkit t = Toolkit.getDefaultToolkit(); - topLeft.y -= t.getScreenInsets(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration()).top; - } +// if (Emulator.getFrame().isFullscreenActive()) { +// Toolkit t = Toolkit.getDefaultToolkit(); +// topLeft.y -= t.getScreenInsets(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration()).top; +// } } // Scale X and Y to the clamping range of the mouse (will this work for most software?) double width = clampMax.x - clampMin.x; - double x = currentMouseLocation.getX() - topLeft.x; + double x = 0; +// double x = currentMouseLocation.getX() - topLeft.x; x *= width; x /= d.width; x += clampMin.x; @@ -499,7 +500,8 @@ public class CardAppleMouse extends Card implements MouseListener { } double height = clampMax.y - clampMin.y; - double y = currentMouseLocation.getY() - topLeft.y; + double y = 0; +// double y = currentMouseLocation.getY() - topLeft.y; y *= height; y /= d.height; y += clampMin.y; diff --git a/src/main/java/jace/hardware/CardDiskII.java b/src/main/java/jace/hardware/CardDiskII.java index d212306..10355ae 100644 --- a/src/main/java/jace/hardware/CardDiskII.java +++ b/src/main/java/jace/hardware/CardDiskII.java @@ -77,9 +77,9 @@ public class CardDiskII extends Card implements Reconfigurable, MediaConsumerPar currentDrive = drive1; drive1.reset(); drive2.reset(); - if (Emulator.getFrame() != null) { - Emulator.getFrame().removeIndicators(this); - } +// if (Emulator.getFrame() != null) { +// Emulator.getFrame().removeIndicators(this); +// } // Motherboard.cancelSpeedRequest(this); } @@ -108,7 +108,7 @@ public class CardDiskII extends Card implements Reconfigurable, MediaConsumerPar case 0x9: // drive on currentDrive.setOn(true); - Emulator.getFrame().addIndicator(this, currentDrive.getIcon()); +// Emulator.getFrame().addIndicator(this, currentDrive.getIcon()); break; case 0xA: diff --git a/src/main/java/jace/hardware/CardRamFactor.java b/src/main/java/jace/hardware/CardRamFactor.java index 995822a..e994a64 100644 --- a/src/main/java/jace/hardware/CardRamFactor.java +++ b/src/main/java/jace/hardware/CardRamFactor.java @@ -92,7 +92,7 @@ public class CardRamFactor extends Card { @Override protected void handleIOAccess(int register, TYPE type, int value, RAMEvent e) { - Emulator.getFrame().addIndicator(this, indicator); +// Emulator.getFrame().addIndicator(this, indicator); value &= 0x0ff; switch (register) { case 0: diff --git a/src/main/java/jace/hardware/CardSSC.java b/src/main/java/jace/hardware/CardSSC.java index aab5c98..2de66e8 100644 --- a/src/main/java/jace/hardware/CardSSC.java +++ b/src/main/java/jace/hardware/CardSSC.java @@ -204,7 +204,7 @@ public class CardSSC extends Card implements Reconfigurable, Runnable { newValue |= (PORT_CONNECTED && inputAvailable()) ? 0x00 : 0x01; } if (register == ACIA_Data) { - Emulator.getFrame().addIndicator(this, activityIndicator); +// Emulator.getFrame().addIndicator(this, activityIndicator); newValue = getInputByte(); if (RECV_IRQ_ENABLED) { triggerIRQ(); @@ -256,7 +256,7 @@ public class CardSSC extends Card implements Reconfigurable, Runnable { break; case WRITE: if (register == ACIA_Data) { - Emulator.getFrame().addIndicator(this, activityIndicator); +// Emulator.getFrame().addIndicator(this, activityIndicator); sendOutputByte(value & 0x0FF); if (TRANS_IRQ_ENABLED) { triggerIRQ(); diff --git a/src/main/java/jace/hardware/CardThunderclock.java b/src/main/java/jace/hardware/CardThunderclock.java index 782177c..236eda8 100644 --- a/src/main/java/jace/hardware/CardThunderclock.java +++ b/src/main/java/jace/hardware/CardThunderclock.java @@ -157,7 +157,7 @@ public class CardThunderclock extends Card { clockIcon.setDescription("Slot " + getSlot()); long now = System.currentTimeMillis(); if ((now - lastShownIcon) > MIN_WAIT) { - Emulator.getFrame().addIndicator(this, clockIcon, 3000); +// Emulator.getFrame().addIndicator(this, clockIcon, 3000); } lastShownIcon = now; } @@ -325,6 +325,6 @@ public class CardThunderclock extends Card { ram.writeByte(patchLoc + 1, (byte) year); ram.writeByte(patchLoc + 2, (byte) MOS65C02.OPCODE.NOP.getCode()); ram.writeByte(patchLoc + 3, (byte) MOS65C02.OPCODE.NOP.getCode()); - Emulator.getFrame().addIndicator(this, clockFixIcon, 4000); +// Emulator.getFrame().addIndicator(this, clockFixIcon, 4000); } } \ No newline at end of file diff --git a/src/main/java/jace/hardware/massStorage/CardMassStorage.java b/src/main/java/jace/hardware/massStorage/CardMassStorage.java index 4457210..4deec3d 100644 --- a/src/main/java/jace/hardware/massStorage/CardMassStorage.java +++ b/src/main/java/jace/hardware/massStorage/CardMassStorage.java @@ -159,7 +159,7 @@ public class CardMassStorage extends Card implements MediaConsumerParent { MOS65C02 cpu = (MOS65C02) computer.getCpu(); // System.out.println(e.getType()+" "+Integer.toHexString(e.getAddress())+" from instruction at "+Integer.toHexString(cpu.getProgramCounter())); if (type.isRead()) { - Emulator.getFrame().addIndicator(this, currentDrive.getIcon()); +// Emulator.getFrame().addIndicator(this, currentDrive.getIcon()); if (drive1.getCurrentDisk() == null && drive2.getCurrentDisk() == null) { e.setNewValue(0); return; diff --git a/src/main/java/jace/library/MediaEditUI.java b/src/main/java/jace/library/MediaEditUI.java index 269a0bf..ef1b01d 100644 --- a/src/main/java/jace/library/MediaEditUI.java +++ b/src/main/java/jace/library/MediaEditUI.java @@ -287,7 +287,7 @@ public class MediaEditUI extends javax.swing.JPanel { private void SaveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SaveButtonActionPerformed persist(); library.refreshUI(); - Emulator.getFrame().closeDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME); +// Emulator.getFrame().closeDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME); }//GEN-LAST:event_SaveButtonActionPerformed /** @@ -310,7 +310,7 @@ public class MediaEditUI extends javax.swing.JPanel { private void CancellationButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CancellationButtonActionPerformed if (EmulatorUILogic.confirm("Abandon unsaved changes? Are you sure?")) { - Emulator.getFrame().closeDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME); +// Emulator.getFrame().closeDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME); } }//GEN-LAST:event_CancellationButtonActionPerformed diff --git a/src/main/java/jace/library/MediaLibraryUI.form b/src/main/java/jace/library/MediaLibraryUI.form index f8a0bd7..5a4c303 100644 --- a/src/main/java/jace/library/MediaLibraryUI.form +++ b/src/main/java/jace/library/MediaLibraryUI.form @@ -19,7 +19,7 @@ - + diff --git a/src/main/java/jace/library/MediaLibraryUI.java b/src/main/java/jace/library/MediaLibraryUI.java index 5d3c961..b336add 100644 --- a/src/main/java/jace/library/MediaLibraryUI.java +++ b/src/main/java/jace/library/MediaLibraryUI.java @@ -243,11 +243,11 @@ public class MediaLibraryUI extends javax.swing.JPanel { return; } System.out.println(getSelectedEntry().name); - Emulator.getFrame().registerModalDialog( - MediaLibrary.getInstance().buildEditInstance(this, getSelectedEntry()), - MEDIA_MANAGER_EDIT_DIALOG_NAME, - MEDIA_MANAGER_DIALOG_NAME, true); - Emulator.getFrame().showDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME); +// Emulator.getFrame().registerModalDialog( +// MediaLibrary.getInstance().buildEditInstance(this, getSelectedEntry()), +// MEDIA_MANAGER_EDIT_DIALOG_NAME, +// MEDIA_MANAGER_DIALOG_NAME, true); +// Emulator.getFrame().showDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME); }//GEN-LAST:event_ViewEditActionPerformed private void RemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RemoveActionPerformed @@ -264,11 +264,11 @@ public class MediaLibraryUI extends javax.swing.JPanel { }//GEN-LAST:event_RemoveActionPerformed private void CreateNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CreateNewActionPerformed - Emulator.getFrame().registerModalDialog( - MediaLibrary.getInstance().buildEditInstance(this, null), - MEDIA_MANAGER_EDIT_DIALOG_NAME, - MEDIA_MANAGER_DIALOG_NAME, true); - Emulator.getFrame().showDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME); +// Emulator.getFrame().registerModalDialog( +// MediaLibrary.getInstance().buildEditInstance(this, null), +// MEDIA_MANAGER_EDIT_DIALOG_NAME, +// MEDIA_MANAGER_DIALOG_NAME, true); +// Emulator.getFrame().showDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME); }//GEN-LAST:event_CreateNewActionPerformed private void FavoriteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FavoriteActionPerformed diff --git a/src/main/java/jace/state/State.java b/src/main/java/jace/state/State.java index 0f790c9..50f1e26 100644 --- a/src/main/java/jace/state/State.java +++ b/src/main/java/jace/state/State.java @@ -18,11 +18,11 @@ */ package jace.state; -import java.awt.image.BufferedImage; import java.io.Serializable; import java.util.HashMap; import java.util.HashSet; import java.util.Set; +import javafx.scene.image.Image; /** * A state is nothing more than a map of captured variable values, except that a @@ -40,7 +40,7 @@ public class State extends HashMap implements Seria State nextState; // Tail is only correct on the head node, everything else will likely be null State tail; - BufferedImage screenshot; + Image screenshot; /** * Removing the next state allows a LRU buffer of states -- but states can't diff --git a/src/main/java/jace/state/StateManager.java b/src/main/java/jace/state/StateManager.java index adec856..2d20703 100644 --- a/src/main/java/jace/state/StateManager.java +++ b/src/main/java/jace/state/StateManager.java @@ -37,6 +37,8 @@ import java.util.Set; import java.util.WeakHashMap; import java.util.logging.Level; import java.util.logging.Logger; +import javafx.scene.image.Image; +import javafx.scene.image.WritableImage; /** * @@ -334,12 +336,9 @@ public class StateManager implements Reconfigurable { stateCount++; } - private BufferedImage getScreenshot() { - BufferedImage screen = computer.getVideo().getFrameBuffer(); - ColorModel cm = screen.getColorModel(); - boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); - WritableRaster raster = screen.copyData(null); - return new BufferedImage(cm, raster, isAlphaPremultiplied, null); + private Image getScreenshot() { + Image screen = computer.getVideo().getFrameBuffer(); + return new WritableImage(screen.getPixelReader(), (int) screen.getWidth(), (int) screen.getHeight()); } private State captureAlphaState() { diff --git a/src/main/java/jace/ui/AbstractEmulatorFrame.java b/src/main/java/jace/ui/AbstractEmulatorFrame.java index dc23def..41b75d2 100644 --- a/src/main/java/jace/ui/AbstractEmulatorFrame.java +++ b/src/main/java/jace/ui/AbstractEmulatorFrame.java @@ -276,7 +276,7 @@ public abstract class AbstractEmulatorFrame extends javax.swing.JFrame implement computer.getVideo().setWidth(width1); computer.getVideo().setHeight(height1); if (!isFullscreen || !fullscreenEnforceRatio) { - computer.getVideo().setScreen(getScreenGraphics()); +// computer.getVideo().setScreen(getScreenGraphics()); } computer.getVideo().forceRefresh(); screen.validate(); @@ -333,7 +333,7 @@ public abstract class AbstractEmulatorFrame extends javax.swing.JFrame implement g.fill(getBounds()); Graphics2D gg = (Graphics2D) g.create(b.x, b.y, b.width, b.height); gg.scale((double) b.width / (double) sw, (double) b.height / (double) sh); - computer.getVideo().setScreen(gg); +// computer.getVideo().setScreen(gg); computer.getVideo().resume(); computer.resume(); } else { diff --git a/src/main/resources/fxml/JaceUI.fxml b/src/main/resources/fxml/JaceUI.fxml index c6b866e..a08bf4d 100644 --- a/src/main/resources/fxml/JaceUI.fxml +++ b/src/main/resources/fxml/JaceUI.fxml @@ -1,5 +1,6 @@ + @@ -7,9 +8,9 @@ - + - + diff --git a/target/classes/fxml/JaceUI.fxml b/target/classes/fxml/JaceUI.fxml index c6b866e..a08bf4d 100644 --- a/target/classes/fxml/JaceUI.fxml +++ b/target/classes/fxml/JaceUI.fxml @@ -1,5 +1,6 @@ + @@ -7,9 +8,9 @@ - + - + diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties index 362eaa0..f2600f2 100644 --- a/target/maven-archiver/pom.properties +++ b/target/maven-archiver/pom.properties @@ -1,5 +1,5 @@ #Generated by Maven -#Sat Sep 20 01:41:50 CDT 2014 +#Tue Feb 03 00:36:09 CST 2015 version=2.0-SNAPSHOT groupId=org.badvision artifactId=jace diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst index e20f000..3f31591 100644 --- a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -220,7 +220,6 @@ jace/apple2e/softswitch/IntC8SoftSwitch$1.class jace/config/ConfigurableField.class jace/core/Video.class jace/hardware/mockingboard/NoiseGenerator.class -jace/Emulator$1.class jace/applesoft/Command$TOKEN.class jace/core/RAMEvent$VALUE.class jace/apple2e/softswitch/Memory2SoftSwitch.class @@ -243,7 +242,6 @@ jace/cheat/MemorySpy$3.class jace/library/MediaEditUI$2.class jace/hardware/mockingboard/R6522.class jace/library/MediaCache.class -jace/Emulator$2.class jace/apple2e/VideoNTSC$rgbMode.class jace/ConvertDiskImage.class jace/config/ClassSelection.class