2017-12-29 00:48:35 +00:00
|
|
|
package jace.lawless;
|
|
|
|
|
2023-07-03 20:44:23 +00:00
|
|
|
import java.util.Arrays;
|
|
|
|
|
2018-02-01 15:08:54 +00:00
|
|
|
import jace.Emulator;
|
2017-12-29 00:48:35 +00:00
|
|
|
import jace.apple2e.RAM128k;
|
|
|
|
import jace.apple2e.VideoNTSC;
|
|
|
|
import jace.core.Computer;
|
|
|
|
import jace.core.PagedMemory;
|
2021-11-09 17:20:19 +00:00
|
|
|
import jace.core.Video;
|
2017-12-29 00:48:35 +00:00
|
|
|
import javafx.scene.image.WritableImage;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Lawless-enhanced video output for readable text
|
|
|
|
*/
|
|
|
|
public class LawlessVideo extends VideoNTSC {
|
|
|
|
|
|
|
|
private static RenderEngine activeEngine = RenderEngine.UNKNOWN;
|
2018-03-17 17:21:09 +00:00
|
|
|
private boolean titleScreen = true;
|
2021-11-09 17:20:19 +00:00
|
|
|
private final boolean[][] activeMask = new boolean[192][80];
|
2020-02-24 15:06:24 +00:00
|
|
|
|
|
|
|
|
2021-11-09 17:20:19 +00:00
|
|
|
public enum RenderEngine {
|
2018-03-17 17:21:09 +00:00
|
|
|
FULL_COLOR,
|
|
|
|
FULL_TEXT(new int[]{
|
2020-02-24 15:06:24 +00:00
|
|
|
2, 6, 78, 186
|
2018-03-17 17:21:09 +00:00
|
|
|
}),
|
2017-12-29 00:48:35 +00:00
|
|
|
_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,
|
2020-02-24 15:06:24 +00:00
|
|
|
44, 143, 76, 183,
|
2017-12-29 00:48:35 +00:00
|
|
|
8, 172, 14, 182,}),
|
2018-03-17 17:21:09 +00:00
|
|
|
MAP(new int[]{
|
|
|
|
2, 6, 78, 11,
|
|
|
|
2, 11, 4, 186,
|
2020-02-24 15:06:24 +00:00
|
|
|
76, 11, 78, 186,
|
2018-03-17 17:21:09 +00:00
|
|
|
2, 182, 78, 186,
|
|
|
|
28, 3, 52, 6
|
2020-02-24 15:06:24 +00:00
|
|
|
}),
|
|
|
|
STORYBOOK(new int[]{
|
|
|
|
0, 0, 39, 191,
|
|
|
|
39, 130, 78, 191
|
|
|
|
}),
|
2020-07-28 14:34:51 +00:00
|
|
|
TITLE(new int[]{
|
2022-02-08 07:28:27 +00:00
|
|
|
16, 154, 64, 190
|
2020-07-28 14:34:51 +00:00
|
|
|
}),
|
2018-03-17 17:21:09 +00:00
|
|
|
UNKNOWN;
|
2017-12-29 00:48:35 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2021-11-09 17:20:19 +00:00
|
|
|
}
|
2017-12-29 00:48:35 +00:00
|
|
|
|
|
|
|
public LawlessVideo(Computer computer) {
|
|
|
|
super(computer);
|
2022-03-04 02:10:20 +00:00
|
|
|
this.vblankStart();
|
2017-12-29 00:48:35 +00:00
|
|
|
}
|
|
|
|
|
2018-02-05 04:30:24 +00:00
|
|
|
public void setEngine(RenderEngine e) {
|
2018-03-17 17:21:09 +00:00
|
|
|
if (activeEngine != e) {
|
|
|
|
titleScreen = false;
|
|
|
|
activeEngine = e;
|
|
|
|
for (int y=0; y < 192; y++) {
|
|
|
|
System.arraycopy(activeEngine.colorMask[y], 0, activeMask[y], 0, 80);
|
|
|
|
}
|
2023-07-03 20:44:23 +00:00
|
|
|
|
|
|
|
Emulator.withComputer(c->c.onNextVBL(Video::forceRefresh));
|
2018-03-17 17:21:09 +00:00
|
|
|
System.out.println("Detected engine: " + e.name());
|
|
|
|
} else {
|
2020-02-24 15:06:24 +00:00
|
|
|
System.out.println("Detected engine same as before: " + e.name());
|
2018-02-05 04:30:24 +00:00
|
|
|
}
|
|
|
|
}
|
2017-12-29 00:48:35 +00:00
|
|
|
|
|
|
|
static public int[] divBy56 = new int[560];
|
|
|
|
|
|
|
|
static {
|
|
|
|
for (int i = 0; i < 560; i++) {
|
|
|
|
divBy56[i] = i / 56;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getSummary(int row) {
|
|
|
|
PagedMemory mainMemory = ((RAM128k) computer.getMemory()).getMainMemory();
|
|
|
|
int rowAddr = getCurrentWriter().getYOffset(row);
|
|
|
|
int total = 0;
|
|
|
|
for (int i = rowAddr + 4; i < rowAddr + 14; i++) {
|
|
|
|
total += mainMemory.readByte(i) & 0x07f;
|
|
|
|
}
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void hblankStart(WritableImage screen, int y, boolean isDirty) {
|
|
|
|
int rowStart = getCurrentWriter().getYOffset(y);
|
2017-12-29 08:01:14 +00:00
|
|
|
if (rowStart >= 0x02000) {
|
2018-02-05 04:30:24 +00:00
|
|
|
boolean[] color = activeMask[y];
|
2017-12-29 08:01:14 +00:00
|
|
|
if (titleScreen) {
|
2018-03-17 17:21:09 +00:00
|
|
|
color = RenderEngine.FULL_COLOR.colorMask[y];
|
2017-12-29 00:48:35 +00:00
|
|
|
}
|
|
|
|
System.arraycopy(color, 0, colorActive, 0, 80);
|
|
|
|
}
|
2018-03-17 17:21:09 +00:00
|
|
|
super.hblankStart(screen, y, isDirty);
|
2017-12-29 00:48:35 +00:00
|
|
|
}
|
|
|
|
}
|