Simplified the text enhancement hacks and bumped speed back to 200%
This commit is contained in:
parent
d81d0fedd7
commit
2ed008c9c3
|
@ -5,6 +5,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import jace.apple2e.MOS65C02;
|
||||
import jace.apple2e.RAM128k;
|
||||
import jace.apple2e.VideoNTSC;
|
||||
import jace.cheat.Cheats.Cheat;
|
||||
|
@ -144,7 +145,7 @@ public class LawlessLegends extends Application {
|
|||
c.coldStart();
|
||||
try {
|
||||
Thread.sleep(watchdogDelay);
|
||||
if (!romStarted.get() || !c.isRunning() || c.getCpu().getProgramCounter() == 0xc700 || c.getCpu().getProgramCounter() == 0) {
|
||||
if (!romStarted.get() || !c.isRunning() || c.getCpu().getProgramCounter() == MOS65C02.FASTBOOT || c.getCpu().getProgramCounter() == 0) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.WARNING, "Boot not detected, performing a cold start");
|
||||
Logger.getLogger(getClass().getName()).log(Level.WARNING, "Old PC: {0}", c.getCpu().getProgramCounter());
|
||||
resetEmulator();
|
||||
|
|
|
@ -64,7 +64,7 @@ public class Apple2e extends Computer {
|
|||
static int IRQ_VECTOR = 0x003F2;
|
||||
|
||||
@ConfigurableField(name = "Production mode", shortName = "production")
|
||||
public boolean PRODUCTION_MODE = false;
|
||||
public boolean PRODUCTION_MODE = true;
|
||||
@ConfigurableField(name = "Slot 1", shortName = "s1card")
|
||||
public DeviceSelection<Cards> card1 = new DeviceSelection<>(Cards.class, null);
|
||||
@ConfigurableField(name = "Slot 2", shortName = "s2card")
|
||||
|
@ -116,6 +116,9 @@ public class Apple2e extends Computer {
|
|||
try {
|
||||
setCpu(new MOS65C02());
|
||||
setMotherboard(new Motherboard(null));
|
||||
if (PRODUCTION_MODE) {
|
||||
getMotherboard().setSpeedInPercentage(200);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
System.err.println("Unable to initialize virtual machine");
|
||||
t.printStackTrace(System.err);
|
||||
|
@ -135,6 +138,11 @@ public class Apple2e extends Computer {
|
|||
r.resetState();
|
||||
for (SoftSwitches s : SoftSwitches.values()) {
|
||||
if ((s.getSwitch() instanceof VideoSoftSwitch)) {
|
||||
if (s == SoftSwitches.TEXT && PRODUCTION_MODE) {
|
||||
s.getSwitch().setState(true);
|
||||
} else {
|
||||
s.getSwitch().reset();
|
||||
}
|
||||
s.getSwitch().reset();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,9 +40,9 @@ public class MOS65C02 extends CPU {
|
|||
private static final Logger LOG = Logger.getLogger(MOS65C02.class.getName());
|
||||
|
||||
public boolean readAddressTriggersEvent = true;
|
||||
static int RESET_VECTOR = 0x00FFFC;
|
||||
static int INT_VECTOR = 0x00FFFE;
|
||||
static int FASTBOOT = 0x00FAA9;
|
||||
public static int RESET_VECTOR = 0x00FFFC;
|
||||
public static int INT_VECTOR = 0x00FFFE;
|
||||
public static int FASTBOOT = 0x00FAA9;
|
||||
@Stateful
|
||||
public int A = 0x0FF;
|
||||
@Stateful
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package jace.core;
|
||||
|
||||
import jace.apple2e.SoftSwitches;
|
||||
|
||||
/**
|
||||
* A RAM event is defined as anything that causes a read or write to the
|
||||
* mainboard RAM of the computer. This could be the result of an indirect
|
||||
|
@ -147,4 +149,21 @@ public class RAMEvent {
|
|||
public final boolean isIntercepted() {
|
||||
return valueIntercepted;
|
||||
}
|
||||
|
||||
public boolean isMainMemory() {
|
||||
if (type.isRead() && SoftSwitches.RAMRD.isOn()) {
|
||||
return false;
|
||||
} else if (!type.isRead() && SoftSwitches.RAMWRT.isOn()) {
|
||||
return false;
|
||||
} else if (address < 0x0200) {
|
||||
// Check if zero page is pointed to auxiliary memory
|
||||
return SoftSwitches.AUXZP.isOff();
|
||||
}
|
||||
if ((address >= 0x400 && address < 0x0800) || (address >= 0x2000 && address < 0x4000)) {
|
||||
if (SoftSwitches._80STORE.isOn() && SoftSwitches.PAGE2.isOn()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
import jace.Emulator;
|
||||
import jace.apple2e.VideoDHGR;
|
||||
import jace.cheat.Cheats;
|
||||
import jace.core.RAMEvent;
|
||||
import jace.lawless.LawlessVideo.RenderEngine;
|
||||
import javafx.util.Duration;
|
||||
|
||||
/**
|
||||
|
@ -45,12 +45,8 @@ public class LawlessHacks extends Cheats {
|
|||
@Override
|
||||
public void registerListeners() {
|
||||
// Observe graphics changes
|
||||
addCheat("Lawless Legends Graphics Modes", RAMEvent.TYPE.ANY, (e) -> {
|
||||
int addr = e.getAddress();
|
||||
if (addr >= MODE_SOFTSWITCH_MIN && e.getAddress() <= MODE_SOFTSWITCH_MAX) {
|
||||
setEngineByOrdinal(e.getAddress() - MODE_SOFTSWITCH_MIN);
|
||||
}
|
||||
}, MODE_SOFTSWITCH_MIN, MODE_SOFTSWITCH_MAX);
|
||||
addCheat("Lawless Text Speedup", RAMEvent.TYPE.EXECUTE, this::fastText, 0x0ee00, 0x0ee00 + 0x0f00);
|
||||
addCheat("Lawless Text Enhancement", RAMEvent.TYPE.WRITE, this::enhanceText, 0x02000, 0x03fff);
|
||||
addCheat("Lawless Legends Music Commands", RAMEvent.TYPE.WRITE, (e) -> {
|
||||
playSound(e.getNewValue());
|
||||
}, SFX_TRIGGER);
|
||||
|
@ -65,14 +61,33 @@ public class LawlessHacks extends Cheats {
|
|||
public void tick() {
|
||||
}
|
||||
|
||||
private void setEngineByOrdinal(int mode) {
|
||||
// Speed up text rendering
|
||||
private void fastText(RAMEvent e) {
|
||||
if (e.isMainMemory() && e.getOldValue() != 0x060) {
|
||||
Emulator.withComputer((c->c.getMotherboard().requestSpeed(this)));
|
||||
} else {
|
||||
Emulator.withComputer((c->c.getMotherboard().cancelSpeedRequest(this)));
|
||||
}
|
||||
}
|
||||
|
||||
// Enhance text rendering by forcing the text to be pure B&W
|
||||
private void enhanceText(RAMEvent e) {
|
||||
if (!e.isMainMemory()) {
|
||||
return;
|
||||
}
|
||||
int pc = Emulator.withComputer(c->c.getCpu().getProgramCounter(), 0);
|
||||
boolean drawingText = pc == 0x0ee46 || pc > 0x0f300;
|
||||
Emulator.withVideo(v -> {
|
||||
if (v instanceof LawlessVideo) {
|
||||
LawlessVideo video = (LawlessVideo) v;
|
||||
if (mode >= 0 && mode < RenderEngine.values().length) {
|
||||
video.setEngine(RenderEngine.values()[mode]);
|
||||
} else {
|
||||
video.setEngine(RenderEngine.UNKNOWN);
|
||||
int addr = e.getAddress();
|
||||
int y = VideoDHGR.identifyHiresRow(addr);
|
||||
if (y >= 0 && y <= 192) {
|
||||
int x = addr - video.getCurrentWriter().getYOffset(y);
|
||||
if (x >= 0 && x < 40) {
|
||||
video.activeMask[y][x*2] = !drawingText;
|
||||
video.activeMask[y][x*2+1] = !drawingText;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2,94 +2,23 @@ package jace.lawless;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
import jace.Emulator;
|
||||
import jace.apple2e.RAM128k;
|
||||
import jace.apple2e.VideoNTSC;
|
||||
import jace.core.PagedMemory;
|
||||
import jace.core.Video;
|
||||
import javafx.scene.image.WritableImage;
|
||||
|
||||
/**
|
||||
* Lawless-enhanced video output for readable text
|
||||
*/
|
||||
public class LawlessVideo extends VideoNTSC {
|
||||
public final boolean[][] activeMask = new boolean[192][80];
|
||||
|
||||
private static RenderEngine activeEngine = RenderEngine.UNKNOWN;
|
||||
private boolean titleScreen = true;
|
||||
private final boolean[][] activeMask = new boolean[192][80];
|
||||
|
||||
|
||||
public enum RenderEngine {
|
||||
FULL_COLOR,
|
||||
FULL_TEXT(new int[]{
|
||||
2, 6, 78, 186
|
||||
}),
|
||||
_2D(new int[]{
|
||||
9, 8, 34, 17,
|
||||
44, 24, 76, 136,
|
||||
44, 143, 76, 184
|
||||
}),
|
||||
_3D(new int[]{
|
||||
9, 8, 34, 17,
|
||||
44, 24, 76, 136,
|
||||
44, 143, 76, 183,
|
||||
8, 172, 14, 182,}),
|
||||
MAP(new int[]{
|
||||
2, 6, 78, 11,
|
||||
2, 11, 4, 186,
|
||||
76, 11, 78, 186,
|
||||
2, 182, 78, 186,
|
||||
28, 3, 52, 6
|
||||
}),
|
||||
STORYBOOK(new int[]{
|
||||
0, 0, 39, 191,
|
||||
39, 130, 78, 191
|
||||
}),
|
||||
TITLE(new int[]{
|
||||
16, 154, 64, 190
|
||||
}),
|
||||
UNKNOWN;
|
||||
boolean[][] colorMask;
|
||||
|
||||
RenderEngine(int[] mask) {
|
||||
this();
|
||||
for (int i = 0; i < mask.length; i += 4) {
|
||||
int x1 = mask[i],
|
||||
y1 = mask[i + 1],
|
||||
x2 = mask[i + 2],
|
||||
y2 = mask[i + 3];
|
||||
for (int y = y1; y < y2; y++) {
|
||||
for (int x = x1; x < x2; x++) {
|
||||
colorMask[y][x] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderEngine() {
|
||||
colorMask = new boolean[192][80];
|
||||
for (int y = 0; y < 192; y++) {
|
||||
colorMask[y] = new boolean[80];
|
||||
Arrays.fill(colorMask[y], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public LawlessVideo() {
|
||||
super();
|
||||
this.vblankStart();
|
||||
}
|
||||
|
||||
public void setEngine(RenderEngine e) {
|
||||
if (activeEngine != e) {
|
||||
titleScreen = false;
|
||||
activeEngine = e;
|
||||
for (int y=0; y < 192; y++) {
|
||||
System.arraycopy(activeEngine.colorMask[y], 0, activeMask[y], 0, 80);
|
||||
}
|
||||
|
||||
Emulator.withComputer(c->c.onNextVBL(Video::forceRefresh));
|
||||
System.out.println("Detected engine: " + e.name());
|
||||
for (boolean[] row : activeMask) {
|
||||
Arrays.fill(row, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,7 +29,6 @@ public class LawlessVideo extends VideoNTSC {
|
|||
divBy56[i] = i / 56;
|
||||
}
|
||||
}
|
||||
|
||||
public int getSummary(int row) {
|
||||
PagedMemory mainMemory = ((RAM128k) getMemory()).getMainMemory();
|
||||
int rowAddr = getCurrentWriter().getYOffset(row);
|
||||
|
@ -118,11 +46,7 @@ public class LawlessVideo extends VideoNTSC {
|
|||
}
|
||||
int rowStart = getCurrentWriter().getYOffset(y);
|
||||
if (rowStart >= 0x02000) {
|
||||
boolean[] color = activeMask[y];
|
||||
if (titleScreen) {
|
||||
color = RenderEngine.FULL_COLOR.colorMask[y];
|
||||
}
|
||||
System.arraycopy(color, 0, colorActive, 0, 80);
|
||||
System.arraycopy(activeMask[y], 0, colorActive, 0, 80);
|
||||
}
|
||||
super.hblankStart(screen, y, isDirty);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue