From 424b76a8a620061a824da4af7d1abb014782a55c Mon Sep 17 00:00:00 2001 From: XDrake99 Date: Mon, 6 Feb 2017 21:38:17 +0100 Subject: [PATCH] Differenciated the three variable types (known, unknown, solution) --- libs/lwjgl/LICENSE | 29 ++ libs/lwjgl/build.txt | 1 + libs/lwjgl/dyncall_license.txt | 14 + libs/lwjgl/glfw_license.txt | 21 + libs/lwjgl/jemalloc_license.txt | 23 + libs/lwjgl/khronos_license.txt | 22 + src/org/warp/picalculator/TestDrivers.java | 30 ++ .../warp/picalculator/device/Keyboard.java | 28 +- .../warp/picalculator/device/PIDisplay.java | 452 ++++++++++++++++++ .../device/graphicengine/Display.java | 296 ++++++++++++ .../device/graphicengine/RAWFont.java | 181 +++++++ .../warp/picalculator/gui/DisplayManager.java | 145 +++--- .../gui/graphicengine/GraphicEngine.java | 2 + .../gui/graphicengine/cpu/CPUEngine.java | 7 +- .../gui/graphicengine/cpu/SwingWindow.java | 2 +- .../gui/graphicengine/gpu/GPUEngine.java | 10 +- .../gui/graphicengine/gpu/NEWTWindow.java | 4 +- .../gui/screens/MathInputScreen.java | 121 ++--- .../warp/picalculator/math/Calculator.java | 2 +- .../math/functions/Expression.java | 2 +- .../picalculator/math/functions/Variable.java | 49 +- 21 files changed, 1285 insertions(+), 156 deletions(-) create mode 100644 libs/lwjgl/LICENSE create mode 100644 libs/lwjgl/build.txt create mode 100644 libs/lwjgl/dyncall_license.txt create mode 100644 libs/lwjgl/glfw_license.txt create mode 100644 libs/lwjgl/jemalloc_license.txt create mode 100644 libs/lwjgl/khronos_license.txt create mode 100644 src/org/warp/picalculator/TestDrivers.java create mode 100644 src/org/warp/picalculator/device/PIDisplay.java create mode 100644 src/org/warp/picalculator/device/graphicengine/Display.java create mode 100644 src/org/warp/picalculator/device/graphicengine/RAWFont.java diff --git a/libs/lwjgl/LICENSE b/libs/lwjgl/LICENSE new file mode 100644 index 00000000..a983c18a --- /dev/null +++ b/libs/lwjgl/LICENSE @@ -0,0 +1,29 @@ +Copyright (c) 2012-present Lightweight Java Game Library +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +- Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +- Neither the name Lightweight Java Game Library nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/libs/lwjgl/build.txt b/libs/lwjgl/build.txt new file mode 100644 index 00000000..e454bfa6 --- /dev/null +++ b/libs/lwjgl/build.txt @@ -0,0 +1 @@ +LWJGL 3.1.1 build 16 \ No newline at end of file diff --git a/libs/lwjgl/dyncall_license.txt b/libs/lwjgl/dyncall_license.txt new file mode 100644 index 00000000..f119bb7c --- /dev/null +++ b/libs/lwjgl/dyncall_license.txt @@ -0,0 +1,14 @@ +Copyright (c) 2007-2015 Daniel Adler , + Tassilo Philipp + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/libs/lwjgl/glfw_license.txt b/libs/lwjgl/glfw_license.txt new file mode 100644 index 00000000..e7c49d62 --- /dev/null +++ b/libs/lwjgl/glfw_license.txt @@ -0,0 +1,21 @@ +Copyright (c) 2002-2006 Marcus Geelnard +Copyright (c) 2006-2010 Camilla Berglund + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would + be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. diff --git a/libs/lwjgl/jemalloc_license.txt b/libs/lwjgl/jemalloc_license.txt new file mode 100644 index 00000000..c95c2baa --- /dev/null +++ b/libs/lwjgl/jemalloc_license.txt @@ -0,0 +1,23 @@ +Copyright (C) 2002-2014 Jason Evans . +All rights reserved. +Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved. +Copyright (C) 2009-2014 Facebook, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright notice(s), + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice(s), + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/libs/lwjgl/khronos_license.txt b/libs/lwjgl/khronos_license.txt new file mode 100644 index 00000000..96c8f0cd --- /dev/null +++ b/libs/lwjgl/khronos_license.txt @@ -0,0 +1,22 @@ +/* +** Copyright (c) 2013-2014 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ \ No newline at end of file diff --git a/src/org/warp/picalculator/TestDrivers.java b/src/org/warp/picalculator/TestDrivers.java new file mode 100644 index 00000000..c8b6adf7 --- /dev/null +++ b/src/org/warp/picalculator/TestDrivers.java @@ -0,0 +1,30 @@ +package org.warp.picalculator; + +public class TestDrivers { + public static void main(String[] args) { + System.out.println("Test started."); + String className; + className = "jogamp.newt.driver.bcm.vc.iv.DisplayDriver"; + if (exists(className)) { + System.out.println("[FOUND] "+className); + } else { + System.out.println("[NOT FOUND] "+className); + } + className = ".bcm.vc.iv.DisplayDriver"; + if (exists(className)) { + System.out.println("[FOUND] "+className); + } else { + System.out.println("[NOT FOUND] "+className); + } + System.out.println("Test finished."); + } + + public static boolean exists(String className) { + try { + Class.forName(className); + return true; + } catch( ClassNotFoundException e ) { + return false; + } + } +} diff --git a/src/org/warp/picalculator/device/Keyboard.java b/src/org/warp/picalculator/device/Keyboard.java index 8675f340..652d66b1 100644 --- a/src/org/warp/picalculator/device/Keyboard.java +++ b/src/org/warp/picalculator/device/Keyboard.java @@ -29,6 +29,8 @@ public class Keyboard { private static volatile boolean[][] precedentStates = new boolean[8][8]; public static volatile boolean[][] debugKeysDown = new boolean[8][8]; public static volatile int debugKeyCode = -1; + + private static volatile boolean refreshRequest = false; public static void startKeyboard() { final Thread kt = new Thread(() -> { @@ -178,9 +180,9 @@ public class Keyboard { case com.jogamp.newt.event.KeyEvent.VK_ENTER: case KeyEvent.VK_ENTER: if (Keyboard.shift) { - Keyboard.keyPressed(Key.SIMPLIFY); + Keyboard.keyPressed(Key.STEP); } else if (!Keyboard.shift && !Keyboard.alpha) { - Keyboard.keyPressed(Key.SOLVE); + Keyboard.keyPressed(Key.SIMPLIFY); } else { Keyboard.keyPressed(Key.NONE); } @@ -421,11 +423,11 @@ public class Keyboard { } } else if (row == 1 && col == 8) { if (shift) { - keyPressed(Key.SIMPLIFY); + keyPressed(Key.STEP); } else if (alpha) { keyPressed(Key.NONE); } else { - keyPressed(Key.SOLVE); + keyPressed(Key.SIMPLIFY); } } else if (row == 2 && col == 8) { if (shift) { @@ -752,7 +754,7 @@ public class Keyboard { } } if (refresh) { -// PIDisplay.display.repaint(); + refreshRequest = true; } } } @@ -782,7 +784,15 @@ public class Keyboard { } public static enum Key { - POWER, debug_DEG, debug_RAD, debug_GRA, SHIFT, ALPHA, NONE, HISTORY_BACK, HISTORY_FORWARD, SURD_MODE, DRG_CYCLE, LETTER_X, LETTER_Y, SIMPLIFY, SOLVE, BRIGHTNESS_CYCLE, BRIGHTNESS_CYCLE_REVERSE, DOT, NUM0, NUM1, NUM2, NUM3, NUM4, NUM5, NUM6, NUM7, NUM8, NUM9, PARENTHESIS_OPEN, PARENTHESIS_CLOSE, PLUS, MINUS, PLUS_MINUS, MULTIPLY, DIVIDE, EQUAL, DELETE, RESET, LEFT, RIGHT, UP, DOWN, OK, debug1, debug2, debug3, debug4, debug5, SQRT, ROOT, POWER_OF_2, POWER_OF_x, SINE, COSINE, TANGENT, ARCSINE, ARCCOSINE, ARCTANGENT, PI + POWER, debug_DEG, debug_RAD, debug_GRA, SHIFT, ALPHA, NONE, HISTORY_BACK, HISTORY_FORWARD, SURD_MODE, DRG_CYCLE, LETTER_X, LETTER_Y, STEP, SIMPLIFY, BRIGHTNESS_CYCLE, BRIGHTNESS_CYCLE_REVERSE, DOT, NUM0, NUM1, NUM2, NUM3, NUM4, NUM5, NUM6, NUM7, NUM8, NUM9, PARENTHESIS_OPEN, PARENTHESIS_CLOSE, PLUS, MINUS, PLUS_MINUS, MULTIPLY, DIVIDE, EQUAL, DELETE, RESET, LEFT, RIGHT, UP, DOWN, OK, debug1, debug2, debug3, debug4, debug5, SQRT, ROOT, POWER_OF_2, POWER_OF_x, SINE, COSINE, TANGENT, ARCSINE, ARCCOSINE, ARCTANGENT, PI + } + + public static boolean popRefreshRequest() { + if (refreshRequest) { + refreshRequest = false; + return true; + } + return false; } } @@ -829,9 +839,9 @@ public class Keyboard { | | | | | | | | | | | | |5,8---|4,8---|3,8---|2,8---|1,8-----------------| -| 0 | . | | | SOLVE | -| | | |PI | SIMPLIFY | -| X | Y | Z |DRGCYCL| | +| 0 | . | | | SIMPLIFY | +| | | |PI | STEP | +| X | Y | Z |DRGCYCL|SOLVE FOR [x] | |------|------|------|------|--------------------| diff --git a/src/org/warp/picalculator/device/PIDisplay.java b/src/org/warp/picalculator/device/PIDisplay.java new file mode 100644 index 00000000..dd2068cb --- /dev/null +++ b/src/org/warp/picalculator/device/PIDisplay.java @@ -0,0 +1,452 @@ +package org.warp.picalculator.device; + +import static org.warp.picalculator.device.graphicengine.Display.Render.getMatrixOfImage; +import static org.warp.picalculator.device.graphicengine.Display.Render.glClear; +import static org.warp.picalculator.device.graphicengine.Display.Render.glColor; +import static org.warp.picalculator.device.graphicengine.Display.Render.glColor3i; +import static org.warp.picalculator.device.graphicengine.Display.Render.glColor4i; +import static org.warp.picalculator.device.graphicengine.Display.Render.glDrawLine; +import static org.warp.picalculator.device.graphicengine.Display.Render.glDrawSkin; +import static org.warp.picalculator.device.graphicengine.Display.Render.glDrawStringCenter; +import static org.warp.picalculator.device.graphicengine.Display.Render.glDrawStringLeft; +import static org.warp.picalculator.device.graphicengine.Display.Render.glDrawStringRight; +import static org.warp.picalculator.device.graphicengine.Display.Render.glFillRect; +import static org.warp.picalculator.device.graphicengine.Display.Render.glSetFont; + +import java.awt.image.BufferedImage; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import org.warp.picalculator.Main; +import org.warp.picalculator.Utils; +import org.warp.picalculator.device.graphicengine.Display; +import org.warp.picalculator.device.graphicengine.RAWFont; +import org.warp.picalculator.device.graphicengine.Screen; +import com.pi4j.wiringpi.Gpio; + +/** + * STB Truetype oversampling demo. + * + *

+ * This is a Java port of https:/ + * /github + * .com/nothings/stb/blob/master/tests/oversample/main.c. + *

+ */ +public final class PIDisplay { + public static PIDisplay INSTANCE; + private static float brightness; + + private static int[] skin; + private static int[] skinSize; + public static RAWFont[] fonts; + + public static String error = null; + public String[] errorStackTrace = null; + public final static int[] glyphsHeight = new int[] { 9, 6, 12, 9 }; + + public static Screen screen; + public static String displayDebugString = ""; + + public PIDisplay(Screen screen) { + setScreen(screen); + INSTANCE = this; + loop(); + } + /* + * private void load_skin() { + * try { + * skin_tex = glGenTextures(); + * glBindTexture(GL_TEXTURE_2D, skin_tex); + * glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + * + * InputStream in = new FileInputStream("skin.png"); + * PNGDecoder decoder = new PNGDecoder(in); + * + * System.out.println("width="+decoder.getWidth()); + * System.out.println("height="+decoder.getHeight()); + * + * ByteBuffer buf = + * ByteBuffer.allocateDirect(4*decoder.getWidth()*decoder.getHeight()); + * decoder.decode(buf, decoder.getWidth()*4, Format.RGBA); + * buf.flip(); + * + * skin = buf; + * skin_w = decoder.getWidth(); + * skin_h = decoder.getHeight(); + * glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, skin_w, + * skin_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, skin); + * } catch (IOException ex) { + * ex.printStackTrace(); + * } + * } + */ + + public void setScreen(Screen screen) { + if (screen.initialized == false) { + if (screen.canBeInHistory) { + PIDisplay.currentSession = 0; + for (int i = PIDisplay.sessions.length - 1; i >= 1; i--) { + PIDisplay.sessions[i] = PIDisplay.sessions[i - 1]; + } + PIDisplay.sessions[0] = screen; + } else { + PIDisplay.currentSession = -1; + } + } + screen.d = this; + try { + screen.create(); + PIDisplay.screen = screen; + if (screen.initialized == false) { + screen.initialize(); + } + } catch (Exception e) { + e.printStackTrace(); + System.exit(0); + } + } + + public void replaceScreen(Screen screen) { + if (screen.initialized == false) { + if (screen.canBeInHistory) { + PIDisplay.sessions[PIDisplay.currentSession] = screen; + } else { + PIDisplay.currentSession = -1; + for (int i = 0; i < PIDisplay.sessions.length - 2; i++) { + PIDisplay.sessions[i] = PIDisplay.sessions[i + 1]; + } + } + } + screen.d = this; + try { + screen.create(); + PIDisplay.screen = screen; + if (screen.initialized == false) { + screen.initialize(); + } + } catch (Exception e) { + e.printStackTrace(); + System.exit(0); + } + } + + public boolean canGoBack() { + if (PIDisplay.currentSession == -1) { + return PIDisplay.sessions[0] != null; + } + if (PIDisplay.screen != PIDisplay.sessions[PIDisplay.currentSession]) { + + } else if (PIDisplay.currentSession + 1 < PIDisplay.sessions.length) { + if (PIDisplay.sessions[PIDisplay.currentSession + 1] != null) { + + } else { + return false; + } + } else { + return false; + } + if (PIDisplay.sessions[PIDisplay.currentSession] != null) { + return true; + } + return false; + } + + public void goBack() { + if (canGoBack()) { + if (PIDisplay.currentSession >= 0 && PIDisplay.screen != PIDisplay.sessions[PIDisplay.currentSession]) { + } else { + PIDisplay.currentSession += 1; + } + PIDisplay.screen = PIDisplay.sessions[PIDisplay.currentSession]; + } + } + + public boolean canGoForward() { + if (PIDisplay.currentSession <= 0) { // -1 e 0 + return false; + } + if (PIDisplay.screen != PIDisplay.sessions[PIDisplay.currentSession]) { + + } else if (PIDisplay.currentSession > 0) { + if (PIDisplay.sessions[PIDisplay.currentSession - 1] != null) { + + } else { + return false; + } + } else { + return false; + } + if (PIDisplay.sessions[PIDisplay.currentSession] != null) { + return true; + } + return false; + } + + public void goForward() { + if (canGoForward()) { + if (PIDisplay.screen != PIDisplay.sessions[PIDisplay.currentSession]) { + + } else { + PIDisplay.currentSession -= 1; + } + PIDisplay.screen = PIDisplay.sessions[PIDisplay.currentSession]; + } + } + + public Screen getScreen() { + return PIDisplay.screen; + } + + private void load_skin() throws IOException { + BufferedImage img = ImageIO.read(Main.instance.getClass().getResource("/skin.png")); + skin = getMatrixOfImage(img); + skinSize = new int[] { img.getWidth(), img.getHeight() }; + } + + private void load_fonts() { + fonts = new RAWFont[7]; + fonts[0] = new RAWFont(); + fonts[0].create("big"); + fonts[1] = new RAWFont(); + fonts[1].create("small"); + fonts[2] = new RAWFont(); + fonts[2].create("ex"); + fonts[3] = new RAWFont(); + fonts[3].create("big"); + fonts[4] = new RAWFont(); + fonts[4].create("32"); + fonts[5] = new RAWFont(); + fonts[5].create("square"); + glSetFont(fonts[0]); + } + + private void draw_init() { + glClear(); + } + + public static void drawSkinPart(int x, int y, int sx1, int sy1, int sx2, int sy2) { + glDrawSkin(skinSize[0], skin, x, y, sx1, sy1, sx2, sy2, false); + } + + private void draw_status() { + glColor(0xFFc5c2af); + glFillRect(0, 0, Main.screenSize[0], 20); + glColor3i(0, 0, 0); + glDrawLine(0, 20, Main.screenSize[0]-1, 20); + glColor3i(0, 0, 0); + if (Keyboard.shift) { + drawSkinPart(2 + 18 * 0, 2, 16 * 2, 16 * 0, 16 + 16 * 2, 16 + 16 * 0); + } else { + drawSkinPart(2 + 18 * 0, 2, 16 * 3, 16 * 0, 16 + 16 * 3, 16 + 16 * 0); + } + if (Keyboard.alpha) { + drawSkinPart(2 + 18 * 1, 2, 16 * 0, 16 * 0, 16 + 16 * 0, 16 + 16 * 0); + } else { + drawSkinPart(2 + 18 * 1, 2, 16 * 1, 16 * 0, 16 + 16 * 1, 16 + 16 * 0); + } + /* + if (Calculator.angleMode == AngleMode.DEG) { + drawSkinPart(8 + 18 * 2, 2, 16 * 4, 16 * 0, 16 + 16 * 4, 16 + 16 * 0); + drawSkinPart(8 + 18 * 3, 2, 16 * 7, 16 * 0, 16 + 16 * 7, 16 + 16 * 0); + drawSkinPart(8 + 18 * 4, 2, 16 * 9, 16 * 0, 16 + 16 * 9, 16 + 16 * 0); + } else if (Calculator.angleMode == AngleMode.RAD) { + drawSkinPart(8 + 18 * 2, 2, 16 * 5, 16 * 0, 16 + 16 * 5, 16 + 16 * 0); + drawSkinPart(8 + 18 * 3, 2, 16 * 6, 16 * 0, 16 + 16 * 6, 16 + 16 * 0); + drawSkinPart(8 + 18 * 4, 2, 16 * 9, 16 * 0, 16 + 16 * 9, 16 + 16 * 0); + } else if (Calculator.angleMode == AngleMode.GRA) { + drawSkinPart(8 + 18 * 2, 2, 16 * 5, 16 * 0, 16 + 16 * 5, 16 + 16 * 0); + drawSkinPart(8 + 18 * 3, 2, 16 * 7, 16 * 0, 16 + 16 * 7, 16 + 16 * 0); + drawSkinPart(8 + 18 * 4, 2, 16 * 8, 16 * 0, 16 + 16 * 8, 16 + 16 * 0); + } else { + drawSkinPart(8 + 18 * 2, 2, 16 * 5, 16 * 0, 16 + 16 * 5, 16 + 16 * 0); + drawSkinPart(8 + 18 * 3, 2, 16 * 7, 16 * 0, 16 + 16 * 7, 16 + 16 * 0); + drawSkinPart(8 + 18 * 4, 2, 16 * 9, 16 * 0, 16 + 16 * 9, 16 + 16 * 0); + }*/ + + int padding = 2; + + int brightness = (int) (Math.ceil(PIDisplay.brightness * 4)); + if (brightness <= 1) { + drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 10, 16 * 0, 16 + 16 * 10, 16 + 16 * 0); + } else if (brightness == 2) { + drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 11, 16 * 0, 16 + 16 * 11, 16 + 16 * 0); + } else if (brightness == 3) { + drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 12, 16 * 0, 16 + 16 * 12, 16 + 16 * 0); + } else if (brightness >= 4) { + drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 13, 16 * 0, 16 + 16 * 13, 16 + 16 * 0); + } else { + Utils.debug.println("Brightness error"); + } + + padding += 18 + 6; + + boolean canGoBack = canGoBack(); + boolean canGoForward = canGoForward(); + + if (Main.haxMode) { + drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 18, 16 * 0, 16 + 16 * 18, 16 + 16 * 0); + padding += 18 + 6; + } + + if (canGoBack && canGoForward) { + drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 14, 16 * 0, 16 + 16 * 14, 16 + 16 * 0); + } else if (canGoBack) { + drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 15, 16 * 0, 16 + 16 * 15, 16 + 16 * 0); + } else if (canGoForward) { + drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 16, 16 * 0, 16 + 16 * 16, 16 + 16 * 0); + } else { + drawSkinPart(Main.screenSize[0] - (padding + 16), 2, 16 * 17, 16 * 0, 16 + 16 * 17, 16 + 16 * 0); + } + + padding += 18; + + } + + private void draw_screen() { + screen.render(); + } + + private void draw_bottom() { + glDrawStringLeft(2, 90, displayDebugString); + } + + private void draw_world() { + glColor3i(255, 255, 255); + + if (error != null) { + glSetFont(Utils.getFont(false, false)); + glColor3i(129, 28, 22); + glDrawStringRight(Main.screenSize[0] - 2, Main.screenSize[1]- PIDisplay.glyphsHeight[1] - 2, "ANDREA CAVALLI'S CALCULATOR"); + glColor3i(149, 32, 26); + glDrawStringCenter((Main.screenSize[0] / 2), 22, error); + glColor3i(164, 34, 28); + int i = 22; + for (String stackPart : errorStackTrace) { + glDrawStringLeft(2, 22 + i, stackPart); + i += 11; + } + glSetFont(fonts[0]); + glColor3i(129, 28, 22); + glDrawStringCenter((Main.screenSize[0] / 2), 11, "UNEXPECTED EXCEPTION"); + } else { + draw_screen(); + draw_status(); + draw_bottom(); + } + } + + private void draw() { + draw_init(); + draw_world(); + } + + private long precTime = -1; + + public void refresh() { + float dt = 0; + long newtime = System.nanoTime(); + if (precTime == -1) { + dt = 0; + } else { + dt = (float) ((newtime - precTime) / 1000000000d); + } + precTime = newtime; + /* + * Calcoli + */ + checkDisplayResized(); + + screen.beforeRender(dt); + + if(dt >= 0.03 || screen.mustBeRefreshed()) { + draw(); + } + + } + + private void checkDisplayResized() { + if (Display.wasResized()) { + Main.screenSize[0] = Display.getWidth(); + Main.screenSize[1]= Display.getHeight(); + } + }; + + public void loop() { + try { + load_skin(); + load_fonts(); + Display.create(); + + try { + screen.initialize(); + } catch (Exception e) { + e.printStackTrace(); + System.exit(0); + } + + Display.start(); + + Main.instance.afterStart(); + + double extratime = 0; + while (Display.initialized) { + long start = System.currentTimeMillis(); + Display.repaint(); + long end = System.currentTimeMillis(); + double delta = (end - start) / 1000d; + int deltaInt = (int) Math.floor(delta); + int extraTimeInt = (int) Math.floor(extratime); + if (extraTimeInt + deltaInt < 50) { + Thread.sleep(50 - (extraTimeInt + deltaInt)); + extratime = 0; + } else { + extratime += delta - 50d; + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + } + } + + public static void changeBrightness(float change) { + setBrightness(brightness + change); + } + + public static void setBrightness(float newval) { + if (newval >= 0.1 && newval <= 1) { + brightness = newval; + if (Utils.debugOn == false) { + Gpio.pwmWrite(12, (int) Math.ceil(brightness*1024)); +// SoftPwm.softPwmWrite(12, (int)(Math.ceil(brightness*10))); + } + } + } + + public static void cycleBrightness(boolean reverse) { + final float step = reverse?-0.1f:0.1f; + if (brightness + step > 1f) { + setBrightness(0.1f); + } else if (brightness + step < 0.1f) { + setBrightness(1.0f); + } else { + changeBrightness(step); + } + } + + public static float getBrightness() { + return brightness; + } + + public float[] colore = new float[] { 0.0f, 0.0f, 0.0f, 1.0f }; + public static int currentSession = 0; + public static Screen[] sessions = new Screen[5]; + + public static void colore(float f1, float f2, float f3, float f4) { + PIDisplay.INSTANCE.colore = new float[] { f1, f2, f3, f4 }; + glColor4i((int) (f1 * 255), (int) (f2 * 255), (int) (f3 * 255), (int) (f4 * 255)); + } +} \ No newline at end of file diff --git a/src/org/warp/picalculator/device/graphicengine/Display.java b/src/org/warp/picalculator/device/graphicengine/Display.java new file mode 100644 index 00000000..59a943d4 --- /dev/null +++ b/src/org/warp/picalculator/device/graphicengine/Display.java @@ -0,0 +1,296 @@ +package org.warp.picalculator.device.graphicengine; + +import java.awt.FontMetrics; +import java.awt.image.BufferedImage; + +import org.warp.picalculator.Main; +import org.warp.picalculator.Utils; +import org.warp.picalculator.device.PIDisplay; + +public class Display { + + private static SwingWindow INSTANCE = new SwingWindow(); + public static int[] size = new int[] { 1, 1 }; + public static BufferedImage g = new BufferedImage(size[0], size[1], BufferedImage.TYPE_INT_RGB); + static int[] canvas2d = new int[1]; + public static int color = 0xFF000000; + public static boolean initialized = false; + + public static void setTitle(String title) { + INSTANCE.setTitle(title); + } + + public static void setResizable(boolean r) { + INSTANCE.setResizable(r); + if (!r) + INSTANCE.setUndecorated(true); + } + + public static void setDisplayMode(final int ww, final int wh) { + INSTANCE.setSize(ww, wh); + size = new int[] { ww, wh }; + canvas2d = new int[ww * wh]; + g = new BufferedImage(ww, wh, BufferedImage.TYPE_INT_ARGB); + INSTANCE.wasResized = false; + } + + public static void create() { + Display.setResizable(Utils.debugOn&!Utils.debugThirdScreen); + Display.setDisplayMode(Main.screenSize[0], Main.screenSize[1]); + INSTANCE.setVisible(true); + initialized = true; + } + + public static boolean wasResized() { + if (INSTANCE.wasResized) { + size = new int[] { INSTANCE.getWidth(), INSTANCE.getHeight() }; + canvas2d = new int[size[0] * size[1]]; + g = new BufferedImage(size[0], size[1], BufferedImage.TYPE_INT_ARGB); + INSTANCE.wasResized = false; + return true; + } + return false; + } + + public static int getWidth() { + return INSTANCE.getWidth()-Main.screenPos[0]; + } + + public static int getHeight() { + return INSTANCE.getHeight()-Main.screenPos[1]; + } + + public static void destroy() { + initialized = false; + INSTANCE.setVisible(false); + INSTANCE.dispose(); + } + + public static void start() { + } + + @Deprecated() + public static void refresh() { + if (PIDisplay.screen == null || (PIDisplay.error != null && PIDisplay.error.length() > 0) || PIDisplay.screen == null || PIDisplay.screen.mustBeRefreshed()) { + Display.INSTANCE.c.repaint(); + } + } + + public static void repaint() { + Display.INSTANCE.c.repaint(); + } + + public static abstract class Startable { + public Startable() { + this.force = false; + } + + public Startable(boolean force) { + this.force = force; + } + + public boolean force = false; + + public abstract void run(); + } + + public static class Render { + public static int clearcolor = 0xFFc5c2af; + public static RAWFont currentFont; + + public static void glColor3i(int r, int gg, int b) { + glColor4i(r, gg, b, 255); + } + + public static void glColor(int c) { + color = c & 0xFFFFFFFF; + } + + public static void glClearColor(int c) { + clearcolor = c & 0xFFFFFFFF; + } + + public static void glColor4i(int red, int green, int blue, int alpha) { + color = (alpha << 24) + (red << 16) + (green << 8) + (blue); + } + + public static void glClearColor(int red, int green, int blue, int alpha) { + clearcolor = (alpha << 24) + (red << 16) + (green << 8) + (blue); + } + + public static void glClear() { + for (int x = 0; x < size[0]; x++) { + for (int y = 0; y < size[1]; y++) { + canvas2d[x + y * size[0]] = clearcolor; + } + } + } + + public static void glDrawSkin(int skinwidth, int[] skin, int x0, int y0, int s0, int t0, int s1, int t1, boolean transparent) { + x0+=Main.screenPos[0]; + y0+=Main.screenPos[1]; + int oldColor; + int newColor; + int onex = s0 <= s1?1:-1; + int oney = t0 <= t1?1:-1; + int width = 0; + int height = 0; + if (onex == -1) { + int s00 = s0; + s0 = s1; + s1 = s00; + width = s1-s0; + } + if (oney == -1) { + int t00 = t0; + t0 = t1; + t1 = t00; + height = t1-t0; + } + if (x0 >= size[0] || y0 >= size[0]) { + return; + } + if (x0 + width >= size[0]) { + s1 = size[0] - x0 + s0; + } + if (y0 + height >= size[1]) { + t1 = size[1] - y0 + t0; + } + if (x0 < 0) { + if (onex == -1) { + width += x0; + s1 += x0 + 1; + } else { + s0 -= x0; + } + x0 = 0; + } + if (y0 < 0) { + if (oney == -1) { + height += y0; + t1 += y0 + 1; + } else { + t0 -= y0; + } + y0 = 0; + } + for (int texx = 0; texx < s1 - s0; texx++) { + for (int texy = 0; texy < t1 - t0; texy++) { + newColor = skin[(s0 + texx) + (t0 + texy) * skinwidth]; + if (transparent) { + oldColor = canvas2d[(x0 + texx*onex + width) + (y0 + texy*oney + height) * size[0]]; + float a2 = (newColor >> 24 & 0xFF) / 255f; + float a1 = 1f-a2; + int r = (int) ((oldColor >> 16 & 0xFF) * a1 + (newColor >> 16 & 0xFF) * a2); + int g = (int) ((oldColor >> 8 & 0xFF) * a1 + (newColor >> 8 & 0xFF) * a2); + int b = (int) ((oldColor & 0xFF) * a1 + (newColor & 0xFF) * a2); + newColor = 0xFF000000 | r << 16 | g << 8 | b; + } + canvas2d[(x0 + texx*onex + width) + (y0 + texy*oney + height) * size[0]] = newColor; + } + } + } + + public static void glDrawLine(int x0, int y0, int x1, int y1) { + x0+=Main.screenPos[0]; + x1+=Main.screenPos[0]; + y0+=Main.screenPos[1]; + y1+=Main.screenPos[1]; + if (x0 >= size[0] || y0 >= size[0]) { + return; + } + if (y0 == y1) { + for (int x = 0; x <= x1 - x0; x++) { + canvas2d[x0 + x + y0 * size[0]] = color; + } + } else if (x0 == x1) { + for (int y = 0; y <= y1 - y0; y++) { + canvas2d[x0 + (y0 + y) * size[0]] = color; + } + } else { + int m = (y1 - y0) / (x1 - x0); + for (int texx = 0; texx <= x1 - x0; texx++) { + if (x0 + texx < size[0] && y0 + (m * texx) < size[1]) { + canvas2d[(x0 + texx) + (y0 + (m * texx)) * size[0]] = color; + } + } + } + } + + public static void glFillRect(int x0, int y0, int w1, int h1) { + x0+=Main.screenPos[0]; + y0+=Main.screenPos[1]; + int x1 = x0+w1; + int y1 = y0+h1; + if (x0 >= size[0] || y0 >= size[0]) { + return; + } + if (x1 >= size[0]) { + x1 = size[0]; + } + if (y1 >= size[1]) { + y1 = size[1]; + } + final int sizeW = size[0]; + for (int x = x0; x < x1; x++) { + for (int y = y0; y < y1; y++) { + canvas2d[(x) + (y) * sizeW] = color; + } + } + } + + public static int[] getMatrixOfImage(BufferedImage bufferedImage) { + int width = bufferedImage.getWidth(null); + int height = bufferedImage.getHeight(null); + int[] pixels = new int[width * height]; + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + pixels[i + j * width] = bufferedImage.getRGB(i, j); + } + } + + return pixels; + } + + public static void glDrawStringLeft(int x, int y, String text) { + x+=Main.screenPos[0]; + y+=Main.screenPos[1]; + final int[] chars = currentFont.getCharIndexes(text); + currentFont.drawText(canvas2d, size, x, y, chars, color); + } + + public static void glDrawStringCenter(int x, int y, String text) { + glDrawStringLeft(x - (glGetStringWidth(Display.Render.currentFont, text) / 2), y, text); + } + + public static void glDrawStringRight(int x, int y, String text) { + glDrawStringLeft(x - glGetStringWidth(Display.Render.currentFont, text), y, text); + } + + public static void glSetFont(RAWFont font) { + if (currentFont != font) { + currentFont = font; + } + } + + public static int glGetStringWidth(RAWFont rf, String text) { + int w =(rf.charW+1)*text.length(); + if (text.length() > 0) { + return w-1; + } else { + return 0; + } + // return text.length()*6; + } + + public static int glGetFontWidth(FontMetrics fm, String text) { + return fm.stringWidth(text); + } + + @Deprecated + public static int glGetCurrentFontHeight() { + return currentFont.charH; + } + + } +} diff --git a/src/org/warp/picalculator/device/graphicengine/RAWFont.java b/src/org/warp/picalculator/device/graphicengine/RAWFont.java new file mode 100644 index 00000000..3e1b988f --- /dev/null +++ b/src/org/warp/picalculator/device/graphicengine/RAWFont.java @@ -0,0 +1,181 @@ +package org.warp.picalculator.device.graphicengine; + +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; +import java.io.File; +import java.io.IOException; +import java.lang.ref.WeakReference; +import java.net.URL; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.imageio.ImageIO; + +import org.warp.picalculator.Main; +import org.warp.picalculator.Utils; + +/** + * + * @author andreacv + */ +public class RAWFont { + + public boolean[][] rawchars; + public int[] chars32; + public int minBound = 10; + public int maxBound = 0; + public int charW; + public int charH; + public int charS; + public int charIntCount; + public static final int intBits = 31; + + public void create(String name) { + try { + loadFont("/font_"+name+".rft"); + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + chars32 = new int[(maxBound-minBound)*charIntCount]; + for (int charIndex = 0; charIndex < maxBound-minBound; charIndex++) { + boolean[] currentChar = rawchars[charIndex]; + if (currentChar == null) { + int currentInt = 0; + int currentBit = 0; + for (int i = 0; i < charS; i++) { + if (currentInt*intBits+currentBit >= (currentInt+1)*intBits) { + currentInt += 1; + currentBit = 0; + } + chars32[charIndex*charIntCount+currentInt] = (chars32[charIndex*charIntCount+currentInt] << 1) + 1; + currentBit += 1; + } + } else { + int currentInt = 0; + int currentBit = 0; + for (int i = 0; i < charS; i++) { + if (currentBit >= intBits) { + currentInt += 1; + currentBit = 0; + } + chars32[charIndex*charIntCount+currentInt] = (chars32[charIndex*charIntCount+currentInt]) | ((currentChar[i] ? 1 : 0) << currentBit); + currentBit++; + } + } + } + + Object obj = new Object(); + WeakReference ref = new WeakReference<>(obj); + obj = null; + while (ref.get() != null) { + System.gc(); + } + } + + private void loadFont(String string) throws IOException { + URL res = Main.instance.getClass().getResource(string); + int[] file = Utils.realBytes(Utils.convertStreamToByteArray(res.openStream(), res.getFile().length())); + int filelength = file.length; + if (filelength >= 16) { + if (file[0x0] == 114 && file[0x1] == 97 && file[0x2] == 119 && file[0x3] == 0xFF && file[0x8] == 0xFF && file[0xD] == 0xFF) { + charW = file[0x4] << 8 | file[0x5]; + charH = file[0x6] << 8 | file[0x7]; + charS = charW*charH; + charIntCount = (int) Math.ceil(((double)charS)/((double)intBits)); + minBound = file[0x9] << 24 | file[0xA] << 16 | file[0xB] << 8 | file[0xC]; + maxBound = file[0xE] << 24 | file[0xF] << 16 | file[0x10] << 8 | file[0x11]; + if (maxBound <= minBound) { + maxBound = 10000; //TODO remove it: temp fix + } + rawchars = new boolean[maxBound-minBound][]; + int index = 0x12; + while (index < filelength) { + try { + int charIndex = file[index] << 8 | file[index+1]; + boolean[] rawchar = new boolean[charS]; + int charbytescount = 0; + while (charbytescount*8 < charS) { + charbytescount+=1; + } + int currentBit = 0; + for (int i = 0; i <= charbytescount; i++) { + for (int bit = 0; bit < 8; bit++) { + if (currentBit >= charS) { + break; + } + rawchar[currentBit] = (((file[index + 2 + i] >> (8-1-bit)) & 0x1)==1)?true:false; + currentBit++; + } + } + rawchars[charIndex - minBound] = rawchar; + index += 2 + charbytescount; + } + catch (Exception ex) { + ex.printStackTrace(); + System.out.println(string); + System.exit(-1); + } + } + } else { + throw new IOException(); + } + } else { + throw new IOException(); + } + } + + public int[] getCharIndexes(String txt) { + final int l = txt.length(); + int[] indexes = new int[l]; + char[] chars = txt.toCharArray(); + for (int i = 0; i < l; i++) { + indexes[i] = (chars[i] & 0xFFFF)-minBound; + } + return indexes; + } + + @SuppressWarnings("unused") + private void saveArray(int[] screen, String coutputpng) { + BufferedImage bi = new BufferedImage(300, 200, BufferedImage.TYPE_INT_RGB); + final int[] a = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData(); + System.arraycopy(screen, 0, a, 0, screen.length); + try { + ImageIO.write(bi, "PNG", new File(coutputpng)); + } catch (IOException ex) { + Logger.getLogger(RAWFont.class.getName()).log(Level.SEVERE, null, ex); + } + } + + public void drawText(int[] screen, int[] screenSize, int x, int y, int[] text, int color) { + final int screenLength = screen.length; + int screenPos = 0; + + + int currentInt; + int currentIntBitPosition; + int bitData; + int cpos; + int j; + final int l = text.length; + for (int i = 0; i < l; i++) { + cpos = (i * (charW + 1)); + final int charIndex = text[i]; + for (int dy = 0; dy < charH; dy++) { + for (int dx = 0; dx < charW; dx++) { + j = x + cpos + dx; + if (j > 0 & j < screenSize[0]) { + int bit = dx + dy * charW; + currentInt = (int) (Math.floor(bit)/(intBits)); + currentIntBitPosition = bit-(currentInt*intBits); + bitData = (chars32[charIndex*charIntCount+currentInt] >> currentIntBitPosition) & 1; + screenPos = x + cpos + dx + (y + dy) * screenSize[0]; + if (bitData == 1 & screenLength > screenPos) { + screen[screenPos] = color; + } + } + } + } + } + } +} diff --git a/src/org/warp/picalculator/gui/DisplayManager.java b/src/org/warp/picalculator/gui/DisplayManager.java index c69d1d09..6ca9cf38 100644 --- a/src/org/warp/picalculator/gui/DisplayManager.java +++ b/src/org/warp/picalculator/gui/DisplayManager.java @@ -26,6 +26,7 @@ public final class DisplayManager implements RenderingLoop { private static float brightness; public static final GraphicEngine engine = chooseGraphicEngine(); + public static final boolean supportsPauses = engine.doesRefreshPauses(); public static Renderer renderer; public static Skin guiSkin; @@ -343,22 +344,7 @@ public final class DisplayManager implements RenderingLoop { @Override public void refresh() { - float dt = 0; - final long newtime = System.nanoTime(); - if (precTime == -1) { - dt = 0; - } else { - dt = (float) ((newtime - precTime) / 1000000000d); - } - precTime = newtime; - /* - * Calcoli - */ - checkDisplayResized(); - - screen.beforeRender(dt); - - if (dt >= 0.03 || screen.mustBeRefreshed()) { + if (supportsPauses == false || (Keyboard.popRefreshRequest() || screen.mustBeRefreshed())) { draw(); } @@ -385,68 +371,83 @@ public final class DisplayManager implements RenderingLoop { System.exit(0); } - //Debug thread - Thread dbgthrd = new Thread(() -> { + //Working thread + Thread workThread = new Thread(() -> { try { while (true) { - for (int i = 0; i < 10; i++) { - System.out.println("============"); - OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean(); - for (Method method : operatingSystemMXBean.getClass().getDeclaredMethods()) { - method.setAccessible(true); - if (method.getName().startsWith("get") && Modifier.isPublic(method.getModifiers())) { - Object value; - try { - value = method.invoke(operatingSystemMXBean); - } catch (Exception e) { - value = e; - } // try - boolean percent = false; - boolean mb = false; - String displayName = method.getName(); - String displayValue = value.toString(); - if (displayName.endsWith("CpuLoad")) { - percent = true; - } - if (displayName.endsWith("MemorySize")) { - mb = true; - } - ArrayList arr = new ArrayList<>(); - arr.add("getFreePhysicalMemorySize"); - arr.add("getProcessCpuLoad"); - arr.add("getSystemCpuLoad"); - arr.add("getTotalPhysicalMemorySize"); - if (arr.contains(displayName)) { - if (percent) { - try { - System.out.println(displayName + " = " + (((int)(Float.parseFloat(displayValue) * 10000f))/100f) + "%"); - }catch(Exception ex) { - System.out.println(displayName + " = " + displayValue); - } - } else if (mb) { - try { - System.out.println(displayName + " = " + (Long.parseLong(displayValue) / 1024L / 1024L) + " MB"); - }catch(Exception ex) { - System.out.println(displayName + " = " + displayValue); - } - } else { - System.out.println(displayName + " = " + displayValue); - } - } - } // if - } // for - System.out.println("============"); - Thread.sleep(5000); + float dt = 0; + final long newtime = System.nanoTime(); + if (precTime == -1) { + dt = 0; + } else { + dt = (float) ((newtime - precTime) / 1000000000d); } + precTime = newtime; + /* + * Calcoli + */ + checkDisplayResized(); + + screen.beforeRender(dt); + + Thread.sleep(50); +// for (int i = 0; i < 10; i++) { +// System.out.println("============"); +// OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean(); +// for (Method method : operatingSystemMXBean.getClass().getDeclaredMethods()) { +// method.setAccessible(true); +// if (method.getName().startsWith("get") && Modifier.isPublic(method.getModifiers())) { +// Object value; +// try { +// value = method.invoke(operatingSystemMXBean); +// } catch (Exception e) { +// value = e; +// } // try +// boolean percent = false; +// boolean mb = false; +// String displayName = method.getName(); +// String displayValue = value.toString(); +// if (displayName.endsWith("CpuLoad")) { +// percent = true; +// } +// if (displayName.endsWith("MemorySize")) { +// mb = true; +// } +// ArrayList arr = new ArrayList<>(); +// arr.add("getFreePhysicalMemorySize"); +// arr.add("getProcessCpuLoad"); +// arr.add("getSystemCpuLoad"); +// arr.add("getTotalPhysicalMemorySize"); +// if (arr.contains(displayName)) { +// if (percent) { +// try { +// System.out.println(displayName + " = " + (((int)(Float.parseFloat(displayValue) * 10000f))/100f) + "%"); +// }catch(Exception ex) { +// System.out.println(displayName + " = " + displayValue); +// } +// } else if (mb) { +// try { +// System.out.println(displayName + " = " + (Long.parseLong(displayValue) / 1024L / 1024L) + " MB"); +// }catch(Exception ex) { +// System.out.println(displayName + " = " + displayValue); +// } +// } else { +// System.out.println(displayName + " = " + displayValue); +// } +// } +// } // if +// } // for +// System.out.println("============"); +// Thread.sleep(5000); +// } } } catch (final InterruptedException e) { - // TODO Auto-generated catch block e.printStackTrace(); } }); - dbgthrd.setDaemon(true); - dbgthrd.setName("Debug performance thread"); - //dbgthrd.start(); + workThread.setDaemon(true); + workThread.setName("Work thread"); + workThread.start(); engine.start(this); @@ -464,8 +465,10 @@ public final class DisplayManager implements RenderingLoop { if (newval >= 0 && newval <= 1) { brightness = newval; if (Utils.debugOn == false) { - Gpio.pwmWrite(12, (int) Math.ceil(brightness * 1024)); + Gpio.pwmWrite(12, (int) Math.ceil(brightness * 1024f)); // SoftPwm.softPwmWrite(12, (int)(Math.ceil(brightness*10))); + } else { + Utils.debug.println("Brightness: " + newval); } } } diff --git a/src/org/warp/picalculator/gui/graphicengine/GraphicEngine.java b/src/org/warp/picalculator/gui/graphicengine/GraphicEngine.java index a06bdf5c..42db692c 100644 --- a/src/org/warp/picalculator/gui/graphicengine/GraphicEngine.java +++ b/src/org/warp/picalculator/gui/graphicengine/GraphicEngine.java @@ -37,4 +37,6 @@ public interface GraphicEngine { public void waitUntilExit(); public boolean isSupported(); + + public boolean doesRefreshPauses(); } diff --git a/src/org/warp/picalculator/gui/graphicengine/cpu/CPUEngine.java b/src/org/warp/picalculator/gui/graphicengine/cpu/CPUEngine.java index 47bb1773..5c4ce9cc 100644 --- a/src/org/warp/picalculator/gui/graphicengine/cpu/CPUEngine.java +++ b/src/org/warp/picalculator/gui/graphicengine/cpu/CPUEngine.java @@ -107,7 +107,7 @@ public class CPUEngine implements GraphicEngine { e.printStackTrace(); } }); - th.setName("Game loop thread"); + th.setName("CPU rendering thread"); th.setDaemon(true); th.start(); } @@ -451,4 +451,9 @@ public class CPUEngine implements GraphicEngine { public boolean isSupported() { return GraphicsEnvironment.isHeadless() == false; } + + @Override + public boolean doesRefreshPauses() { + return true; + } } diff --git a/src/org/warp/picalculator/gui/graphicengine/cpu/SwingWindow.java b/src/org/warp/picalculator/gui/graphicengine/cpu/SwingWindow.java index 61c3b310..126a56bd 100644 --- a/src/org/warp/picalculator/gui/graphicengine/cpu/SwingWindow.java +++ b/src/org/warp/picalculator/gui/graphicengine/cpu/SwingWindow.java @@ -120,7 +120,7 @@ public class SwingWindow extends JFrame { break; case KeyEvent.VK_ENTER: if (!Keyboard.shift && !Keyboard.alpha) { - Keyboard.keyReleased(Key.SOLVE); + Keyboard.keyReleased(Key.SIMPLIFY); } else { Keyboard.keyReleased(Key.NONE); } diff --git a/src/org/warp/picalculator/gui/graphicengine/gpu/GPUEngine.java b/src/org/warp/picalculator/gui/graphicengine/gpu/GPUEngine.java index 6e770806..7c002011 100644 --- a/src/org/warp/picalculator/gui/graphicengine/gpu/GPUEngine.java +++ b/src/org/warp/picalculator/gui/graphicengine/gpu/GPUEngine.java @@ -129,11 +129,13 @@ public class GPUEngine implements org.warp.picalculator.gui.graphicengine.Graphi boolean available = GLProfile.isAvailable(GLProfile.GL2ES1); if (!available) { System.err.println(GLProfile.glAvailabilityToString()); - try { - Thread.sleep(1000); - } catch(Exception e) {} } - return available; + return false; + } + + @Override + public boolean doesRefreshPauses() { + return false; } } diff --git a/src/org/warp/picalculator/gui/graphicengine/gpu/NEWTWindow.java b/src/org/warp/picalculator/gui/graphicengine/gpu/NEWTWindow.java index 19a41b85..56d22152 100644 --- a/src/org/warp/picalculator/gui/graphicengine/gpu/NEWTWindow.java +++ b/src/org/warp/picalculator/gui/graphicengine/gpu/NEWTWindow.java @@ -89,7 +89,7 @@ class NEWTWindow implements GLEventListener { System.out.println("Loaded OpenGL"); // We may at this point tweak the caps and request a translucent drawable caps.setBackgroundOpaque(true); //transparency window -// caps.setSampleBuffers(false); + caps.setSampleBuffers(false); final GLWindow glWindow = GLWindow.create(caps); window = glWindow; @@ -184,7 +184,7 @@ class NEWTWindow implements GLEventListener { break; case KeyEvent.VK_ENTER: if (!Keyboard.shift && !Keyboard.alpha) { - Keyboard.keyReleased(Key.SOLVE); + Keyboard.keyReleased(Key.SIMPLIFY); } else { Keyboard.keyReleased(Key.NONE); } diff --git a/src/org/warp/picalculator/gui/screens/MathInputScreen.java b/src/org/warp/picalculator/gui/screens/MathInputScreen.java index 0654d907..eba3723f 100644 --- a/src/org/warp/picalculator/gui/screens/MathInputScreen.java +++ b/src/org/warp/picalculator/gui/screens/MathInputScreen.java @@ -32,8 +32,8 @@ import org.warp.picalculator.math.functions.Number; public class MathInputScreen extends Screen { - public volatile String equazioneCorrente = ""; - public volatile String nuovaEquazione = ""; + public volatile String currentExpression = ""; + public volatile String newExpression = ""; public volatile int caretPos = 0; public volatile boolean showCaret = true; public volatile float showCaretDelta = 0f; @@ -42,7 +42,7 @@ public class MathInputScreen extends Screen { public int scrollX = 0; public int errorLevel = 0; // 0 = nessuno, 1 = risultato, 2 = tutto boolean mustRefresh = true; - boolean afterDoNextStep = false; + boolean firstStep = true; public MathInputScreen() { super(); @@ -115,9 +115,9 @@ public class MathInputScreen extends Screen { } public void interpreta(boolean temporary) throws Error { - final String eqn = nuovaEquazione; + final String eqn = newExpression; if (!temporary) { - equazioneCorrente = eqn; + currentExpression = eqn; } calc.parseInputString(eqn); @@ -131,8 +131,8 @@ public class MathInputScreen extends Screen { showCaret = !showCaret; showCaretDelta = 0f; } - if (caretPos > nuovaEquazione.length()) { - caretPos = nuovaEquazione.length(); + if (caretPos > newExpression.length()) { + caretPos = newExpression.length(); } if (DisplayManager.error == null) { @@ -165,9 +165,9 @@ public class MathInputScreen extends Screen { final int textColor = 0xFF000000; final int padding = 4; DisplayManager.renderer.glColor(textColor); - final int caretRealPos = MathematicalSymbols.getGraphicRepresentation(nuovaEquazione.substring(0, caretPos)).length() * (fontBig.getCharacterWidth() + 1); - final String inputTextWithoutCaret = MathematicalSymbols.getGraphicRepresentation(nuovaEquazione); - final boolean tooLongI = padding + fontBig.getStringWidth(nuovaEquazione) + padding >= Main.screenSize[0]; + final int caretRealPos = MathematicalSymbols.getGraphicRepresentation(newExpression.substring(0, caretPos)).length() * (fontBig.getCharacterWidth() + 1); + final String inputTextWithoutCaret = MathematicalSymbols.getGraphicRepresentation(newExpression); + final boolean tooLongI = padding + fontBig.getStringWidth(newExpression) + padding >= Main.screenSize[0]; int scrollI = 0; if (tooLongI) { scrollI = -scrollX; @@ -246,17 +246,17 @@ public class MathInputScreen extends Screen { @Override public boolean keyPressed(Key k) { switch (k) { - case SIMPLIFY: - if (nuovaEquazione.length() > 0) { - if (!afterDoNextStep) { + case STEP: + if (newExpression.length() > 0) { + if (firstStep) { try { try { interpreta(true); showVariablesDialog(() -> { - equazioneCorrente = nuovaEquazione; + currentExpression = newExpression; calc.f2 = calc.f; - afterDoNextStep = true; - simplify(); + firstStep = false; + step(); }); } catch (final Exception ex) { if (Utils.debugOn) { @@ -273,15 +273,15 @@ public class MathInputScreen extends Screen { System.err.println(e.id); } } else { - simplify(); + step(); } } return true; - case SOLVE: + case SIMPLIFY: if (DisplayManager.error != null) { Utils.debug.println("Resetting after error..."); DisplayManager.error = null; - equazioneCorrente = null; + currentExpression = null; calc.f = null; calc.f2 = null; calc.resultsCount = 0; @@ -289,15 +289,15 @@ public class MathInputScreen extends Screen { } else { try { try { - if (afterDoNextStep) { - simplify(); + if (!firstStep) { + step(); } else { - if (nuovaEquazione != equazioneCorrente && nuovaEquazione.length() > 0) { + if (newExpression != currentExpression && newExpression.length() > 0) { changeEquationScreen(); interpreta(true); showVariablesDialog(() -> { - equazioneCorrente = nuovaEquazione; - solve(); + currentExpression = newExpression; + simplify(); }); } } @@ -414,36 +414,36 @@ public class MathInputScreen extends Screen { typeChar(MathematicalSymbols.ARC_TANGENT); return true; case DELETE: - if (nuovaEquazione.length() > 0) { + if (newExpression.length() > 0) { if (caretPos > 0) { caretPos -= 1; - nuovaEquazione = nuovaEquazione.substring(0, caretPos) + nuovaEquazione.substring(caretPos + 1, nuovaEquazione.length()); + newExpression = newExpression.substring(0, caretPos) + newExpression.substring(caretPos + 1, newExpression.length()); } else { - nuovaEquazione = nuovaEquazione.substring(1); + newExpression = newExpression.substring(1); } try { interpreta(true); } catch (final Error e) {} } - afterDoNextStep = false; + firstStep = true; return true; case LEFT: if (caretPos > 0) { caretPos -= 1; } else { - caretPos = nuovaEquazione.length(); + caretPos = newExpression.length(); } - scrollX = fontBig.getStringWidth(nuovaEquazione.substring(0, caretPos) + "|||"); + scrollX = fontBig.getStringWidth(newExpression.substring(0, caretPos) + "|||"); showCaret = true; showCaretDelta = 0L; return true; case RIGHT: - if (caretPos < nuovaEquazione.length()) { + if (caretPos < newExpression.length()) { caretPos += 1; } else { caretPos = 0; } - scrollX = fontBig.getStringWidth(nuovaEquazione.substring(0, caretPos) + "|||"); + scrollX = fontBig.getStringWidth(newExpression.substring(0, caretPos) + "|||"); showCaret = true; showCaretDelta = 0L; return true; @@ -454,8 +454,8 @@ public class MathInputScreen extends Screen { return true; } else { caretPos = 0; - nuovaEquazione = ""; - afterDoNextStep = false; + newExpression = ""; + firstStep = false; if (calc.f != null) { calc.f = new ArrayList<>(); } @@ -466,8 +466,8 @@ public class MathInputScreen extends Screen { if (calc.exactMode == false) { calc.f2 = solveExpression(calc.f2); } else { - equazioneCorrente = ""; - Keyboard.keyPressed(Key.SOLVE); + currentExpression = ""; + Keyboard.keyPressed(Key.SIMPLIFY); } return true; case debug1: @@ -475,8 +475,8 @@ public class MathInputScreen extends Screen { return true; case HISTORY_BACK: if (DisplayManager.INSTANCE.canGoBack()) { - if (equazioneCorrente != null && equazioneCorrente.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession + 1] instanceof MathInputScreen) { - nuovaEquazione = equazioneCorrente; + if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession + 1] instanceof MathInputScreen) { + newExpression = currentExpression; try { interpreta(true); } catch (final Error e) {} @@ -485,8 +485,8 @@ public class MathInputScreen extends Screen { return false; case HISTORY_FORWARD: if (DisplayManager.INSTANCE.canGoForward()) { - if (equazioneCorrente != null && equazioneCorrente.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession - 1] instanceof MathInputScreen) { - nuovaEquazione = equazioneCorrente; + if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession - 1] instanceof MathInputScreen) { + newExpression = currentExpression; try { interpreta(true); } catch (final Error e) {} @@ -546,7 +546,7 @@ public class MathInputScreen extends Screen { return null; } - protected void simplify() { + protected void step() { try { try { showVariablesDialog(); @@ -602,7 +602,7 @@ public class MathInputScreen extends Screen { } } - protected void solve() { + protected void simplify() { try { try { for (final Function f : calc.f) { @@ -645,11 +645,11 @@ public class MathInputScreen extends Screen { } private void changeEquationScreen() { - if (equazioneCorrente != null && equazioneCorrente.length() > 0) { + if (currentExpression != null && currentExpression.length() > 0) { final MathInputScreen cloned = clone(); - cloned.caretPos = cloned.equazioneCorrente.length(); - cloned.nuovaEquazione = cloned.equazioneCorrente; - cloned.scrollX = fontBig.getStringWidth(cloned.equazioneCorrente); + cloned.caretPos = cloned.currentExpression.length(); + cloned.newExpression = cloned.currentExpression; + cloned.scrollX = fontBig.getStringWidth(cloned.currentExpression); try { cloned.interpreta(true); } catch (final Error e) {} @@ -662,12 +662,12 @@ public class MathInputScreen extends Screen { public void typeChar(String chr) { final int len = chr.length(); - nuovaEquazione = nuovaEquazione.substring(0, caretPos) + chr + nuovaEquazione.substring(caretPos, nuovaEquazione.length()); + newExpression = newExpression.substring(0, caretPos) + chr + newExpression.substring(caretPos, newExpression.length()); caretPos += len; - scrollX = fontBig.getStringWidth(nuovaEquazione.substring(0, caretPos) + "|||"); + scrollX = fontBig.getStringWidth(newExpression.substring(0, caretPos) + "|||"); showCaret = true; showCaretDelta = 0L; - afterDoNextStep = false; + firstStep = true; try { interpreta(true); } catch (final Error e) {} @@ -685,15 +685,16 @@ public class MathInputScreen extends Screen { public void showVariablesDialog(final Runnable runnable) { final Thread ct = new Thread(() -> { - final ArrayList variablesInFunctions = getVariables(calc.f.toArray(new Function[calc.f.size()])); + final ArrayList unknownsInFunctions = getUnknowns(calc.f.toArray(new Function[calc.f.size()])); + unknownsInFunctions.clear(); //TODO: Remove this line to test the new variables dialog for (final VariableValue f : calc.variablesValues) { - if (variablesInFunctions.contains(f.v)) { - variablesInFunctions.remove(f.v); + if (unknownsInFunctions.contains(f.v)) { + unknownsInFunctions.remove(f.v); } } boolean cancelled = false; - for (final Function f : variablesInFunctions) { + for (final Function f : unknownsInFunctions) { final ChooseVariableValueScreen cvs = new ChooseVariableValueScreen(this, new VariableValue((Variable) f, new Number(calc, 0))); DisplayManager.INSTANCE.setScreen(cvs); try { @@ -727,15 +728,15 @@ public class MathInputScreen extends Screen { ct.start(); } - private ArrayList getVariables(Function[] fncs) { + private ArrayList getUnknowns(Function[] fncs) { final ArrayList res = new ArrayList<>(); for (final Function f : fncs) { if (f instanceof FunctionTwoValues) { - res.addAll(getVariables(new Function[] { ((FunctionTwoValues) f).getVariable1(), ((FunctionTwoValues) f).getVariable2() })); + res.addAll(getUnknowns(new Function[] { ((FunctionTwoValues) f).getVariable1(), ((FunctionTwoValues) f).getVariable2() })); } else if (f instanceof FunctionMultipleValues) { - res.addAll(getVariables(((FunctionMultipleValues) f).getVariables())); + res.addAll(getUnknowns(((FunctionMultipleValues) f).getVariables())); } else if (f instanceof AnteriorFunction) { - res.addAll(getVariables(new Function[] { ((AnteriorFunction) f).getVariable() })); + res.addAll(getUnknowns(new Function[] { ((AnteriorFunction) f).getVariable() })); } else if (f instanceof Variable) { if (!res.contains(f)) { res.add(f); @@ -750,8 +751,8 @@ public class MathInputScreen extends Screen { final MathInputScreen es = this; final MathInputScreen es2 = new MathInputScreen(); es2.scrollX = es.scrollX; - es2.nuovaEquazione = es.nuovaEquazione; - es2.equazioneCorrente = es.equazioneCorrente; + es2.newExpression = es.newExpression; + es2.currentExpression = es.currentExpression; es2.showCaret = es.showCaret; es2.showCaretDelta = es.showCaretDelta; es2.caretPos = es.caretPos; @@ -761,7 +762,7 @@ public class MathInputScreen extends Screen { es2.autoscroll = es.autoscroll; es2.errorLevel = es.errorLevel; es2.mustRefresh = es.mustRefresh; - es2.afterDoNextStep = es.afterDoNextStep; + es2.firstStep = es.firstStep; // es2.calc.variablesValues = Utils.cloner.deepClone(es.calc.variablesValues); es2.calc = Utils.cloner.deepClone(es.calc); return es2; diff --git a/src/org/warp/picalculator/math/Calculator.java b/src/org/warp/picalculator/math/Calculator.java index c2c0e6a5..1dfaa585 100644 --- a/src/org/warp/picalculator/math/Calculator.java +++ b/src/org/warp/picalculator/math/Calculator.java @@ -111,7 +111,7 @@ public class Calculator { final ArrayList fncs = new ArrayList<>(); if (eqn.length() > 0) { try { - fncs.add(parseString(eqn.replace("sqrt", "Ⓐ").replace("^", "Ⓑ"))); + fncs.add(parseString(eqn.replace("sqrt", MathematicalSymbols.SQUARE_ROOT).replace("^", MathematicalSymbols.POWER))); } catch (final Exception ex) { } diff --git a/src/org/warp/picalculator/math/functions/Expression.java b/src/org/warp/picalculator/math/functions/Expression.java index 0c821210..e615cd4d 100644 --- a/src/org/warp/picalculator/math/functions/Expression.java +++ b/src/org/warp/picalculator/math/functions/Expression.java @@ -308,7 +308,7 @@ public class Expression extends FunctionMultipleValues { break; default: if (Utils.isInArray(charI, MathematicalSymbols.variables())) { - f = new Variable(root, charI); + f = new Variable(root, charI, Variable.V_TYPE.UNKNOWN); } else { if (charI == "(" || charI == ")") { throw new Error(Errors.UNBALANCED_BRACKETS); diff --git a/src/org/warp/picalculator/math/functions/Variable.java b/src/org/warp/picalculator/math/functions/Variable.java index da17b04e..f46c02cd 100644 --- a/src/org/warp/picalculator/math/functions/Variable.java +++ b/src/org/warp/picalculator/math/functions/Variable.java @@ -16,24 +16,35 @@ public class Variable implements Function { protected int width; protected int height; protected int line; + protected int[] varColor; protected boolean small; protected final Calculator root; + protected V_TYPE type = V_TYPE.KNOWN; - public Variable(Calculator root, char val) { + public Variable(Calculator root, char val, V_TYPE type) { this.root = root; var = val; + this.type = type; } - public Variable(Calculator root, String s) throws Error { - this(root, s.charAt(0)); + public Variable(Calculator root, String s, V_TYPE type) throws Error { + this(root, s.charAt(0), type); } public char getChar() { return var; } - public void setChar(char val) { - var = val; + public Variable setChar(char val) { + return new Variable(root, val, type); + } + + public V_TYPE getType() { + return type; + } + + public Variable setType(V_TYPE typ) { + return new Variable(root, var, typ); } @Override @@ -41,6 +52,24 @@ public class Variable implements Function { line = calcLine(); height = calcHeight(); width = calcWidth(); + varColor = new int[3]; + switch (type) { + case KNOWN: + varColor[0] = 0; + varColor[1] = 200; + varColor[2] = 0; + break; + case UNKNOWN: + varColor[0] = 200; + varColor[1] = 0; + varColor[2] = 0; + break; + case SOLUTION: + varColor[0] = 0; + varColor[1] = 0; + varColor[2] = 200; + break; + } } @Override @@ -63,7 +92,9 @@ public class Variable implements Function { @Override public void draw(int x, int y) { Utils.getFont(small).use(DisplayManager.engine); + DisplayManager.renderer.glColor3i(varColor[0], varColor[1], varColor[2]); DisplayManager.renderer.glDrawStringLeft(x + 1, y, toString()); + DisplayManager.renderer.glColor3i(0, 0, 0); } @Override @@ -135,7 +166,7 @@ public class Variable implements Function { @Override public boolean equals(Object o) { if (o instanceof Variable) { - return ((Variable) o).getChar() == var; + return ((Variable) o).getChar() == var && ((Variable) o).getType() == type; } return false; } @@ -144,4 +175,10 @@ public class Variable implements Function { public Calculator getRoot() { return root; } + + public static enum V_TYPE { + KNOWN, + UNKNOWN, + SOLUTION + } }