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.
This commit is contained in:
Brendan Robert 2015-02-03 00:55:25 -06:00
parent 34addf37f8
commit 0ccb63558f
28 changed files with 416 additions and 406 deletions

3
.gitignore vendored
View File

@ -11,4 +11,5 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid* hs_err_pid*
/jace/nbproject/private/ /jace/nbproject/private/
/jace/target/ /jace/target/
*.jace.conf

View File

@ -49,13 +49,6 @@ public class Emulator {
instance = new Emulator(args); instance = new Emulator(args);
} }
public static AbstractEmulatorFrame getFrame() {
if (instance != null) {
return instance.theApp;
} else {
return null;
}
}
public static Apple2e computer; public static Apple2e computer;
public AbstractEmulatorFrame theApp; public AbstractEmulatorFrame theApp;
@ -90,90 +83,91 @@ public class Emulator {
Configuration.applySettings(settings); Configuration.applySettings(settings);
// theApp = new MainFrame(); // theApp = new MainFrame();
theApp = new EmulatorFrame(computer); // theApp = new EmulatorFrame(computer);
try { // try {
theApp.setIconImage(ImageIO.read(Emulator.class.getClassLoader().getResourceAsStream("jace/data/woz_figure.gif"))); // theApp.setIconImage(ImageIO.read(Emulator.class.getClassLoader().getResourceAsStream("jace/data/woz_figure.gif")));
} catch (IOException ex) { // } catch (IOException ex) {
Logger.getLogger(Emulator.class.getName()).log(Level.SEVERE, null, ex); // Logger.getLogger(Emulator.class.getName()).log(Level.SEVERE, null, ex);
} // }
//theApp.setBounds(new Rectangle((140*6),(192*3))); // //theApp.setBounds(new Rectangle((140*6),(192*3)));
theApp.setVisible(true); // theApp.setVisible(true);
theApp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // theApp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theApp.setFocusTraversalKeysEnabled(false); // theApp.setFocusTraversalKeysEnabled(false);
theApp.setTitle("Java Apple Computer Emulator"); // theApp.setTitle("Java Apple Computer Emulator");
theApp.addKeyListener(computer.getKeyboard().getListener()); // theApp.addKeyListener(computer.getKeyboard().getListener());
theApp.addComponentListener(new ComponentListener() { // theApp.addComponentListener(new ComponentListener() {
// theApp.screen.addComponentListener(new ComponentListener() { // // theApp.screen.addComponentListener(new ComponentListener() {
@Override // @Override
public void componentResized(ComponentEvent e) { // public void componentResized(ComponentEvent e) {
// System.out.println("Screen resized"); //// System.out.println("Screen resized");
resizeVideo(); // resizeVideo();
} // }
//
@Override // @Override
public void componentMoved(ComponentEvent e) { // public void componentMoved(ComponentEvent e) {
resizeVideo(); // resizeVideo();
} // }
//
@Override // @Override
public void componentShown(ComponentEvent e) { // public void componentShown(ComponentEvent e) {
} // }
//
@Override // @Override
public void componentHidden(ComponentEvent e) { // public void componentHidden(ComponentEvent e) {
} // }
}); // });
theApp.addWindowListener(new WindowListener() { // theApp.addWindowListener(new WindowListener() {
@Override // @Override
public void windowOpened(WindowEvent e) { // public void windowOpened(WindowEvent e) {
} // }
//
@Override // @Override
public void windowClosing(WindowEvent e) { // public void windowClosing(WindowEvent e) {
} // }
//
@Override // @Override
public void windowClosed(WindowEvent e) { // public void windowClosed(WindowEvent e) {
} // }
//
@Override // @Override
public void windowIconified(WindowEvent e) { // public void windowIconified(WindowEvent e) {
computer.getVideo().suspend(); // computer.getVideo().suspend();
} // }
//
@Override // @Override
public void windowDeiconified(WindowEvent e) { // public void windowDeiconified(WindowEvent e) {
computer.getVideo().resume(); // computer.getVideo().resume();
resizeVideo(); // resizeVideo();
} // }
//
@Override // @Override
public void windowActivated(WindowEvent e) { // public void windowActivated(WindowEvent e) {
resizeVideo(); // resizeVideo();
} // }
//
@Override // @Override
public void windowDeactivated(WindowEvent e) { // public void windowDeactivated(WindowEvent e) {
resizeVideo(); // resizeVideo();
} // }
}); // });
EmulatorUILogic.registerDebugger(); EmulatorUILogic.registerDebugger();
computer.getVideo().setScreen(theApp.getScreenGraphics()); // computer.getVideo().setScreen(theApp.getScreenGraphics());
computer.coldStart(); computer.coldStart();
} }
public static void resizeVideo() { public static void resizeVideo() {
AbstractEmulatorFrame window = getFrame(); // AbstractEmulatorFrame window = getFrame();
if (window != null) { // if (window != null) {
window.resizeVideo(); // window.resizeVideo();
} // }
} }
public static Component getScreen() { public static Component getScreen() {
AbstractEmulatorFrame window = getFrame();
if (window != null) {
return window.getScreen();
}
return null; return null;
// AbstractEmulatorFrame window = getFrame();
// if (window != null) {
// return window.getScreen();
// }
// return null;
} }
} }

View File

@ -33,6 +33,7 @@ import jace.library.MediaLibrary;
import jace.ui.AbstractEmulatorFrame; import jace.ui.AbstractEmulatorFrame;
import jace.ui.DebuggerPanel; import jace.ui.DebuggerPanel;
import java.awt.Color; import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.HeadlessException; import java.awt.HeadlessException;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
@ -44,6 +45,9 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; 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.imageio.ImageIO;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.JLabel; import javax.swing.JLabel;
@ -75,22 +79,22 @@ public class EmulatorUILogic {
} }
public static void updateCPURegisters(MOS65C02 cpu) { public static void updateCPURegisters(MOS65C02 cpu) {
DebuggerPanel debuggerPanel = Emulator.getFrame().getDebuggerPanel(); // DebuggerPanel debuggerPanel = Emulator.getFrame().getDebuggerPanel();
debuggerPanel.valueA.setText(Integer.toHexString(cpu.A)); // debuggerPanel.valueA.setText(Integer.toHexString(cpu.A));
debuggerPanel.valueX.setText(Integer.toHexString(cpu.X)); // debuggerPanel.valueX.setText(Integer.toHexString(cpu.X));
debuggerPanel.valueY.setText(Integer.toHexString(cpu.Y)); // debuggerPanel.valueY.setText(Integer.toHexString(cpu.Y));
debuggerPanel.valuePC.setText(Integer.toHexString(cpu.getProgramCounter())); // debuggerPanel.valuePC.setText(Integer.toHexString(cpu.getProgramCounter()));
debuggerPanel.valueSP.setText(Integer.toHexString(cpu.getSTACK())); // debuggerPanel.valueSP.setText(Integer.toHexString(cpu.getSTACK()));
debuggerPanel.valuePC2.setText(cpu.getFlags()); // debuggerPanel.valuePC2.setText(cpu.getFlags());
debuggerPanel.valueINST.setText(cpu.disassemble()); // debuggerPanel.valueINST.setText(cpu.disassemble());
} }
public static void enableDebug(boolean b) { public static void enableDebug(boolean b) {
DebuggerPanel debuggerPanel = Emulator.getFrame().getDebuggerPanel(); // DebuggerPanel debuggerPanel = Emulator.getFrame().getDebuggerPanel();
debugger.setActive(b); // debugger.setActive(b);
debuggerPanel.enableDebug.setSelected(b); // debuggerPanel.enableDebug.setSelected(b);
debuggerPanel.setBackground( // debuggerPanel.setBackground(
b ? Color.RED : new Color(0, 0, 0x040)); // b ? Color.RED : new Color(0, 0, 0x040));
} }
public static void enableTrace(boolean b) { public static void enableTrace(boolean b) {
@ -187,13 +191,13 @@ public class EmulatorUILogic {
@InvokableAction( @InvokableAction(
name = "BRUN file", name = "BRUN file",
category = "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", 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") alternatives = "Execute program;Load binary;Load program;Load rom;Play single-load game")
public static void runFile() { public static void runFile() {
Emulator.computer.pause(); Emulator.computer.pause();
JFileChooser select = new JFileChooser(); JFileChooser select = new JFileChooser();
select.showDialog(Emulator.getFrame(), "Execute binary file"); // select.showDialog(Emulator.getFrame(), "Execute binary file");
File binary = select.getSelectedFile(); File binary = select.getSelectedFile();
if (binary == null) { if (binary == null) {
Emulator.computer.resume(); Emulator.computer.resume();
@ -237,49 +241,49 @@ public class EmulatorUILogic {
@InvokableAction( @InvokableAction(
name = "Adjust display", name = "Adjust display",
category = "display", category = "display",
description = "Adjusts window size to 1:1 aspect ratio for optimal viewing.", 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;") alternatives = "Adjust screen;Adjust window size;Adjust aspect ratio;Fix screen;Fix window size;Fix aspect ratio;Correct aspect ratio;")
static public void scaleIntegerRatio() { static public void scaleIntegerRatio() {
AbstractEmulatorFrame frame = Emulator.getFrame(); // AbstractEmulatorFrame frame = Emulator.getFrame();
if (frame == null) { // if (frame == null) {
return; // return;
} // }
Emulator.computer.pause(); // Emulator.computer.pause();
frame.enforceIntegerRatio(); // frame.enforceIntegerRatio();
Emulator.computer.resume(); // Emulator.computer.resume();
} }
@InvokableAction( @InvokableAction(
name = "Toggle Debug", name = "Toggle Debug",
category = "debug", category = "debug",
description = "Show/hide the debug panel", description = "Show/hide the debug panel",
alternatives = "Show Debug;Hide Debug") alternatives = "Show Debug;Hide Debug")
public static void toggleDebugPanel() { public static void toggleDebugPanel() {
AbstractEmulatorFrame frame = Emulator.getFrame(); // AbstractEmulatorFrame frame = Emulator.getFrame();
if (frame == null) { // if (frame == null) {
return; // return;
} // }
frame.setShowDebug(!frame.isShowDebug()); // frame.setShowDebug(!frame.isShowDebug());
frame.reconfigure(); // frame.reconfigure();
Emulator.resizeVideo(); // Emulator.resizeVideo();
} }
public static void toggleFullscreen() { public static void toggleFullscreen() {
AbstractEmulatorFrame frame = Emulator.getFrame(); // AbstractEmulatorFrame frame = Emulator.getFrame();
if (frame == null) { // if (frame == null) {
return; // return;
} // }
Emulator.computer.pause(); // Emulator.computer.pause();
frame.toggleFullscreen(); // frame.toggleFullscreen();
Emulator.computer.resume(); // Emulator.computer.resume();
} }
@InvokableAction( @InvokableAction(
name = "Save Raw Screenshot", name = "Save Raw Screenshot",
category = "general", category = "general",
description = "Save raw (RAM) format of visible screen", description = "Save raw (RAM) format of visible screen",
alternatives = "screendump, raw screenshot") alternatives = "screendump, raw screenshot")
public static void saveScreenshotRaw() throws FileNotFoundException, IOException { public static void saveScreenshotRaw() throws FileNotFoundException, IOException {
SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss"); SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss");
String timestamp = df.format(new Date()); String timestamp = df.format(new Date());
@ -317,16 +321,15 @@ public class EmulatorUILogic {
@InvokableAction( @InvokableAction(
name = "Save Screenshot", name = "Save Screenshot",
category = "general", category = "general",
description = "Save image of visible screen", description = "Save image of visible screen",
alternatives = "Save image,save framebuffer,screenshot") alternatives = "Save image,save framebuffer,screenshot")
public static void saveScreenshot() throws HeadlessException, IOException { public static void saveScreenshot() throws HeadlessException, IOException {
JFileChooser select = new JFileChooser(); JFileChooser select = new JFileChooser();
Emulator.computer.pause(); Emulator.computer.pause();
BufferedImage i = Emulator.computer.getVideo().getFrameBuffer(); Image i = Emulator.computer.getVideo().getFrameBuffer();
BufferedImage j = new BufferedImage(i.getWidth(), i.getHeight(), i.getType()); BufferedImage bufImageARGB = SwingFXUtils.fromFXImage(i, null);
j.getGraphics().drawImage(i, 0, 0, null); // select.showSaveDialog(Emulator.getFrame());
select.showSaveDialog(Emulator.getFrame());
File targetFile = select.getSelectedFile(); File targetFile = select.getSelectedFile();
if (targetFile == null) { if (targetFile == null) {
return; return;
@ -334,38 +337,47 @@ public class EmulatorUILogic {
String filename = targetFile.getName(); String filename = targetFile.getName();
System.out.println("Writing screenshot to " + filename); System.out.println("Writing screenshot to " + filename);
String extension = filename.substring(filename.lastIndexOf(".") + 1); 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"; public static final String CONFIGURATION_DIALOG_NAME = "Configuration";
@InvokableAction( @InvokableAction(
name = "Configuration", name = "Configuration",
category = "general", category = "general",
description = "Edit emulator configuraion", description = "Edit emulator configuraion",
alternatives = "Reconfigure,Preferences,Settings") alternatives = "Reconfigure,Preferences,Settings")
public static void showConfig() { public static void showConfig() {
if (Emulator.getFrame().getModalDialogUI(CONFIGURATION_DIALOG_NAME) == null) { // if (Emulator.getFrame().getModalDialogUI(CONFIGURATION_DIALOG_NAME) == null) {
JPanel ui = new ConfigurationPanel(); // JPanel ui = new ConfigurationPanel();
Emulator.getFrame().registerModalDialog(ui, CONFIGURATION_DIALOG_NAME, null, false); // Emulator.getFrame().registerModalDialog(ui, CONFIGURATION_DIALOG_NAME, null, false);
} // }
Emulator.getFrame().showDialog(CONFIGURATION_DIALOG_NAME); // Emulator.getFrame().showDialog(CONFIGURATION_DIALOG_NAME);
} }
public static final String MEDIA_MANAGER_DIALOG_NAME = "Media Manager"; public static final String MEDIA_MANAGER_DIALOG_NAME = "Media Manager";
public static final String MEDIA_MANAGER_EDIT_DIALOG_NAME = "Media Details"; public static final String MEDIA_MANAGER_EDIT_DIALOG_NAME = "Media Details";
@InvokableAction( @InvokableAction(
name = "Media Manager", name = "Media Manager",
category = "general", category = "general",
description = "Show the media manager", description = "Show the media manager",
alternatives = "Insert disk;Eject disk;Browse;Download;Select") alternatives = "Insert disk;Eject disk;Browse;Download;Select")
public static void showMediaManager() { public static void showMediaManager() {
if (Emulator.getFrame().getModalDialogUI(MEDIA_MANAGER_DIALOG_NAME) == null) { // if (Emulator.getFrame().getModalDialogUI(MEDIA_MANAGER_DIALOG_NAME) == null) {
Emulator.getFrame().registerModalDialog(MediaLibrary.getInstance().buildUserInterface(), MEDIA_MANAGER_DIALOG_NAME, null, false); // Emulator.getFrame().registerModalDialog(MediaLibrary.getInstance().buildUserInterface(), MEDIA_MANAGER_DIALOG_NAME, null, false);
} // }
Emulator.getFrame().showDialog(MEDIA_MANAGER_DIALOG_NAME); // Emulator.getFrame().showDialog(MEDIA_MANAGER_DIALOG_NAME);
} }
public static boolean confirm(String message) { 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;
} }
} }

View File

@ -31,6 +31,7 @@ public class JaceApplication extends Application {
try { try {
AnchorPane node = (AnchorPane) fxmlLoader.load(); AnchorPane node = (AnchorPane) fxmlLoader.load();
controller = fxmlLoader.getController(); controller = fxmlLoader.getController();
controller.initialize();
Scene s = new Scene(node); Scene s = new Scene(node);
primaryStage.setScene(s); primaryStage.setScene(s);
} catch (IOException exception) { } catch (IOException exception) {
@ -38,6 +39,13 @@ public class JaceApplication extends Application {
} }
primaryStage.show(); 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());
});
} }
/** /**

View File

@ -6,11 +6,11 @@
package jace; package jace;
import jace.core.Video;
import javafx.scene.canvas.Canvas; import javafx.scene.canvas.Canvas;
import java.net.URL;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.scene.image.ImageView;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
/** /**
@ -21,18 +21,20 @@ public class JaceUIController {
@FXML @FXML
private ResourceBundle resources; private ResourceBundle resources;
@FXML
private Canvas displayCanvas;
@FXML @FXML
private Region notificationRegion; private Region notificationRegion;
@FXML
private ImageView appleScreen;
@FXML @FXML
public void initialize() { 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 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());
}
} }

View File

@ -237,13 +237,11 @@ public class Apple2e extends Computer {
Graphics g = null; Graphics g = null;
if (getVideo() != null) { if (getVideo() != null) {
getVideo().suspend(); getVideo().suspend();
g = getVideo().getScreen();
} }
try { try {
setVideo((Video) videoRenderer.getValue().getConstructor(Computer.class).newInstance(this)); setVideo((Video) videoRenderer.getValue().getConstructor(Computer.class).newInstance(this));
getVideo().configureVideoMode(); getVideo().configureVideoMode();
getVideo().reconfigure(); getVideo().reconfigure();
getVideo().setScreen(g);
Emulator.resizeVideo(); Emulator.resizeVideo();
getVideo().resume(); getVideo().resume();
} catch (InstantiationException | IllegalAccessException ex) { } catch (InstantiationException | IllegalAccessException ex) {

View File

@ -25,10 +25,10 @@ import jace.core.RAMEvent;
import jace.core.RAMListener; import jace.core.RAMListener;
import jace.core.Video; import jace.core.Video;
import jace.core.VideoWriter; import jace.core.VideoWriter;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.util.logging.Logger; 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 * 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 * configureVideoMode). The quality of the color rendering is sub-par compared
* to VideoNTSC. * to VideoNTSC.
* *
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com * @author Brendan Robert (BLuRry) brendan.robert@gmail.com
*/ */
public class VideoDHGR extends Video { public class VideoDHGR extends Video {
// Reorder bits 3,2,1,0 -> 0,3,2,1 // Reorder bits 3,2,1,0 -> 0,3,2,1
@ -79,7 +79,7 @@ public class VideoDHGR extends Video {
} }
@Override @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); displayHires(screen, xOffset, y, yGraphicsOffset + 0x02000);
} }
}; };
@ -90,7 +90,7 @@ public class VideoDHGR extends Video {
} }
@Override @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); displayHires(screen, xOffset, y, yGraphicsOffset + 0x04000);
} }
}; };
@ -101,7 +101,7 @@ public class VideoDHGR extends Video {
} }
@Override @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); displayDoubleHires(screen, xOffset, y, yGraphicsOffset + 0x02000);
} }
@ -117,7 +117,7 @@ public class VideoDHGR extends Video {
} }
@Override @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); displayDoubleHires(screen, xOffset, y, yGraphicsOffset + 0x04000);
} }
@ -133,7 +133,7 @@ public class VideoDHGR extends Video {
} }
@Override @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); displayText(screen, xOffset, y, yTextOffset + 0x0400);
} }
}; };
@ -144,7 +144,7 @@ public class VideoDHGR extends Video {
} }
@Override @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); displayText(screen, xOffset, y, yTextOffset + 0x0800);
} }
}; };
@ -155,7 +155,7 @@ public class VideoDHGR extends Video {
} }
@Override @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); displayText80(screen, xOffset, y, yTextOffset + 0x0400);
} }
@ -171,7 +171,7 @@ public class VideoDHGR extends Video {
} }
@Override @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); displayText80(screen, xOffset, y, yTextOffset + 0x0800);
} }
@ -187,7 +187,7 @@ public class VideoDHGR extends Video {
} }
@Override @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); displayLores(screen, xOffset, y, yTextOffset + 0x0400);
} }
@ -203,7 +203,7 @@ public class VideoDHGR extends Video {
} }
@Override @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); displayLores(screen, xOffset, y, yTextOffset + 0x0800);
} }
@ -219,7 +219,7 @@ public class VideoDHGR extends Video {
} }
@Override @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); displayDoubleLores(screen, xOffset, y, yTextOffset + 0x0400);
} }
@ -235,7 +235,7 @@ public class VideoDHGR extends Video {
} }
@Override @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); displayDoubleLores(screen, xOffset, y, yTextOffset + 0x0800);
} }
@ -251,7 +251,7 @@ public class VideoDHGR extends Video {
} }
@Override @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); displayMixed(screen, xOffset, y, yTextOffset, yGraphicsOffset);
} }
@ -288,7 +288,7 @@ public class VideoDHGR extends Video {
// color burst per byte (chat mauve compatibility) // color burst per byte (chat mauve compatibility)
boolean[] useColor = new boolean[80]; 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 // Skip odd columns since this does two at once
if ((xOffset & 0x01) == 1) { if ((xOffset & 0x01) == 1) {
return; return;
@ -314,7 +314,7 @@ public class VideoDHGR extends Video {
} }
boolean extraHalfBit = false; 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 // Skip odd columns since this does two at once
if ((xOffset & 0x01) == 1) { if ((xOffset & 0x01) == 1) {
return; return;
@ -369,40 +369,40 @@ public class VideoDHGR extends Video {
value |= 0x10000000; value |= 0x10000000;
} }
hgrToDhgr[bb1][bb2] = value; hgrToDhgr[bb1][bb2] = value;
hgrToDhgrBW[bb1 & 0x0ff][bb2] = hgrToDhgrBW[bb1 & 0x0ff][bb2]
byteDoubler((byte) bb1) | (byteDoubler((byte) bb2) << 14); = 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; int c1 = ((RAM128k) computer.getMemory()).getMainMemory().readByte(rowAddress + xOffset) & 0x0FF;
if ((y & 7) < 4) { if ((y & 7) < 4) {
c1 &= 15; c1 &= 15;
} else { } else {
c1 >>= 4; c1 >>= 4;
} }
DataBuffer b = screen.getRaster().getDataBuffer(); Color color = Palette.color[c1];
int yOffset = xyOffset[y][times14[xOffset]];
int color = Palette.color[c1].getRGB();
// Unrolled loop, faster // Unrolled loop, faster
b.setElem(yOffset++, color); PixelWriter writer = screen.getPixelWriter();
b.setElem(yOffset++, color); int x = xOffset * 7;
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, 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 c1 = ((RAM128k) computer.getMemory()).getAuxVideoMemory().readByte(rowAddress + xOffset) & 0x0FF;
int c2 = ((RAM128k) computer.getMemory()).getMainMemory().readByte(rowAddress + xOffset) & 0x0FF; int c2 = ((RAM128k) computer.getMemory()).getMainMemory().readByte(rowAddress + xOffset) & 0x0FF;
if ((y & 7) < 4) { if ((y & 7) < 4) {
@ -412,25 +412,26 @@ public class VideoDHGR extends Video {
c1 >>= 4; c1 >>= 4;
c2 >>= 4; c2 >>= 4;
} }
DataBuffer b = screen.getRaster().getDataBuffer(); PixelWriter writer = screen.getPixelWriter();
int yOffset = xyOffset[y][times14[xOffset]]; // int yOffset = xyOffset[y][times14[xOffset]];
int color = Palette.color[c1].getRGB(); Color color = Palette.color[c1];
int color2 = Palette.color[c2].getRGB();
// Unrolled loop, faster // Unrolled loop, faster
b.setElem(yOffset++, color); int x = xOffset * 7;
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color2); writer.setColor(x++, y, color);
b.setElem(yOffset++, color2); color = Palette.color[c2];
b.setElem(yOffset++, color2); writer.setColor(x++, y, color);
b.setElem(yOffset++, color2); writer.setColor(x++, y, color);
b.setElem(yOffset++, color2); writer.setColor(x++, y, color);
b.setElem(yOffset++, color2); writer.setColor(x++, y, color);
b.setElem(yOffset++, color2); writer.setColor(x++, y, color);
writer.setColor(x++, y, color);
writer.setColor(x++, y, color);
} }
boolean flashInverse = false; boolean flashInverse = false;
int flashTimer = 0; int flashTimer = 0;
@ -456,8 +457,6 @@ public class VideoDHGR extends Video {
// 80-BF - Normal characters (uppercase only) // 80-BF - Normal characters (uppercase only)
// C0-DF - Normal characters (repeat 80-9F) // C0-DF - Normal characters (repeat 80-9F)
// E0-FF - Normal characters (lowercase) // E0-FF - Normal characters (lowercase)
// MAP1: Normal map, flash inverse = false // MAP1: Normal map, flash inverse = false
CHAR_MAP1 = new int[256]; CHAR_MAP1 = new int[256];
// MAP2: Normal map, flash inverse = true // MAP2: Normal map, flash inverse = true
@ -544,7 +543,7 @@ public class VideoDHGR extends Video {
return currentCharMap[b & 0x0ff]; 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 // Skip odd columns since this does two at once
if ((xOffset & 0x01) == 1) { if ((xOffset & 0x01) == 1) {
return; return;
@ -561,7 +560,7 @@ public class VideoDHGR extends Video {
showBW(screen, times14[xOffset], y, out); 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 // Skip odd columns since this does two at once
if ((xOffset & 0x01) == 1) { if ((xOffset & 0x01) == 1) {
return; return;
@ -576,7 +575,7 @@ public class VideoDHGR extends Video {
showBW(screen, times14[xOffset], y, bits); 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); mixed.actualWriter().displayByte(screen, xOffset, y, textOffset, graphicsOffset);
} }
protected boolean hiresMode = false; protected boolean hiresMode = false;
@ -586,50 +585,50 @@ public class VideoDHGR extends Video {
public void configureVideoMode() { public void configureVideoMode() {
boolean page2 = SoftSwitches.PAGE2.isOn() && SoftSwitches._80STORE.isOff(); boolean page2 = SoftSwitches.PAGE2.isOn() && SoftSwitches._80STORE.isOff();
dhgrMode = SoftSwitches._80COL.getState() && SoftSwitches.DHIRES.getState() && SoftSwitches.HIRES.getState(); dhgrMode = SoftSwitches._80COL.getState() && SoftSwitches.DHIRES.getState() && SoftSwitches.HIRES.getState();
currentTextWriter = currentTextWriter
SoftSwitches._80COL.getState() = SoftSwitches._80COL.getState()
? page2 ? page2
? text80Page2 : text80Page1 ? text80Page2 : text80Page1
: page2 : page2
? textPage2 : textPage1; ? textPage2 : textPage1;
currentGraphicsWriter = currentGraphicsWriter
SoftSwitches._80COL.getState() && SoftSwitches.DHIRES.getState() = SoftSwitches._80COL.getState() && SoftSwitches.DHIRES.getState()
? SoftSwitches.HIRES.getState() ? SoftSwitches.HIRES.getState()
? page2 ? page2
? dhiresPage2 : dhiresPage1 ? dhiresPage2 : dhiresPage1
: page2 : page2
? dloresPage2 : dloresPage1 ? dloresPage2 : dloresPage1
: SoftSwitches.HIRES.getState() : SoftSwitches.HIRES.getState()
? page2 ? page2
? hiresPage2 : hiresPage1 ? hiresPage2 : hiresPage1
: page2 : page2
? loresPage2 : loresPage1; ? loresPage2 : loresPage1;
setCurrentWriter( setCurrentWriter(
SoftSwitches.TEXT.getState() ? currentTextWriter SoftSwitches.TEXT.getState() ? currentTextWriter
: SoftSwitches.MIXED.getState() ? mixed : SoftSwitches.MIXED.getState() ? mixed
: currentGraphicsWriter); : currentGraphicsWriter);
hiresMode = !SoftSwitches.DHIRES.getState(); 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(); //Graphics2D g = (Graphics2D) screen.getGraphics();
DataBuffer b = screen.getRaster().getDataBuffer(); int x = xOffset * 7;
int yOffset = xyOffset[y][xOffset]; PixelWriter writer = screen.getPixelWriter();
try { try {
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
int color = Palette.color[flipNybble[dhgrWord & 15]].getRGB(); Color color = Palette.color[flipNybble[dhgrWord & 15]];
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
b.setElem(yOffset++, color); writer.setColor(x++, y, color);
dhgrWord >>= 4; dhgrWord >>= 4;
} }
} catch (ArrayIndexOutOfBoundsException ex) { } catch (ArrayIndexOutOfBoundsException ex) {
Logger.getLogger(getClass().getName()).warning("Went out of bounds in video display"); Logger.getLogger(getClass().getName()).warning("Went out of bounds in video display");
} }
} }
static final int BLACK = Color.BLACK.getRGB(); static final Color BLACK = Color.BLACK;
static final int WHITE = Color.WHITE.getRGB(); static final Color WHITE = Color.WHITE;
static final int[][] xyOffset; static final int[][] xyOffset;
static { 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; int color = 0;
// Using the data buffer directly is about 15 times faster than setRGB // Using the data buffer directly is about 15 times faster than setRGB
// This is because setRGB does extra (useless) color model logic // This is because setRGB does extra (useless) color model logic
// For that matter even Graphics.drawLine is faster than setRGB! // 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 // This is equivilant to y*560 but is 5% faster
// Also, adding xOffset now makes it additionally 5% faster // Also, adding xOffset now makes it additionally 5% faster
//int yOffset = ((y << 4) + (y << 5) + (y << 9))+xOffset; //int yOffset = ((y << 4) + (y << 5) + (y << 9))+xOffset;
//is this lookup faster? int x = xOffset * 7;
int yOffset = xyOffset[y][xOffset]; PixelWriter writer = screen.getPixelWriter();
for (int i = 0; i < 28; i++) { for (int i = 0; i < 28; i++) {
// yOffset++ is used instead of yOffset+i, because it is faster // 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; dhgrWord >>= 1;
} }
} }
@ -742,7 +740,7 @@ public class VideoDHGR extends Video {
} }
@Override @Override
public void hblankStart(BufferedImage screen, int y, boolean isDirty) { public void hblankStart(WritableImage screen, int y, boolean isDirty) {
// Do nothing // Do nothing
} }
} }

View File

@ -23,24 +23,24 @@ import jace.core.Computer;
import jace.core.RAMEvent; import jace.core.RAMEvent;
import jace.core.RAMListener; import jace.core.RAMListener;
import jace.core.Video; import jace.core.Video;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
/** /**
* Provides a clean color monitor simulation, complete with text-friendly * Provides a clean color monitor simulation, complete with text-friendly
* palette and mixed color/bw (mode 7) rendering. This class extends the * palette and mixed color/bw (mode 7) rendering. This class extends the
* VideoDHGR class to provide all necessary video writers and other rendering * VideoDHGR class to provide all necessary video writers and other rendering
* mechanics, and then overrides the actual output routines (showBW, showDhgr) with more suitable * mechanics, and then overrides the actual output routines (showBW, showDhgr)
* (and much prettier) alternatives. Rather than draw to the video buffer every * with more suitable (and much prettier) alternatives. Rather than draw to the
* cycle, rendered screen info is pushed into a buffer with mask bits (to * video buffer every cycle, rendered screen info is pushed into a buffer with
* indicate B&W vs color) And the actual conversion happens at the end of the * mask bits (to indicate B&W vs color) And the actual conversion happens at the
* scanline during the HBLANK period. This video rendering was inspired by * end of the scanline during the HBLANK period. This video rendering was
* Blargg but was ultimately rewritten from scratch once the color palette was * inspired by Blargg but was ultimately rewritten from scratch once the color
* implemented. * palette was implemented.
* *
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com * @author Brendan Robert (BLuRry) brendan.robert@gmail.com
*/ */
public class VideoNTSC extends VideoDHGR { public class VideoNTSC extends VideoDHGR {
@ -69,19 +69,21 @@ public class VideoNTSC extends VideoDHGR {
} }
@Override @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) { if (lastKnownY != y) {
lastKnownY = y; lastKnownY = y;
pos = rowStart = divBy28[xOffset]; pos = rowStart = divBy28[xOffset];
colorActive = false; colorActive = false;
} else { } else {
if (pos > 20) pos-=20; if (pos > 20) {
pos -= 20;
}
} }
doDisplay(screen, xOffset, y, dhgrWord); doDisplay(screen, xOffset, y, dhgrWord);
} }
@Override @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) { if (lastKnownY != y) {
lastKnownY = y; lastKnownY = y;
pos = rowStart = divBy28[xOffset]; pos = rowStart = divBy28[xOffset];
@ -91,7 +93,7 @@ public class VideoNTSC extends VideoDHGR {
} }
@Override @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 // Skip odd columns since this does two at once
if ((xOffset & 0x01) == 1) { if ((xOffset & 0x01) == 1) {
return; return;
@ -119,14 +121,16 @@ public class VideoNTSC extends VideoDHGR {
scanline[pos++] = pat; scanline[pos++] = pat;
} }
private void doDisplay(BufferedImage screen, int xOffset, int y, int dhgrWord) { private void doDisplay(WritableImage screen, int xOffset, int y, int dhgrWord) {
if (pos >= 20) pos -= 20; if (pos >= 20) {
pos -= 20;
}
scanline[pos] = dhgrWord; scanline[pos] = dhgrWord;
pos++; pos++;
} }
@Override @Override
public void hblankStart(BufferedImage screen, int y, boolean isDirty) { public void hblankStart(WritableImage screen, int y, boolean isDirty) {
if (isDirty) { if (isDirty) {
renderScanline(screen, y); renderScanline(screen, y);
} }
@ -146,14 +150,14 @@ public class VideoNTSC extends VideoDHGR {
} }
} }
private void renderScanline(BufferedImage screen, int y) { private void renderScanline(WritableImage screen, int y) {
DataBuffer b = screen.getRaster().getDataBuffer(); PixelWriter writer = screen.getPixelWriter();
try { try {
// This is equivilant to y*560 but is 5% faster // This is equivilant to y*560 but is 5% faster
//int yOffset = ((y << 4) + (y << 5) + (y << 9))+xOffset; //int yOffset = ((y << 4) + (y << 5) + (y << 9))+xOffset;
// For some reason this jumps up to 40 in the wayout title screen (?) // For some reason this jumps up to 40 in the wayout title screen (?)
int p = pyOffset[y][rowStart]; int p = 0;
if (rowStart > 0) { if (rowStart > 0) {
getCurrentWriter().markDirty(y); getCurrentWriter().markDirty(y);
} }
@ -185,9 +189,9 @@ public class VideoNTSC extends VideoDHGR {
byteCounter++; byteCounter++;
} }
if (isBW) { if (isBW) {
b.setElem(p++, ((bits & 0x8) == 0) ? BLACK : WHITE); writer.setColor(p++, y, ((bits & 0x8) == 0) ? BLACK : WHITE);
} else { } else {
b.setElem(p++, activePalette[i % 4][bits & 0x07f]); writer.setArgb(p++, y, activePalette[i % 4][bits & 0x07f]);
} }
bits >>= 1; bits >>= 1;
if (i == 20) { if (i == 20) {
@ -196,7 +200,7 @@ public class VideoNTSC extends VideoDHGR {
} }
} else { } else {
for (int i = 0; i < 28; i++) { 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; bits >>= 1;
if (i == 20) { if (i == 20) {
bits |= add << (hiresMode ? 9 : 10); bits |= add << (hiresMode ? 9 : 10);
@ -208,7 +212,7 @@ public class VideoNTSC extends VideoDHGR {
for (int s = rowStart; s < 20; s++) { for (int s = rowStart; s < 20; s++) {
int bits = scanline[s]; int bits = scanline[s];
for (int i = 0; i < 28; i++) { 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; bits >>= 1;
} }
} }
@ -265,8 +269,8 @@ public class VideoNTSC extends VideoDHGR {
} }
double y1 = yiq[col][0]; double y1 = yiq[col][0];
double y2 = ((double) level / (double) maxLevel); double y2 = ((double) level / (double) maxLevel);
solidPalette[offset][pattern] = (255 << 24) | yiqToRgb(y1, 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] = (255 << 24) | yiqToRgb(y2, 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. // 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 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 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); 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) { public static double normalize(double x, double minX, double maxX) {

View File

@ -18,7 +18,7 @@
*/ */
package jace.core; 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) * 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 public Color[] color;
static { static {
color = new Color[16]; color = new Color[16];
color[ 0] = new Color( 0, 0, 0); color[ 0] = new Color( 0, 0, 0, 1);
color[ 1] = new Color(208, 0, 48); color[ 1] = new Color(208, 0, 48, 1);
color[ 2] = new Color( 0, 0,128); color[ 2] = new Color( 0, 0,128, 1);
color[ 3] = new Color(255, 0,255); color[ 3] = new Color(255, 0,255, 1);
color[ 4] = new Color( 0,128, 0); color[ 4] = new Color( 0,128, 0, 1);
color[ 5] = new Color(128,128,128); color[ 5] = new Color(128,128,128, 1);
color[ 6] = new Color( 0, 0,255); color[ 6] = new Color( 0, 0,255, 1);
color[ 7] = new Color( 96,160,255); color[ 7] = new Color( 96,160,255, 1);
color[ 8] = new Color(128, 80, 0); color[ 8] = new Color(128, 80, 0, 1);
color[ 9] = new Color(255,128, 0); color[ 9] = new Color(255,128, 0, 1);
color[10] = new Color(192,192,192); color[10] = new Color(192,192,192, 1);
color[11] = new Color(255,144,128); color[11] = new Color(255,144,128, 1);
color[12] = new Color( 0,255, 0); color[12] = new Color( 0,255, 0, 1);
color[13] = new Color(255,255, 0); color[13] = new Color(255,255, 0, 1);
color[14] = new Color( 64,255,144); color[14] = new Color( 64,255,144, 1);
color[15] = new Color(255,255,255); color[15] = new Color(255,255,255, 1);
} }
} }

View File

@ -96,13 +96,13 @@ public class Utility {
try { try {
// Try to create an instance of the object // Try to create an instance of the object
String className = pckgname + "." + classname; String className = pckgname + "." + classname;
// System.out.println("Class: " + className); System.out.println("Class: " + className);
Class c = Class.forName(className); Class c = Class.forName(className);
if (clazz.isAssignableFrom(c)) { if (clazz.isAssignableFrom(c)) {
output.add(c); output.add(c);
} }
} catch (ClassNotFoundException cnfex) { } catch (Throwable ex) {
System.err.println(cnfex); System.err.println(ex);
} }
} else { } else {
// System.out.println("Skipping non class: " + filename); // System.out.println("Skipping non class: " + filename);
@ -284,7 +284,7 @@ public class Utility {
} }
public static void runModalProcess(String title, final Runnable runnable) { 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(); final JProgressBar progressBar = new JProgressBar();
progressBar.setIndeterminate(true); progressBar.setIndeterminate(true);
final JPanel contentPane = new JPanel(); final JPanel contentPane = new JPanel();
@ -292,16 +292,16 @@ public class Utility {
contentPane.setLayout(new BorderLayout()); contentPane.setLayout(new BorderLayout());
contentPane.add(new JLabel(title), BorderLayout.NORTH); contentPane.add(new JLabel(title), BorderLayout.NORTH);
contentPane.add(progressBar, BorderLayout.CENTER); contentPane.add(progressBar, BorderLayout.CENTER);
frame.setContentPane(contentPane); // frame.setContentPane(contentPane);
frame.pack(); // frame.pack();
frame.setLocationRelativeTo(null); // frame.setLocationRelativeTo(null);
frame.setVisible(true); // frame.setVisible(true);
//
new Thread(() -> { // new Thread(() -> {
runnable.run(); // runnable.run();
frame.setVisible(false); // frame.setVisible(false);
frame.dispose(); // frame.dispose();
}).start(); // }).start();
} }
public static class RankingComparator implements Comparator<String> { public static class RankingComparator implements Comparator<String> {
@ -399,7 +399,7 @@ public class Utility {
public static void gripe(final String message) { public static void gripe(final String message) {
EventQueue.invokeLater(() -> { EventQueue.invokeLater(() -> {
JOptionPane.showMessageDialog(Emulator.getFrame(), message, "Error", JOptionPane.ERROR_MESSAGE); // JOptionPane.showMessageDialog(Emulator.getFrame(), message, "Error", JOptionPane.ERROR_MESSAGE);
}); });
} }

View File

@ -22,8 +22,8 @@ import jace.state.Stateful;
import jace.Emulator; import jace.Emulator;
import jace.config.ConfigurableField; import jace.config.ConfigurableField;
import jace.config.InvokableAction; import jace.config.InvokableAction;
import java.awt.Graphics; import javafx.scene.image.Image;
import java.awt.image.BufferedImage; import javafx.scene.image.WritableImage;
/** /**
* Generic abstraction of a 560x192 video output device which renders 40 columns * 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 { public abstract class Video extends Device {
@Stateful @Stateful
BufferedImage video; WritableImage video;
WritableImage visible;
VideoWriter currentWriter; VideoWriter currentWriter;
Graphics screen;
private byte floatingBus = 0; private byte floatingBus = 0;
private int width = 560; private int width = 560;
private int height = 192; private int height = 192;
@ -94,7 +94,8 @@ public abstract class Video extends Device {
public Video(Computer computer) { public Video(Computer computer) {
super(computer); super(computer);
suspend(); suspend();
video = new BufferedImage(560, 192, BufferedImage.TYPE_INT_RGB); video = new WritableImage(560, 192);
visible = new WritableImage(560, 192);
vPeriod = 0; vPeriod = 0;
hPeriod = 0; hPeriod = 0;
forceRefresh(); forceRefresh();
@ -116,15 +117,6 @@ public abstract class Video extends Device {
return height; return height;
} }
public void setScreen(Graphics g) {
screen = g;
}
public Graphics getScreen() {
return screen;
}
public VideoWriter getCurrentWriter() { public VideoWriter getCurrentWriter() {
return currentWriter; return currentWriter;
} }
@ -139,14 +131,14 @@ public abstract class Video extends Device {
public static int MIN_SCREEN_REFRESH = 15; public static int MIN_SCREEN_REFRESH = 15;
public void redraw() { public void redraw() {
if (screen == null || video == null) {
return;
}
screenDirty = false; screenDirty = false;
screen.drawImage(video, 0, 0, width, height, null); javafx.application.Platform.runLater(() -> {
if (Emulator.getFrame() != null) { visible.getPixelWriter().setPixels(0, 0, 560, 192, video.getPixelReader(), 0, 0);
Emulator.getFrame().repaintIndicators(); });
} // screen.drawImage(video, 0, 0, width, height, null);
// if (Emulator.getFrame() != null) {
// Emulator.getFrame().repaintIndicators();
// }
} }
public void vblankStart() { public void vblankStart() {
@ -157,7 +149,7 @@ public abstract class Video extends Device {
abstract public void vblankEnd(); 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) { public void setScannerLocation(int loc) {
scannerAddress = loc; scannerAddress = loc;
@ -294,7 +286,7 @@ public abstract class Video extends Device {
return "vid"; return "vid";
} }
public BufferedImage getFrameBuffer() { public Image getFrameBuffer() {
return video; return visible;
} }
} }

View File

@ -18,7 +18,7 @@
*/ */
package jace.core; 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 * 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 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 // 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() { public VideoWriter actualWriter() {

View File

@ -349,7 +349,7 @@ public class CardAppleMouse extends Card implements MouseListener {
*/ */
private void initMouse() { private void initMouse() {
mouseActive.setDescription("Active"); mouseActive.setDescription("Active");
Emulator.getFrame().addIndicator(this, mouseActive, 2000); // Emulator.getFrame().addIndicator(this, mouseActive, 2000);
setClampWindowX(0, 0x3ff); setClampWindowX(0, 0x3ff);
setClampWindowY(0, 0x3ff); setClampWindowY(0, 0x3ff);
clearMouse(); clearMouse();
@ -463,31 +463,32 @@ public class CardAppleMouse extends Card implements MouseListener {
if (drawingArea == null) { if (drawingArea == null) {
return; return;
} }
Graphics2D screen = (Graphics2D) computer.getVideo().getScreen(); // Graphics2D screen = (Graphics2D) computer.getVideo().getScreen();
// Point currentMouseLocation = MouseInfo.getPointerInfo().getLocation(); // Point currentMouseLocation = MouseInfo.getPointerInfo().getLocation();
// Point topLeft = drawingArea.getLocationOnScreen(); // Point topLeft = drawingArea.getLocationOnScreen();
Point currentMouseLocation = Emulator.getFrame().getContentPane().getMousePosition(); Point currentMouseLocation = null; // = Emulator.getFrame().getContentPane().getMousePosition();
if (currentMouseLocation == null) return; // if (currentMouseLocation == null) return;
// Point topLeft = drawingArea.getLocationOnScreen(); // Point topLeft = drawingArea.getLocationOnScreen();
Point topLeft = new Point(0,0); Point topLeft = new Point(0,0);
Dimension d = drawingArea.getBounds().getSize(); Dimension d = drawingArea.getBounds().getSize();
if (screen.getTransform() != null) { // if (screen.getTransform() != null) {
d = new Dimension((int) (screen.getTransform().getScaleX() * d.width), // d = new Dimension((int) (screen.getTransform().getScaleX() * d.width),
(int) (screen.getTransform().getScaleY() * d.height)); // (int) (screen.getTransform().getScaleY() * d.height));
topLeft.x += screen.getTransform().getTranslateX(); // topLeft.x += screen.getTransform().getTranslateX();
topLeft.y += screen.getTransform().getTranslateY(); // topLeft.y += screen.getTransform().getTranslateY();
} // }
if (fullscreenFix) { if (fullscreenFix) {
if (Emulator.getFrame().isFullscreenActive()) { // if (Emulator.getFrame().isFullscreenActive()) {
Toolkit t = Toolkit.getDefaultToolkit(); // Toolkit t = Toolkit.getDefaultToolkit();
topLeft.y -= t.getScreenInsets(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration()).top; // 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?) // Scale X and Y to the clamping range of the mouse (will this work for most software?)
double width = clampMax.x - clampMin.x; double width = clampMax.x - clampMin.x;
double x = currentMouseLocation.getX() - topLeft.x; double x = 0;
// double x = currentMouseLocation.getX() - topLeft.x;
x *= width; x *= width;
x /= d.width; x /= d.width;
x += clampMin.x; x += clampMin.x;
@ -499,7 +500,8 @@ public class CardAppleMouse extends Card implements MouseListener {
} }
double height = clampMax.y - clampMin.y; double height = clampMax.y - clampMin.y;
double y = currentMouseLocation.getY() - topLeft.y; double y = 0;
// double y = currentMouseLocation.getY() - topLeft.y;
y *= height; y *= height;
y /= d.height; y /= d.height;
y += clampMin.y; y += clampMin.y;

View File

@ -77,9 +77,9 @@ public class CardDiskII extends Card implements Reconfigurable, MediaConsumerPar
currentDrive = drive1; currentDrive = drive1;
drive1.reset(); drive1.reset();
drive2.reset(); drive2.reset();
if (Emulator.getFrame() != null) { // if (Emulator.getFrame() != null) {
Emulator.getFrame().removeIndicators(this); // Emulator.getFrame().removeIndicators(this);
} // }
// Motherboard.cancelSpeedRequest(this); // Motherboard.cancelSpeedRequest(this);
} }
@ -108,7 +108,7 @@ public class CardDiskII extends Card implements Reconfigurable, MediaConsumerPar
case 0x9: case 0x9:
// drive on // drive on
currentDrive.setOn(true); currentDrive.setOn(true);
Emulator.getFrame().addIndicator(this, currentDrive.getIcon()); // Emulator.getFrame().addIndicator(this, currentDrive.getIcon());
break; break;
case 0xA: case 0xA:

View File

@ -92,7 +92,7 @@ public class CardRamFactor extends Card {
@Override @Override
protected void handleIOAccess(int register, TYPE type, int value, RAMEvent e) { protected void handleIOAccess(int register, TYPE type, int value, RAMEvent e) {
Emulator.getFrame().addIndicator(this, indicator); // Emulator.getFrame().addIndicator(this, indicator);
value &= 0x0ff; value &= 0x0ff;
switch (register) { switch (register) {
case 0: case 0:

View File

@ -204,7 +204,7 @@ public class CardSSC extends Card implements Reconfigurable, Runnable {
newValue |= (PORT_CONNECTED && inputAvailable()) ? 0x00 : 0x01; newValue |= (PORT_CONNECTED && inputAvailable()) ? 0x00 : 0x01;
} }
if (register == ACIA_Data) { if (register == ACIA_Data) {
Emulator.getFrame().addIndicator(this, activityIndicator); // Emulator.getFrame().addIndicator(this, activityIndicator);
newValue = getInputByte(); newValue = getInputByte();
if (RECV_IRQ_ENABLED) { if (RECV_IRQ_ENABLED) {
triggerIRQ(); triggerIRQ();
@ -256,7 +256,7 @@ public class CardSSC extends Card implements Reconfigurable, Runnable {
break; break;
case WRITE: case WRITE:
if (register == ACIA_Data) { if (register == ACIA_Data) {
Emulator.getFrame().addIndicator(this, activityIndicator); // Emulator.getFrame().addIndicator(this, activityIndicator);
sendOutputByte(value & 0x0FF); sendOutputByte(value & 0x0FF);
if (TRANS_IRQ_ENABLED) { if (TRANS_IRQ_ENABLED) {
triggerIRQ(); triggerIRQ();

View File

@ -157,7 +157,7 @@ public class CardThunderclock extends Card {
clockIcon.setDescription("Slot " + getSlot()); clockIcon.setDescription("Slot " + getSlot());
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if ((now - lastShownIcon) > MIN_WAIT) { if ((now - lastShownIcon) > MIN_WAIT) {
Emulator.getFrame().addIndicator(this, clockIcon, 3000); // Emulator.getFrame().addIndicator(this, clockIcon, 3000);
} }
lastShownIcon = now; lastShownIcon = now;
} }
@ -325,6 +325,6 @@ public class CardThunderclock extends Card {
ram.writeByte(patchLoc + 1, (byte) year); ram.writeByte(patchLoc + 1, (byte) year);
ram.writeByte(patchLoc + 2, (byte) MOS65C02.OPCODE.NOP.getCode()); ram.writeByte(patchLoc + 2, (byte) MOS65C02.OPCODE.NOP.getCode());
ram.writeByte(patchLoc + 3, (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);
} }
} }

View File

@ -159,7 +159,7 @@ public class CardMassStorage extends Card implements MediaConsumerParent {
MOS65C02 cpu = (MOS65C02) computer.getCpu(); MOS65C02 cpu = (MOS65C02) computer.getCpu();
// System.out.println(e.getType()+" "+Integer.toHexString(e.getAddress())+" from instruction at "+Integer.toHexString(cpu.getProgramCounter())); // System.out.println(e.getType()+" "+Integer.toHexString(e.getAddress())+" from instruction at "+Integer.toHexString(cpu.getProgramCounter()));
if (type.isRead()) { if (type.isRead()) {
Emulator.getFrame().addIndicator(this, currentDrive.getIcon()); // Emulator.getFrame().addIndicator(this, currentDrive.getIcon());
if (drive1.getCurrentDisk() == null && drive2.getCurrentDisk() == null) { if (drive1.getCurrentDisk() == null && drive2.getCurrentDisk() == null) {
e.setNewValue(0); e.setNewValue(0);
return; return;

View File

@ -287,7 +287,7 @@ public class MediaEditUI extends javax.swing.JPanel {
private void SaveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SaveButtonActionPerformed private void SaveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SaveButtonActionPerformed
persist(); persist();
library.refreshUI(); library.refreshUI();
Emulator.getFrame().closeDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME); // Emulator.getFrame().closeDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME);
}//GEN-LAST:event_SaveButtonActionPerformed }//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 private void CancellationButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CancellationButtonActionPerformed
if (EmulatorUILogic.confirm("Abandon unsaved changes? Are you sure?")) { 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 }//GEN-LAST:event_CancellationButtonActionPerformed

View File

@ -19,7 +19,7 @@
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="orderToolbar" min="-2" max="-2" attributes="0"/> <Component id="orderToolbar" min="-2" max="-2" attributes="0"/>
<Component id="tocPane" pref="207" max="32767" attributes="0"/> <Component id="tocPane" max="32767" attributes="0"/>
</Group> </Group>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Group type="102" attributes="0">

View File

@ -243,11 +243,11 @@ public class MediaLibraryUI extends javax.swing.JPanel {
return; return;
} }
System.out.println(getSelectedEntry().name); System.out.println(getSelectedEntry().name);
Emulator.getFrame().registerModalDialog( // Emulator.getFrame().registerModalDialog(
MediaLibrary.getInstance().buildEditInstance(this, getSelectedEntry()), // MediaLibrary.getInstance().buildEditInstance(this, getSelectedEntry()),
MEDIA_MANAGER_EDIT_DIALOG_NAME, // MEDIA_MANAGER_EDIT_DIALOG_NAME,
MEDIA_MANAGER_DIALOG_NAME, true); // MEDIA_MANAGER_DIALOG_NAME, true);
Emulator.getFrame().showDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME); // Emulator.getFrame().showDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME);
}//GEN-LAST:event_ViewEditActionPerformed }//GEN-LAST:event_ViewEditActionPerformed
private void RemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RemoveActionPerformed 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 }//GEN-LAST:event_RemoveActionPerformed
private void CreateNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CreateNewActionPerformed private void CreateNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CreateNewActionPerformed
Emulator.getFrame().registerModalDialog( // Emulator.getFrame().registerModalDialog(
MediaLibrary.getInstance().buildEditInstance(this, null), // MediaLibrary.getInstance().buildEditInstance(this, null),
MEDIA_MANAGER_EDIT_DIALOG_NAME, // MEDIA_MANAGER_EDIT_DIALOG_NAME,
MEDIA_MANAGER_DIALOG_NAME, true); // MEDIA_MANAGER_DIALOG_NAME, true);
Emulator.getFrame().showDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME); // Emulator.getFrame().showDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME);
}//GEN-LAST:event_CreateNewActionPerformed }//GEN-LAST:event_CreateNewActionPerformed
private void FavoriteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FavoriteActionPerformed private void FavoriteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FavoriteActionPerformed

View File

@ -18,11 +18,11 @@
*/ */
package jace.state; package jace.state;
import java.awt.image.BufferedImage;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javafx.scene.image.Image;
/** /**
* A state is nothing more than a map of captured variable values, except that a * A state is nothing more than a map of captured variable values, except that a
@ -40,7 +40,7 @@ public class State extends HashMap<ObjectGraphNode, StateValue> implements Seria
State nextState; State nextState;
// Tail is only correct on the head node, everything else will likely be null // Tail is only correct on the head node, everything else will likely be null
State tail; State tail;
BufferedImage screenshot; Image screenshot;
/** /**
* Removing the next state allows a LRU buffer of states -- but states can't * Removing the next state allows a LRU buffer of states -- but states can't

View File

@ -37,6 +37,8 @@ import java.util.Set;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; 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++; stateCount++;
} }
private BufferedImage getScreenshot() { private Image getScreenshot() {
BufferedImage screen = computer.getVideo().getFrameBuffer(); Image screen = computer.getVideo().getFrameBuffer();
ColorModel cm = screen.getColorModel(); return new WritableImage(screen.getPixelReader(), (int) screen.getWidth(), (int) screen.getHeight());
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = screen.copyData(null);
return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
} }
private State captureAlphaState() { private State captureAlphaState() {

View File

@ -276,7 +276,7 @@ public abstract class AbstractEmulatorFrame extends javax.swing.JFrame implement
computer.getVideo().setWidth(width1); computer.getVideo().setWidth(width1);
computer.getVideo().setHeight(height1); computer.getVideo().setHeight(height1);
if (!isFullscreen || !fullscreenEnforceRatio) { if (!isFullscreen || !fullscreenEnforceRatio) {
computer.getVideo().setScreen(getScreenGraphics()); // computer.getVideo().setScreen(getScreenGraphics());
} }
computer.getVideo().forceRefresh(); computer.getVideo().forceRefresh();
screen.validate(); screen.validate();
@ -333,7 +333,7 @@ public abstract class AbstractEmulatorFrame extends javax.swing.JFrame implement
g.fill(getBounds()); g.fill(getBounds());
Graphics2D gg = (Graphics2D) g.create(b.x, b.y, b.width, b.height); 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); gg.scale((double) b.width / (double) sw, (double) b.height / (double) sh);
computer.getVideo().setScreen(gg); // computer.getVideo().setScreen(gg);
computer.getVideo().resume(); computer.getVideo().resume();
computer.resume(); computer.resume();
} else { } else {

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import javafx.scene.canvas.*?> <?import javafx.scene.canvas.*?>
<?import java.lang.*?> <?import java.lang.*?>
<?import java.util.*?> <?import java.util.*?>
@ -7,9 +8,9 @@
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="384.0" prefWidth="560.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="jace.JaceUIController"> <AnchorPane id="AnchorPane" prefHeight="384.0" prefWidth="560.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="jace.JaceUIController">
<children> <children>
<Canvas fx:id="displayCanvas" height="384.0" width="560.0" />
<Region fx:id="notificationRegion" prefHeight="50.0" prefWidth="510.0" AnchorPane.bottomAnchor="5.0" AnchorPane.rightAnchor="5.0" /> <Region fx:id="notificationRegion" prefHeight="50.0" prefWidth="510.0" AnchorPane.bottomAnchor="5.0" AnchorPane.rightAnchor="5.0" />
<ImageView fx:id="appleScreen" fitHeight="384.0" fitWidth="560.0" pickOnBounds="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children> </children>
</AnchorPane> </AnchorPane>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import javafx.scene.canvas.*?> <?import javafx.scene.canvas.*?>
<?import java.lang.*?> <?import java.lang.*?>
<?import java.util.*?> <?import java.util.*?>
@ -7,9 +8,9 @@
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="384.0" prefWidth="560.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="jace.JaceUIController"> <AnchorPane id="AnchorPane" prefHeight="384.0" prefWidth="560.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="jace.JaceUIController">
<children> <children>
<Canvas fx:id="displayCanvas" height="384.0" width="560.0" />
<Region fx:id="notificationRegion" prefHeight="50.0" prefWidth="510.0" AnchorPane.bottomAnchor="5.0" AnchorPane.rightAnchor="5.0" /> <Region fx:id="notificationRegion" prefHeight="50.0" prefWidth="510.0" AnchorPane.bottomAnchor="5.0" AnchorPane.rightAnchor="5.0" />
<ImageView fx:id="appleScreen" fitHeight="384.0" fitWidth="560.0" pickOnBounds="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children> </children>
</AnchorPane> </AnchorPane>

View File

@ -1,5 +1,5 @@
#Generated by Maven #Generated by Maven
#Sat Sep 20 01:41:50 CDT 2014 #Tue Feb 03 00:36:09 CST 2015
version=2.0-SNAPSHOT version=2.0-SNAPSHOT
groupId=org.badvision groupId=org.badvision
artifactId=jace artifactId=jace

View File

@ -220,7 +220,6 @@ jace/apple2e/softswitch/IntC8SoftSwitch$1.class
jace/config/ConfigurableField.class jace/config/ConfigurableField.class
jace/core/Video.class jace/core/Video.class
jace/hardware/mockingboard/NoiseGenerator.class jace/hardware/mockingboard/NoiseGenerator.class
jace/Emulator$1.class
jace/applesoft/Command$TOKEN.class jace/applesoft/Command$TOKEN.class
jace/core/RAMEvent$VALUE.class jace/core/RAMEvent$VALUE.class
jace/apple2e/softswitch/Memory2SoftSwitch.class jace/apple2e/softswitch/Memory2SoftSwitch.class
@ -243,7 +242,6 @@ jace/cheat/MemorySpy$3.class
jace/library/MediaEditUI$2.class jace/library/MediaEditUI$2.class
jace/hardware/mockingboard/R6522.class jace/hardware/mockingboard/R6522.class
jace/library/MediaCache.class jace/library/MediaCache.class
jace/Emulator$2.class
jace/apple2e/VideoNTSC$rgbMode.class jace/apple2e/VideoNTSC$rgbMode.class
jace/ConvertDiskImage.class jace/ConvertDiskImage.class
jace/config/ClassSelection.class jace/config/ClassSelection.class