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