Created Framebuffer Engine implementation
This commit is contained in:
parent
d22faf0359
commit
d5f0514208
@ -68,6 +68,9 @@ public class Main {
|
|||||||
if (arg.contains("gpu")) {
|
if (arg.contains("gpu")) {
|
||||||
Utils.forceEngine = "gpu";
|
Utils.forceEngine = "gpu";
|
||||||
}
|
}
|
||||||
|
if (arg.contains("fb")) {
|
||||||
|
Utils.forceEngine = "fb";
|
||||||
|
}
|
||||||
if (arg.contains("ms-dos")) {
|
if (arg.contains("ms-dos")) {
|
||||||
Utils.headlessOverride = true;
|
Utils.headlessOverride = true;
|
||||||
Utils.msDosMode = true;
|
Utils.msDosMode = true;
|
||||||
|
@ -13,6 +13,7 @@ import org.warp.picalculator.gui.graphicengine.Renderer;
|
|||||||
import org.warp.picalculator.gui.graphicengine.RenderingLoop;
|
import org.warp.picalculator.gui.graphicengine.RenderingLoop;
|
||||||
import org.warp.picalculator.gui.graphicengine.Skin;
|
import org.warp.picalculator.gui.graphicengine.Skin;
|
||||||
import org.warp.picalculator.gui.graphicengine.cpu.CPUEngine;
|
import org.warp.picalculator.gui.graphicengine.cpu.CPUEngine;
|
||||||
|
import org.warp.picalculator.gui.graphicengine.framebuffer.FBEngine;
|
||||||
import org.warp.picalculator.gui.graphicengine.gpu.GPUEngine;
|
import org.warp.picalculator.gui.graphicengine.gpu.GPUEngine;
|
||||||
import org.warp.picalculator.gui.graphicengine.headless24bit.Headless24bitEngine;
|
import org.warp.picalculator.gui.graphicengine.headless24bit.Headless24bitEngine;
|
||||||
import org.warp.picalculator.gui.graphicengine.headless256.Headless256Engine;
|
import org.warp.picalculator.gui.graphicengine.headless256.Headless256Engine;
|
||||||
@ -84,6 +85,11 @@ public final class DisplayManager implements RenderingLoop {
|
|||||||
|
|
||||||
private GraphicEngine chooseGraphicEngine() {
|
private GraphicEngine chooseGraphicEngine() {
|
||||||
GraphicEngine d;
|
GraphicEngine d;
|
||||||
|
d = new FBEngine();
|
||||||
|
if (d.isSupported()) {
|
||||||
|
Utils.out.println(1, "Using FB Graphic Engine");
|
||||||
|
return d;
|
||||||
|
}
|
||||||
d = new GPUEngine();
|
d = new GPUEngine();
|
||||||
if (d.isSupported()) {
|
if (d.isSupported()) {
|
||||||
Utils.out.println(1, "Using GPU Graphic Engine");
|
Utils.out.println(1, "Using GPU Graphic Engine");
|
||||||
|
@ -15,7 +15,9 @@ public interface GraphicEngine {
|
|||||||
|
|
||||||
public void setDisplayMode(final int ww, final int wh);
|
public void setDisplayMode(final int ww, final int wh);
|
||||||
|
|
||||||
public void create();
|
public default void create() {
|
||||||
|
create(null);
|
||||||
|
};
|
||||||
|
|
||||||
public void create(Runnable object);
|
public void create(Runnable object);
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ public class CPUFont implements BinaryFont {
|
|||||||
public static final int intBits = 31;
|
public static final int intBits = 31;
|
||||||
private final boolean isResource;
|
private final boolean isResource;
|
||||||
|
|
||||||
CPUFont(String fontName) throws IOException {
|
public CPUFont(String fontName) throws IOException {
|
||||||
this(fontName, false);
|
this(fontName, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ public class CPUFont implements BinaryFont {
|
|||||||
load("/font_" + fontName + ".rft", onlyRaw);
|
load("/font_" + fontName + ".rft", onlyRaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPUFont(String path, String fontName) throws IOException {
|
public CPUFont(String path, String fontName) throws IOException {
|
||||||
this(path, fontName, false);
|
this(path, fontName, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +273,9 @@ public class CPUFont implements BinaryFont {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void use(GraphicEngine d) {
|
public void use(GraphicEngine d) {
|
||||||
((CPURenderer) d.getRenderer()).currentFont = this;
|
if (d.getRenderer() instanceof CPURenderer) {
|
||||||
|
((CPURenderer) d.getRenderer()).currentFont = this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -15,7 +15,7 @@ public class CPUSkin implements Skin {
|
|||||||
public int[] skinSize;
|
public int[] skinSize;
|
||||||
private final boolean isResource;
|
private final boolean isResource;
|
||||||
|
|
||||||
CPUSkin(String file) throws IOException {
|
public CPUSkin(String file) throws IOException {
|
||||||
isResource = !new File(file).exists();
|
isResource = !new File(file).exists();
|
||||||
load(file);
|
load(file);
|
||||||
}
|
}
|
||||||
@ -48,7 +48,9 @@ public class CPUSkin implements Skin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void use(GraphicEngine d) {
|
public void use(GraphicEngine d) {
|
||||||
((CPURenderer) d.getRenderer()).currentSkin = this;
|
if (d.getRenderer() instanceof CPURenderer) {
|
||||||
|
((CPURenderer) d.getRenderer()).currentSkin = this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,210 @@
|
|||||||
|
package org.warp.picalculator.gui.graphicengine.framebuffer;
|
||||||
|
|
||||||
|
import java.awt.GraphicsEnvironment;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.nio.MappedByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
|
import org.warp.picalculator.Utils;
|
||||||
|
import org.warp.picalculator.gui.graphicengine.BinaryFont;
|
||||||
|
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
|
||||||
|
import org.warp.picalculator.gui.graphicengine.Renderer;
|
||||||
|
import org.warp.picalculator.gui.graphicengine.RenderingLoop;
|
||||||
|
import org.warp.picalculator.gui.graphicengine.Skin;
|
||||||
|
import org.warp.picalculator.gui.graphicengine.cpu.CPUFont;
|
||||||
|
import org.warp.picalculator.gui.graphicengine.cpu.CPUSkin;
|
||||||
|
|
||||||
|
import sun.nio.ch.DirectBuffer;
|
||||||
|
|
||||||
|
public class FBEngine implements GraphicEngine {
|
||||||
|
|
||||||
|
private static final int FB_DISPLAY_WIDTH = 320;
|
||||||
|
private static final int FB_DISPLAY_HEIGHT = 480;
|
||||||
|
private static final int FB_DISPLAY_BPP = 32;
|
||||||
|
private static final int WIDTH = 480;
|
||||||
|
private static final int HEIGHT = 320;
|
||||||
|
private static final int[] SIZE = new int[] {WIDTH, HEIGHT};
|
||||||
|
public FBRenderer r;
|
||||||
|
private MappedByteBuffer fb, realFb;
|
||||||
|
private RandomAccessFile fbFileRW;
|
||||||
|
public volatile boolean initialized = false;
|
||||||
|
public Semaphore exitSemaphore = new Semaphore(0);
|
||||||
|
private boolean resizedTrigger = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getSize() {
|
||||||
|
return SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInitialized() {
|
||||||
|
return initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTitle(String title) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResizable(boolean r) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDisplayMode(int ww, int wh) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create(Runnable onInitialized) {
|
||||||
|
resizedTrigger = true;
|
||||||
|
File fbFile = new File("/dev/fb1");
|
||||||
|
try {
|
||||||
|
fbFileRW = new RandomAccessFile(fbFile, "rw");
|
||||||
|
final long fbLen = FB_DISPLAY_HEIGHT*FB_DISPLAY_WIDTH*(FB_DISPLAY_BPP/8);
|
||||||
|
fb = (MappedByteBuffer) MappedByteBuffer.allocateDirect((int) fbLen);
|
||||||
|
realFb = fbFileRW.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, fbLen);
|
||||||
|
|
||||||
|
r = new FBRenderer(this, fb);
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
if (onInitialized != null)
|
||||||
|
onInitialized.run();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
System.err.println("Cannot read framebuffer fb1");
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean wasResized() {
|
||||||
|
if (resizedTrigger) {
|
||||||
|
resizedTrigger = false;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWidth() {
|
||||||
|
return WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHeight() {
|
||||||
|
return HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
try {
|
||||||
|
fbFileRW.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(RenderingLoop d) {
|
||||||
|
final Thread th = new Thread(() -> {
|
||||||
|
try {
|
||||||
|
double extratime = 0;
|
||||||
|
while (initialized) {
|
||||||
|
final long start = System.currentTimeMillis();
|
||||||
|
d.refresh();
|
||||||
|
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 < 50) {
|
||||||
|
Thread.sleep(50 - (extraTimeInt + deltaInt));
|
||||||
|
extratime = 0;
|
||||||
|
} else {
|
||||||
|
extratime += delta - 50d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (final InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
th.setName("CPU rendering thread");
|
||||||
|
th.setDaemon(true);
|
||||||
|
th.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int _________________TMP = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void repaint() {
|
||||||
|
if (_________________TMP % 100 == 0) {
|
||||||
|
System.out.println(System.currentTimeMillis());
|
||||||
|
_________________TMP = 0;
|
||||||
|
}
|
||||||
|
_________________TMP++;
|
||||||
|
realFb.clear();
|
||||||
|
realFb.put(fb);
|
||||||
|
for (int i = 0; i < fb.capacity()/2; i++) {
|
||||||
|
realFb.put(i, (byte) (0xFF));
|
||||||
|
}
|
||||||
|
for (int i = fb.capacity()/2; i < fb.capacity(); i++) {
|
||||||
|
realFb.put(i, (byte) (0x18));
|
||||||
|
}
|
||||||
|
realFb.force();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Renderer getRenderer() {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BinaryFont loadFont(String fontName) throws IOException {
|
||||||
|
return new CPUFont(fontName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BinaryFont loadFont(String path, String fontName) throws IOException {
|
||||||
|
return new CPUFont(path, fontName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Skin loadSkin(String file) throws IOException {
|
||||||
|
return new CPUSkin(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void waitForExit() {
|
||||||
|
try {
|
||||||
|
exitSemaphore.acquire();
|
||||||
|
} catch (InterruptedException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSupported() {
|
||||||
|
if (Utils.forceEngine != null && Utils.forceEngine != "fb")
|
||||||
|
return false;
|
||||||
|
if (Utils.headlessOverride) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
File fbFile = new File("/dev/fb1");
|
||||||
|
try {
|
||||||
|
fbFileRW = new RandomAccessFile(fbFile, "rw");
|
||||||
|
fbFileRW.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, fbFile.length());
|
||||||
|
fbFileRW.close();
|
||||||
|
return true;
|
||||||
|
} catch (IOException ex) {
|
||||||
|
System.err.println("Cannot read framebuffer fb1.");
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doesRefreshPauses() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,140 @@
|
|||||||
|
package org.warp.picalculator.gui.graphicengine.framebuffer;
|
||||||
|
|
||||||
|
import java.nio.MappedByteBuffer;
|
||||||
|
|
||||||
|
import org.warp.picalculator.gui.graphicengine.BinaryFont;
|
||||||
|
import org.warp.picalculator.gui.graphicengine.Renderer;
|
||||||
|
|
||||||
|
public class FBRenderer implements Renderer {
|
||||||
|
|
||||||
|
public FBRenderer(FBEngine fbEngine, MappedByteBuffer fb) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glColor3i(int r, int gg, int b) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glColor(int c) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glColor4i(int red, int green, int blue, int alpha) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glColor3f(float red, float green, float blue) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glColor4f(float red, float green, float blue, float alpha) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glClearColor4i(int red, int green, int blue, int alpha) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glClearColor4f(float red, float green, float blue, float alpha) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int glGetClearColor() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glClearColor(int c) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glClear(int screenWidth, int screenHeight) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glDrawLine(float x0, float y0, float x1, float y1) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glFillRect(float x, float y, float width, float height, float uvX, float uvY, float uvWidth,
|
||||||
|
float uvHeight) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glFillColor(float x, float y, float width, float height) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glDrawCharLeft(int x, int y, char ch) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glDrawCharCenter(int x, int y, char ch) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glDrawCharRight(int x, int y, char ch) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glDrawStringLeft(float x, float y, String text) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glDrawStringCenter(float x, float y, String text) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glDrawStringRight(float x, float y, String text) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glClearSkin() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BinaryFont getCurrentFont() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user