Issue #22: Minor progress hooking up state manager; still doesn't work and crashes the emulator when triggered. :/

This commit is contained in:
Brendan Robert 2016-02-23 01:45:11 -06:00
parent 3f115624e6
commit 6515c90856
4 changed files with 43 additions and 20 deletions

View File

@ -46,6 +46,7 @@ public class Emulator {
* @param args * @param args
*/ */
public Emulator(List<String> args) { public Emulator(List<String> args) {
instance = this;
computer = new Apple2e(); computer = new Apple2e();
Configuration.buildTree(); Configuration.buildTree();
Configuration.loadSettings(); Configuration.loadSettings();

View File

@ -29,10 +29,9 @@ 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
* per scanline. This also triggers VBL and updates the physical screen. * per scanline. This also triggers VBL and updates the physical screen.
* Subclasses are used to manage actual rendering via ScreenWriter * Subclasses are used to manage actual rendering via ScreenWriter
* implementations. * implementations. Created on November 10, 2006, 4:29 PM
* Created on November 10, 2006, 4:29 PM
* *
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com * @author Brendan Robert (BLuRry) brendan.robert@gmail.com
*/ */
@Stateful @Stateful
public abstract class Video extends Device { public abstract class Video extends Device {
@ -90,6 +89,7 @@ public abstract class Video extends Device {
/** /**
* Creates a new instance of Video * Creates a new instance of Video
*
* @param computer * @param computer
*/ */
public Video(Computer computer) { public Video(Computer computer) {
@ -99,21 +99,21 @@ public abstract class Video extends Device {
visible = new WritableImage(560, 192); visible = new WritableImage(560, 192);
vPeriod = 0; vPeriod = 0;
hPeriod = 0; hPeriod = 0;
forceRefresh(); _forceRefresh();
} }
public void setWidth(int w) { public void setWidth(int w) {
width = w; width = w;
} }
public int getWidth() { public int getWidth() {
return width; return width;
} }
public void setHeight(int h) { public void setHeight(int h) {
height = h; height = h;
} }
public int getHeight() { public int getHeight() {
return height; return height;
} }
@ -136,6 +136,7 @@ public abstract class Video extends Device {
visible.getPixelWriter().setPixels(0, 0, 560, 192, video.getPixelReader(), 0, 0); visible.getPixelWriter().setPixels(0, 0, 560, 192, video.getPixelReader(), 0, 0);
} }
}; };
public void redraw() { public void redraw() {
screenDirty = false; screenDirty = false;
javafx.application.Platform.runLater(redrawScreen); javafx.application.Platform.runLater(redrawScreen);
@ -209,8 +210,8 @@ public abstract class Video extends Device {
abstract public void configureVideoMode(); abstract public void configureVideoMode();
protected static int byteDoubler(byte b) { protected static int byteDoubler(byte b) {
int num = int num
// Skip hi-bit because it's not used in display = // Skip hi-bit because it's not used in display
// ((b&0x080)<<7) | // ((b&0x080)<<7) |
((b & 0x040) << 6) ((b & 0x040) << 6)
| ((b & 0x020) << 5) | ((b & 0x020) << 5)
@ -271,18 +272,22 @@ public abstract class Video extends Device {
} }
@InvokableAction(name = "Refresh screen", @InvokableAction(name = "Refresh screen",
category = "display", category = "display",
description = "Marks screen contents as changed, forcing full screen redraw", description = "Marks screen contents as changed, forcing full screen redraw",
alternatives = "redraw", alternatives = "redraw",
defaultKeyMapping = {"ctrl+shift+r"}) defaultKeyMapping = {"ctrl+shift+r"})
public static final void forceRefresh() { public static final void forceRefresh() {
if (Emulator.computer != null && Emulator.computer.video != null) { if (Emulator.computer != null && Emulator.computer.video != null) {
Emulator.computer.video.lineDirty = true; Emulator.computer.video._forceRefresh();
Emulator.computer.video.screenDirty = true;
Emulator.computer.video.forceRedrawRowCount = APPLE_SCREEN_LINES + 1;
} }
} }
private void _forceRefresh() {
lineDirty = true;
screenDirty = true;
forceRedrawRowCount = APPLE_SCREEN_LINES + 1;
}
@Override @Override
public String getShortName() { public String getShortName() {
return "vid"; return "vid";

View File

@ -21,6 +21,7 @@ package jace.state;
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.LinkedHashSet;
import java.util.Set; import java.util.Set;
import javafx.scene.image.Image; import javafx.scene.image.Image;
@ -78,7 +79,7 @@ public class State extends HashMap<ObjectGraphNode, StateValue> implements Seria
} }
public void apply() { public void apply() {
Set<ObjectGraphNode> applied = new HashSet<>(); Set<ObjectGraphNode> applied = new LinkedHashSet<>();
State current = this; State current = this;
while (current != null) { while (current != null) {
for (StateValue val : current.values()) { for (StateValue val : current.values()) {

View File

@ -21,14 +21,17 @@ package jace.state;
import jace.Emulator; import jace.Emulator;
import jace.apple2e.SoftSwitches; import jace.apple2e.SoftSwitches;
import jace.config.ConfigurableField; import jace.config.ConfigurableField;
import jace.config.InvokableAction;
import jace.config.Reconfigurable; import jace.config.Reconfigurable;
import jace.core.Computer; import jace.core.Computer;
import jace.core.PagedMemory; import jace.core.PagedMemory;
import jace.core.Video;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -37,6 +40,7 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.WritableImage; import javafx.scene.image.WritableImage;
import javafx.scene.input.KeyCode;
/** /**
* *
@ -64,12 +68,13 @@ public class StateManager implements Reconfigurable {
private ObjectGraphNode<BufferedImage> imageGraphNode; private ObjectGraphNode<BufferedImage> imageGraphNode;
Computer computer; Computer computer;
private StateManager(Computer computer) { private StateManager(Computer computer) {
this.computer = computer; this.computer = computer;
} }
private void buildStateMap() { private void buildStateMap() {
allStateVariables = new HashSet<>(); allStateVariables = new LinkedHashSet<>();
objectLookup = new WeakHashMap<>(); objectLookup = new WeakHashMap<>();
ObjectGraphNode emulator = new ObjectGraphNode(Emulator.instance); ObjectGraphNode emulator = new ObjectGraphNode(Emulator.instance);
emulator.name = "Emulator"; emulator.name = "Emulator";
@ -295,7 +300,7 @@ public class StateManager implements Reconfigurable {
public void captureState() { public void captureState() {
// If the state graph is invalidated it means we have to abandon all // If the state graph is invalidated it means we have to abandon all
// previously captured states. This helps ensure that rewinding will // previously captured states. This helps ensure that rewinding will
// not result in an unintended or invalid state. // not result in an unintended or invalid state.
if (!isValid) { if (!isValid) {
alphaState = null; alphaState = null;
@ -402,6 +407,17 @@ public class StateManager implements Reconfigurable {
captureState(); captureState();
} }
@InvokableAction(
name = "Rewind",
alternatives = "Timewarp",
description = "Go back 1 second",
defaultKeyMapping = {"ctrl+shift+Open Bracket"}
)
public static void beKindRewind() {
StateManager manager = getInstance(Emulator.computer);
new Thread(()->manager.rewind(60 / manager.captureFrequency)).start();
}
public void rewind(int numStates) { public void rewind(int numStates) {
boolean resume = computer.pause(); boolean resume = computer.pause();
State state = alphaState.tail; State state = alphaState.tail;
@ -412,7 +428,7 @@ public class StateManager implements Reconfigurable {
state.apply(); state.apply();
alphaState.tail = state; alphaState.tail = state;
state.nextState = null; state.nextState = null;
computer.getVideo().forceRefresh(); Video.forceRefresh();
System.gc(); System.gc();
if (resume) { if (resume) {
computer.resume(); computer.resume();