Updated color mode detection to use sofswitch method. Changed default emulator color mode and speed to 2x

This commit is contained in:
Brendan Robert 2018-03-17 12:21:09 -05:00
parent ba18a6d290
commit c9c91d2fe0
4 changed files with 46 additions and 74 deletions

View File

@ -86,7 +86,7 @@ public class EmulatorUILogic implements Reconfigurable {
category = "General",
name = "Speed Setting"
)
public int speedSetting = 1;
public int speedSetting = 2;
@ConfigurableField(
category = "General",

View File

@ -51,8 +51,8 @@ import javafx.scene.paint.Color;
public class VideoNTSC extends VideoDHGR {
@ConfigurableField(name = "Text palette", shortName = "textPalette", defaultValue = "false", description = "Use text-friendly color palette")
public boolean useTextPalette = true;
int activePalette[][] = TEXT_PALETTE;
public boolean useTextPalette = false;
int activePalette[][] = SOLID_PALETTE;
@ConfigurableField(name = "Video 7", shortName = "video7", defaultValue = "true", description = "Enable Video 7 RGB rendering support")
public boolean enableVideo7 = true;
// Scanline represents 560 bits, divided up into 28-bit words
@ -73,10 +73,10 @@ public class VideoNTSC extends VideoDHGR {
}
public static enum VideoMode {
Color("Color"),
TextFriendly("Text-friendly color"),
Mode7("Mode7 Mixed RGB"),
Color("Color"),
Mode7TextFriendly("Mode7 with Text-friendly palette"),
Mode7("Mode7 Mixed RGB"),
Monochrome("Mono"),
Greenscreen("Green"),
Amber("Amber");

View File

@ -17,10 +17,10 @@ public class LawlessHacks extends Cheats {
int FONT_ROUTINES_END = 0x0f800;
int FONT_SPEEDUP_CYCLES = 10000;
int FONT_ROUTINES_LEN = 0x0f00;
int ENGINE_ADDR = 0x06000;
int ENGINE_FIRST_OPCODE = ENGINE_ADDR + (13 * 3);
int DETECT_ENGINE_WRITE = 0x060FF;
// Modes specified by the game engine
int MODE_SOFTSWITCH = 0x0C020;
public LawlessHacks(Computer computer) {
super(computer);
}
@ -31,7 +31,7 @@ public class LawlessHacks extends Cheats {
addCheat(RAMEvent.TYPE.WRITE, (e) -> {
if (e.getAddress() >= 0x02000 && e.getAddress() <= 0x05FFF) {
((LawlessVideo) computer.getVideo()).setBWFlag(e.getAddress(),
SoftSwitches.RAMWRT.getState() ||
!SoftSwitches.RAMWRT.getState() ||
computer.getCpu().getProgramCounter() < FONT_ROUTINES ||
computer.getCpu().getProgramCounter() > FONT_ROUTINES_END);
}
@ -43,11 +43,12 @@ public class LawlessHacks extends Cheats {
}
}, FONT_ROUTINES, FONT_ROUTINES | 0x0ff);
// Try to detect engines changing
addCheat(RAMEvent.TYPE.WRITE, false, (e) -> {
if (e.getAddress() == DETECT_ENGINE_WRITE) {
detectActiveEngine();
addCheat(RAMEvent.TYPE.ANY, false, (e) -> {
if ((e.getAddress() & 0x0FFF0) == MODE_SOFTSWITCH) {
System.out.println("Trapped " + e.getType().toString() + " to $"+Integer.toHexString(e.getAddress()));
setEngineByOrdinal(e.getAddress() - MODE_SOFTSWITCH);
}
}, DETECT_ENGINE_WRITE);
}, MODE_SOFTSWITCH, MODE_SOFTSWITCH | 0x0f);
}
@Override
@ -59,35 +60,12 @@ public class LawlessHacks extends Cheats {
public void tick() {
}
private void detectActiveEngine() {
private void setEngineByOrdinal(int mode) {
LawlessVideo video = (LawlessVideo) computer.getVideo();
// for (int i = 0x06000; i < 0x06080;) {
// System.out.printf("%04x: ", i);
// for (int j = 0; j < 16; j++, i++) {
// System.out.printf("%02x ", computer.getMemory().readRaw(i) & 0x0ff);
// }
// System.out.println();
// }
int firstPageByte = computer.getMemory().readRaw(ENGINE_ADDR) & 0x0ff;
int firstDataByte = computer.getMemory().readRaw(ENGINE_FIRST_OPCODE) & 0x0ff;
int secondDataByte = computer.getMemory().readRaw(ENGINE_FIRST_OPCODE + 1) & 0x0ff;
if (firstPageByte == MOS65C02.OPCODE.JMP_AB.getCode()
&& firstDataByte == MOS65C02.OPCODE.LDX_ZP.getCode()) {
// 2D Engine: First instruction is LDX MAP_PARTITION
video.setEngine(RenderEngine._2D);
} else if (firstPageByte == MOS65C02.OPCODE.JMP_AB.getCode()
&& firstDataByte == 0
&& secondDataByte == 0) {
// 3D Engine: First byte is a zero for MapHeader
video.setEngine(RenderEngine._3D);
} else if (firstPageByte == MOS65C02.OPCODE.JMP_AB.getCode()
&& firstDataByte == 0
&& secondDataByte == 0x067) {
// 3D Engine: First byte is a zero for MapHeader
video.setEngine(RenderEngine.PORTRAIT);
if (mode >= 0 && mode < RenderEngine.values().length) {
video.setEngine(RenderEngine.values()[mode]);
} else {
video.setEngine(RenderEngine.UNKNOWN);
}
}
}
}

View File

@ -1,7 +1,6 @@
package jace.lawless;
import jace.Emulator;
import jace.LawlessLegends;
import jace.apple2e.RAM128k;
import jace.apple2e.VideoNTSC;
import jace.core.Computer;
@ -15,12 +14,15 @@ import javafx.scene.image.WritableImage;
public class LawlessVideo extends VideoNTSC {
private static RenderEngine activeEngine = RenderEngine.UNKNOWN;
private boolean invActive = false;
private boolean titleScreen = false;
private boolean titleScreen = true;
private boolean[][] activeMask = new boolean[192][80];
public static enum RenderEngine {
FULL_COLOR,
FULL_TEXT(new int[]{
2, 6, 78, 186
}),
_2D(new int[]{
9, 8, 34, 17,
44, 24, 76, 136,
@ -31,10 +33,14 @@ public class LawlessVideo extends VideoNTSC {
44, 24, 76, 136,
44, 143, 76, 184,
8, 172, 14, 182,}),
INVENTORY(new int[]{
2, 6, 78, 186
}),
PORTRAIT, UNKNOWN;
MAP(new int[]{
2, 6, 78, 11,
2, 11, 4, 186,
76, 11, 78, 186,
2, 182, 78, 186,
28, 3, 52, 6
}),
UNKNOWN;
boolean[][] colorMask;
RenderEngine(int[] mask) {
@ -66,12 +72,17 @@ public class LawlessVideo extends VideoNTSC {
}
public void setEngine(RenderEngine e) {
activeEngine = e;
for (int y=0; y < 192; y++) {
System.arraycopy(e.colorMask[y], 0, activeMask[y], 0, 80);
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.computer.onNextVBL(() -> Emulator.computer.getVideo().forceRefresh());
System.out.println("Detected engine: " + e.name());
} else {
System.out.println("Detected engine same as before: " + e.name());
}
Emulator.computer.onNextVBL(() -> Emulator.computer.getVideo().forceRefresh());
System.out.println("Detected engine: " + e.name());
}
public void setBWFlag(int addr, boolean b) {
@ -81,6 +92,7 @@ public class LawlessVideo extends VideoNTSC {
return;
}
int col = addr - VideoNTSC.calculateHiresOffset(row);
/*
if (row > 20 && row < 136 && col < 20) {
boolean prev = activeMask[row][col*2];
activeMask[row][col*2] = b;
@ -89,6 +101,7 @@ public class LawlessVideo extends VideoNTSC {
redraw();
}
}
*/
}
static public int[] divBy56 = new int[560];
@ -99,21 +112,6 @@ public class LawlessVideo extends VideoNTSC {
}
}
@Override
public void vblankStart() {
super.vblankStart();
// Row 5 = Black
int row4 = getSummary(4);
int row5 = getSummary(5);
int row6 = getSummary(6);
int row7 = getSummary(7);
// Rows 6,7 = White
invActive = row5 == 0
&& row6 == 1270
&& row7 == 1270;
titleScreen = row4 == 828 && row5 == 513 && row6 == 382;
}
public int getSummary(int row) {
PagedMemory mainMemory = ((RAM128k) computer.getMemory()).getMainMemory();
int rowAddr = getCurrentWriter().getYOffset(row);
@ -130,14 +128,10 @@ public class LawlessVideo extends VideoNTSC {
if (rowStart >= 0x02000) {
boolean[] color = activeMask[y];
if (titleScreen) {
color = RenderEngine.UNKNOWN.colorMask[y];
} else if (invActive) {
color = RenderEngine.INVENTORY.colorMask[y];
} else if (activeEngine == RenderEngine.PORTRAIT) {
color = RenderEngine._2D.colorMask[y];
color = RenderEngine.FULL_COLOR.colorMask[y];
}
System.arraycopy(color, 0, colorActive, 0, 80);
}
super.hblankStart(screen, y, isDirty); //To change body of generated methods, choose Tools | Templates.
super.hblankStart(screen, y, isDirty);
}
}