334 lines
8.3 KiB
Java
334 lines
8.3 KiB
Java
package org.warp.picalculator.gui.graphicengine.headless24bit;
|
|
|
|
import java.io.IOException;
|
|
import java.util.logging.ConsoleHandler;
|
|
|
|
import org.fusesource.jansi.AnsiConsole;
|
|
import org.fusesource.jansi.internal.WindowsSupport;
|
|
import org.warp.picalculator.StaticVars;
|
|
import org.warp.picalculator.Utils;
|
|
import org.warp.picalculator.device.Keyboard;
|
|
import org.warp.picalculator.event.Key;
|
|
import org.warp.picalculator.flow.Observable;
|
|
import org.warp.picalculator.gui.graphicengine.Renderer;
|
|
import org.warp.picalculator.gui.graphicengine.RenderingLoop;
|
|
|
|
public class Headless24bitEngine implements org.warp.picalculator.gui.graphicengine.GraphicEngine {
|
|
|
|
private final Headless24bitRenderer r = new Headless24bitRenderer();
|
|
private boolean stopped = true;
|
|
private RenderingLoop renderLoop;
|
|
public static final int C_MUL_X = 4;//8;
|
|
public static final int C_MUL_Y = 8;//8;
|
|
protected static final int C_WIDTH = StaticVars.screenSize[0] / C_MUL_X;//Main.screenSize[0]/2;//;60;
|
|
protected static final int C_HEIGHT = StaticVars.screenSize[1] / C_MUL_Y;//Main.screenSize[1]/3;//;40;
|
|
private String title = StaticVars.calculatorName;
|
|
private boolean win = false;
|
|
private Key precKey = null;
|
|
|
|
@Override
|
|
public int[] getSize() {
|
|
new ConsoleHandler();
|
|
return new int[] { r.size[0], r.size[1] };
|
|
}
|
|
|
|
@Override
|
|
public boolean isInitialized() {
|
|
return !stopped;
|
|
}
|
|
|
|
@Override
|
|
public void setTitle(String title) {
|
|
this.title = title;
|
|
}
|
|
|
|
@Override
|
|
public void setResizable(boolean r) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
@Override
|
|
public void setDisplayMode(int ww, int wh) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
private long outHandle;
|
|
|
|
@Override
|
|
public void create() {
|
|
this.create(null);
|
|
}
|
|
|
|
@Override
|
|
public void create(Runnable onInitialized) {
|
|
StaticVars.outputLevel = -1;
|
|
AnsiConsole.systemInstall();
|
|
if (Utils.isWindows() && !StaticVars.startupArguments.isMSDOSModeEnabled()) {
|
|
win = true;
|
|
WindowsSupport.setConsoleMode(0x0200);
|
|
final Thread t = new Thread(() -> {
|
|
int ch = -1;
|
|
while (true) {
|
|
if (precKey != null) {
|
|
Keyboard.keyReleased(precKey);
|
|
precKey = null;
|
|
}
|
|
ch = WindowsSupport.readByte();
|
|
Key key = null;
|
|
switch (ch) {
|
|
case 72: { // UP
|
|
key = Key.UP;
|
|
break;
|
|
}
|
|
case 80: { // DOWN
|
|
key = Key.DOWN;
|
|
break;
|
|
}
|
|
case 77: { // RIGHT
|
|
key = Key.RIGHT;
|
|
break;
|
|
}
|
|
case 75: { // LEFT
|
|
key = Key.LEFT;
|
|
break;
|
|
}
|
|
case 49: { // 1
|
|
key = Key.NUM1;
|
|
break;
|
|
}
|
|
case 50: { // 2
|
|
key = Key.NUM2;
|
|
break;
|
|
}
|
|
case 51: { // 3
|
|
key = Key.NUM3;
|
|
break;
|
|
}
|
|
case 52: { // 4
|
|
key = Key.NUM4;
|
|
break;
|
|
}
|
|
case 53: { // 5
|
|
key = Key.NUM5;
|
|
break;
|
|
}
|
|
case 54: { // 6
|
|
key = Key.NUM6;
|
|
break;
|
|
}
|
|
default: {
|
|
key = Key.NONE;
|
|
break;
|
|
}
|
|
}
|
|
if (key != null) {
|
|
Keyboard.keyPressed(key);
|
|
}
|
|
|
|
}
|
|
});
|
|
t.setDaemon(true);
|
|
t.start();
|
|
}
|
|
stopped = false;
|
|
if (onInitialized != null) {
|
|
onInitialized.run();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Observable<Integer[]> onResize() {
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public int getWidth() {
|
|
return r.size[0];
|
|
}
|
|
|
|
@Override
|
|
public int getHeight() {
|
|
return r.size[1];
|
|
}
|
|
|
|
@Override
|
|
public void destroy() {
|
|
stopped = true;
|
|
}
|
|
|
|
@Override
|
|
public void start(RenderingLoop d) {
|
|
renderLoop = d;
|
|
final Thread th = new Thread(() -> {
|
|
try {
|
|
double extratime = 0;
|
|
while (!stopped) {
|
|
final long start = System.currentTimeMillis();
|
|
repaint();
|
|
final long end = System.currentTimeMillis();
|
|
final double delta = (end - start) / 1000d;
|
|
final int deltaInt = (int) Math.floor(delta);
|
|
final int extraTimeInt = (int) Math.floor(extratime);
|
|
if (extraTimeInt + deltaInt < 200) {
|
|
Thread.sleep(200 - (extraTimeInt + deltaInt));
|
|
extratime = 0;
|
|
} else {
|
|
extratime += delta - 200d;
|
|
}
|
|
}
|
|
} catch (final InterruptedException e) {
|
|
e.printStackTrace();
|
|
}
|
|
});
|
|
th.setName("Console rendering thread");
|
|
th.setDaemon(true);
|
|
th.start();
|
|
}
|
|
|
|
@Override
|
|
public void repaint() {
|
|
renderLoop.refresh();
|
|
r.curColor = new int[] { 0x00, 0x87, 0x00 };
|
|
r.glDrawStringCenter((C_WIDTH * C_MUL_X) / 2, 0, title);
|
|
if (win) {
|
|
WindowsSupport.writeConsole(Headless24bitRenderer.ANSI_PREFIX + "0;0f");
|
|
WindowsSupport.writeConsole(Headless24bitRenderer.ANSI_PREFIX + "?12l");
|
|
WindowsSupport.writeConsole(Headless24bitRenderer.ANSI_PREFIX + "?25l");
|
|
} else {
|
|
AnsiConsole.out.print(Headless24bitRenderer.ANSI_PREFIX + "0;0f");
|
|
AnsiConsole.out.print(Headless24bitRenderer.ANSI_PREFIX + "?12l");
|
|
AnsiConsole.out.print(Headless24bitRenderer.ANSI_PREFIX + "?25l");
|
|
}
|
|
int[] precBgColor = new int[] { -1, -1, -1 };
|
|
int[] precFgColor = new int[] { -1, -1, -1 };
|
|
int[] curBgColor = new int[] { -1, -1, -1 };
|
|
int[] curFgColor = new int[] { -1, -1, -1 };
|
|
String out = "";
|
|
char outchar = ' ';
|
|
for (int y = 0; y < C_HEIGHT; y++) {
|
|
for (int x = 0; x < C_WIDTH; x++) {
|
|
//BG color
|
|
int[][] pixs = new int[C_MUL_X * C_MUL_Y][];
|
|
for (int paddY = 0; paddY < C_MUL_Y; paddY++) {
|
|
for (int paddX = 0; paddX < C_MUL_X; paddX++) {
|
|
pixs[paddX + paddY * C_MUL_X] = r.bgColorMatrixSs[(x * C_MUL_X + paddX) + (y * C_MUL_Y + paddY) * r.size[0]];
|
|
}
|
|
}
|
|
int[] newpix = new int[3];
|
|
for (final int[] pix : pixs) {
|
|
newpix[0] += pix[0];
|
|
newpix[1] += pix[1];
|
|
newpix[2] += pix[2];
|
|
}
|
|
newpix[0] /= pixs.length;
|
|
newpix[1] /= pixs.length;
|
|
newpix[2] /= pixs.length;
|
|
r.bgColorMatrix[x + y * C_WIDTH] = newpix;
|
|
|
|
//FG color
|
|
pixs = new int[C_MUL_X * C_MUL_Y][];
|
|
for (int paddY = 0; paddY < C_MUL_Y; paddY++) {
|
|
for (int paddX = 0; paddX < C_MUL_X; paddX++) {
|
|
pixs[paddX + paddY * C_MUL_X] = r.fgColorMatrixSs[(x * C_MUL_X + paddX) + (y * C_MUL_Y + paddY) * r.size[0]];
|
|
}
|
|
}
|
|
newpix = new int[3];
|
|
for (final int[] pix : pixs) {
|
|
newpix[0] += pix[0];
|
|
newpix[1] += pix[1];
|
|
newpix[2] += pix[2];
|
|
}
|
|
newpix[0] /= pixs.length;
|
|
newpix[1] /= pixs.length;
|
|
newpix[2] /= pixs.length;
|
|
r.fgColorMatrix[x + y * C_WIDTH] = newpix;
|
|
}
|
|
}
|
|
for (int y = 0; y < C_HEIGHT; y++) {
|
|
for (int x = 0; x < C_WIDTH; x++) {
|
|
curBgColor = r.bgColorMatrix[x + y * C_WIDTH];
|
|
curFgColor = r.fgColorMatrix[x + y * C_WIDTH];
|
|
if (precBgColor != curBgColor) {
|
|
out = Headless24bitRenderer.ANSI_PREFIX + Headless24bitRenderer.ansiBgColorPrefix + curBgColor[0] + ";" + curBgColor[1] + ";" + curBgColor[2] + Headless24bitRenderer.ansiColorSuffix;
|
|
if (win) {
|
|
WindowsSupport.writeConsole(out);
|
|
} else {
|
|
AnsiConsole.out.print(out);
|
|
}
|
|
}
|
|
if (precFgColor != curFgColor) {
|
|
out = Headless24bitRenderer.ANSI_PREFIX + Headless24bitRenderer.ansiFgColorPrefix + curFgColor[0] + ";" + curFgColor[1] + ";" + curFgColor[2] + Headless24bitRenderer.ansiColorSuffix;
|
|
if (win) {
|
|
WindowsSupport.writeConsole(out);
|
|
} else {
|
|
AnsiConsole.out.print(out);
|
|
}
|
|
}
|
|
|
|
outchar = r.charmatrix[x + y * C_WIDTH];
|
|
if (win) {
|
|
WindowsSupport.writeConsole(outchar + "");
|
|
} else {
|
|
AnsiConsole.out.print(outchar);
|
|
}
|
|
|
|
precBgColor = curBgColor;
|
|
precFgColor = curFgColor;
|
|
}
|
|
|
|
if (win) {
|
|
//System.out.println(ch);
|
|
WindowsSupport.writeConsole("\r\n");
|
|
} else {
|
|
AnsiConsole.out.println();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Renderer getRenderer() {
|
|
return r;
|
|
}
|
|
|
|
@Override
|
|
public Headless24bitFont loadFont(String file) throws IOException {
|
|
return new Headless24bitFont();
|
|
}
|
|
|
|
@Override
|
|
public Headless24bitFont loadFont(String path, String file) throws IOException {
|
|
return new Headless24bitFont();
|
|
}
|
|
|
|
@Override
|
|
public Headless24bitSkin loadSkin(String file) throws IOException {
|
|
return new Headless24bitSkin(file);
|
|
}
|
|
|
|
@Override
|
|
public void waitForExit() {
|
|
try {
|
|
do {
|
|
Thread.sleep(500);
|
|
} while (stopped == false);
|
|
} catch (final InterruptedException e) {
|
|
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean isSupported() {
|
|
if (StaticVars.startupArguments.isMSDOSModeEnabled() || (StaticVars.startupArguments.isEngineForced() && StaticVars.startupArguments.isHeadless24bitEngineForced() == false)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean doesRefreshPauses() {
|
|
return true;
|
|
}
|
|
}
|