Better GPU memory handling
This commit is contained in:
parent
35294797a3
commit
ca41857f0c
5
pom.xml
5
pom.xml
@ -50,6 +50,11 @@
|
||||
<artifactId>jansi</artifactId>
|
||||
<version>1.15</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ar.com.hjg</groupId>
|
||||
<artifactId>pngj</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
|
@ -15,6 +15,8 @@ import java.lang.reflect.Modifier;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.nevec.rjm.BigDecimalMath;
|
||||
@ -716,4 +718,23 @@ public class Utils {
|
||||
public static boolean isWindows() {
|
||||
return (OS.indexOf("win") >= 0);
|
||||
}
|
||||
|
||||
public static LinkedList<BigInteger> mcm(LinkedList<BigInteger> factors1, LinkedList<BigInteger> factors2) {
|
||||
LinkedList<BigInteger> mcm = new LinkedList<>();
|
||||
Iterator<BigInteger> i1 = factors1.iterator();
|
||||
while(i1.hasNext()) {
|
||||
BigInteger int1 = i1.next();
|
||||
Iterator<BigInteger> i2 = factors2.iterator();
|
||||
while(i2.hasNext()) {
|
||||
BigInteger int2 = i2.next();
|
||||
if (int1.equals(int2)) {
|
||||
i1.remove();
|
||||
i2.remove();
|
||||
mcm.add(int1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return mcm;
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import org.warp.picalculator.device.chip.SerialToParallel;
|
||||
import org.warp.picalculator.gui.DisplayManager;
|
||||
import org.warp.picalculator.gui.GUIErrorMessage;
|
||||
import org.warp.picalculator.gui.screens.KeyboardDebugScreen;
|
||||
import org.warp.picalculator.gui.screens.MarioScreen;
|
||||
import org.warp.picalculator.gui.screens.Screen;
|
||||
|
||||
import com.pi4j.wiringpi.Gpio;
|
||||
@ -589,7 +590,7 @@ public class Keyboard {
|
||||
refresh = true;
|
||||
break;
|
||||
case BRIGHTNESS_CYCLE_REVERSE:
|
||||
//DisplayManager.INSTANCE.setScreen(new MarioScreen()); //TODO: rimuovere: prova
|
||||
if (StaticVars.debugOn) DisplayManager.INSTANCE.setScreen(new MarioScreen()); //TODO: rimuovere: prova
|
||||
DisplayManager.INSTANCE.cycleBrightness(true);
|
||||
refresh = true;
|
||||
break;
|
||||
|
@ -33,7 +33,9 @@ public interface GraphicEngine {
|
||||
|
||||
public Renderer getRenderer();
|
||||
|
||||
public BinaryFont loadFont(String file) throws IOException;
|
||||
public BinaryFont loadFont(String fontName) throws IOException;
|
||||
|
||||
public BinaryFont loadFont(String path, String fontName) throws IOException;
|
||||
|
||||
public Skin loadSkin(String file) throws IOException;
|
||||
|
||||
|
@ -160,8 +160,13 @@ public class CPUEngine implements GraphicEngine {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryFont loadFont(String file) throws IOException {
|
||||
return new CPUFont(file);
|
||||
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
|
||||
|
@ -6,6 +6,8 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ -15,6 +17,8 @@ import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.graphicengine.BinaryFont;
|
||||
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
|
||||
|
||||
import com.sun.xml.internal.bind.v2.model.util.ArrayInfoUtil;
|
||||
|
||||
public class CPUFont implements BinaryFont {
|
||||
|
||||
public boolean[][] rawchars;
|
||||
@ -25,22 +29,36 @@ public class CPUFont implements BinaryFont {
|
||||
public int charH;
|
||||
public int charS;
|
||||
public int charIntCount;
|
||||
public LinkedList<Integer[]> intervals;
|
||||
public int intervalsTotalSize = 0;
|
||||
public static final int intBits = 31;
|
||||
private final boolean isResource;
|
||||
|
||||
CPUFont(String file) throws IOException {
|
||||
load(file);
|
||||
CPUFont(String fontName) throws IOException {
|
||||
isResource = true;
|
||||
load("/font_" + fontName + ".rft");
|
||||
}
|
||||
|
||||
CPUFont(String path, String fontName) throws IOException {
|
||||
isResource = false;
|
||||
load(path + "/font_" + fontName + ".rft");
|
||||
}
|
||||
|
||||
public static CPUFont loadTemporaryFont(String name) throws IOException {
|
||||
return new CPUFont(name);
|
||||
}
|
||||
|
||||
public static CPUFont loadTemporaryFont(String path, String name) throws IOException {
|
||||
return new CPUFont(path, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(String name) throws IOException {
|
||||
loadFont("/font_" + name + ".rft");
|
||||
chars32 = new int[(maxBound - minBound) * charIntCount];
|
||||
for (int charIndex = 0; charIndex < maxBound - minBound; charIndex++) {
|
||||
final boolean[] currentChar = rawchars[charIndex];
|
||||
public void load(String path) throws IOException {
|
||||
Utils.out.println(Utils.OUTPUTLEVEL_DEBUG_MIN, "Loading font " + path);
|
||||
loadFont(path);
|
||||
chars32 = new int[(intervalsTotalSize) * charIntCount];
|
||||
for (int charCompressedIndex = 0; charCompressedIndex < intervalsTotalSize; charCompressedIndex++) {
|
||||
final boolean[] currentChar = rawchars[charCompressedIndex];
|
||||
if (currentChar == null) {
|
||||
int currentInt = 0;
|
||||
int currentBit = 0;
|
||||
@ -49,7 +67,7 @@ public class CPUFont implements BinaryFont {
|
||||
currentInt += 1;
|
||||
currentBit = 0;
|
||||
}
|
||||
chars32[charIndex * charIntCount + currentInt] = (chars32[charIndex * charIntCount + currentInt] << 1) + 1;
|
||||
chars32[charCompressedIndex * charIntCount + currentInt] = (chars32[charCompressedIndex * charIntCount + currentInt] << 1) + 1;
|
||||
currentBit += 1;
|
||||
}
|
||||
} else {
|
||||
@ -60,7 +78,7 @@ public class CPUFont implements BinaryFont {
|
||||
currentInt += 1;
|
||||
currentBit = 0;
|
||||
}
|
||||
chars32[charIndex * charIntCount + currentInt] = (chars32[charIndex * charIntCount + currentInt]) | ((currentChar[i] ? 1 : 0) << currentBit);
|
||||
chars32[charCompressedIndex * charIntCount + currentInt] = (chars32[charCompressedIndex * charIntCount + currentInt]) | ((currentChar[i] ? 1 : 0) << currentBit);
|
||||
currentBit++;
|
||||
}
|
||||
}
|
||||
@ -75,7 +93,7 @@ public class CPUFont implements BinaryFont {
|
||||
}
|
||||
|
||||
private void loadFont(String string) throws IOException {
|
||||
final URL res = this.getClass().getResource(string);
|
||||
final URL res = isResource ? this.getClass().getResource(string) : new File(string).toURI().toURL();
|
||||
final int[] file = Utils.realBytes(Utils.convertStreamToByteArray(res.openStream(), res.getFile().length()));
|
||||
final int filelength = file.length;
|
||||
if (filelength >= 16) {
|
||||
@ -123,11 +141,70 @@ public class CPUFont implements BinaryFont {
|
||||
} else {
|
||||
throw new IOException();
|
||||
}
|
||||
findIntervals();
|
||||
/*int[] screen = new int[rawchars.length * charW * charH];
|
||||
for (int i = 0; i < rawchars.length; i++) {
|
||||
if (rawchars[i] != null)
|
||||
for (int charX = 0; charX < charW; charX++) {
|
||||
for (int charY = 0; charY < charH; charY++) {
|
||||
int x = i * charW + charX;
|
||||
int y = charY;
|
||||
screen[x + y * rawchars.length * charW] = rawchars[i][charX + charY * charW] ? 0xFF000000 : 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
System.out.println((('1' & 0xFFFF) - minBound) + "=>"+ (getCharIndexes("1")[0]));
|
||||
this.saveArray(screen, rawchars.length * charW, charH, "N:\\TimedTemp"+string+".png");
|
||||
System.out.println();
|
||||
System.out.println();
|
||||
*/
|
||||
}
|
||||
|
||||
private void findIntervals() {
|
||||
intervals = new LinkedList<Integer[]>();
|
||||
int beginIndex = -1;
|
||||
int endIndex = 0;
|
||||
int intervalSize = 0;
|
||||
int holeSize = 0;
|
||||
for (int i = 0; i < rawchars.length; i++) {
|
||||
if (rawchars[i] != null) {
|
||||
beginIndex = i;
|
||||
int firstNull = 0;
|
||||
while(i+firstNull < rawchars.length && rawchars[i+firstNull] != null) {
|
||||
firstNull++;
|
||||
}
|
||||
endIndex = beginIndex + firstNull - 1;
|
||||
i = endIndex;
|
||||
if (endIndex >= 0) {
|
||||
intervalSize = endIndex - beginIndex + 1;
|
||||
intervals.add(new Integer[] {beginIndex, endIndex, intervalSize});
|
||||
intervalsTotalSize += intervalSize;
|
||||
}
|
||||
beginIndex = -1;
|
||||
}
|
||||
}
|
||||
int lastIndex = 0;
|
||||
boolean[][] newrawchars = new boolean[intervalsTotalSize][];
|
||||
for (Integer[] interval: intervals) {
|
||||
if (rawchars.length - (interval[0]) - interval[2] < 0) {
|
||||
System.err.println(interval[0] + "-" + interval[1] + "(" + interval[2] + ")");
|
||||
System.err.println(rawchars.length - (interval[0]) - interval[2]);
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (newrawchars.length - (lastIndex-1) - interval[2] < 0) {
|
||||
System.err.println(newrawchars.length - (lastIndex-1) - interval[2]);
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
System.arraycopy(rawchars, interval[0], newrawchars, lastIndex, interval[2]);
|
||||
lastIndex += interval[2];
|
||||
}
|
||||
rawchars = newrawchars;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void saveArray(int[] screen, String coutputpng) {
|
||||
final BufferedImage bi = new BufferedImage(300, 200, BufferedImage.TYPE_INT_RGB);
|
||||
private void saveArray(int[] screen, int w, int h, String coutputpng) {
|
||||
final BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
final int[] a = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData();
|
||||
System.arraycopy(screen, 0, a, 0, screen.length);
|
||||
try {
|
||||
@ -142,7 +219,19 @@ public class CPUFont implements BinaryFont {
|
||||
final int[] indexes = new int[l];
|
||||
final char[] chars = txt.toCharArray();
|
||||
for (int i = 0; i < l; i++) {
|
||||
indexes[i] = (chars[i] & 0xFFFF) - minBound;
|
||||
int originalIndex = chars[i] & 0xFFFF;
|
||||
int compressedIndex = 0;
|
||||
for (Integer[] interval : intervals) {
|
||||
if (interval[0] > originalIndex) {
|
||||
break;
|
||||
} else if (originalIndex <= interval[1]) {
|
||||
compressedIndex+=(originalIndex-interval[0]);
|
||||
break;
|
||||
} else {
|
||||
compressedIndex+=interval[2];
|
||||
}
|
||||
}
|
||||
indexes[i] = compressedIndex;
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ public class CPURenderer implements Renderer {
|
||||
currentIntBitPosition = bit - (currentInt * CPUFont.intBits);
|
||||
bitData = (currentFont.chars32[charIndex * currentFont.charIntCount + currentInt] >> currentIntBitPosition) & 1;
|
||||
screenPos = ix + cpos + dx + (iy + dy) * screenSize[0];
|
||||
if (bitData == 1 & screenLength > screenPos) {
|
||||
if (bitData == 1 & screenLength > screenPos & screenPos >= 0) {
|
||||
screen[screenPos] = color;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.warp.picalculator.gui.graphicengine.cpu;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
@ -12,14 +13,16 @@ public class CPUSkin implements Skin {
|
||||
|
||||
public int[] skinData;
|
||||
public int[] skinSize;
|
||||
private final boolean isResource;
|
||||
|
||||
CPUSkin(String file) throws IOException {
|
||||
isResource = !new File(file).exists();
|
||||
load(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(String file) throws IOException {
|
||||
final BufferedImage img = ImageIO.read(this.getClass().getResource("/" + file));
|
||||
final BufferedImage img = ImageIO.read(isResource ? this.getClass().getResource("/" + file) : new File(file).toURI().toURL());
|
||||
skinData = getMatrixOfImage(img);
|
||||
skinSize = new int[] { img.getWidth(), img.getHeight() };
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.warp.picalculator.gui.graphicengine.gpu;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@ -121,14 +122,26 @@ public class GPUEngine implements GraphicEngine {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryFont loadFont(String file) throws IOException {
|
||||
public BinaryFont loadFont(String name) throws IOException {
|
||||
for (Entry<String, GPUFont> entry : fontCache.entrySet()) {
|
||||
if (entry.getKey().equals(file)) {
|
||||
if (entry.getKey().equals(name)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
GPUFont font = new GPUFont(this, file);
|
||||
fontCache.put(file, font);
|
||||
GPUFont font = new GPUFont(this, name);
|
||||
fontCache.put(name, font);
|
||||
return font;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryFont loadFont(String path, String name) throws IOException {
|
||||
for (Entry<String, GPUFont> entry : fontCache.entrySet()) {
|
||||
if (entry.getKey().equals(name)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
GPUFont font = new GPUFont(this, path, name);
|
||||
fontCache.put(name, font);
|
||||
return font;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
package org.warp.picalculator.gui.graphicengine.gpu;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.warp.picalculator.gui.graphicengine.BinaryFont;
|
||||
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
|
||||
@ -10,6 +13,15 @@ import org.warp.picalculator.gui.graphicengine.cpu.CPUFont;
|
||||
import com.jogamp.opengl.GLException;
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
|
||||
import ar.com.hjg.pngj.IImageLine;
|
||||
import ar.com.hjg.pngj.ImageInfo;
|
||||
import ar.com.hjg.pngj.ImageLineHelper;
|
||||
import ar.com.hjg.pngj.ImageLineInt;
|
||||
import ar.com.hjg.pngj.PngReader;
|
||||
import ar.com.hjg.pngj.PngWriter;
|
||||
import ar.com.hjg.pngj.chunks.ChunkCopyBehaviour;
|
||||
import ar.com.hjg.pngj.chunks.PngChunkTextVar;
|
||||
|
||||
public class GPUFont implements BinaryFont {
|
||||
|
||||
public Texture texture;
|
||||
@ -19,26 +31,40 @@ public class GPUFont implements BinaryFont {
|
||||
public int charH;
|
||||
public int minCharIndex;
|
||||
public int maxCharIndex;
|
||||
|
||||
public LinkedList<Integer[]> intervals;
|
||||
public int memoryWidth;
|
||||
public int memoryHeight;
|
||||
public int memoryWidthOfEachColumn;
|
||||
|
||||
private boolean initialized = false;
|
||||
private BufferedImage tmpFont;
|
||||
private ByteArrayOutputStream tmpFont;
|
||||
|
||||
GPUFont(GraphicEngine g, String file) throws IOException {
|
||||
load(file);
|
||||
((GPUEngine) g).registerFont(this);
|
||||
GPUFont(GraphicEngine g, String name) throws IOException {
|
||||
this((GPUEngine) g, null, name);
|
||||
}
|
||||
|
||||
public GPUFont(GraphicEngine g, String path, String name) throws IOException {
|
||||
load(path, name);
|
||||
((GPUEngine) g).registerFont(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(String file) throws IOException {
|
||||
CPUFont font = CPUFont.loadTemporaryFont(file);
|
||||
public void load(String name) throws IOException {
|
||||
load(null, name);
|
||||
}
|
||||
|
||||
public void load(String path, String name) throws IOException {
|
||||
CPUFont font;
|
||||
if (path == null) {
|
||||
font = CPUFont.loadTemporaryFont(name);
|
||||
} else {
|
||||
font = CPUFont.loadTemporaryFont(path, name);
|
||||
}
|
||||
charW = font.charW;
|
||||
charH = font.charH;
|
||||
minCharIndex = font.minBound;
|
||||
maxCharIndex = font.maxBound;
|
||||
intervals = font.intervals;
|
||||
pregenTexture(font.rawchars);
|
||||
font = null;
|
||||
}
|
||||
@ -56,41 +82,64 @@ public class GPUFont implements BinaryFont {
|
||||
public int getCharIndex(char ch) {
|
||||
return (ch & 0xFFFF) - minCharIndex;
|
||||
}
|
||||
|
||||
|
||||
private void pregenTexture(boolean[][] chars) {
|
||||
final double totalChars = maxCharIndex - minCharIndex;
|
||||
final int w = powerOf2((int) (Math.ceil(Math.sqrt(totalChars) * charW)));
|
||||
final int h = powerOf2((int) (Math.ceil(Math.sqrt(totalChars) * charH)));
|
||||
final int maxIndexW = (int) Math.floor(((double) w) / ((double) charW)) - 1;
|
||||
BufferedImage bfi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
|
||||
int indexX = 0;
|
||||
int indexY = 0;
|
||||
for (int i = 0; i < totalChars; i++) {
|
||||
boolean[] currentChar = chars[i];
|
||||
if (currentChar != null && currentChar.length > 0) {
|
||||
for (int charY = 0; charY < charH; charY++) {
|
||||
final int totalChars = maxCharIndex - minCharIndex;
|
||||
int w = powerOf2((int) (Math.ceil(Math.sqrt(totalChars) * charW)));
|
||||
int h = powerOf2((int) (Math.ceil(Math.sqrt(totalChars) * charH)));
|
||||
int maxIndexW = (int) Math.floor(((double) w) / ((double) charW)) - 1;
|
||||
int maxIndexH = (int) Math.floor(((double) h) / ((double) charH)) - 1;
|
||||
if (w > h) {
|
||||
System.out.println("w > h");
|
||||
h = powerOf2((int) (Math.ceil((((double)totalChars)/((double)(maxIndexW))) * charH)));
|
||||
maxIndexH = (int) Math.floor(((double) h) / ((double) charH)) - 1;
|
||||
} else {
|
||||
System.out.println("w <= h");
|
||||
w = powerOf2((int) (Math.ceil((((double)totalChars)/((double)(maxIndexH))) * charW)));
|
||||
maxIndexW = (int) Math.floor(((double) w) / ((double) charW)) - 1;
|
||||
}
|
||||
// final int h = powerOf2((int) (Math.ceil(Math.sqrt(totalChars) * charH)));
|
||||
|
||||
System.out.println(((int)Math.ceil(Math.sqrt(totalChars) * charW)) + " * " + ((int)Math.ceil(Math.sqrt(totalChars) * charH)) + " --> " + w + " * " + h);
|
||||
|
||||
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(w*h*8*4);
|
||||
final ImageInfo imi = new ImageInfo(w, h, 8, true); // 8 bits per channel, alpha
|
||||
// open image for writing to a output stream
|
||||
final PngWriter png = new PngWriter(outputStream, imi);
|
||||
for (int y = 0; y < png.imgInfo.rows; y++) {
|
||||
ImageLineInt iline = new ImageLineInt(imi);
|
||||
int[] xValues = new int[imi.cols];
|
||||
for (int indexX = 0; indexX < maxIndexW; indexX++) {// this line will be written to all rows
|
||||
final int charY = (y % charH);
|
||||
final int indexY = (y - charY)/charH;
|
||||
final int i = indexY * maxIndexW + indexX;
|
||||
boolean[] currentChar;
|
||||
if (i < totalChars && (currentChar=chars[i]) != null) {
|
||||
for (int charX = 0; charX < charW; charX++) {
|
||||
if (currentChar[charY * charW + charX]) {
|
||||
bfi.setRGB(indexX * charW + charX, indexY * charH + charY, 0xFFFFFFFF);
|
||||
if (i > 0 & i < totalChars && currentChar != null && currentChar[charX + charY * charW]) {
|
||||
xValues[indexX * charW + charX] = 0xFFFFFFFF;
|
||||
}
|
||||
// ImageLineHelper.setPixelRGBA8(iline, x, color, color, color, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
indexX++;
|
||||
if (indexX >= maxIndexW) {
|
||||
indexX = 0;
|
||||
indexY += 1;
|
||||
ImageLineHelper.setPixelsRGBA8(iline, xValues);
|
||||
if (y % 200 == 0) {
|
||||
System.out.println(y + "/" + png.imgInfo.rows);
|
||||
}
|
||||
currentChar = null;
|
||||
png.writeRow(iline);
|
||||
}
|
||||
png.end();
|
||||
|
||||
try {
|
||||
memoryWidth = w;
|
||||
memoryHeight = h;
|
||||
memoryWidthOfEachColumn = maxIndexW;
|
||||
textureW = bfi.getWidth();
|
||||
textureH = bfi.getHeight();
|
||||
this.tmpFont = bfi;
|
||||
} catch (GLException e) {
|
||||
textureW = w;
|
||||
textureH = h;
|
||||
outputStream.flush();
|
||||
this.tmpFont = outputStream;
|
||||
} catch (GLException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -98,13 +147,14 @@ public class GPUFont implements BinaryFont {
|
||||
private void genTexture() {
|
||||
try {
|
||||
texture = GPURenderer.importTexture(tmpFont);
|
||||
tmpFont = null;
|
||||
} catch (GLException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private int powerOf2(int a) {
|
||||
return (int) (a == 0 ? 0 : Math.pow(2, 32 - Integer.numberOfLeadingZeros(a - 1)));
|
||||
private int powerOf2(int i) {
|
||||
return i >1 ? Integer.highestOneBit(i-1)<<1 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,11 +3,14 @@ package org.warp.picalculator.gui.graphicengine.gpu;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
@ -239,17 +242,37 @@ public class GPURenderer implements Renderer {
|
||||
return tex;
|
||||
}
|
||||
|
||||
static BufferedImage openTexture(String file) throws GLException, IOException {
|
||||
return ImageIO.read(GPURenderer.class.getClassLoader().getResource(file));
|
||||
static OpenedTextureData openTexture(String file) throws GLException, IOException {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
BufferedImage img = ImageIO.read(!Files.exists(Paths.get(file)) ? GPURenderer.class.getResource("/" + file) : new File(file).toURI().toURL());
|
||||
ImageIO.write(img, "png", os);
|
||||
return new OpenedTextureData(img.getWidth(), img.getHeight(), os);
|
||||
}
|
||||
|
||||
public static class OpenedTextureData {
|
||||
public final int w;
|
||||
public final int h;
|
||||
public final ByteArrayOutputStream os;
|
||||
|
||||
/**
|
||||
* @param w
|
||||
* @param h
|
||||
* @param os
|
||||
*/
|
||||
public OpenedTextureData(int w, int h, ByteArrayOutputStream os) {
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
this.os = os;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static Texture importTexture(BufferedImage img) throws GLException, IOException {
|
||||
final ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
ImageIO.write(img, "png", os);
|
||||
static Texture importTexture(ByteArrayOutputStream os) throws GLException, IOException {
|
||||
final InputStream fis = new ByteArrayInputStream(os.toByteArray());
|
||||
final Texture tex = TextureIO.newTexture(fis, false, TextureIO.PNG);
|
||||
tex.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
|
||||
tex.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
|
||||
os = null;
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,14 @@
|
||||
package org.warp.picalculator.gui.graphicengine.gpu;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
|
||||
import org.warp.picalculator.gui.graphicengine.Skin;
|
||||
import org.warp.picalculator.gui.graphicengine.gpu.GPURenderer.OpenedTextureData;
|
||||
|
||||
import com.jogamp.opengl.GL;
|
||||
import com.jogamp.opengl.GL2ES1;
|
||||
@ -26,7 +30,7 @@ public class GPUSkin implements Skin {
|
||||
|
||||
@Override
|
||||
public void load(String file) throws IOException {
|
||||
if ((this.getClass().getClassLoader().getResource(file)) == null) {
|
||||
if (!Files.exists(Paths.get(file)) && (this.getClass().getClassLoader().getResource(file)) == null) {
|
||||
throw new IOException("File '" + file + "' not found!");
|
||||
}
|
||||
texturePath = file;
|
||||
@ -35,11 +39,11 @@ public class GPUSkin implements Skin {
|
||||
@Override
|
||||
public void initialize(GraphicEngine d) {
|
||||
try {
|
||||
final BufferedImage i = GPURenderer.openTexture(texturePath);
|
||||
final OpenedTextureData i = GPURenderer.openTexture(texturePath);
|
||||
final GL2ES1 gl = GPURenderer.gl;
|
||||
t = GPURenderer.importTexture(i);
|
||||
w = i.getWidth();
|
||||
h = i.getHeight();
|
||||
t = GPURenderer.importTexture(i.os);
|
||||
w = i.w;
|
||||
h = i.h;
|
||||
t.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
|
||||
initialized = true;
|
||||
} catch (GLException | IOException e) {
|
||||
|
@ -295,6 +295,11 @@ public class Headless24bitEngine implements org.warp.picalculator.gui.graphiceng
|
||||
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);
|
||||
|
@ -252,6 +252,11 @@ public class Headless256Engine implements org.warp.picalculator.gui.graphicengin
|
||||
return new Headless256Font();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Headless256Font loadFont(String path, String file) throws IOException {
|
||||
return new Headless256Font();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Headless256Skin loadSkin(String file) throws IOException {
|
||||
return new Headless256Skin(file);
|
||||
|
@ -252,6 +252,11 @@ public class Headless8Engine implements org.warp.picalculator.gui.graphicengine.
|
||||
return new Headless8Font();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Headless8Font loadFont(String path, String file) throws IOException {
|
||||
return new Headless8Font();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Headless8Skin loadSkin(String file) throws IOException {
|
||||
return new Headless8Skin(file);
|
||||
|
@ -14,9 +14,14 @@ public class MarioScreen extends Screen {
|
||||
private static Skin skin;
|
||||
private static Skin groundskin;
|
||||
private static BinaryFont easterfont;
|
||||
private static BinaryFont fu32font;
|
||||
private static Skin easterskin;
|
||||
private int easterNum = 0;
|
||||
private float easterElapsed = 0;
|
||||
private int easterMax = 21;
|
||||
private String[] easterFu32 = new String[] {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g"};
|
||||
private int easterFu32Num = 0;
|
||||
private float easterFu32Elapsed = 0;
|
||||
private boolean errored;
|
||||
public float[] marioPos = new float[] { 30, 0 };
|
||||
public float[] marioForces = new float[] { 0, 0 };
|
||||
@ -43,11 +48,17 @@ public class MarioScreen extends Screen {
|
||||
groundskin = DisplayManager.INSTANCE.engine.loadSkin("marioground.png");
|
||||
if (easterfont == null)
|
||||
try {
|
||||
easterfont = DisplayManager.INSTANCE.engine.loadFont("easter");
|
||||
easterfont = DisplayManager.INSTANCE.engine.loadFont("X:\\CESTINO\\ALTRO", "easter");
|
||||
} catch (Exception ex) {}
|
||||
if (fu32font == null)
|
||||
try {
|
||||
fu32font = DisplayManager.INSTANCE.engine.loadFont("X:\\CESTINO\\ALTRO", "fu32");
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
if (easterskin == null)
|
||||
try {
|
||||
easterskin = DisplayManager.INSTANCE.engine.loadSkin("font_easter.png");
|
||||
easterskin = DisplayManager.INSTANCE.engine.loadSkin("X:\\CESTINO\\ALTRO\\font_easter.png");
|
||||
} catch (Exception ex) {}
|
||||
} catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -128,6 +139,17 @@ public class MarioScreen extends Screen {
|
||||
}
|
||||
marioForces[0] *= 0.75;
|
||||
|
||||
easterElapsed += dt;
|
||||
while (easterElapsed >= 0.04) {
|
||||
easterNum = (easterNum + 1) % easterMax;
|
||||
easterElapsed -= 0.04;
|
||||
}
|
||||
easterFu32Elapsed += dt;
|
||||
while (easterFu32Elapsed >= 1.5) {
|
||||
easterFu32Num = (easterFu32Num + 1) % easterFu32.length;
|
||||
easterFu32Elapsed -= 1.5;
|
||||
}
|
||||
|
||||
DisplayManager.INSTANCE.renderer.glClearColor(0xff9290ff);
|
||||
}
|
||||
}
|
||||
@ -159,6 +181,18 @@ public class MarioScreen extends Screen {
|
||||
DisplayManager.INSTANCE.renderer.glFillRect(16 * 8, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16);
|
||||
|
||||
// EASTER EGG
|
||||
if (fu32font != null) {
|
||||
DisplayManager.INSTANCE.renderer.glColor3f(1,1,1);
|
||||
DisplayManager.INSTANCE.renderer.glFillColor(DisplayManager.INSTANCE.engine.getWidth()-256, DisplayManager.INSTANCE.engine.getHeight() / 2 - 128, 256, 256);
|
||||
fu32font.use(DisplayManager.INSTANCE.engine);
|
||||
DisplayManager.INSTANCE.renderer.glColor3f(0, 0, 0);
|
||||
DisplayManager.INSTANCE.renderer.glDrawStringRight(DisplayManager.INSTANCE.engine.getWidth(), DisplayManager.INSTANCE.engine.getHeight() / 2 - 128, easterFu32[easterFu32Num]);
|
||||
}
|
||||
if (easterskin != null) {
|
||||
easterskin.use(DisplayManager.INSTANCE.engine);
|
||||
DisplayManager.INSTANCE.renderer.glColor4f(1, 1, 1, 0.7f);
|
||||
DisplayManager.INSTANCE.renderer.glFillRect(0, StaticVars.screenSize[1] - 128, 224, 128, easterNum * 224, 0, 224, 128);
|
||||
}
|
||||
if (easterfont != null) {
|
||||
easterfont.use(DisplayManager.INSTANCE.engine);
|
||||
DisplayManager.INSTANCE.renderer.glColor(0xFF000000);
|
||||
@ -176,11 +210,6 @@ public class MarioScreen extends Screen {
|
||||
DisplayManager.INSTANCE.renderer.glColor(0xFFffede7);
|
||||
DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - easterfont.getCharacterHeight(), "G");
|
||||
}
|
||||
if (easterskin != null) {
|
||||
easterskin.use(DisplayManager.INSTANCE.engine);
|
||||
DisplayManager.INSTANCE.renderer.glFillRect(0, StaticVars.screenSize[1] - 128, 224, 128, easterNum * 224, 0, 224, 128);
|
||||
easterNum = (easterNum < easterMax) ? easterNum + 1 : 0;
|
||||
}
|
||||
|
||||
//DRAW MARIO
|
||||
skin.use(DisplayManager.INSTANCE.engine);
|
||||
|
@ -1,9 +1,11 @@
|
||||
package org.warp.picalculator.math.functions;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.gui.expression.blocks.Block;
|
||||
import org.warp.picalculator.gui.expression.blocks.BlockContainer;
|
||||
import org.warp.picalculator.gui.expression.blocks.BlockDivision;
|
||||
@ -57,8 +59,8 @@ public class Division extends FunctionOperator {
|
||||
if (((Number) variable1).isInteger() && ((Number) variable2).isInteger()) {
|
||||
LinkedList<BigInteger> factors1 = ((Number) variable1).getFactors();
|
||||
LinkedList<BigInteger> factors2 = ((Number) variable2).getFactors();
|
||||
factors1.retainAll(factors2);
|
||||
return factors1.size() > 0 /* true if there is at least one common factor */;
|
||||
LinkedList<BigInteger> mcm = Utils.mcm(factors1, factors2);
|
||||
return mcm.size() > 0 /* true if there is at least one common factor */;
|
||||
} else if (((Number) variable1).divide((Number) variable2).isInteger()) {
|
||||
return true;
|
||||
} else {
|
||||
@ -97,10 +99,10 @@ public class Division extends FunctionOperator {
|
||||
if (getMathContext().exactMode && (((Number) variable1).isInteger() && ((Number) variable2).isInteger())) {
|
||||
LinkedList<BigInteger> factors1 = ((Number) variable1).getFactors();
|
||||
LinkedList<BigInteger> factors2 = ((Number) variable2).getFactors();
|
||||
factors1.retainAll(factors2);
|
||||
LinkedList<BigInteger> mcm = Utils.mcm(factors1, factors2);
|
||||
BigInteger nmb1 = ((Number) this.getParameter1()).term.toBigIntegerExact();
|
||||
BigInteger nmb2 = ((Number) this.getParameter2()).term.toBigIntegerExact();
|
||||
for (BigInteger i : factors1) {
|
||||
for (BigInteger i : mcm) {
|
||||
nmb1 = nmb1.divide(i);
|
||||
nmb2 = nmb2.divide(i);
|
||||
}
|
||||
|
@ -2,11 +2,14 @@ package org.warp.picalculator.math.functions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.nevec.rjm.BigDecimalMath;
|
||||
import org.warp.picalculator.Error;
|
||||
import org.warp.picalculator.gui.expression.blocks.Block;
|
||||
import org.warp.picalculator.gui.expression.blocks.BlockChar;
|
||||
import org.warp.picalculator.math.Function;
|
||||
import org.warp.picalculator.math.MathContext;
|
||||
import org.warp.picalculator.Utils;
|
||||
import org.warp.picalculator.math.MathematicalSymbols;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
@ -59,13 +62,24 @@ public class Variable implements Function {
|
||||
|
||||
@Override
|
||||
public boolean isSimplified() {
|
||||
if (root.exactMode == false) {
|
||||
if (var == MathematicalSymbols.PI) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Function> simplify() throws Error {
|
||||
final List<Function> result = new ObjectArrayList<>();
|
||||
result.add(this);
|
||||
if (root.exactMode == false) {
|
||||
if (var == MathematicalSymbols.PI) {
|
||||
result.add(new Number(root, BigDecimalMath.pi(new java.math.MathContext(Utils.scale, Utils.scaleMode2))));
|
||||
}
|
||||
} else {
|
||||
result.add(this);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user