forked from Apple-2-Tools/jace
Added better standalone testing for command line arguments. Got video mode to be a first-class startup parameter
This commit is contained in:
parent
553d439ff8
commit
cc0cead894
@ -18,15 +18,15 @@
|
||||
*/
|
||||
package jace;
|
||||
|
||||
import jace.config.Configuration;
|
||||
import jace.apple2e.Apple2e;
|
||||
import jace.config.Configuration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created on January 15, 2007, 10:10 PM
|
||||
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
||||
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
||||
*/
|
||||
public class Emulator {
|
||||
|
||||
@ -51,6 +51,10 @@ public class Emulator {
|
||||
Configuration.buildTree();
|
||||
Configuration.loadSettings();
|
||||
mainThread = Thread.currentThread();
|
||||
applyConfiguration(args);
|
||||
}
|
||||
|
||||
public void applyConfiguration(List<String> args) {
|
||||
Map<String, String> settings = new LinkedHashMap<>();
|
||||
if (args != null) {
|
||||
for (int i = 0; i < args.size(); i++) {
|
||||
|
@ -30,7 +30,6 @@ import jace.core.Computer;
|
||||
import jace.core.Debugger;
|
||||
import jace.core.RAM;
|
||||
import jace.core.RAMListener;
|
||||
import static jace.core.Utility.*;
|
||||
import jace.ide.IdeController;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@ -59,6 +58,8 @@ import javafx.scene.layout.AnchorPane;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import static jace.core.Utility.*;
|
||||
|
||||
/**
|
||||
* This class contains miscellaneous user-invoked actions such as debugger
|
||||
* operations and running arbitrary files in the emulator. It is possible for
|
||||
@ -81,7 +82,7 @@ public class EmulatorUILogic implements Reconfigurable {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ConfigurableField(
|
||||
category = "General",
|
||||
name = "Speed Setting"
|
||||
@ -450,7 +451,7 @@ public class EmulatorUILogic implements Reconfigurable {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@InvokableAction(
|
||||
name = "About",
|
||||
category = "general",
|
||||
@ -459,7 +460,7 @@ public class EmulatorUILogic implements Reconfigurable {
|
||||
defaultKeyMapping = {"ctrl+shift+."})
|
||||
public static void showAboutWindow() {
|
||||
//TODO: Implement
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean confirm(String message) {
|
||||
// return JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(Emulator.getFrame(), message);
|
||||
@ -560,6 +561,8 @@ public class EmulatorUILogic implements Reconfigurable {
|
||||
|
||||
@Override
|
||||
public void reconfigure() {
|
||||
JaceApplication.getApplication().controller.setSpeed(speedSetting);
|
||||
if (JaceApplication.getApplication() != null) {
|
||||
JaceApplication.getApplication().controller.setSpeed(speedSetting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ package jace.apple2e;
|
||||
|
||||
import jace.Emulator;
|
||||
import jace.EmulatorUILogic;
|
||||
import static jace.apple2e.VideoDHGR.BLACK;
|
||||
import jace.config.ConfigurableField;
|
||||
import jace.config.InvokableAction;
|
||||
import jace.core.Computer;
|
||||
@ -34,6 +33,8 @@ import javafx.scene.image.PixelWriter;
|
||||
import javafx.scene.image.WritableImage;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
import static jace.apple2e.VideoDHGR.BLACK;
|
||||
|
||||
/**
|
||||
* Provides a clean color monitor simulation, complete with text-friendly
|
||||
* palette and mixed color/bw (mode 7) rendering. This class extends the
|
||||
@ -59,6 +60,9 @@ public class VideoNTSC extends VideoDHGR {
|
||||
int[] scanline = new int[20];
|
||||
static public int[] divBy28 = new int[560];
|
||||
|
||||
@ConfigurableField(name = "Video Mode", category = "video", shortName = "mode", defaultValue = "TextFriendly", description = "Set Video Mode (Color|TextFriendly|Mode7|Mode7TextFriendly|Monochrome|Greenscreen|Amber)")
|
||||
public static VideoMode videoMode = VideoMode.TextFriendly;
|
||||
|
||||
static {
|
||||
for (int i = 0; i < 560; i++) {
|
||||
divBy28[i] = i / 28;
|
||||
@ -81,58 +85,68 @@ public class VideoNTSC extends VideoDHGR {
|
||||
Greenscreen("Green"),
|
||||
Amber("Amber");
|
||||
String name;
|
||||
|
||||
VideoMode(String n) {
|
||||
name = n;
|
||||
}
|
||||
}
|
||||
|
||||
static int currentMode = -1;
|
||||
|
||||
@InvokableAction(name = "Toggle video mode",
|
||||
category = "video",
|
||||
alternatives = "Gfx mode;color;b&w;monochrome",
|
||||
defaultKeyMapping = {"ctrl+shift+g"})
|
||||
public static void changeVideoMode() {
|
||||
VideoNTSC thiss = (VideoNTSC) Emulator.computer.video;
|
||||
int currentMode = Arrays.asList(VideoMode.values()).indexOf(thiss.getVideoMode());
|
||||
currentMode++;
|
||||
if (currentMode >= VideoMode.values().length) {
|
||||
currentMode = 0;
|
||||
}
|
||||
thiss.monochomeMode = false;
|
||||
thiss.setVideoMode(VideoMode.values()[currentMode]);
|
||||
}
|
||||
|
||||
public void setVideoMode(VideoMode mode) {
|
||||
videoMode = mode;
|
||||
monochomeMode = false;
|
||||
WHITE = Color.WHITE;
|
||||
switch (VideoMode.values()[currentMode]) {
|
||||
switch (mode) {
|
||||
case Amber:
|
||||
thiss.monochomeMode = true;
|
||||
monochomeMode = true;
|
||||
WHITE = Color.web("ff8000");
|
||||
break;
|
||||
case Greenscreen:
|
||||
thiss.monochomeMode = true;
|
||||
monochomeMode = true;
|
||||
WHITE = Color.web("0ccc68");
|
||||
break;
|
||||
case Monochrome:
|
||||
thiss.monochomeMode = true;
|
||||
monochomeMode = true;
|
||||
break;
|
||||
case Color:
|
||||
thiss.useTextPalette = false;
|
||||
thiss.enableVideo7 = false;
|
||||
useTextPalette = false;
|
||||
enableVideo7 = false;
|
||||
break;
|
||||
case Mode7:
|
||||
thiss.useTextPalette = false;
|
||||
thiss.enableVideo7 = true;
|
||||
useTextPalette = false;
|
||||
enableVideo7 = true;
|
||||
break;
|
||||
case Mode7TextFriendly:
|
||||
thiss.useTextPalette = true;
|
||||
thiss.enableVideo7 = true;
|
||||
useTextPalette = true;
|
||||
enableVideo7 = true;
|
||||
break;
|
||||
case TextFriendly:
|
||||
thiss.useTextPalette = true;
|
||||
thiss.enableVideo7 = false;
|
||||
useTextPalette = true;
|
||||
enableVideo7 = false;
|
||||
break;
|
||||
}
|
||||
thiss.activePalette = thiss.useTextPalette ? TEXT_PALETTE : SOLID_PALETTE;
|
||||
EmulatorUILogic.notify("Video mode: "+VideoMode.values()[currentMode].name);
|
||||
activePalette = useTextPalette ? TEXT_PALETTE : SOLID_PALETTE;
|
||||
EmulatorUILogic.notify("Video mode: " + mode.name);
|
||||
forceRefresh();
|
||||
}
|
||||
|
||||
|
||||
public VideoMode getVideoMode() {
|
||||
return videoMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void showBW(WritableImage screen, int x, int y, int dhgrWord) {
|
||||
int pos = divBy28[x];
|
||||
@ -235,6 +249,7 @@ public class VideoNTSC extends VideoDHGR {
|
||||
}
|
||||
|
||||
boolean monochomeMode = false;
|
||||
|
||||
private void renderScanline(WritableImage screen, int y) {
|
||||
int p = 0;
|
||||
if (rowStart != 0) {
|
||||
@ -364,12 +379,13 @@ public class VideoNTSC extends VideoDHGR {
|
||||
|
||||
@Override
|
||||
public void reconfigure() {
|
||||
setVideoMode(videoMode);
|
||||
activePalette = useTextPalette ? TEXT_PALETTE : SOLID_PALETTE;
|
||||
super.reconfigure();
|
||||
}
|
||||
// The following section captures changes to the RGB mode
|
||||
// The details of this are in Brodener's patent application #4631692
|
||||
// http://www.freepatentsonline.com/4631692.pdf
|
||||
// http://www.freepatentsonline.com/4631692.pdf
|
||||
// as well as the AppleColor adapter card manual
|
||||
// http://apple2.info/download/Ext80ColumnAppleColorCardHR.pdf
|
||||
rgbMode graphicsMode = rgbMode.MIX;
|
||||
@ -426,7 +442,7 @@ public class VideoNTSC extends VideoDHGR {
|
||||
}));
|
||||
rgbStateListeners.add(memory.observe(RAMEvent.TYPE.EXECUTE, 0x0fa62, (e) -> {
|
||||
// When reset hook is called, reset the graphics mode
|
||||
// This is useful in case a program is running that
|
||||
// This is useful in case a program is running that
|
||||
// is totally clueless how to set the RGB state correctly.
|
||||
f1 = true;
|
||||
f2 = true;
|
||||
|
@ -25,7 +25,7 @@ import jace.core.SoftSwitch;
|
||||
* A memory softswitch is a softswitch which triggers a memory reconfiguration
|
||||
* after its value is changed.
|
||||
*
|
||||
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
||||
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
||||
*/
|
||||
public class MemorySoftSwitch extends SoftSwitch {
|
||||
|
||||
@ -48,11 +48,15 @@ public class MemorySoftSwitch extends SoftSwitch {
|
||||
// Todo: Implement floating bus, maybe?
|
||||
@Override
|
||||
protected byte readSwitch() {
|
||||
byte value = computer.getVideo().getFloatingBus();
|
||||
if (getState()) {
|
||||
return (byte) (value | 0x080);
|
||||
if (computer.getVideo() == null) {
|
||||
return 0x00;
|
||||
} else {
|
||||
return (byte) (value & 0x07f);
|
||||
byte value = computer.getVideo().getFloatingBus();
|
||||
if (getState()) {
|
||||
return (byte) (value | 0x080);
|
||||
} else {
|
||||
return (byte) (value & 0x07f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,6 @@ import java.util.logging.Logger;
|
||||
import java.util.stream.Stream;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.control.TreeItem;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
|
||||
/**
|
||||
@ -190,16 +189,17 @@ public class Configuration implements Reconfigurable {
|
||||
}
|
||||
|
||||
public void setFieldValue(String field, Serializable value) {
|
||||
setChanged(true);
|
||||
if (value != null) {
|
||||
if (value.equals(getFieldValue(field))) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (getFieldValue(field) == null) {
|
||||
setChanged(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
setChanged(true);
|
||||
setRawFieldValue(field, value);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package jace.core;
|
||||
|
||||
import jace.Emulator;
|
||||
import jace.config.Configuration;
|
||||
import jace.config.InvokableAction;
|
||||
import java.io.File;
|
||||
@ -25,7 +26,6 @@ import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import org.reflections.Reflections;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@ -38,7 +38,6 @@ import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Alert;
|
||||
@ -49,6 +48,7 @@ import javafx.scene.effect.DropShadow;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.paint.Color;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
/**
|
||||
* This is a set of helper functions which do not belong anywhere else.
|
||||
@ -104,7 +104,7 @@ public class Utility {
|
||||
}
|
||||
return dist[m][n];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Normalize distance based on longest string
|
||||
* @param s
|
||||
@ -114,7 +114,7 @@ public class Utility {
|
||||
public static int adjustedLevenshteinDistance(String s, String t) {
|
||||
return Math.max(s.length(), t.length()) - levenshteinDistance(s, t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Compare strings based on a tally of similar patterns found, using a fixed
|
||||
@ -156,6 +156,9 @@ public class Utility {
|
||||
|
||||
public static void setHeadlessMode(boolean headless) {
|
||||
isHeadless = headless;
|
||||
if (Emulator.instance == null && headless) {
|
||||
Emulator.instance = new Emulator(Collections.emptyList());
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isHeadlessMode() {
|
||||
@ -515,7 +518,7 @@ public class Utility {
|
||||
// }
|
||||
return actions.get(actionsList.get(0));
|
||||
}
|
||||
|
||||
|
||||
private static int getActionNameMatch(String str, InvokableAction action) {
|
||||
int nameMatch = levenshteinDistance(str, action.name());
|
||||
if (action.alternatives() != null) {
|
||||
|
79
src/test/java/jace/scripting/TestCommandlineArgs.java
Normal file
79
src/test/java/jace/scripting/TestCommandlineArgs.java
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2019 Brendan Robert
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package jace.scripting;
|
||||
|
||||
import jace.Emulator;
|
||||
import jace.apple2e.Apple2e;
|
||||
import jace.apple2e.MOS65C02;
|
||||
import jace.apple2e.VideoNTSC;
|
||||
import jace.apple2e.VideoNTSC.VideoMode;
|
||||
import jace.core.Computer;
|
||||
import jace.core.RAM;
|
||||
import jace.core.SoundMixer;
|
||||
import jace.core.Utility;
|
||||
import java.util.Arrays;
|
||||
import javafx.embed.swing.JFXPanel;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Check out various command line arguments to see if they do the right thing
|
||||
*/
|
||||
public class TestCommandlineArgs {
|
||||
|
||||
static Computer computer;
|
||||
static MOS65C02 cpu;
|
||||
static RAM ram;
|
||||
|
||||
@BeforeClass
|
||||
public static void initJavaFX() {
|
||||
new JFXPanel();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
Utility.setHeadlessMode(true);
|
||||
SoundMixer.MUTE = true;
|
||||
computer = new Apple2e();
|
||||
cpu = (MOS65C02) computer.getCpu();
|
||||
ram = computer.getMemory();
|
||||
Emulator.computer = (Apple2e) computer;
|
||||
computer.pause();
|
||||
cpu.suspend();
|
||||
cpu.clearState();
|
||||
}
|
||||
|
||||
static String GRAPHICS_MODE = "vid.videomode";
|
||||
|
||||
@Test
|
||||
public void testVideoModes() {
|
||||
for (VideoMode mode : VideoMode.values()) {
|
||||
Emulator.instance.applyConfiguration(Arrays.asList("-" + GRAPHICS_MODE, mode.name().toLowerCase()));
|
||||
assertTrue("Should be NTSC video module", computer.video instanceof VideoNTSC);
|
||||
VideoNTSC video = (VideoNTSC) computer.video;
|
||||
assertEquals("Should have switched to " + mode.name() + " mode", mode, video.getVideoMode());
|
||||
|
||||
Emulator.instance.applyConfiguration(Arrays.asList("-" + GRAPHICS_MODE, mode.name().toUpperCase()));
|
||||
assertTrue("Should be NTSC video module", computer.video instanceof VideoNTSC);
|
||||
video = (VideoNTSC) computer.video;
|
||||
assertEquals("Should have switched to " + mode.name() + " mode", mode, video.getVideoMode());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user