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

View File

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

View File

@ -21,14 +21,17 @@ package jace.state;
import jace.Emulator;
import jace.apple2e.SoftSwitches;
import jace.config.ConfigurableField;
import jace.config.InvokableAction;
import jace.config.Reconfigurable;
import jace.core.Computer;
import jace.core.PagedMemory;
import jace.core.Video;
import java.awt.image.BufferedImage;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -37,6 +40,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import javafx.scene.input.KeyCode;
/**
*
@ -64,12 +68,13 @@ public class StateManager implements Reconfigurable {
private ObjectGraphNode<BufferedImage> imageGraphNode;
Computer computer;
private StateManager(Computer computer) {
this.computer = computer;
}
private void buildStateMap() {
allStateVariables = new HashSet<>();
allStateVariables = new LinkedHashSet<>();
objectLookup = new WeakHashMap<>();
ObjectGraphNode emulator = new ObjectGraphNode(Emulator.instance);
emulator.name = "Emulator";
@ -295,7 +300,7 @@ public class StateManager implements Reconfigurable {
public void captureState() {
// 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.
if (!isValid) {
alphaState = null;
@ -402,6 +407,17 @@ public class StateManager implements Reconfigurable {
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) {
boolean resume = computer.pause();
State state = alphaState.tail;
@ -412,7 +428,7 @@ public class StateManager implements Reconfigurable {
state.apply();
alphaState.tail = state;
state.nextState = null;
computer.getVideo().forceRefresh();
Video.forceRefresh();
System.gc();
if (resume) {
computer.resume();