Cleanup of some parts, but more importantly huge bugfix to get config load/save and other config options showing up. Config is now very close to 100% bug-free

This commit is contained in:
Brendan Robert 2015-03-17 00:57:25 -05:00
parent 555f125a3b
commit 5416b0a787
4 changed files with 77 additions and 43 deletions

View File

@ -45,10 +45,10 @@ import javafx.scene.image.WritableImage;
public class VideoNTSC extends VideoDHGR { public class VideoNTSC extends VideoDHGR {
@ConfigurableField(name = "Text palette", shortName = "textPalette", defaultValue = "false", description = "Use text-friendly color palette") @ConfigurableField(name = "Text palette", shortName = "textPalette", defaultValue = "false", description = "Use text-friendly color palette")
public static boolean useTextPalette = false; public Boolean useTextPalette = true;
static int activePalette[][]; int activePalette[][] = textPalette;
@ConfigurableField(name = "Video 7", shortName = "video7", defaultValue = "true", description = "Enable Video 7 RGB rendering support") @ConfigurableField(name = "Video 7", shortName = "video7", defaultValue = "true", description = "Enable Video 7 RGB rendering support")
public static boolean enableVideo7 = false; public Boolean enableVideo7 = true;
// Scanline represents 560 bits, divided up into 28-bit words // Scanline represents 560 bits, divided up into 28-bit words
int[] scanline = new int[20]; int[] scanline = new int[20];
static int[] divBy28 = new int[560]; static int[] divBy28 = new int[560];
@ -305,8 +305,6 @@ public class VideoNTSC extends VideoDHGR {
textPalette[offset][pattern] = 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.
activePalette = solidPalette;
} }
static public int yiqToRgb(double y, double i, double q) { static public int yiqToRgb(double y, double i, double q) {
@ -336,7 +334,7 @@ public class VideoNTSC extends VideoDHGR {
// http://www.freepatentsonline.com/4631692.pdf // http://www.freepatentsonline.com/4631692.pdf
// as well as the AppleColor adapter card manual // as well as the AppleColor adapter card manual
// http://apple2.info/download/Ext80ColumnAppleColorCardHR.pdf // http://apple2.info/download/Ext80ColumnAppleColorCardHR.pdf
rgbMode graphicsMode = rgbMode.color; rgbMode graphicsMode = rgbMode.mix;
public static enum rgbMode { public static enum rgbMode {

View File

@ -28,9 +28,9 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType; import java.lang.reflect.GenericArrayType;
@ -39,10 +39,14 @@ import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@ -51,7 +55,6 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.scene.control.TreeItem; import javafx.scene.control.TreeItem;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
/** /**
@ -93,11 +96,11 @@ public class Configuration implements Reconfigurable {
} }
return null; return null;
} }
public static ImageView getChangedIcon() { public static ImageView getChangedIcon() {
return new ImageView(Utility.loadIcon("icon_exclaim.gif")); return new ImageView(Utility.loadIcon("icon_exclaim.gif"));
} }
@Override @Override
public String getName() { public String getName() {
return "Configuration"; return "Configuration";
@ -124,20 +127,47 @@ public class Configuration implements Reconfigurable {
public transient ConfigNode root; public transient ConfigNode root;
public transient ConfigNode parent; public transient ConfigNode parent;
private ObservableList<ConfigNode> children; private transient ObservableList<ConfigNode> children;
public transient Reconfigurable subject; public transient Reconfigurable subject;
private transient boolean changed = true;
public Map<String, Serializable> settings = new TreeMap<>(); public Map<String, Serializable> settings = new TreeMap<>();
public Map<String, String[]> hotkeys = new TreeMap<>();; public Map<String, String[]> hotkeys = new TreeMap<>();
private boolean changed = true; public String name;
private String id;
private void writeObject(java.io.ObjectOutputStream out)
throws IOException {
out.writeObject(id);
out.writeObject(name);
out.writeObject(settings);
out.writeObject(hotkeys);
out.writeObject(children.toArray());
}
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
children = super.getChildren();
id = (String) in.readObject();
name = (String) in.readObject();
settings = (Map) in.readObject();
hotkeys = (Map) in.readObject();
Object[] nodeArray = (Object[]) in.readObject();
for (Object child : nodeArray) {
children.add((ConfigNode) child);
}
}
private void readObjectNoData()
throws ObjectStreamException {
name = "Bad read";
}
@Override @Override
public String toString() { public String toString() {
if (subject == null) { return name;
return "???";
}
return subject.getName();
} }
public ConfigNode(Reconfigurable subject) { public ConfigNode(Reconfigurable subject) {
this(null, subject); this(null, subject);
this.root = null; this.root = null;
@ -145,7 +175,13 @@ public class Configuration implements Reconfigurable {
} }
public ConfigNode(ConfigNode parent, Reconfigurable subject) { public ConfigNode(ConfigNode parent, Reconfigurable subject) {
this(parent, subject, subject.getName());
}
public ConfigNode(ConfigNode parent, Reconfigurable subject, String id) {
super(); super();
this.id = id;
this.name = subject.getName();
this.subject = subject; this.subject = subject;
this.children = getChildren(); this.children = getChildren();
this.parent = parent; this.parent = parent;
@ -191,36 +227,36 @@ public class Configuration implements Reconfigurable {
return children.remove(child); return children.remove(child);
} }
private ConfigNode findChild(String childName) { private ConfigNode findChild(String id) {
for (ConfigNode node : children) { for (ConfigNode node : children) {
if (childName.equalsIgnoreCase(node.toString())) { if (id.equalsIgnoreCase(node.id)) {
return node; return node;
} }
} }
return null; return null;
} }
private void putChild(String childName, ConfigNode newChild) { private void putChild(String id, ConfigNode newChild) {
removeChild(childName); removeChild(id);
int index = 0; int index = 0;
for (ConfigNode node : children) { for (ConfigNode node : children) {
int compare = node.toString().compareToIgnoreCase(childName); int compare = node.toString().compareToIgnoreCase(id);
if (compare >= 0) { if (compare >= 0) {
break; break;
} else { } else {
index++; index++;
} }
} }
children.add(index, newChild); children.add(index, newChild);
} }
private void setChanged(boolean b) { private void setChanged(boolean b) {
changed = b; changed = b;
if (!changed) { if (!changed) {
setGraphic(null); setGraphic(null);
} else { } else {
setGraphic(getChangedIcon()); setGraphic(getChangedIcon());
} }
} }
} }
public static ConfigNode BASE; public static ConfigNode BASE;
@ -252,10 +288,10 @@ public class Configuration implements Reconfigurable {
} }
for (Field f : node.subject.getClass().getFields()) { for (Field f : node.subject.getClass().getFields()) {
System.out.println("Evaluating field " + f.getName()); // System.out.println("Evaluating field " + f.getName());
try { try {
Object o = f.get(node.subject); Object o = f.get(node.subject);
if (/*o == null ||*/visited.contains(o)) { if (!f.getType().isPrimitive() && visited.contains(o)) {
continue; continue;
} }
visited.add(o); visited.add(o);
@ -278,7 +314,7 @@ public class Configuration implements Reconfigurable {
if (o instanceof Reconfigurable) { if (o instanceof Reconfigurable) {
Reconfigurable r = (Reconfigurable) o; Reconfigurable r = (Reconfigurable) o;
ConfigNode child = node.findChild(f.getName()); ConfigNode child = node.findChild(r.getName());
if (child == null || !child.subject.equals(o)) { if (child == null || !child.subject.equals(o)) {
child = new ConfigNode(node, r); child = new ConfigNode(node, r);
node.putChild(f.getName(), child); node.putChild(f.getName(), child);
@ -287,13 +323,13 @@ public class Configuration implements Reconfigurable {
} else if (o.getClass().isArray()) { } else if (o.getClass().isArray()) {
String fieldName = f.getName(); String fieldName = f.getName();
Class type = o.getClass().getComponentType(); Class type = o.getClass().getComponentType();
System.out.println("Evaluating " + node.subject.getShortName() + "." + fieldName + "; type is " + type.toGenericString()); // System.out.println("Evaluating " + node.subject.getShortName() + "." + fieldName + "; type is " + type.toGenericString());
List<Reconfigurable> children = new ArrayList<>(); List<Reconfigurable> children = new ArrayList<>();
if (!Reconfigurable.class.isAssignableFrom(type)) { if (!Reconfigurable.class.isAssignableFrom(type)) {
System.out.println("Looking at type " + type.getName() + " to see if optional"); // System.out.println("Looking at type " + type.getName() + " to see if optional");
if (Optional.class.isAssignableFrom(type)) { if (Optional.class.isAssignableFrom(type)) {
Type genericTypes = f.getGenericType(); Type genericTypes = f.getGenericType();
System.out.println("Looking at generic parmeters " + genericTypes.getTypeName() + " for reconfigurable class, type "+genericTypes.getClass().getName()); // System.out.println("Looking at generic parmeters " + genericTypes.getTypeName() + " for reconfigurable class, type " + genericTypes.getClass().getName());
if (genericTypes instanceof GenericArrayType) { if (genericTypes instanceof GenericArrayType) {
GenericArrayType aType = (GenericArrayType) genericTypes; GenericArrayType aType = (GenericArrayType) genericTypes;
ParameterizedType pType = (ParameterizedType) aType.getGenericComponentType(); ParameterizedType pType = (ParameterizedType) aType.getGenericComponentType();
@ -322,15 +358,15 @@ public class Configuration implements Reconfigurable {
} }
for (int i = 0; i < children.size(); i++) { for (int i = 0; i < children.size(); i++) {
Reconfigurable child = children.get(i); Reconfigurable child = children.get(i);
String childName = fieldName + i; String childId = fieldName + i;
if (child == null) { if (child == null) {
node.removeChild(childName); node.removeChild(childId);
continue; continue;
} }
ConfigNode grandchild = node.findChild(childName); ConfigNode grandchild = node.findChild(childId);
if (grandchild == null || !grandchild.subject.equals(child)) { if (grandchild == null || !grandchild.subject.equals(child)) {
grandchild = new ConfigNode(node, child); grandchild = new ConfigNode(node, child, childId);
node.putChild(childName, grandchild); node.putChild(childId, grandchild);
} }
buildTree(grandchild, visited); buildTree(grandchild, visited);
} }
@ -383,7 +419,6 @@ public class Configuration implements Reconfigurable {
{ {
boolean successful = false; boolean successful = false;
ObjectInputStream ois = null; ObjectInputStream ois = null;
FileInputStream fis = null;
try { try {
ois = new ObjectInputStream(new FileInputStream(getSettingsFile())); ois = new ObjectInputStream(new FileInputStream(getSettingsFile()));
ConfigNode newRoot = (ConfigNode) ois.readObject(); ConfigNode newRoot = (ConfigNode) ois.readObject();

View File

@ -82,6 +82,7 @@ public abstract class RAM implements Reconfigurable {
} }
public void addCard(Card c, int slot) { public void addCard(Card c, int slot) {
removeCard(slot);
cards[slot] = Optional.of(c); cards[slot] = Optional.of(c);
c.setSlot(slot); c.setSlot(slot);
c.attach(); c.attach();

View File

@ -49,7 +49,7 @@ public class Joystick extends Device {
@ConfigurableField(name = "Enabled", shortName = "enabled", description = "If unchecked, then there is no joystick support.") @ConfigurableField(name = "Enabled", shortName = "enabled", description = "If unchecked, then there is no joystick support.")
public boolean enabled; public boolean enabled;
@ConfigurableField(name = "Center Mouse", description = "Moves mouse back to the center of the screen, can get annoying.") @ConfigurableField(name = "Center Mouse", shortName="center", description = "Moves mouse back to the center of the screen, can get annoying.")
public boolean centerMouse; public boolean centerMouse;
@ConfigurableField(name = "Use keyboard", shortName = "useKeys", description = "Arrow keys will control joystick instead of the mouse.") @ConfigurableField(name = "Use keyboard", shortName = "useKeys", description = "Arrow keys will control joystick instead of the mouse.")
public boolean useKeyboard; public boolean useKeyboard;