Compare commits

...

116 Commits

Author SHA1 Message Date
Andrea Cavalli
d288e0d96c Fix empty input movement 2023-08-23 16:54:06 +02:00
Andrea Cavalli
7ae4315837 Refactor caret positioning 2023-08-23 16:47:55 +02:00
Andrea Cavalli
3031966145 Fix zoom, rename block functions 2023-08-23 12:04:27 +02:00
Andrea Cavalli
0aceed466d Fix gpu input, update jogl 2023-08-18 17:47:05 +02:00
1ec7bee089 Temp 2022-03-14 11:22:38 +01:00
12329c5ffe Merge remote-tracking branch 'origin/master'
# Conflicts:
#	core/src/main/java/it/cavallium/warppi/gui/CalculatorHUD.java
2019-12-16 16:59:05 +01:00
0335dadcea Fixed preview url 2019-12-16 16:54:10 +01:00
0671f0d6b5 Removed javascript optimizations due to a TeaVM compilation bug 2019-11-16 02:02:25 +01:00
4c29eeb31c Bugfixes
Fixed implicit multiplication symbols, zoom is now 1x, debug steps are printed, fixed missing numeric chars, changed RootSquare base class to FunctionSingle, added two hardcoded multiplication rules, added rootsquarerule, isolated the swing engine from the window, added 2 Fractions rules and 1 exponent rule
2019-11-16 01:32:47 +01:00
26dc8369a7 Bugfixes 2019-11-02 23:13:19 +01:00
70ff11da7f Added bounded render contexts 2019-11-01 18:04:01 +01:00
a9dd7de800 Merge remote-tracking branch 'master/dev' 2019-11-01 15:39:27 +01:00
da387d1165 Removed old libraries 2019-11-01 15:25:01 +01:00
8e11197368 Updated .gitignore 2019-11-01 13:35:30 +01:00
fb43f00485
Merge pull request #8 from razzolini/rules-dsl
Implement a domain-specific language for the definition of algebraic manipulation rules
2019-10-29 22:16:55 +01:00
a74f047655 Fix/improve hashCode for Functions
Some types of Function had hashCode methods which didn't match the
behavior of equals, while others could simply be rewritten in a simpler
way by using Objects.hash.
2019-10-25 22:48:49 +02:00
0c316226e6 Make Function.equals test for exact equality instead of equivalence
Actually, testing for equivalence was only partially implemented (by
considering the commutative property for some FunctionOperators).

Additionally, should it be needed in the future, equivalence testing
would probably be better implemented as a separate, specialized method
anyway.
2019-10-25 22:30:10 +02:00
d8f401cb22 Remove zip file handling code and zip4j dependency
.zip files were only used to cache compiled Java rules, and the new rule
system has nothing to cache.
2019-10-25 20:49:31 +02:00
5c7411d44c Contextualized methods 2019-10-25 13:59:20 +02:00
12406c787b Ensure that lex and parse methods are only called once per instance 2019-09-09 18:34:52 +02:00
c37f7f52b3 Specify that TabExpandedString only works on single lines 2019-09-09 18:34:52 +02:00
804fee4db0 Use tab-expanded column numbers when formatting DSL errors 2019-09-09 18:34:52 +02:00
b3f2ad82d0 Migrate from JUnit 4 to 5 2019-09-09 18:34:52 +02:00
fc119efedc Remove language level specification from warppi-core pom.xml
The language level is specified in the root pom.xml file, and there's no
need to override it here.
2019-09-09 18:34:52 +02:00
082f694b1b Tweak DSL error formatting
- Add a blank line between the DslFilesException stack trace and
   formatted error messages.
 - Quote the sub-function name in the message for UndefinedSubFunction
   errors.
2019-09-09 18:34:52 +02:00
fbb6cf590d Throw an exception when a sub-function is undefined in SubFunctionPattern.replace 2019-09-09 18:34:52 +02:00
feb894bacd Improve SubFunctionPattern documentation 2019-09-09 18:34:52 +02:00
b4fc6dd019 Improve PatternRule documentation 2019-09-09 18:34:52 +02:00
eb8fcaafb9 Keep track of identifiers separately for each SubFunctionPattern object 2019-09-09 18:34:52 +02:00
c8656d1b30 Improve DSL front-end documentation 2019-08-12 11:28:39 +02:00
e297d3592f Reduce creation of Map objects in Pattern matching 2019-08-12 11:28:39 +02:00
a76511ea19 Remove the warppi-rules module 2019-08-12 11:28:39 +02:00
2b9fb97648 Make DSL rule loading work on TeaVM 2019-08-12 11:28:39 +02:00
e5b64ce218 Make TeaVMStorageUtils.read work instead of hanging 2019-08-09 17:53:47 +02:00
fef30042ce Avoid using methods which are not available on TeaVM 2019-08-08 14:36:07 +02:00
d4b91c4d4f Merge branch 'master' into rules-dsl 2019-08-08 12:52:59 +02:00
7819e19e6f Make Function visitor an inner interface of Function 2019-08-07 13:11:59 +02:00
86c7da8c81 Test Lexer with empty input 2019-08-07 13:11:59 +02:00
aeb0388925 Implement DSL error pretty-printing 2019-08-07 13:11:59 +02:00
17d1bddbf1 Fixed picture bug 2019-04-29 23:07:24 +02:00
9e1e751a59 Implemented TouchDevice and DeviceStateDevice 2019-04-09 22:38:22 +02:00
87d4daf195 Updated gitignore 2019-04-09 18:23:35 +02:00
60f91fbc2e Better boot code 2019-04-09 18:19:06 +02:00
ff7dd21788 More appropriate class names 2019-02-27 23:29:03 +01:00
c906c43b8b Updated TeaVM to the latest snapshot and fixed panels history behaviour 2019-02-25 13:12:22 +01:00
788f9663e2 Use Collections.emptyMap and Collections.singletonMap in pattern matching code 2019-02-12 11:40:50 +01:00
04d01565da Correctly handle and report unterminated multiline comments in Lexer 2019-02-11 16:31:03 +01:00
e86a7a6346 Remove Java rule compiling and loading code 2019-02-11 15:55:29 +01:00
fd074b16b7 Do not load DSL rules on JavaScript platforms 2019-02-11 15:11:59 +01:00
2e36bc83bf Fix incorrect rules and port them to the DSL 2019-02-11 12:21:43 +01:00
b9c025d74c Make function rules built-in 2019-02-10 19:59:38 +01:00
7d9b08affd Port most non-function rules from Java to the DSL 2019-02-10 19:05:25 +01:00
6b814b84b6 Add comments to incorrect rules and partially fix ExpandRule1 2019-02-10 19:05:25 +01:00
df5de92931 Make NegativePattern match and produce negative numbers 2019-02-10 19:05:13 +01:00
d18e2d3708 Test the content of DslAggregateExceptions in RulesDslTest 2019-02-07 20:20:58 +01:00
e65f20382f Document the RulesDsl class and its makeRules method 2019-02-04 18:07:51 +01:00
92ad2a9c1e Remove unused imports 2019-01-31 20:39:56 +01:00
57011ceb86 Make EquationsSystemPattern patterns field private (was accidentally package-private) 2019-01-31 20:38:35 +01:00
8eba0cd568 Correctly store sub-function identifiers for rules with the same name and identical rules 2019-01-31 19:23:37 +01:00
2a347e6d19 Allow unary operators in power exponent 2019-01-31 13:10:02 +01:00
ebbf8b013a Replace DslException with the DslError interface and the SyntaxException wrapper 2019-01-31 12:55:15 +01:00
0d89711772 Report DSL errors from RulesDsl.makeRules as a DslAggregateException 2019-01-30 21:47:00 +01:00
f930242ee8 Properly report undefined sub-functions in replacement patterns 2019-01-30 21:47:00 +01:00
3a5ccdfc13 Keep track of sub-function identifier tokens for error reporting 2019-01-30 21:47:00 +01:00
bdb1fc738e Implement multiple error reporting and recovery in Parser 2019-01-30 21:47:00 +01:00
f0d2cdc1ab Implement multiple error reporting and recovery in Lexer 2019-01-29 12:08:35 +01:00
1e0d2e5a0e Create base class for DSL exceptions 2019-01-28 21:13:24 +01:00
1304755c25 Implement loading of DSL rules 2019-01-28 18:19:27 +01:00
c00b71e2ba Remove unneeded throws spec from PatternRule.execute 2019-01-27 21:18:53 +01:00
bea2eb67c8 Check that sub-functions in replacement patterns are defined 2019-01-27 21:18:53 +01:00
ba468d199a Add method to get sub-functions from patterns 2019-01-27 21:18:44 +01:00
591813402d Prevent instantiation of PatternUtils 2019-01-27 19:56:18 +01:00
a92c3a3272 Implement and test RulesDsl.makeRules 2019-01-27 19:24:49 +01:00
6ab69a1613 Implement and test Parser (with temporary error handling) 2019-01-27 19:24:49 +01:00
b959fac770 Implement equals (and hashCode) in PatternRule and patterns for testing 2019-01-27 19:24:49 +01:00
6c8323daf9 Set Java language level to 9 2019-01-27 19:24:49 +01:00
c069e00178 Fix string indentation in LexerTest 2019-01-27 19:24:49 +01:00
27b128a6ea Add single and multi-line comments 2018-11-23 18:52:36 +01:00
da91a5df33 Implement Lexer (with temporary error handling and basic tests) 2018-11-22 20:04:48 +01:00
61d40330be Define the representation for tokens 2018-11-22 19:59:30 +01:00
fa2b9f20a8 Define a temporarily empty RulesDsl.makeRules method
When complete, this method will execute the DSL front-end, and return
the list of rules, if successful, otherwise report errors.
2018-11-20 19:27:04 +01:00
26416dd8f8 Implement ConstantPattern 2018-11-20 19:07:34 +01:00
5238c32380 Implement Pattern-based Rule 2018-11-19 13:05:28 +01:00
101e90ad03 Remove EmptyNumber overload from FunctionVisitor 2018-11-19 10:49:33 +01:00
2ceca91acf Merge branch 'master' into rules-dsl 2018-11-19 10:38:34 +01:00
87151ed606 Fixed graphic glitches when changing screen 2018-10-23 17:28:05 +02:00
76d9d77e13 Extra 2018-10-16 22:26:05 +02:00
7e394a84bf Fix indentation 2018-10-16 21:55:24 +02:00
4e5a77eb3e Add minimal (indentation-only) .editorconfig file 2018-10-16 21:52:06 +02:00
cd6768d608 Extra 2018-10-16 21:42:36 +02:00
21d8c37903 Handle RootSquare functions with RootPattern 2018-10-16 20:33:01 +02:00
6e5ed8ef94 Fixed buggy keyboard behavior 2018-10-16 20:03:12 +02:00
66a04607b3 Fix RootSquare equality with other RootSquare instances 2018-10-16 19:57:26 +02:00
b65723a2c6 Implement EquationsSystemPattern 2018-10-16 19:36:34 +02:00
c2dc02c0e1 Implement equals for EquationsSystem as ordered parameter equality 2018-10-16 19:33:44 +02:00
f7a7f6d200 Extra 2018-10-16 19:28:43 +02:00
53e2416426 Implement EquationPattern 2018-10-16 18:46:49 +02:00
2aeb396b53 Implement equals for Equation 2018-10-16 18:45:37 +02:00
38c8710929 Extra 2018-10-16 17:37:21 +02:00
1a51ae5698 Extra 2018-10-16 15:56:27 +02:00
95560e12b7 Implement UndefinedPattern 2018-10-06 19:14:24 +02:00
957e85b4d0 Extract duplicated PatternTest code to testMultiplePatterns method 2018-10-06 18:45:28 +02:00
0ec3974f41 Implement patterns for most FunctionSingles 2018-10-06 18:41:32 +02:00
54fc13b211 Implement equals for trigonometric functions 2018-10-06 18:38:39 +02:00
2ca5a8391a Implement patterns for most FunctionOperators 2018-10-06 17:41:15 +02:00
0574744921 Create PatternUtils helper class 2018-10-06 16:47:03 +02:00
be5ae2d475 Add missing 'final' specifiers 2018-10-06 15:21:22 +02:00
21de6349f4 Use actual MathContext instead of null in Pattern replace 2018-10-06 15:21:22 +02:00
0afacf7ddc Implement NegativePattern 2018-10-06 15:21:22 +02:00
64553c86e7 Implement NumberPattern 2018-10-06 15:21:22 +02:00
5450d67497 Implement SumPattern 2018-10-06 15:21:22 +02:00
277589e7a9 Create VisitorPattern abstract base class 2018-10-06 15:21:22 +02:00
72de605659 Define FunctionVisitor and corresponding accept method 2018-10-06 15:21:22 +02:00
75fe857139 Implement SubFunctionPattern 2018-10-06 15:21:22 +02:00
0a386c13f4 Create empty PatternTest class. 2018-10-06 15:21:22 +02:00
d88f6a05f9 Define the Pattern interface and its core methods 2018-10-06 15:21:22 +02:00
423 changed files with 11596 additions and 37733 deletions

4
.editorconfig Normal file
View File

@ -0,0 +1,4 @@
root = true
[*]
indent_style = tab

270
.gitignore vendored
View File

@ -1,7 +1,5 @@
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
!/target/*.jar
@ -9,7 +7,7 @@
*.war
*.jar
*.ear
*Thumbs.db
Thumbs.db
font_gputest1.rft
font_gputest12.rft
font_gputest2.rft
@ -26,10 +24,11 @@ math-rules-cache.zip
/backups/
/Resources_and_Videos/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
/bin/
# Created by https://www.gitignore.io/api/git,java,maven,eclipse,intellij,intellij+all,intellij+iml
# Edit at https://www.gitignore.io/?templates=git,java,maven,eclipse,intellij,intellij+all,intellij+iml
### Eclipse ###
.metadata
bin/
tmp/
@ -85,3 +84,262 @@ local.properties
.cache-main
.scala_dependencies
.worksheet
### Eclipse Patch ###
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Annotation Processing
.apt_generated
.sts4-cache/
### Git ###
# Created by git for backups. To disable backups in Git:
# $ git config --global mergetool.keepBackup false
*.orig
# Created by git when using merge tools for conflicts
*.BACKUP.*
*.BASE.*
*.LOCAL.*
*.REMOTE.*
*_BACKUP_*.txt
*_BASE_*.txt
*_LOCAL_*.txt
*_REMOTE_*.txt
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
.idea/**/sonarlint/
# SonarQube Plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator/
### Intellij+all ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
# Generated files
# Sensitive or high-churn files
# Gradle
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
# Mongo Explorer plugin
# File-based project format
# IntelliJ
# mpeltonen/sbt-idea plugin
# JIRA plugin
# Cursive Clojure plugin
# Crashlytics plugin (for Android Studio and IntelliJ)
# Editor-based Rest Client
# Android studio 3.1+ serialized cache file
### Intellij+all Patch ###
# Ignores the whole .idea folder and all .iml files
# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
.idea/
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
*.iml
modules.xml
.idea/misc.xml
*.ipr
# Sonarlint plugin
.idea/sonarlint
### Intellij+iml ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
# Generated files
# Sensitive or high-churn files
# Gradle
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
# Mongo Explorer plugin
# File-based project format
# IntelliJ
# mpeltonen/sbt-idea plugin
# JIRA plugin
# Cursive Clojure plugin
# Crashlytics plugin (for Android Studio and IntelliJ)
# Editor-based Rest Client
# Android studio 3.1+ serialized cache file
### Intellij+iml Patch ###
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
### Java ###
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
.flattened-pom.xml
# End of https://www.gitignore.io/api/git,java,maven,eclipse,intellij,intellij+all,intellij+iml

3
.gitmodules vendored
View File

@ -1,6 +1,3 @@
[submodule "Flow"]
path = Flow
url = https://github.com/Cavallium/Flow
[submodule "bigdecimal-math"]
path = bigdecimal-math
url = https://github.com/Cavallium/bigdecimal-math

1
Flow

@ -1 +0,0 @@
Subproject commit fc24680f8f2178fa550174c75d7dbacb6065358c

View File

@ -9,7 +9,7 @@ Step-by-step algebra calculator for Raspberry PI.
# Live preview
This preview has been built using TeaVM: a JVM made in javascript.
Obviously it runs slower than the original.
https://local.cavallium.it/webtests/warppiweb/
https://local.cavallium.it/calculator/
# Keypad PCB
https://workspace.circuitmaker.com/Projects/Details/Andrea-Cavalli/Scientific-calculator-Keypad

@ -1 +1 @@
Subproject commit b08a4a6aca41fbc6bf0c4bd252f716d518d368a5
Subproject commit da70aa7ba3bcae0e2e76fde338c56696ff25ea96

View File

@ -18,8 +18,9 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>it.cavallium</groupId>
<artifactId>warppi</artifactId>
<version>0.9.0a3</version>
<version>0.10.0-alpha</version>
</parent>
<artifactId>warppi-core</artifactId>
@ -14,20 +14,15 @@
<description>WarpPI Calculator core project</description>
<dependencies>
<dependency>
<groupId>it.cavallium</groupId>
<artifactId>warppi-flow</artifactId>
<version>0.9.0a3</version>
</dependency>
<dependency>
<groupId>it.cavallium</groupId>
<artifactId>warppi-util</artifactId>
<version>0.9.0a3</version>
<version>0.10.0-alpha</version>
</dependency>
<dependency>
<groupId>it.cavallium</groupId>
<artifactId>bigdecimal-math</artifactId>
<version>0.9.0a3</version>
<version>0.10.0-alpha</version>
</dependency>
<dependency>
<groupId>it.unimi.dsi</groupId>
@ -46,11 +41,22 @@
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependency>
<groupId>com.flowpowered</groupId>
<artifactId>flow-nbt</artifactId>
<version>1.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -1,146 +0,0 @@
package it.cavallium.warppi;
import java.io.IOException;
import it.cavallium.warppi.Platform.ConsoleUtils;
import it.cavallium.warppi.boot.StartupArguments;
import it.cavallium.warppi.device.HardwareDevice;
import it.cavallium.warppi.device.HardwareTouchDevice;
import it.cavallium.warppi.device.InputManager;
import it.cavallium.warppi.device.Keyboard;
import it.cavallium.warppi.flow.BehaviorSubject;
import it.cavallium.warppi.flow.Observable;
import it.cavallium.warppi.gui.DisplayManager;
import it.cavallium.warppi.gui.HUD;
import it.cavallium.warppi.gui.HardwareDisplay;
import it.cavallium.warppi.gui.screens.Screen;
import it.cavallium.warppi.util.ClassUtils;
public class Engine {
public static final Engine INSTANCE = new Engine();
private static Platform platform;
private static boolean running = false;
private static BehaviorSubject<LoadingStatus> loadPhase = BehaviorSubject.create();
private final BehaviorSubject<Boolean> loaded = BehaviorSubject.create(false);
private HardwareDevice hardwareDevice;
private Engine() {}
/**
* Start an instance of the calculator.
*
* @param platform
* Platform implementation
* @param screen
* Default screen to show at startup
* @param disp
* Hardware display
* @param hud
* Head-up display
* @param args
* Startup arguments
* @throws InterruptedException
* @throws IOException
*/
public static void start(final Platform platform, final Screen screen, final HardwareDisplay disp,
final HardwareTouchDevice touchdevice, final HUD hud, final StartupArguments args)
throws InterruptedException, IOException {
if (Engine.running) {
throw new RuntimeException("Already running!");
} else {
Engine.running = true;
Engine.INSTANCE.startInstance(platform, screen, disp, touchdevice, hud, args);
}
}
private void startInstance(final Platform platform, final Screen screen, final HardwareDisplay disp,
final HardwareTouchDevice touchdevice, final HUD hud, final StartupArguments args)
throws InterruptedException, IOException {
Engine.platform = platform;
platform.getConsoleUtils().out().println("WarpPI Calculator");
initializeEnvironment(args);
final Thread currentThread = Thread.currentThread();
currentThread.setPriority(Thread.MAX_PRIORITY);
Engine.getPlatform().setThreadName(currentThread, "Main thread");
final DisplayManager dm = new DisplayManager(disp, hud, screen, "WarpPI Calculator by Andrea Cavalli (@Cavallium)");
final Keyboard k = new Keyboard();
final InputManager im = new InputManager(k, touchdevice);
hardwareDevice = new HardwareDevice(dm, im);
hardwareDevice.setup(() -> Engine.loadPhase.onNext(new LoadingStatus()));
}
private void onShutdown() {
Engine.platform.getConsoleUtils().out().println(1, "Shutdown...");
beforeShutdown();
Engine.platform.getConsoleUtils().out().println(1, "");
Engine.platform.getConsoleUtils().out().println(1, "Closed.");
Engine.getPlatform().exit(0);
}
private void initializeEnvironment(final StartupArguments args) throws IOException {
ClassUtils.classLoader = this.getClass();
StaticVars.startupArguments = args;
StaticVars.debugWindow2x = args.isZoomed();
if (args.isVerboseLoggingEnabled() || args.isDebugEnabled()) {
StaticVars.outputLevel = ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE;
}
Engine.platform.getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, args);
checkDeviceType();
if (args.isRaspberryModeAllowed() == false) {
Engine.getPlatform().setRunningOnRaspberry(false);
}
if (Engine.getPlatform().isRunningOnRaspberry()) {
Engine.getPlatform().getGpio().wiringPiSetupPhys();
Engine.getPlatform().getGpio().pinMode(12, Engine.getPlatform().getGpio().valuePwmOutput());
} else {
StaticVars.screenPos = new int[] { 0, 0 };
if (Engine.getPlatform().isJavascript() == false) {
Engine.getPlatform().getSettings().setDebugEnabled(true);
}
}
}
private void checkDeviceType() {
// TODO Auto-generated method stub
}
public void beforeShutdown() {
Keyboard.stopKeyboard();
}
public Observable<Boolean> isLoaded() {
return loaded;
}
public Observable<LoadingStatus> getLoadPhase() {
return Engine.loadPhase;
}
public HardwareDevice getHardwareDevice() {
return hardwareDevice;
}
public static Platform getPlatform() {
return Engine.platform;
}
public static class LoadingStatus {
protected LoadingStatus() {
}
public void done() {
Engine.INSTANCE.loaded.onNext(true);
Engine.INSTANCE.hardwareDevice.getDisplayManager().waitForExit();
Engine.INSTANCE.onShutdown();
}
public void failed() {
Engine.INSTANCE.onShutdown();
}
}
}

View File

@ -3,13 +3,16 @@ package it.cavallium.warppi;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.boot.StartupArguments;
import it.cavallium.warppi.device.DeviceStateDevice;
import it.cavallium.warppi.device.display.BacklightOutputDevice;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.device.input.KeyboardInputDevice;
import it.cavallium.warppi.device.input.TouchInputDevice;
import it.cavallium.warppi.util.Error;
public interface Platform {
@ -18,7 +21,7 @@ public interface Platform {
Gpio getGpio();
StorageUtils getStorageUtils();
PlatformStorage getPlatformStorage();
ImageUtils getImageUtils();
@ -52,21 +55,29 @@ public interface Platform {
URLClassLoader newURLClassLoader(URL[] urls);
Map<String, GraphicEngine> getEnginesList();
TouchInputDevice getTouchInputDevice();
KeyboardInputDevice getKeyboardInputDevice();
DisplayOutputDevice getDisplayOutputDevice();
GraphicEngine getEngine(String string) throws NullPointerException;
BacklightOutputDevice getBacklightOutputDevice();
DeviceStateDevice getDeviceStateDevice();
void throwNewExceptionInInitializerError(String text);
String[] stacktraceToString(Error e);
void loadPlatformRules();
void zip(String targetPath, String destinationFilePath, String password);
void unzip(String targetZipFilePath, String destinationFolderPath, String password);
boolean compile(String[] command, PrintWriter printWriter, PrintWriter errors);
/**
* Determines the list of files containing DSL rules to load.
*
* @return a <code>List</code> of paths of files which contain DSL rules.
* Each <code>String</code> in the returned <code>List</code> can be passed as an argument to
* {@link PlatformStorage#getResourceStream(String)} to access the corresponding file's contents.
* @throws IOException if an IO error occurs while getting the list of rule file paths.
*/
List<String> getRuleFilePaths() throws IOException;
public interface Gpio {
int valueOutput();
@ -97,7 +108,7 @@ public interface Platform {
Object getBoardType();
}
public interface ConsoleUtils {
int OUTPUTLEVEL_NODEBUG = 0;
int OUTPUTLEVEL_DEBUG_MIN = 1;
@ -122,7 +133,7 @@ public interface Platform {
}
}
public interface StorageUtils {
public interface PlatformStorage {
int OpenOptionWrite = 0;
int OpenOptionCreate = 1;
@ -157,7 +168,7 @@ public interface Platform {
List<String> readAllLines(InputStream input) throws IOException;
String getBasePath();
File getRootPath();
}
public interface Semaphore {
@ -204,4 +215,6 @@ public interface Platform {
}
void setArguments(StartupArguments args);
}

View File

@ -1,29 +1,15 @@
package it.cavallium.warppi;
import java.util.function.Function;
import it.cavallium.warppi.boot.StartupArguments;
import it.cavallium.warppi.flow.BehaviorSubject;
import it.cavallium.warppi.flow.Observable;
import it.cavallium.warppi.util.EventSubmitter;
/*
* TODO: Move everything to Engine.Settings
*/
public class StaticVars {
public static final boolean zoomed = true;
public static int[] screenPos = new int[] { 0, 0 };
public static final int[] screenSize = new int[] { 480, 320 };
public static final boolean zoomedFonts = true;
public static int outputLevel = 0;
public static boolean debugWindow2x = false;
public static BehaviorSubject<Float> windowZoom = BehaviorSubject.create(2F);
public static Function<Float, Float> windowZoomFunction = (val) -> {
if (StaticVars.debugWindow2x) {
return val + 1;
} else {
return val;
}
};
public static Observable<Float> windowZoom$ = StaticVars.windowZoom.map(StaticVars.windowZoomFunction);
public static EventSubmitter<Float> windowZoom = new EventSubmitter<>(1F);
public static StartupArguments startupArguments;
private StaticVars() {

View File

@ -0,0 +1,143 @@
package it.cavallium.warppi;
import it.cavallium.warppi.Platform.ConsoleUtils;
import it.cavallium.warppi.boot.StartupArguments;
import it.cavallium.warppi.device.Device;
import it.cavallium.warppi.device.DeviceStateDevice;
import it.cavallium.warppi.device.display.BacklightOutputDevice;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.device.input.InputManager;
import it.cavallium.warppi.device.input.Keyboard;
import it.cavallium.warppi.device.input.KeyboardInputDevice;
import it.cavallium.warppi.device.input.TouchInputDevice;
import it.cavallium.warppi.gui.DisplayManager;
import it.cavallium.warppi.gui.HUD;
import it.cavallium.warppi.gui.screens.Screen;
import it.cavallium.warppi.util.ClassUtils;
import it.cavallium.warppi.util.EventSubmitter;
import it.cavallium.warppi.util.RunnableWithException;
import java.io.IOException;
public class WarpPI {
public static final WarpPI INSTANCE = new WarpPI();
private static Platform platform;
private static boolean running = false;
private final EventSubmitter<Boolean> loaded = EventSubmitter.create(false);
private Device device;
private WarpPI() {
}
/**
* Start an instance of the calculator.
*
* @param platform Platform implementation
* @param screen Default screen to show at startup
* @param hud Head-up display
* @param args Startup arguments
* @throws InterruptedException
* @throws IOException
*/
public static void start(final Platform platform, final Screen screen, final HUD hud, final StartupArguments args, final RunnableWithException onLoading) throws IOException {
if (WarpPI.running) {
throw new RuntimeException("Already running!");
} else {
WarpPI.running = true;
WarpPI.INSTANCE.startInstance(platform, screen, hud, args, onLoading);
}
}
private void startInstance(final Platform platform, final Screen screen,
final HUD hud, final StartupArguments args, final RunnableWithException onLoading)
throws IOException {
WarpPI.platform = platform;
// Set arguments on platform before everything else
platform.setArguments(args);
platform.getConsoleUtils().out().println("WarpPI Calculator");
initializeEnvironment(args);
final Thread currentThread = Thread.currentThread();
currentThread.setPriority(Thread.MAX_PRIORITY);
WarpPI.getPlatform().setThreadName(currentThread, "Main thread");
try {
final DisplayOutputDevice display = platform.getDisplayOutputDevice();
final BacklightOutputDevice backlight = platform.getBacklightOutputDevice();
final DisplayManager dm = new DisplayManager(display, backlight, hud, screen, "WarpPI Calculator by Andrea Cavalli (@Cavallium)");
final KeyboardInputDevice keyboard = platform.getKeyboardInputDevice();
final TouchInputDevice touchscreen = platform.getTouchInputDevice();
final DeviceStateDevice deviceState = platform.getDeviceStateDevice();
final InputManager im = new InputManager(keyboard, touchscreen);
device = new Device(dm, im, deviceState);
device.setup();
onLoading.run();
this.loadingCompleted();
} catch (Exception ex) {
this.loadingFailed(ex);
}
this.onShutdown();
}
private void onShutdown() {
WarpPI.platform.getConsoleUtils().out().println(1, "Shutdown...");
beforeShutdown();
WarpPI.platform.getConsoleUtils().out().println(1, "");
WarpPI.platform.getConsoleUtils().out().println(1, "Closed.");
WarpPI.getPlatform().exit(0);
}
private void initializeEnvironment(final StartupArguments args) throws IOException {
ClassUtils.classLoader = this.getClass();
StaticVars.startupArguments = args;
StaticVars.windowZoom.submit(args.isZoomed() ? 2f : 1f);
if (args.isVerboseLoggingEnabled() || args.isDebugEnabled()) {
StaticVars.outputLevel = ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE;
}
WarpPI.platform.getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, args);
checkDeviceType();
if (args.isRaspberryModeAllowed() == false) {
WarpPI.getPlatform().setRunningOnRaspberry(false);
}
if (WarpPI.getPlatform().isRunningOnRaspberry()) {
WarpPI.getPlatform().getGpio().wiringPiSetupPhys();
WarpPI.getPlatform().getGpio().pinMode(12, WarpPI.getPlatform().getGpio().valuePwmOutput());
} else {
if (WarpPI.getPlatform().isJavascript() == false) {
WarpPI.getPlatform().getSettings().setDebugEnabled(true);
}
}
}
private void checkDeviceType() {
// TODO Auto-generated method stub
}
public void beforeShutdown() {
Keyboard.stopKeyboard();
}
public EventSubmitter<Boolean> isLoaded() {
return loaded;
}
public Device getHardwareDevice() {
return device;
}
public static Platform getPlatform() {
return WarpPI.platform;
}
private void loadingCompleted() {
WarpPI.INSTANCE.loaded.submit(true);
WarpPI.INSTANCE.device.getDeviceStateDevice().waitForExit();
}
private void loadingFailed(Exception e) {
e.printStackTrace();
}
}

View File

@ -1,81 +1,77 @@
package it.cavallium.warppi.boot;
import java.util.Arrays;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.Engine.LoadingStatus;
package it.cavallium.warppi.boot;
import java.util.Arrays;
import java.util.concurrent.Future;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.Platform;
import it.cavallium.warppi.device.PIHardwareDisplay;
import it.cavallium.warppi.device.PIHardwareTouchDevice;
import it.cavallium.warppi.gui.CalculatorHUD;
import it.cavallium.warppi.gui.screens.LoadingScreen;
import it.cavallium.warppi.math.rules.RulesManager;
import it.cavallium.warppi.util.Error;
public class Boot {
public static void boot(final Platform platform, final String[] args) throws Exception {
Engine.start(platform, new LoadingScreen(), new PIHardwareDisplay(), new PIHardwareTouchDevice(false, false, false), new CalculatorHUD(), Boot.parseStartupArguments(args));
Engine.INSTANCE.getLoadPhase().subscribe(Boot::loadCalculator);
}
private static void loadCalculator(final LoadingStatus loading) {
try {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().setBrightness(0.2f);
RulesManager.initialize();
RulesManager.warmUp();
loading.done();
} catch (InterruptedException | Error e) {
e.printStackTrace();
}
loading.failed();
}
public static StartupArguments parseStartupArguments(final String[] a) {
final StartupArgumentsImpl args = new StartupArgumentsImpl();
Arrays.asList(a).stream().parallel().filter((x) -> x != null).map(String::toLowerCase).forEach(arg -> Boot.parseArgument(args, arg));
return args;
}
public static void parseArgument(final StartupArgumentsImpl args, final String arg) {
switch (arg) {
case "-zoomed":
args.setZoomed(true);
break;
case "-verbose":
args.setVerboseLoggingEnabled(true);
break;
case "-noraspi":
args.setRaspberryModeAllowed(false);
break;
case "nogui":
args.setNoGUIEngineForced(true);
break;
case "ms-dos":
args.setMSDOSModeEnabled(true);
break;
case "html":
args.setHTMLEngineForced(true);
break;
case "gpu":
args.setGPUEngineForced(true);
break;
case "cpu":
args.setCPUEngineForced(true);
break;
case "framebuffer":
args.setFrameBufferEngineForced(true);
break;
case "-debug":
args.setDebugEnabled(true);
break;
case "-uncached":
args.setUncached(true);
break;
default:
// Not using ConsoleUtils because it isn't initialized at this point.
System.out.println("Unrecognized argument " + arg);
break;
}
}
}
import it.cavallium.warppi.gui.CalculatorHUD;
import it.cavallium.warppi.gui.screens.LoadingScreen;
import it.cavallium.warppi.math.rules.RulesManager;
public class Boot {
public static void boot(final Platform platform, final String[] args) throws Exception {
WarpPI.start(
platform,
new LoadingScreen(),
new CalculatorHUD(),
Boot.parseStartupArguments(args),
Boot::loadCalculator);
}
private static void loadCalculator() throws Exception {
WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().setBrightness(0.2f);
//TODO: plugins system: PluginsManager.initialize();
RulesManager.initialize();
RulesManager.warmUp();
}
public static StartupArguments parseStartupArguments(final String[] a) {
final StartupArgumentsImpl args = new StartupArgumentsImpl();
Arrays.asList(a).stream().parallel().filter((x) -> x != null).map(String::toLowerCase).forEach(arg -> Boot.parseArgument(args, arg));
return args;
}
public static void parseArgument(final StartupArgumentsImpl args, final String arg) {
switch (arg) {
case "-zoomed":
args.setZoomed(true);
break;
case "-verbose":
args.setVerboseLoggingEnabled(true);
break;
case "-noraspi":
args.setRaspberryModeAllowed(false);
break;
case "nogui":
args.setNoGUIEngineForced(true);
break;
case "ms-dos":
args.setMSDOSModeEnabled(true);
break;
case "html":
args.setHTMLEngineForced(true);
break;
case "gpu":
args.setGPUEngineForced(true);
break;
case "cpu":
args.setCPUEngineForced(true);
break;
case "framebuffer":
args.setFrameBufferEngineForced(true);
break;
case "-debug":
args.setDebugEnabled(true);
break;
case "-uncached":
args.setUncached(true);
break;
default:
// Not using ConsoleUtils because it isn't initialized at this point.
System.out.println("Unrecognized argument " + arg);
break;
}
}
}

View File

@ -8,7 +8,7 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.UUID;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
public class CacheFile {
private String path;
@ -22,7 +22,7 @@ public class CacheFile {
path = UUID.randomUUID().toString() + ".ser";
} while (new File(path).exists());
try {
File.createTempFile(Engine.getPlatform().getSettings().getCalculatorNameLowercase(), "");
File.createTempFile(WarpPI.getPlatform().getSettings().getCalculatorNameLowercase(), "");
} catch (final IOException e) {
e.printStackTrace();
}

View File

@ -0,0 +1,38 @@
package it.cavallium.warppi.device;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.device.input.InputManager;
import it.cavallium.warppi.gui.DisplayManager;
public class Device {
private final DisplayManager displayManager;
private final InputManager inputManager;
private final DeviceStateDevice deviceState;
public Device(final DisplayManager m, final InputManager im, final DeviceStateDevice dm) {
displayManager = m;
inputManager = im;
deviceState = dm;
}
public DisplayManager getDisplayManager() {
return displayManager;
}
public InputManager getInputManager() {
return inputManager;
}
public DeviceStateDevice getDeviceStateDevice() {
return deviceState;
}
public void setup() {
displayManager.initialize();
inputManager.initialize();
deviceState.initialize();
inputManager.getTouchDevice().listenTouchEvents(displayManager.getTouchEventListener());
}
}

View File

@ -0,0 +1,12 @@
package it.cavallium.warppi.device;
import java.util.concurrent.Future;
public interface DeviceStateDevice {
void initialize();
void waitForExit();
void powerOff();
}

View File

@ -1,32 +0,0 @@
package it.cavallium.warppi.device;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.gui.DisplayManager;
public class HardwareDevice {
private final DisplayManager displayManager;
private final InputManager inputManager;
public HardwareDevice(final DisplayManager m, final InputManager im) {
displayManager = m;
inputManager = im;
}
public DisplayManager getDisplayManager() {
return displayManager;
}
public InputManager getInputManager() {
return inputManager;
}
public void setup(final Runnable r) {
displayManager.initialize();
inputManager.getKeyboard().startKeyboard();
final Thread t = new Thread(r);
Engine.getPlatform().setThreadDaemon(t, false);
Engine.getPlatform().setThreadName(t, "Main thread (after setup)");
t.start();
}
}

View File

@ -1,21 +0,0 @@
package it.cavallium.warppi.device;
import it.cavallium.warppi.event.TouchEventListener;
import it.cavallium.warppi.event.TouchPoint;
public interface HardwareTouchDevice extends TouchEventListener {
boolean getInvertedXY();
boolean getInvertedX();
boolean getInvertedY();
default void setInvertedXY() {}
default void setInvertedX() {}
default void setInvertedY() {}
TouchPoint makePoint(long id, float x, float y, int maxX, int maxY, float radiusX, float radiusY, float force,
float rotationAngle);
}

View File

@ -1,20 +0,0 @@
package it.cavallium.warppi.device;
public class InputManager {
private final Keyboard keyboard;
private final HardwareTouchDevice touchDevice;
public InputManager(final Keyboard k, final HardwareTouchDevice t) {
keyboard = k;
touchDevice = t;
}
public Keyboard getKeyboard() {
return keyboard;
}
public HardwareTouchDevice getTouchDevice() {
return touchDevice;
}
}

View File

@ -1,24 +0,0 @@
package it.cavallium.warppi.device;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.gui.HardwareDisplay;
public class PIHardwareDisplay implements HardwareDisplay {
@Override
public void initialize() {}
@Override
public void shutdown() {}
@Override
public void setBrightness(final double value) {
if (Engine.getPlatform().isRunningOnRaspberry()) {
Engine.getPlatform().getGpio().pwmWrite(12, (int) Math.ceil(value * 1024f));
// SoftPwm.softPwmWrite(12, (int)(Math.ceil(brightness*10)));
} else {
Engine.getPlatform().getConsoleUtils().out().println(1, "Brightness: " + value);
}
}
}

View File

@ -1,113 +0,0 @@
package it.cavallium.warppi.device;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.event.TouchCancelEvent;
import it.cavallium.warppi.event.TouchEndEvent;
import it.cavallium.warppi.event.TouchMoveEvent;
import it.cavallium.warppi.event.TouchPoint;
import it.cavallium.warppi.event.TouchStartEvent;
import it.cavallium.warppi.gui.screens.Screen;
public class PIHardwareTouchDevice implements HardwareTouchDevice {
private final boolean invertXY, invertX, invertY;
public PIHardwareTouchDevice(final boolean invertXY, final boolean invertX, final boolean invertY) {
this.invertXY = invertXY;
this.invertX = invertX;
this.invertY = invertY;
}
@Override
public boolean onTouchStart(final TouchStartEvent e) {
final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen();
boolean refresh = false;
if (scr != null && scr.initialized && scr.onTouchStart(e)) {
refresh = true;
} else {
//Default behavior
}
if (refresh) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().forceRefresh = true;
}
return true;
}
@Override
public boolean onTouchEnd(final TouchEndEvent e) {
final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen();
boolean refresh = false;
if (scr != null && scr.initialized && scr.onTouchEnd(e)) {
refresh = true;
} else {
//Default behavior
}
if (refresh) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().forceRefresh = true;
}
return true;
}
@Override
public boolean onTouchCancel(final TouchCancelEvent e) {
final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen();
boolean refresh = false;
if (scr != null && scr.initialized && scr.onTouchCancel(e)) {
refresh = true;
} else {
//Default behavior
}
if (refresh) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().forceRefresh = true;
}
return true;
}
@Override
public boolean onTouchMove(final TouchMoveEvent e) {
final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen();
boolean refresh = false;
if (scr != null && scr.initialized && scr.onTouchMove(e)) {
refresh = true;
} else {
//Default behavior
}
if (refresh) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().forceRefresh = true;
}
return true;
}
@Override
public boolean getInvertedXY() {
return invertXY;
}
@Override
public boolean getInvertedX() {
return invertX;
}
@Override
public boolean getInvertedY() {
return invertY;
}
@Override
public TouchPoint makePoint(final long id, float x, float y, final int screenWidth, final int screenHeight,
final float radiusX, final float radiusY, final float force, final float rotationAngle) {
if (getInvertedXY()) {
final double oldX = x;
final double oldY = y;
x = (float) (oldY * screenWidth / screenHeight);
y = (float) (oldX * screenHeight / screenWidth);
}
if (getInvertedX()) {
x = screenWidth - x;
}
if (getInvertedY()) {
y = screenHeight - y;
}
return new TouchPoint(id, x, y, radiusX, radiusY, force, rotationAngle);
}
}

View File

@ -1,6 +1,6 @@
package it.cavallium.warppi.device.chip;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
public class ParallelToSerial {
@ -18,16 +18,16 @@ public class ParallelToSerial {
public boolean[] read() {
final boolean[] data = new boolean[8];
Engine.getPlatform().getGpio().digitalWrite(CLK_INH, Engine.getPlatform().getGpio().valueHigh());
Engine.getPlatform().getGpio().digitalWrite(SH_LD, Engine.getPlatform().getGpio().valueLow());
Engine.getPlatform().getGpio().delayMicroseconds(1);
Engine.getPlatform().getGpio().digitalWrite(SH_LD, Engine.getPlatform().getGpio().valueHigh());
Engine.getPlatform().getGpio().digitalWrite(CLK_INH, Engine.getPlatform().getGpio().valueLow());
WarpPI.getPlatform().getGpio().digitalWrite(CLK_INH, WarpPI.getPlatform().getGpio().valueHigh());
WarpPI.getPlatform().getGpio().digitalWrite(SH_LD, WarpPI.getPlatform().getGpio().valueLow());
WarpPI.getPlatform().getGpio().delayMicroseconds(1);
WarpPI.getPlatform().getGpio().digitalWrite(SH_LD, WarpPI.getPlatform().getGpio().valueHigh());
WarpPI.getPlatform().getGpio().digitalWrite(CLK_INH, WarpPI.getPlatform().getGpio().valueLow());
for (int i = 7; i >= 0; i--) {
Engine.getPlatform().getGpio().digitalWrite(CLK, Engine.getPlatform().getGpio().valueHigh());
Engine.getPlatform().getGpio().digitalWrite(CLK, Engine.getPlatform().getGpio().valueLow());
data[i] = Engine.getPlatform().getGpio().digitalRead(QH) == Engine.getPlatform().getGpio().valueHigh() ? true : false;
WarpPI.getPlatform().getGpio().digitalWrite(CLK, WarpPI.getPlatform().getGpio().valueHigh());
WarpPI.getPlatform().getGpio().digitalWrite(CLK, WarpPI.getPlatform().getGpio().valueLow());
data[i] = WarpPI.getPlatform().getGpio().digitalRead(QH) == WarpPI.getPlatform().getGpio().valueHigh() ? true : false;
}
return data;

View File

@ -1,6 +1,6 @@
package it.cavallium.warppi.device.chip;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
public class SerialToParallel {
private final int RCK; //Storage register clock pin (latch pin)
@ -17,15 +17,15 @@ public class SerialToParallel {
if (data.length != 8) {
return;
} else {
Engine.getPlatform().getGpio().digitalWrite(RCK, Engine.getPlatform().getGpio().valueLow());
WarpPI.getPlatform().getGpio().digitalWrite(RCK, WarpPI.getPlatform().getGpio().valueLow());
for (int i = 7; i >= 0; i--) {
Engine.getPlatform().getGpio().digitalWrite(SCK, Engine.getPlatform().getGpio().valueLow());
Engine.getPlatform().getGpio().digitalWrite(SER, data[i]);
Engine.getPlatform().getGpio().digitalWrite(SCK, Engine.getPlatform().getGpio().valueHigh());
WarpPI.getPlatform().getGpio().digitalWrite(SCK, WarpPI.getPlatform().getGpio().valueLow());
WarpPI.getPlatform().getGpio().digitalWrite(SER, data[i]);
WarpPI.getPlatform().getGpio().digitalWrite(SCK, WarpPI.getPlatform().getGpio().valueHigh());
}
Engine.getPlatform().getGpio().digitalWrite(RCK, Engine.getPlatform().getGpio().valueHigh());
WarpPI.getPlatform().getGpio().digitalWrite(RCK, WarpPI.getPlatform().getGpio().valueHigh());
}
}
}

View File

@ -0,0 +1,16 @@
package it.cavallium.warppi.device.display;
public interface BacklightOutputDevice {
/**
* Set the brightness level
* @param value Value from 0.0 to 1.0
*/
void setBrightness(double value);
/**
* Turn on or off the backlight
* @param value true is ON, false is OFF
*/
void setPower(boolean value);
}

View File

@ -0,0 +1,8 @@
package it.cavallium.warppi.device.display;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
public interface DisplayOutputDevice {
public GraphicEngine getGraphicEngine();
public int[] getDisplaySize();
}

View File

@ -0,0 +1,7 @@
package it.cavallium.warppi.device.display;
public class NoDisplaysAvailableException extends RuntimeException {
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,18 @@
package it.cavallium.warppi.device.display;
public class NullBacklightOutputDevice implements BacklightOutputDevice {
private double brightness;
private boolean power;
@Override
public void setBrightness(double value) {
this.brightness = value;
}
@Override
public void setPower(boolean value) {
this.power = value;
}
}

View File

@ -1,4 +1,4 @@
package it.cavallium.warppi.device.graphicengine;
package it.cavallium.warppi.device.display;
import java.io.File;
import java.io.IOException;
@ -7,7 +7,7 @@ import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.util.ClassUtils;
import it.cavallium.warppi.util.Utils;
@ -32,7 +32,7 @@ public class RAWFont {
loadFont("/font_" + name + ".rft");
} catch (final IOException e) {
e.printStackTrace();
Engine.getPlatform().exit(1);
WarpPI.getPlatform().exit(1);
}
chars32 = new int[(maxBound - minBound) * charIntCount];
for (int charIndex = 0; charIndex < maxBound - minBound; charIndex++) {
@ -110,7 +110,7 @@ public class RAWFont {
} catch (final Exception ex) {
ex.printStackTrace();
System.out.println(string);
Engine.getPlatform().exit(-1);
WarpPI.getPlatform().exit(-1);
}
}
} else {

View File

@ -0,0 +1,5 @@
package it.cavallium.warppi.device.input;
public interface HardwareKeyboardDevice {
}

View File

@ -0,0 +1,27 @@
package it.cavallium.warppi.device.input;
import java.util.Objects;
public class InputManager {
private final KeyboardInputDevice keyboard;
private final TouchInputDevice touchDevice;
public InputManager(KeyboardInputDevice keyboard, TouchInputDevice touchscreen) {
this.keyboard = Objects.requireNonNull(keyboard);
this.touchDevice = Objects.requireNonNull(touchscreen);
}
public KeyboardInputDevice getKeyboard() {
return keyboard;
}
public TouchInputDevice getTouchDevice() {
return touchDevice;
}
public void initialize() {
this.keyboard.initialize();
this.touchDevice.initialize();
}
}

View File

@ -1,4 +1,4 @@
package it.cavallium.warppi.device;
package it.cavallium.warppi.device.input;
public interface KeyboardAWTValues {

View File

@ -0,0 +1,7 @@
package it.cavallium.warppi.device.input;
public interface KeyboardInputDevice {
void initialize();
}

View File

@ -1,4 +1,4 @@
package it.cavallium.warppi.device;
package it.cavallium.warppi.device.input;
public interface KeyboardJogampValues {

View File

@ -0,0 +1,41 @@
package it.cavallium.warppi.device.input;
import java.util.function.Consumer;
import it.cavallium.warppi.event.TouchEvent;
import it.cavallium.warppi.event.TouchPoint;
public class NullTouchInputDevice implements TouchInputDevice {
@Override
public boolean getSwappedAxes() {
return false;
}
@Override
public boolean getInvertedX() {
return false;
}
@Override
public boolean getInvertedY() {
return false;
}
@Override
public void listenTouchEvents(Consumer<TouchEvent> touchEventListener) {
}
@Override
public void initialize() {
}
@Override
public TouchPoint makePoint(long id, float x, float y, int maxX, int maxY, float radiusX, float radiusY,
float force, float rotationAngle) {
return new TouchPoint(id, maxX, maxY, radiusX, radiusY, force, rotationAngle);
}
}

View File

@ -0,0 +1,43 @@
package it.cavallium.warppi.device.input;
import java.util.concurrent.Flow.Subscriber;
import java.util.function.Consumer;
import it.cavallium.warppi.event.TouchEvent;
import it.cavallium.warppi.event.TouchEventListener;
import it.cavallium.warppi.event.TouchPoint;
public interface TouchInputDevice {
boolean getSwappedAxes();
boolean getInvertedX();
boolean getInvertedY();
default void setInvertedXY() {}
default void setInvertedX() {}
default void setInvertedY() {}
void listenTouchEvents(Consumer<TouchEvent> touchEventListener);
default TouchPoint makePoint(final long id, float x, float y, final int screenWidth, final int screenHeight,
final float radiusX, final float radiusY, final float force, final float rotationAngle) {
if (getSwappedAxes()) {
final double oldX = x;
final double oldY = y;
x = (float) (oldY * screenWidth / screenHeight);
y = (float) (oldX * screenHeight / screenWidth);
}
if (getInvertedX()) {
x = screenWidth - x;
}
if (getInvertedY()) {
y = screenHeight - y;
}
return new TouchPoint(id, x, y, radiusX, radiusY, force, rotationAngle);
}
void initialize();
}

View File

@ -1,14 +1,18 @@
package it.cavallium.warppi.extra.mario;
import java.io.IOException;
import java.nio.file.NoSuchFileException;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.StaticVars;
import it.cavallium.warppi.Platform.ConsoleUtils;
import it.cavallium.warppi.device.Keyboard;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.device.input.Keyboard;
import it.cavallium.warppi.event.KeyPressedEvent;
import it.cavallium.warppi.event.KeyReleasedEvent;
import it.cavallium.warppi.gui.HistoryBehavior;
import it.cavallium.warppi.gui.RenderContext;
import it.cavallium.warppi.gui.ScreenContext;
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
import it.cavallium.warppi.gui.graphicengine.Skin;
import it.cavallium.warppi.gui.screens.Screen;
@ -45,33 +49,72 @@ public class MarioScreen extends Screen {
}
@Override
public void initialized() {
public void graphicInitialized(ScreenContext ctx) {
try {
if (MarioScreen.skin == null) {
MarioScreen.skin = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("/marioskin.png");
MarioScreen.skin = d.display.getGraphicEngine().loadSkin("/marioskin.png");
}
if (MarioScreen.groundskin == null) {
MarioScreen.groundskin = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("/marioground.png");
MarioScreen.groundskin = d.display.getGraphicEngine().loadSkin("/marioground.png");
}
if (MarioScreen.gpuTest2 == null) {
try {
MarioScreen.gpuTest2 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("N:\\gputest\\gputest2");
MarioScreen.gpuTest2 = d.display.getGraphicEngine().loadFont("N:\\gputest", "gputest2");
} catch (final Exception ex) {}
}
if (MarioScreen.gpuTest1 == null) {
try {
MarioScreen.gpuTest1 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("N:\\gputest\\gputest12");
MarioScreen.gpuTest1 = d.display.getGraphicEngine().loadFont("N:\\gputest", "gputest12");
MarioScreen.gpuTest12 = true;
} catch (final Exception ex) {
MarioScreen.gpuTest12 = false;
try {
MarioScreen.gpuTest1 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("N:\\gputest\\gputest1");
MarioScreen.gpuTest1 = d.display.getGraphicEngine().loadFont("N:\\gputest", "gputest1");
} catch (final Exception ex2) {}
}
}
if (MarioScreen.gpuTest3 == null) {
try {
MarioScreen.gpuTest3 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("N:\\gputest\\font_gputest3.png");
MarioScreen.gpuTest3 = d.display.getGraphicEngine().loadSkin("N:\\gputest\\font_gputest3.png");
} catch (final NoSuchFileException ignored) {
} catch (final Exception ex) {
ex.printStackTrace();
}
}
} catch (final IOException e) {
e.printStackTrace();
}
}
@Override
public void initialized() {
try {
if (MarioScreen.skin == null) {
MarioScreen.skin = d.display.getGraphicEngine().loadSkin("/marioskin.png");
}
if (MarioScreen.groundskin == null) {
MarioScreen.groundskin = d.display.getGraphicEngine().loadSkin("/marioground.png");
}
if (MarioScreen.gpuTest2 == null) {
try {
MarioScreen.gpuTest2 = d.display.getGraphicEngine().loadFont("N:\\gputest\\gputest2");
} catch (final Exception ex) {}
}
if (MarioScreen.gpuTest1 == null) {
try {
MarioScreen.gpuTest1 = d.display.getGraphicEngine().loadFont("N:\\gputest\\gputest12");
MarioScreen.gpuTest12 = true;
} catch (final Exception ex) {
MarioScreen.gpuTest12 = false;
try {
MarioScreen.gpuTest1 = d.display.getGraphicEngine().loadFont("N:\\gputest\\gputest1");
} catch (final Exception ex2) {}
}
}
if (MarioScreen.gpuTest3 == null) {
try {
MarioScreen.gpuTest3 = d.display.getGraphicEngine().loadSkin("N:\\gputest\\font_gputest3.png");
} catch (final NoSuchFileException ignored) {
} catch (final Exception ex) {
ex.printStackTrace();
}
@ -129,7 +172,7 @@ public class MarioScreen extends Screen {
}
@Override
public void beforeRender(final float dt) {
public void beforeRender(ScreenContext ctx, final float dt) {
if (!errored) {
final boolean upPressed = false, downPressed = false, runPressed = false;
g.gameTick(dt, upPressed, downPressed, leftPressed, rightPressed, jumpPressed, runPressed);
@ -145,89 +188,90 @@ public class MarioScreen extends Screen {
gpuCharTestt1Elapsed -= 1.5;
}
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glClearColor(0xff000000);
d.renderer.glClearColor(0xff000000);
}
}
@Override
public void render() {
public void render(RenderContext ctx) {
DisplayOutputDevice display = d.display;
if (errored) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringLeft(0, 20, "ERROR");
d.renderer.glDrawStringLeft(0, 20, "ERROR");
} else {
if (MarioScreen.groundskin != null) {
final double playerX = g.getPlayer().getX();
final double playerY = g.getPlayer().getY();
MarioScreen.groundskin.use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
MarioScreen.groundskin.use(d.display);
final MarioWorld w = g.getCurrentWorld();
final int width = w.getWidth();
final int height = w.getHeight();
final float screenX = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getWidth() / 2f - 8f;
final float screenY = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() / 2f - 8f;
final float screenX = ctx.getWidth() / 2f - 8f;
final float screenY = ctx.getHeight() / 2f - 8f;
final float shiftX = -8 + 16 * (float) playerX;
final float shiftY = -8 + 16 * (height - (float) playerY);
int blue = -1;
for (int ix = 0; ix < width; ix++) {
for (int iy = 0; iy < height; iy++) {
final double distX = Math.abs(playerX - ix);
final double distY = Math.abs(playerY - iy - 1.5d);
if (distX * distX + distY * distY / 2d < 25d) {
final double distY = Math.abs(playerY - iy - 1.2d);
if (distX * distX + distY * distY / 2d < 270d) {
final byte b = w.getBlockIdAt(ix, iy);
if (b == 0) {
if (blue != 1) {
blue = 1;
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xff9290ff);
d.renderer.glColor(0xff9290ff);
}
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillColor(screenX - shiftX + 16 * ix, screenY - shiftY + 16 * (height - iy), 16, 16);
d.renderer.glFillColor(screenX - shiftX + 16 * ix, screenY - shiftY + 16 * (height - iy), 16, 16);
} else {
if (blue != 0) {
blue = 0;
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xffffffff);
d.renderer.glColor(0xffffffff);
}
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillRect(screenX - shiftX + 16 * ix, screenY - shiftY + 16 * (height - iy), 16, 16, 0, 0, 16, 16);
d.renderer.glFillRect(screenX - shiftX + 16 * ix, screenY - shiftY + 16 * (height - iy), 16, 16, 0, 0, 16, 16);
}
}
}
}
if (blue != 0) {
blue = 0;
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xffffffff);
d.renderer.glColor(0xffffffff);
}
//DRAW MARIO
MarioScreen.skin.use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillRect(screenX - (g.getPlayer().flipped ? 3 : 0), screenY, 35, 27, 35 * (g.getPlayer().marioSkinPos[0] + (g.getPlayer().flipped ? 2 : 1)), 27 * g.getPlayer().marioSkinPos[1], 35 * (g.getPlayer().flipped ? -1 : 1), 27);
MarioScreen.skin.use(d.display);
d.renderer.glFillRect(screenX - (g.getPlayer().flipped ? 3 : 0), screenY, 35, 27, 35 * (g.getPlayer().marioSkinPos[0] + (g.getPlayer().flipped ? 2 : 1)), 27 * g.getPlayer().marioSkinPos[1], 35 * (g.getPlayer().flipped ? -1 : 1), 27);
// PIDisplay.renderer.glDrawSkin(getPosX() - 18, 25 + getPosY(), 35 * (marioSkinPos[0] + (flipped ? 2 : 1)), 27 * marioSkinPos[1], 35 * (marioSkinPos[0] + (flipped ? 1 : 2)), 27 * (marioSkinPos[1] + 1), true);
}
// GPU PERFORMANCE TEST
if (MarioScreen.gpuTest1 != null) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor3f(1, 1, 1);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillColor(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getWidth() - (MarioScreen.gpuTest12 ? 512 : 256), Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() / 2 - (MarioScreen.gpuTest12 ? 256 : 128), MarioScreen.gpuTest12 ? 512 : 256, MarioScreen.gpuTest12 ? 512 : 256);
MarioScreen.gpuTest1.use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor3f(0, 0, 0);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getWidth(), Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() / 2 - (MarioScreen.gpuTest12 ? 256 : 128), gpuCharTest1[gpuCharTest1Num]);
d.renderer.glColor3f(1, 1, 1);
d.renderer.glFillColor(ctx.getWidth() - (MarioScreen.gpuTest12 ? 512 : 256), ctx.getHeight() / 2 - (MarioScreen.gpuTest12 ? 256 : 128), MarioScreen.gpuTest12 ? 512 : 256, MarioScreen.gpuTest12 ? 512 : 256);
MarioScreen.gpuTest1.use(d.display);
d.renderer.glColor3f(0, 0, 0);
d.renderer.glDrawStringRight(ctx.getWidth(), ctx.getHeight() / 2 - (MarioScreen.gpuTest12 ? 256 : 128), gpuCharTest1[gpuCharTest1Num]);
}
if (MarioScreen.gpuTest3 != null) {
MarioScreen.gpuTest3.use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor4f(1, 1, 1, 0.7f);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillRect(0, StaticVars.screenSize[1] - 128, 224, 128, gpuTestNum * 224, 0, 224, 128);
MarioScreen.gpuTest3.use(d.display);
d.renderer.glColor4f(1, 1, 1, 0.7f);
d.renderer.glFillRect(0, display.getDisplaySize()[1] - 128, 224, 128, gpuTestNum * 224, 0, 224, 128);
}
if (MarioScreen.gpuTest2 != null) {
MarioScreen.gpuTest2.use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFF000000);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "A");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFF800000);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "B");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFFeea28e);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "C");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFFee7255);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "D");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFFeac0b0);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "E");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFFf3d8ce);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "F");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFFffede7);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "G");
MarioScreen.gpuTest2.use(d.display);
d.renderer.glColor(0xFF000000);
d.renderer.glDrawStringRight(display.getDisplaySize()[0], ctx.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "A");
d.renderer.glColor(0xFF800000);
d.renderer.glDrawStringRight(display.getDisplaySize()[0], ctx.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "B");
d.renderer.glColor(0xFFeea28e);
d.renderer.glDrawStringRight(display.getDisplaySize()[0], ctx.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "C");
d.renderer.glColor(0xFFee7255);
d.renderer.glDrawStringRight(display.getDisplaySize()[0], ctx.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "D");
d.renderer.glColor(0xFFeac0b0);
d.renderer.glDrawStringRight(display.getDisplaySize()[0], ctx.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "E");
d.renderer.glColor(0xFFf3d8ce);
d.renderer.glDrawStringRight(display.getDisplaySize()[0], ctx.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "F");
d.renderer.glColor(0xFFffede7);
d.renderer.glDrawStringRight(display.getDisplaySize()[0], ctx.getHeight() - MarioScreen.gpuTest2.getCharacterHeight(), "G");
}
}
}

View File

@ -0,0 +1,38 @@
package it.cavallium.warppi.extra.tetris;
public class ButtonInfo {
public volatile int pressedCount = 0;
public volatile int releasedCount = 0;
public volatile int unreadCount = 0;
public ButtonInfo() {
}
public void press() {
if (pressedCount <= releasedCount) {
pressedCount = releasedCount + 1;
unreadCount++;
}
}
public void release() {
releasedCount++;
pressedCount = releasedCount;
}
public int readPressed() {
int val = unreadCount;
unreadCount = 0;
return val;
}
public boolean hasUnreadData() {
return unreadCount > 0;
}
public boolean isPressedNow() {
return pressedCount > releasedCount;
}
}

View File

@ -1,33 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class MarioBlock {
private final int x;
private final int y;
private final byte id;
public MarioBlock(final int x, final int y, final byte b) {
this.x = x;
this.y = y;
id = b;
}
public boolean isSolid() {
return MarioBlock.isSolid(id);
}
public byte getID() {
return id;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public static boolean isSolid(final byte id) {
return id != 0b0;
}
}

View File

@ -1,9 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class MarioEnemy extends MarioEntity {
public MarioEnemy(final double x, final double y, final double forceX, final double forceY, final boolean onGround, final boolean subjectToGravity) {
super(x, y, forceX, forceY, onGround, subjectToGravity);
}
}

View File

@ -1,85 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class MarioEntity {
protected double x;
protected double y;
public double forceX;
public double forceY;
public boolean collisionUp;
public boolean collisionDown;
public boolean collisionLeft;
public boolean collisionRight;
public boolean subjectToGravity;
public MarioEntity(final double x, final double y, final double forceX, final double forceY, final boolean onGround, final boolean subjectToGravity) {
this.x = x;
this.y = y;
this.forceX = forceX;
this.forceY = forceY;
collisionDown = onGround;
this.subjectToGravity = subjectToGravity;
}
public void setPosition(final double x, final double y) {
this.x = x;
this.y = y;
}
public void setPosition(final double x, final double y, final boolean onGround) {
this.x = x;
this.y = y;
collisionDown = onGround;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public boolean isOnGround() {
return collisionDown;
}
public void setOnGround(final boolean onGround) {
collisionDown = onGround;
}
public void gameTick(final double dt) {
x = computeFutureDX(dt);
y = computeFutureDY(dt);
forceX = computeFutureForceDX(dt);
forceY = computeFutureForceDY(dt);
}
public double computeFutureDX(final double dt) {
return x + dt * forceX - x;
}
public double computeFutureDY(final double dt) {
final double forceY = this.forceY;
double y = this.y;
if (!collisionDown) {
y += dt * forceY;
}
return y - this.y;
}
public double computeFutureForceDX(final double dt) {
double forceX = this.forceX;
forceX *= 0.75;
return forceX - this.forceX;
}
public double computeFutureForceDY(final double dt) {
double forceY = this.forceY;
if (subjectToGravity && !collisionDown) {
forceY -= dt * 1569.6 / 16f;
} else {
forceY *= 0.75;
}
return forceY - this.forceY;
}
}

View File

@ -1,5 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class MarioEvent {
}

View File

@ -1,69 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class MarioWorld {
private final int[] spawnPoint;
private final int width;
private final int height;
private final byte[][] data;
@SuppressWarnings("unused")
private final MarioEvent[] events;
private final MarioEntity[] entities;
/**
* @param width
* @param height
* @param data
* @param events
* @param marioEnemies
*/
public MarioWorld(final int[] spawnPoint, final int width, final int height, final byte[][] data, final MarioEvent[] events, final MarioEntity[] entities) {
this.spawnPoint = spawnPoint;
this.width = width;
this.height = height;
this.data = data;
this.events = events;
this.entities = entities;
}
public byte getBlockIdAt(final int x, final int y) {
final int idy = height - 1 - y;
if (idy < 0 || idy >= data.length) {
return 0b0;
}
final int idx = x;
if (idx < 0 || idx >= data[0].length) {
return 0b0;
}
return data[idy][idx];
}
public MarioBlock getBlockAt(final int x, final int y) {
return new MarioBlock(x, y, getBlockIdAt(x, y));
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public void reset() {
}
public double getSpawnPointX() {
return spawnPoint[0];
}
public double getSpawnPointY() {
return spawnPoint[1];
}
public MarioEntity[] getEntities() {
return entities;
}
}

View File

@ -1,138 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class PlayerEntity extends MarioEntity {
@SuppressWarnings("unused")
private final int life;
public float walkAnimation = 0;
public float jumptime = 0;
public boolean walking = false;
public boolean running = false;
public boolean jumping = false;
public boolean flipped = false;
public int[] marioSkinPos = new int[] { 0, 0 };
private double controllerDX;
private double controllerDY;
public PlayerEntity(final double x, final double y, final int life) {
super(x, y, 0, 0, true, true);
this.life = life;
}
@Override
public void gameTick(final double dt) {
walkAnimation += dt;
x += computeFutureDX(dt);
y += computeFutureDY(dt);
forceX += computeFutureForceDX(dt);
forceY += computeFutureForceDY(dt);
if (controllerDX == 0) {
walking = false;
walkAnimation = 0;
} else {
if (controllerDX > 0) { //RIGHT
walking = true;
flipped = false;
}
if (controllerDX < 0) { //LEFT
walking = true;
flipped = true;
}
}
if (controllerDY > 0) { //JUMP
if (collisionUp) {
jumptime = Float.MAX_VALUE;
jumping = false;
}
jumptime += dt;
if (jumptime <= 0.5f && !jumping && collisionDown) {
jumping = true;
collisionDown = false;
} else if (jumptime <= 0.5f) {} else {
jumping = false;
}
} else {
jumping = false;
if (collisionDown) {
jumptime = 0;
} else {
jumptime = Float.MAX_VALUE;
}
}
if (!walking & !running & !jumping) {
marioSkinPos[0] = 0;
marioSkinPos[1] = 0;
} else if (collisionDown & walking & !running & !jumping && walkAnimation >= 0.08) {
while (walkAnimation > 0.08) {
walkAnimation -= 0.08;
if (marioSkinPos[0] == 1 & marioSkinPos[1] == 0) {
marioSkinPos[0] += 2;
} else if (marioSkinPos[0] == 3 & marioSkinPos[1] == 0) {
marioSkinPos[0] -= 1;
} else if (marioSkinPos[0] == 2 & marioSkinPos[1] == 0) {
marioSkinPos[0] -= 1;
} else {
marioSkinPos[0] = 1;
marioSkinPos[1] = 0;
}
}
} else if (jumping) {
marioSkinPos[0] = 5;
marioSkinPos[1] = 1;
}
}
@Override
public double computeFutureDX(final double dt) {
return super.computeFutureDX(dt);
}
public double computeFuturedDY(final double dt) {
return super.computeFutureDY(dt);
}
@Override
public double computeFutureForceDX(final double dt) {
double forceX = this.forceX;
if (controllerDX == 0) {} else {
if (controllerDX > 0) {
if (forceX < 500f / 16f) {
forceX += dt * 500f / 16f;
}
}
if (controllerDX < 0) {
if (forceX > -500f / 16f) {
forceX -= dt * 500f / 16f;
}
}
}
return forceX + super.computeFutureForceDX(dt) - this.forceX;
}
@Override
public double computeFutureForceDY(final double dt) {
float jumptime = this.jumptime;
double forceY = this.forceY;
if (controllerDY > 0) { //JUMP
if (collisionUp) {
jumptime = Float.MAX_VALUE;
}
jumptime += dt;
if (jumptime <= 0.5f && !jumping && collisionDown) {
forceY = dt * (4 * 1569.6f) / 16f;
} else if (jumptime <= 0.5f) {
forceY = dt * (4 * 1569.6f) / 16f;
}
}
return forceY + super.computeFutureForceDY(dt) - this.forceY;
}
public void move(final float dt, final double dX, final double dY) {
walkAnimation += dt;
controllerDX = dX;
controllerDY = dY;
}
}

View File

@ -1,5 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class PositionEvent extends MarioEvent {
}

View File

@ -5,17 +5,17 @@ import java.util.Arrays;
public class TetrisGame {
public static final int WIDTH = 10, HEIGHT = 22;
public static final double TICK_TIME = 0.25;
public static final double TICK_TIME = 0.25, DOWN_TIME = 0.10, MOVE_TIMER = 0.125;
private double tickTimer, downTimer, leftTimer, rightTimer, upTimer;
private BlockColor[] grid;
private BlockColor[] hovergrid;
private volatile BlockColor[] renderedGrid;
private GameStatus gameStatus;
private int score;
private double currentTime;
private double tickTimer;
private Tetromino currentTetromino;
private Tetromino nextTetromino;
public TetrisGame() {
resetVariables();
}
@ -25,7 +25,7 @@ public class TetrisGame {
gameStatus = GameStatus.PLAYING;
placeNextTetromino();
}
private void resetVariables() {
grid = new BlockColor[WIDTH * HEIGHT];
hovergrid = new BlockColor[WIDTH * HEIGHT];
@ -39,9 +39,62 @@ public class TetrisGame {
nextTetromino.fixInitialPosition();
}
public void update(float dt, boolean leftPressed, boolean rightPressed, boolean downPressed, boolean okPressed, boolean backPressed) {
public void update(float dt, ButtonInfo leftPressed, ButtonInfo rightPressed, ButtonInfo downPressed,
ButtonInfo upPressed, ButtonInfo okPressed, ButtonInfo backPressed) {
currentTime += dt;
tickTimer += dt;
leftTimer += dt;
rightTimer += dt;
downTimer += dt;
upTimer += dt;
if (leftPressed.hasUnreadData()) {
for (int i = leftPressed.readPressed(); i > 0; i--) {
move(this.currentTetromino, -1, 0, 0);
}
leftTimer = -MOVE_TIMER;
} else if (leftPressed.isPressedNow()) {
while (leftTimer >= MOVE_TIMER) {
leftTimer -= MOVE_TIMER;
move(this.currentTetromino, -1, 0, 0);
}
} else {
leftTimer = 0;
}
if (rightPressed.hasUnreadData()) {
for (int i = rightPressed.readPressed(); i > 0; i--) {
move(this.currentTetromino, 1, 0, 0);
}
rightTimer = -MOVE_TIMER;
} else if (rightPressed.isPressedNow()) {
while (rightTimer >= MOVE_TIMER) {
rightTimer -= MOVE_TIMER;
move(this.currentTetromino, 1, 0, 0);
}
} else {
rightTimer = 0;
}
if (upPressed.hasUnreadData()) {
for (int i = upPressed.readPressed(); i > 0; i--) {
move(this.currentTetromino, 0, 0, 1);
}
upTimer = -MOVE_TIMER;
} else if (upPressed.isPressedNow()) {
while (upTimer >= MOVE_TIMER) {
upTimer -= MOVE_TIMER;
move(this.currentTetromino, 0, 0, 1);
}
} else {
upTimer = 0;
}
if (downPressed.isPressedNow()) {
downPressed.readPressed();
while (downTimer >= DOWN_TIME) {
downTimer -= DOWN_TIME;
move(this.currentTetromino, 0, 1, 0);
}
} else {
downTimer = 0;
}
while (tickTimer >= TICK_TIME) {
tickTimer -= TICK_TIME;
gameTick(leftPressed, rightPressed, downPressed, okPressed, backPressed);
@ -49,35 +102,102 @@ public class TetrisGame {
if (gameStatus == GameStatus.INITIAL) {
playAgain();
} else {
}
renderGrid();
}
public void gameTick(boolean leftPressed, boolean rightPressed, boolean downPressed, boolean okPressed, boolean backPressed) {
this.currentTetromino.setY((byte) (this.currentTetromino.getY() - 1));
public void gameTick(ButtonInfo leftPressed, ButtonInfo rightPressed, ButtonInfo downPressed, ButtonInfo okPressed,
ButtonInfo backPressed) {
if (move(this.currentTetromino, 0, 1, 0)) {
} else {
// Spawn new tetromino and write the old to the permanent grid
drawCurrentTetromino(grid);
checkLines();
placeNextTetromino();
if (move(this.currentTetromino, 0, 0, 0) == false) {
// Lose
this.gameStatus = GameStatus.LOST;
playAgain();
}
}
}
private void checkLines() {
for (int i = HEIGHT - 1; i >= 0; i--) {
boolean scored = true;
while (scored) {
for (int x = 0; x < WIDTH; x++) {
if (this.grid[x + i * WIDTH] == null) {
scored = false;
break;
}
}
if (scored) {
this.score += WIDTH;
for (int x = 0; x < WIDTH; x++) {
int y = i;
while (y > 0) {
this.grid[x + (y) * WIDTH] = this.grid[x + (y - 1) * WIDTH];
y--;
}
}
}
}
}
}
private boolean move(Tetromino t, int dX, int dY, int dRotation) {
byte rot = (byte) ((t.getRotation() + dRotation) % 4);
boolean[] block = t.getRenderedBlock(rot);
int blockSize = t.getTetrominoGridSize();
int half1 = (int) Math.floor(((double) t.getTetrominoGridSize()) / 2d);
int half2 = blockSize - half1;
byte aX = (byte) (t.getX() + dX), aY = (byte) (t.getY() + dY);
int blockX = 0, blockY = 0;
for (int x = aX - half1; x < aX + half2; x++) {
for (int y = aY - half1; y < aY + half2; y++) {
if (block[blockX + blockY * blockSize] == true) {
if (x >= 0 & y >= 0 & x < WIDTH & (x + y * WIDTH) < this.grid.length) {
if (this.grid[x + y * WIDTH] != null) {
return false;
}
} else {
return false;
}
}
blockY++;
}
blockY = 0;
blockX++;
}
t.setRotation(rot);
t.setX(aX);
t.setY(aY);
return true;
}
public void renderGrid() {
this.renderedGrid = Arrays.copyOf(grid, grid.length);
drawCurrentTetromino(this.renderedGrid);
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
final int offset = x+y*WIDTH;
final int offset = x + y * WIDTH;
renderedGrid[offset] = hovergrid[offset] != null ? hovergrid[offset] : renderedGrid[offset];
}
}
}
private void placeNextTetromino() {
currentTetromino = nextTetromino;
nextTetromino = generateRandomTetromino();
nextTetromino.fixInitialPosition();
}
private Tetromino generateRandomTetromino() {
int s = (int) (Math.random() * 7);
final byte middleX = (byte)((WIDTH - 1)/2), middleY = (byte)(HEIGHT - 1), rotation = (byte) (Math.random() * 4);
final byte middleX = (byte) ((WIDTH - 1) / 2), middleY = 0, rotation = (byte) (Math.random() * 4);
switch (s) {
case 0:
return new TetrominoICyan(middleX, middleY, rotation);
@ -96,6 +216,10 @@ public class TetrisGame {
}
}
public Tetromino getNextTetromino() {
return this.nextTetromino;
}
private void drawCurrentTetromino(BlockColor[] grid) {
currentTetromino.draw(grid, WIDTH);
}
@ -103,4 +227,8 @@ public class TetrisGame {
public BlockColor[] getRenderedGrid() {
return renderedGrid;
}
public int getScore() {
return this.score;
}
}

View File

@ -2,14 +2,16 @@ package it.cavallium.warppi.extra.tetris;
import java.io.IOException;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.device.input.Keyboard;
import it.cavallium.warppi.StaticVars;
import it.cavallium.warppi.device.Keyboard;
import it.cavallium.warppi.event.KeyPressedEvent;
import it.cavallium.warppi.event.KeyReleasedEvent;
import it.cavallium.warppi.gui.HistoryBehavior;
import it.cavallium.warppi.gui.RenderContext;
import it.cavallium.warppi.gui.ScreenContext;
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.gui.graphicengine.Skin;
import it.cavallium.warppi.gui.screens.Screen;
@ -18,17 +20,19 @@ public class TetrisScreen extends Screen {
private TetrisGame g;
private boolean leftPressed;
private ButtonInfo leftPressed = new ButtonInfo();
private boolean rightPressed;
private ButtonInfo rightPressed = new ButtonInfo();
private boolean downPressed;
private ButtonInfo upPressed = new ButtonInfo();
private boolean okPressed;
private ButtonInfo downPressed = new ButtonInfo();
private boolean backPressed;
private ButtonInfo okPressed = new ButtonInfo();
private GraphicEngine e;
private ButtonInfo backPressed = new ButtonInfo();
private DisplayOutputDevice e;
private Renderer r;
@ -41,13 +45,16 @@ public class TetrisScreen extends Screen {
@Override
public void initialized() {
}
@Override
public void graphicInitialized(ScreenContext ctx) {
try {
e = d.engine;
e = d.display;
r = d.renderer;
if (TetrisScreen.skin == null) {
TetrisScreen.skin = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("/tetrisskin.png");
TetrisScreen.skin = d.display.getGraphicEngine().loadSkin("/tetrisskin.png");
}
StaticVars.windowZoom.onNext(2f);
} catch (final IOException e) {
e.printStackTrace();
}
@ -59,56 +66,86 @@ public class TetrisScreen extends Screen {
}
@Override
public void beforeRender(final float dt) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glClearColor(0xff000000);
g.update(dt, leftPressed, rightPressed, downPressed, okPressed, backPressed);
public void beforeRender(ScreenContext ctx, final float dt) {
d.renderer.glClearColor(0xff000000);
g.update(dt, leftPressed, rightPressed, downPressed, upPressed, okPressed, backPressed);
}
@Override
public void render() {
public void render(RenderContext ctx) {
DisplayOutputDevice display = d.display;
if (TetrisScreen.skin != null) {
TetrisScreen.skin.use(e);
}
r.glColor3f(1, 1, 1);
BlockColor[] renderedGrid = g.getRenderedGrid();
int centerScreen = StaticVars.screenSize[0]/2;
int centerScreen = ctx.getWidth()/2;
int centerGrid = TetrisGame.WIDTH*6/2-1;
final int leftOffset = centerScreen - centerGrid;
final int topOffset = StaticVars.screenSize[1] - TetrisGame.HEIGHT*6-1;
final int topOffset = ctx.getHeight() - TetrisGame.HEIGHT*6-1;
for (int y = 0; y < TetrisGame.HEIGHT; y++) {
for (int x = 0; x < TetrisGame.WIDTH; x++) {
final int offset = x+y*TetrisGame.WIDTH;
final BlockColor type = renderedGrid[offset];
if (type != null) {
r.glFillRect(leftOffset + x * 5, topOffset + (TetrisGame.HEIGHT+3-y) * 5, 5, 5, renderedGrid[offset].ordinal() * 5, 0, 5, 5);
r.glFillRect(leftOffset + x * 5, topOffset + (y+3) * 5, 5, 5, renderedGrid[offset].ordinal() * 5, 0, 5, 5);
} else {
// r.glFillRect(leftOffset + x * 5, topOffset + y * 5, 5, 5, 1 * 5, 0, 5, 5);
r.glFillRect(leftOffset + x * 5, topOffset + (y+3) * 5, 5, 5, 7 * 5, 0, 5, 5);
}
}
}
Tetromino nextTetromino = g.getNextTetromino();
if (nextTetromino != null) {
r.glColor3f(0.25f, 0.25f, 0.25f);
r.glFillColor(leftOffset + (TetrisGame.WIDTH + 3) * 5, topOffset + 3 * 5, 5*4, 5*4);
r.glColor3f(1,1,1);
boolean[] renderedNextTetromino = nextTetromino.getRenderedBlock();
final BlockColor type = nextTetromino.getColor();
int nextTetrominoGridSize = nextTetromino.getTetrominoGridSize();
int nextGridOffset = 4*5/2 - nextTetrominoGridSize*5/2;
for (int y = 0; y < nextTetrominoGridSize; y++) {
for (int x = 0; x < nextTetrominoGridSize; x++) {
final int offset = x+y*nextTetrominoGridSize;
if (renderedNextTetromino[offset]) {
if (type != null) {
r.glFillRect(leftOffset + nextGridOffset + (TetrisGame.WIDTH + 3 + x) * 5, topOffset + nextGridOffset + (3 + y) * 5, 5, 5, type.ordinal() * 5, 0, 5, 5);
}
}
}
}
}
r.glColor3f(1,1,1);
r.glDrawStringLeft(leftOffset + (TetrisGame.WIDTH + 3) * 5, topOffset + (3+5) * 5, "SCORE:"+g.getScore());
}
@Override
public boolean onKeyPressed(KeyPressedEvent k) {
switch (k.getKey()) {
case LEFT: {
leftPressed = true;
leftPressed.press();
return true;
}
case RIGHT: {
rightPressed = true;
rightPressed.press();
return true;
}
case UP: {
upPressed.press();
return true;
}
case DOWN: {
downPressed = true;
downPressed.press();
return true;
}
case OK: {
okPressed = true;
okPressed.press();
g.playAgain();
return true;
}
case BACK: {
backPressed = true;
backPressed.press();
return true;
}
default: return false;
@ -119,23 +156,27 @@ public class TetrisScreen extends Screen {
public boolean onKeyReleased(KeyReleasedEvent k) {
switch (k.getKey()) {
case LEFT: {
leftPressed = false;
leftPressed.release();
return true;
}
case RIGHT: {
rightPressed = false;
rightPressed.release();
return true;
}
case UP: {
upPressed.release();
return true;
}
case DOWN: {
downPressed = false;
downPressed.release();
return true;
}
case OK: {
okPressed = false;
okPressed.release();
return true;
}
case BACK: {
backPressed = false;
backPressed.release();
return true;
}
default: return false;
@ -148,6 +189,6 @@ public class TetrisScreen extends Screen {
@Override
public String getSessionTitle() {
return "Absolutely Not Tetris";
return "Tetris";
}
}

View File

@ -80,11 +80,15 @@ public abstract class Tetromino {
}
public void fixInitialPosition() {
this.y -= (byte) (this.getTetrominoGridSize()/2);
this.y += (byte) (this.getTetrominoGridSize()/2);
}
public abstract int getTetrominoGridSize();
protected abstract boolean[] getRenderedBlock();
protected abstract boolean[] getRenderedBlock(byte dRotation);
protected boolean[] getRenderedBlock() {
return getRenderedBlock(this.rotation);
}
@Override
public int hashCode() {

View File

@ -11,8 +11,8 @@ public class TetrominoICyan extends Tetromino {
}
@Override
public boolean[] getRenderedBlock() {
switch(getRotation()) {
public boolean[] getRenderedBlock(final byte rotation) {
switch(rotation) {
case 0:
return new boolean[] {
o,o,o,o,

View File

@ -11,8 +11,8 @@ public class TetrominoJBlue extends Tetromino {
}
@Override
public boolean[] getRenderedBlock() {
switch(getRotation()) {
public boolean[] getRenderedBlock(final byte rotation) {
switch(rotation) {
case 0:
return new boolean[] {
w,o,o,

View File

@ -11,8 +11,8 @@ public class TetrominoLOrange extends Tetromino {
}
@Override
public boolean[] getRenderedBlock() {
switch(getRotation()) {
public boolean[] getRenderedBlock(final byte rotation) {
switch(rotation) {
case 0:
return new boolean[] {
o,o,w,

View File

@ -10,7 +10,7 @@ public class TetrominoOYellow extends Tetromino {
}
@Override
public boolean[] getRenderedBlock() {
public boolean[] getRenderedBlock(byte rotation) {
return new boolean[] {
w,w,
w,w,

View File

@ -11,8 +11,8 @@ public class TetrominoSGreen extends Tetromino {
}
@Override
public boolean[] getRenderedBlock() {
switch(getRotation()) {
public boolean[] getRenderedBlock(final byte rotation) {
switch(rotation) {
case 0:
return new boolean[] {
o,w,w,

View File

@ -2,7 +2,7 @@ package it.cavallium.warppi.extra.tetris;
public class TetrominoTPurple extends Tetromino {
public TetrominoTPurple(byte x, byte y, byte rotation) {
super(x, y, rotation, TetrominoType.I_CYAN);
super(x, y, rotation, TetrominoType.T_PURPLE);
}
@Override
@ -11,8 +11,8 @@ public class TetrominoTPurple extends Tetromino {
}
@Override
public boolean[] getRenderedBlock() {
switch(getRotation()) {
public boolean[] getRenderedBlock(byte rotation) {
switch(rotation) {
case 0:
return new boolean[] {
o,w,o,

View File

@ -11,8 +11,8 @@ public class TetrominoZRed extends Tetromino {
}
@Override
public boolean[] getRenderedBlock() {
switch(getRotation()) {
public boolean[] getRenderedBlock(final byte rotation) {
switch(rotation) {
case 0:
return new boolean[] {
w,w,o,

View File

@ -1,8 +1,9 @@
package it.cavallium.warppi.gui;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.device.input.Keyboard;
import it.cavallium.warppi.StaticVars;
import it.cavallium.warppi.device.Keyboard;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.gui.graphicengine.Skin;
@ -25,7 +26,13 @@ public class CalculatorHUD extends HUD {
}
@Override
public void render() {
public void graphicInitialized() throws InterruptedException {
// TODO Auto-generated method stub
}
@Override
public void render(RenderContext ctx) {
// TODO Auto-generated method stub
}
@ -33,23 +40,25 @@ public class CalculatorHUD extends HUD {
@Override
public void renderTopmostBackground() {
final Renderer r = d.renderer;
final GraphicEngine engine = d.engine;
final DisplayOutputDevice display = d.display;
final GraphicEngine engine = display.getGraphicEngine();
r.glColor(0xFFc5c2af);
r.glFillColor(0, 0, engine.getWidth(), 20);
}
@Override
public void renderTopmost() {
final Renderer r = d.renderer;
final GraphicEngine engine = d.engine;
public void renderTopmost(RenderContext ctx) {
final Renderer r = ctx.getRenderer();
final DisplayOutputDevice display = d.display;
final GraphicEngine engine = display.getGraphicEngine();
final Skin guiSkin = d.guiSkin;
//DRAW TOP
r.glColor3i(0, 0, 0);
r.glDrawLine(0, 20, engine.getWidth() - 1, 20);
r.glColor3i(255, 255, 255);
guiSkin.use(engine);
guiSkin.use(display);
if (Keyboard.shift) {
r.glFillRect(2 + 18 * 0, 2, 16, 16, 16 * 2, 16 * 0, 16, 16);
} else {
@ -63,31 +72,31 @@ public class CalculatorHUD extends HUD {
int padding = 2;
final int brightness = (int) Math.ceil(Engine.INSTANCE.getHardwareDevice().getDisplayManager().getBrightness() * 9);
final int brightness = (int) Math.ceil(WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().getBrightness() * 9);
if (brightness <= 10) {
r.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * brightness, 16 * 1, 16, 16);
r.glFillRect(ctx.getWidth() - (padding + 16), 2, 16, 16, 16 * brightness, 16 * 1, 16, 16);
} else {
Engine.getPlatform().getConsoleUtils().out().println(1, "Brightness error");
WarpPI.getPlatform().getConsoleUtils().out().println(1, "Brightness error");
}
padding += 18 + 6;
final boolean canGoBack = Engine.INSTANCE.getHardwareDevice().getDisplayManager().canGoBack();
final boolean canGoForward = Engine.INSTANCE.getHardwareDevice().getDisplayManager().canGoForward();
final boolean canGoBack = WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().canGoBack();
final boolean canGoForward = WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().canGoForward();
if (Engine.getPlatform().getSettings().isDebugEnabled()) {
r.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 18, 16 * 0, 16, 16);
if (WarpPI.getPlatform().getSettings().isDebugEnabled()) {
r.glFillRect(ctx.getWidth() - (padding + 16), 2, 16, 16, 16 * 18, 16 * 0, 16, 16);
padding += 18 + 6;
}
if (canGoBack && canGoForward) {
r.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 14, 16 * 0, 16, 16);
r.glFillRect(ctx.getWidth() - (padding + 16), 2, 16, 16, 16 * 14, 16 * 0, 16, 16);
} else if (canGoBack) {
r.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 15, 16 * 0, 16, 16);
r.glFillRect(ctx.getWidth() - (padding + 16), 2, 16, 16, 16 * 15, 16 * 0, 16, 16);
} else if (canGoForward) {
r.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 16, 16 * 0, 16, 16);
r.glFillRect(ctx.getWidth() - (padding + 16), 2, 16, 16, 16 * 16, 16 * 0, 16, 16);
} else {
r.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 17, 16 * 0, 16, 16);
r.glFillRect(ctx.getWidth() - (padding + 16), 2, 16, 16, 16 * 17, 16 * 0, 16, 16);
}
padding += 18;
@ -95,23 +104,23 @@ public class CalculatorHUD extends HUD {
//DRAW BOTTOM
r.glDrawStringLeft(2, 90, d.displayDebugString);
Utils.getFont(true, false).use(engine);
Utils.getFont(true, false).use(display);
r.glColor4i(255, 0, 0, 40);
r.glDrawStringLeft(1 + 1, StaticVars.screenSize[1] - 7 - 7 + 1, "WORK IN");
r.glDrawStringLeft(1 + 1, ctx.getHeight() - 7 - 7 + 1, "WORK IN");
r.glColor4i(255, 0, 0, 80);
r.glDrawStringLeft(1, StaticVars.screenSize[1] - 7 - 7, "WORK IN");
r.glDrawStringLeft(1, ctx.getHeight() - 7 - 7, "WORK IN");
r.glColor4i(255, 0, 0, 40);
r.glDrawStringLeft(1 + 1, StaticVars.screenSize[1] - 7 + 1, "PROGRESS.");
r.glDrawStringLeft(1 + 1, ctx.getHeight() - 7 + 1, "PROGRESS.");
r.glColor4i(255, 0, 0, 80);
r.glDrawStringLeft(1, StaticVars.screenSize[1] - 7, "PROGRESS.");
r.glDrawStringLeft(1, ctx.getHeight() - 7, "PROGRESS.");
int currentDebugLine = 2;
if (Engine.getPlatform().getSettings().isDebugEnabled()) {
if (WarpPI.getPlatform().getSettings().isDebugEnabled()) {
ObjectArrayList<Screen> allSessions = new ObjectArrayList<>();
for (Screen session : Engine.INSTANCE.getHardwareDevice().getDisplayManager().sessions) {
for (Screen session : WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().sessions) {
allSessions.add(0, session);
}
Screen curScreen = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen();
Screen curScreen = WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().getScreen();
if (curScreen.historyBehavior == HistoryBehavior.DONT_KEEP_IN_HISTORY) {
allSessions.add(curScreen);
}
@ -120,7 +129,7 @@ public class CalculatorHUD extends HUD {
if (session != null) {
String title = session.getSessionTitle();
if (title != null && title.length() > 0) {
Utils.getFont(true).use(engine);
Utils.getFont(true).use(display);
if (session.historyBehavior == HistoryBehavior.DONT_KEEP_IN_HISTORY) {
r.glColor(0xFF3333FF);
} else if (session.historyBehavior == HistoryBehavior.ALWAYS_KEEP_IN_HISTORY) {
@ -128,28 +137,48 @@ public class CalculatorHUD extends HUD {
} else {
r.glColor(0xFF990000);
}
r.glDrawStringLeft(0, StaticVars.screenSize[1] - ((currentDebugLine+1) * (r.getCurrentFont().getCharacterHeight()+1)), "[" + String.format("%1$03d", session.debugScreenID) + "] " + title.toUpperCase());
if (session == Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen()) {
r.glDrawStringLeft(0, ctx.getHeight() - ((currentDebugLine+1) * (r.getCurrentFont().getCharacterHeight()+1)), "[" + String.format("%1$03d", session.debugScreenID) + "] " + title.toUpperCase());
if (session == WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().getScreen()) {
r.glColor(0xFF00CC00);
} else {
r.glColor(0xFF990000);
}
r.glDrawStringLeft(0, StaticVars.screenSize[1] - ((currentDebugLine+1) * (r.getCurrentFont().getCharacterHeight()+1)), " " + title.toUpperCase());
r.glDrawStringLeft(0, ctx.getHeight() - ((currentDebugLine+1) * (r.getCurrentFont().getCharacterHeight()+1)), " " + title.toUpperCase());
}
currentDebugLine++;
}
}
r.glColor(0xFF000000);
r.glDrawStringLeft(5, StaticVars.screenSize[1] - ((currentDebugLine+1) * (r.getCurrentFont().getCharacterHeight()+1)), "DEBUG ENABLED");
r.glDrawStringLeft(5, ctx.getHeight() - ((currentDebugLine+1) * (r.getCurrentFont().getCharacterHeight()+1)), "DEBUG ENABLED");
}
}
@Override
public void beforeRender(final float dt) {
public void beforeRender(ScreenContext ctx, final float dt) {
// TODO Auto-generated method stub
}
@Override
public int getMarginLeft() {
return 0;
}
@Override
public int getMarginTop() {
return 20;
}
@Override
public int getMarginRight() {
return 0;
}
@Override
public int getMarginBottom() {
return 0;
}
@Override
public void renderBackground() {
// TODO Auto-generated method stub

View File

@ -1,34 +1,30 @@
package it.cavallium.warppi.gui;
import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.Platform.ConsoleUtils;
import it.cavallium.warppi.Platform.Semaphore;
import it.cavallium.warppi.StaticVars;
import it.cavallium.warppi.device.Keyboard;
import it.cavallium.warppi.flow.Observable;
import it.cavallium.warppi.flow.Pair;
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.gui.graphicengine.RenderingLoop;
import it.cavallium.warppi.gui.graphicengine.Skin;
import it.cavallium.warppi.gui.graphicengine.impl.nogui.NoGuiEngine;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.device.display.BacklightOutputDevice;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.device.input.Keyboard;
import it.cavallium.warppi.event.*;
import it.cavallium.warppi.gui.graphicengine.*;
import it.cavallium.warppi.gui.screens.Screen;
import it.cavallium.warppi.util.Timer;
import it.cavallium.warppi.util.Utils;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;
public final class DisplayManager implements RenderingLoop {
private static final int tickDuration = 50;
private float brightness;
public final GraphicEngine engine;
public final HardwareDisplay monitor;
public final DisplayOutputDevice display;
public final GraphicEngine graphicEngine;
public final BacklightOutputDevice backlight;
public final boolean supportsPauses;
public Renderer renderer;
@ -51,24 +47,23 @@ public final class DisplayManager implements RenderingLoop {
*/
public boolean forceRefresh;
public DisplayManager(final HardwareDisplay monitor, final HUD hud, final Screen screen, final String title) {
this.monitor = monitor;
public DisplayManager(final DisplayOutputDevice display, final BacklightOutputDevice backlight, final HUD hud, final Screen screen, final String title) {
this.display = display;
this.graphicEngine = display.getGraphicEngine();
this.backlight = backlight;
this.hud = hud;
initialTitle = title;
initialScreen = screen;
screenChange = Engine.getPlatform().newSemaphore();
engine = chooseGraphicEngine();
supportsPauses = engine.doesRefreshPauses();
screenChange = WarpPI.getPlatform().newSemaphore();
supportsPauses = graphicEngine.doesRefreshPauses();
glyphsHeight = new int[] { 9, 6, 12, 9 };
glyphsHeight = new int[]{9, 6, 12, 9};
displayDebugString = "";
errorMessages = new ObjectArrayList<>();
}
public void initialize() {
monitor.initialize();
try {
hud.d = this;
hud.create();
@ -77,96 +72,39 @@ public final class DisplayManager implements RenderingLoop {
}
} catch (final Exception e) {
e.printStackTrace();
Engine.getPlatform().exit(0);
WarpPI.getPlatform().exit(0);
}
try {
engine.create();
renderer = engine.getRenderer();
engine.setTitle(initialTitle);
graphicEngine.create();
renderer = graphicEngine.getRenderer();
graphicEngine.setTitle(initialTitle);
loop();
} catch (final Exception ex) {
ex.printStackTrace();
}
monitor.shutdown();
}
/*
* private void load_skin() {
* try {
* skin_tex = glGenTextures();
* glBindTexture(GL_TEXTURE_2D, skin_tex);
* glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
* 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);
* 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();
* 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();
* }
* }
* 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(); } }
*/
private GraphicEngine chooseGraphicEngine() {
GraphicEngine d;
d = Utils.getOrDefault(Engine.getPlatform().getEnginesList(), "framebuffer engine", null);
if (d != null && d.isSupported()) {
Engine.getPlatform().getConsoleUtils().out().println(1, "Using FB Graphic Engine");
return d;
}
d = Utils.getOrDefault(Engine.getPlatform().getEnginesList(), "CPU engine", null);
if (d != null && d.isSupported()) {
Engine.getPlatform().getConsoleUtils().out().println(1, "Using CPU Graphic Engine");
return d;
}
d = Utils.getOrDefault(Engine.getPlatform().getEnginesList(), "GPU engine", null);
if (d != null && d.isSupported()) {
Engine.getPlatform().getConsoleUtils().out().println(1, "Using GPU Graphic Engine");
return d;
}
d = Utils.getOrDefault(Engine.getPlatform().getEnginesList(), "headless 24 bit engine", null);
if (d != null && d.isSupported()) {
System.err.println("Using Headless 24 bit Engine! This is a problem! No other graphic engines are available.");
return d;
}
d = Utils.getOrDefault(Engine.getPlatform().getEnginesList(), "headless 256 colors engine", null);
if (d != null && d.isSupported()) {
System.err.println("Using Headless 256 Engine! This is a problem! No other graphic engines are available.");
return d;
}
d = Utils.getOrDefault(Engine.getPlatform().getEnginesList(), "headless 8 colors engine", null);
if (d != null && d.isSupported()) {
System.err.println("Using Headless basic Engine! This is a problem! No other graphic engines are available.");
return d;
}
d = Utils.getOrDefault(Engine.getPlatform().getEnginesList(), "HTML5 engine", null);
if (d != null && d.isSupported()) {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "Using Html Graphic Engine");
return d;
}
d = new NoGuiEngine();
if (d != null && d.isSupported()) {
Engine.getPlatform().getConsoleUtils().out().println(1, "Using NoGui Graphic Engine");
return d;
}
throw new UnsupportedOperationException("No graphic engines available.");
}
public void closeScreen() {
boolean isLastSession = sessions[1] == null;
if (!isLastSession) {
@ -186,10 +124,10 @@ public final class DisplayManager implements RenderingLoop {
} else {
currentSession = 0;
}
updateCurrentScreen(sessions[currentSession]);
updateCurrentScreen(sessions[currentSession]);
}
}
public void setScreen(final Screen screen) {
boolean mustBeAddedToHistory = screen.initialized == false;
if (!mustBeAddedToHistory) {
@ -200,34 +138,44 @@ public final class DisplayManager implements RenderingLoop {
mustBeAddedToHistory |= !found;
}
if (mustBeAddedToHistory) {
if (screen.historyBehavior == HistoryBehavior.NORMAL || screen.historyBehavior == HistoryBehavior.ALWAYS_KEEP_IN_HISTORY) {
if (screen.historyBehavior == HistoryBehavior.NORMAL
|| screen.historyBehavior == HistoryBehavior.ALWAYS_KEEP_IN_HISTORY) {
if (currentSession > 0) {
final int sl = sessions.length; //TODO: I don't know why if i don't add +5 or more some items disappear
final int sl = sessions.length; // TODO: I don't know why if i don't add +5 or more some items
// disappear
List<Screen> newSessions = new LinkedList<>();
int i = 0;
for (Screen s : sessions) {
if (i == currentSession) {
currentSession = newSessions.size();
newSessions.add(screen);
}
if (s != null) {
if (i < currentSession) {
if (s.historyBehavior != HistoryBehavior.DONT_KEEP_IN_HISTORY)
newSessions.add(s);
} else {
if (s.historyBehavior == HistoryBehavior.ALWAYS_KEEP_IN_HISTORY) {
newSessions.add(s);
}
} else {
if (s.historyBehavior != HistoryBehavior.DONT_KEEP_IN_HISTORY)
newSessions.add(s);
}
}
i++;
}
sessions = newSessions.toArray(new Screen[5]);
currentSession = newSessions.indexOf(screen);
// sessions = Arrays.copyOfRange(sessions, currentSession, sl);
for (int j = 0; j < sl; j++) {
if (j < newSessions.size()) {
sessions[j] = newSessions.get(j);
} else {
sessions[j] = null;
}
}
} else {
currentSession = 0;
for (int i = sessions.length - 1; i >= 1; i--) {
sessions[i] = sessions[i - 1];
}
sessions[0] = screen;
}
for (int i = sessions.length - 1; i >= 1; i--) {
sessions[i] = sessions[i - 1];
}
sessions[0] = screen;
} else {
currentSession = -1;
}
@ -242,19 +190,20 @@ public final class DisplayManager implements RenderingLoop {
screen.create();
}
this.screen = screen;
screenChange.release();
if (screen.initialized == false) {
screen.initialize();
}
screenChange.release();
} catch (final Exception e) {
e.printStackTrace();
Engine.getPlatform().exit(0);
WarpPI.getPlatform().exit(0);
}
}
public void replaceScreen(final Screen screen) {
if (screen.initialized == false) {
if (screen.historyBehavior == HistoryBehavior.NORMAL || screen.historyBehavior == HistoryBehavior.ALWAYS_KEEP_IN_HISTORY) {
if (screen.historyBehavior == HistoryBehavior.NORMAL
|| screen.historyBehavior == HistoryBehavior.ALWAYS_KEEP_IN_HISTORY) {
sessions[currentSession] = screen;
} else {
currentSession = -1;
@ -267,13 +216,13 @@ public final class DisplayManager implements RenderingLoop {
try {
screen.create();
this.screen = screen;
screenChange.release();
if (screen.initialized == false) {
screen.initialize();
}
screenChange.release();
} catch (final Exception e) {
e.printStackTrace();
Engine.getPlatform().exit(0);
WarpPI.getPlatform().exit(0);
}
}
@ -300,7 +249,8 @@ public final class DisplayManager implements RenderingLoop {
public void goBack() {
if (canGoBack()) {
if (currentSession >= 0 && screen != sessions[currentSession]) {} else {
if (currentSession >= 0 && screen != sessions[currentSession]) {
} else {
currentSession += 1;
}
screen = sessions[currentSession];
@ -350,66 +300,87 @@ public final class DisplayManager implements RenderingLoop {
}
private void load_skin() throws IOException {
guiSkin = engine.loadSkin("/skin.png");
guiSkin = graphicEngine.loadSkin("/skin.png");
}
private void load_fonts() throws IOException {
fonts = new BinaryFont[7];
fonts[0] = engine.loadFont("smal");
fonts[1] = engine.loadFont("smallest");
fonts[2] = engine.loadFont("norm");
fonts[3] = engine.loadFont("smal");
//4
//fonts[5] = engine.loadFont("square");
fonts[0] = graphicEngine.loadFont("smal");
fonts[1] = graphicEngine.loadFont("smallest");
fonts[2] = graphicEngine.loadFont("norm");
fonts[3] = graphicEngine.loadFont("smal");
// 4
// fonts[5] = engine.loadFont("square");
}
private void draw_init() {
if (engine.supportsFontRegistering()) {
final List<BinaryFont> fontsIterator = engine.getRegisteredFonts();
if (graphicEngine.supportsFontRegistering()) {
final List<BinaryFont> fontsIterator = graphicEngine.getRegisteredFonts();
for (final BinaryFont f : fontsIterator) {
if (!f.isInitialized()) {
f.initialize(engine);
f.initialize(display);
}
}
}
renderer.glClear(engine.getWidth(), engine.getHeight());
if (!screen.graphicInitialized) {
try {
var displaySize = display.getDisplaySize();
var scrWidth = displaySize[0] - hud.getMarginLeft() - hud.getMarginRight();
var scrHeight = displaySize[1] - hud.getMarginTop() - hud.getMarginBottom();
var scrCtx = new ScreenContext(graphicEngine, scrWidth, scrHeight);
screen.initializeGraphic(scrCtx);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
renderer.glClear(graphicEngine.getWidth(), graphicEngine.getHeight());
}
private void draw_world() {
var displaySize = display.getDisplaySize();
var scrWidth = displaySize[0] - hud.getMarginLeft() - hud.getMarginRight();
var scrHeight = displaySize[1] - hud.getMarginTop() - hud.getMarginBottom();
var scrCtx = new RenderContext(graphicEngine, renderer.getBoundedInstance(hud.getMarginLeft(), hud.getMarginTop(), scrWidth, scrHeight), scrWidth, scrHeight);
var fullCtx = new RenderContext(graphicEngine, renderer, displaySize[0], displaySize[1]);
renderer.glColor3i(255, 255, 255);
if (error != null) {
final BinaryFont fnt = Utils.getFont(false, false);
if (fnt != null && fnt != engine.getRenderer().getCurrentFont()) {
fnt.use(engine);
if (fnt != null && fnt != graphicEngine.getRenderer().getCurrentFont()) {
fnt.use(display);
}
renderer.glColor3i(129, 28, 22);
renderer.glDrawStringRight(StaticVars.screenSize[0] - 2, StaticVars.screenSize[1] - (fnt.getCharacterHeight() + 2), Engine.getPlatform().getSettings().getCalculatorNameUppercase() + " CALCULATOR");
renderer.glDrawStringRight(display.getDisplaySize()[0] - 2,
display.getDisplaySize()[1] - (fnt.getCharacterHeight() + 2),
WarpPI.getPlatform().getSettings().getCalculatorNameUppercase() + " CALCULATOR");
renderer.glColor3i(149, 32, 26);
renderer.glDrawStringCenter(StaticVars.screenSize[0] / 2, 22, error);
renderer.glDrawStringCenter(display.getDisplaySize()[0] / 2, 22, error);
renderer.glColor3i(164, 34, 28);
int i = 22;
for (final String stackPart : errorStackTrace) {
renderer.glDrawStringLeft(2, 22 + i, stackPart);
i += 11;
}
if (fonts[0] != null && fonts[0] != engine.getRenderer().getCurrentFont()) {
fonts[0].use(engine);
if (fonts[0] != null && fonts[0] != graphicEngine.getRenderer().getCurrentFont()) {
fonts[0].use(display);
}
renderer.glColor3i(129, 28, 22);
renderer.glDrawStringCenter(StaticVars.screenSize[0] / 2, 11, "UNEXPECTED EXCEPTION");
renderer.glDrawStringCenter(display.getDisplaySize()[0] / 2, 11, "UNEXPECTED EXCEPTION");
} else {
if (fonts[0] != null && fonts[0] != engine.getRenderer().getCurrentFont()) {
fonts[0].use(engine);
if (fonts[0] != null && fonts[0] != graphicEngine.getRenderer().getCurrentFont()) {
fonts[0].use(display);
}
if (hud.visible) hud.renderBackground();
screen.render();
if (hud.visible)
hud.renderBackground();
screen.render(scrCtx);
if (hud.visible) {
hud.render();
hud.render(fullCtx);
hud.renderTopmostBackground();
}
screen.renderTopmost();
if (hud.visible) hud.renderTopmost();
screen.renderTopmost(fullCtx);
if (hud.visible)
hud.renderTopmost(fullCtx);
}
}
@ -421,8 +392,8 @@ public final class DisplayManager implements RenderingLoop {
private long precTime = -1;
@Override
public void refresh() {
if (supportsPauses == false || Keyboard.popRefreshRequest() || forceRefresh || screen.mustBeRefreshed()) {
public void refresh(boolean force) {
if (force || supportsPauses == false || Keyboard.popRefreshRequest() || forceRefresh || screen.mustBeRefreshed()) {
forceRefresh = false;
draw();
}
@ -439,45 +410,42 @@ public final class DisplayManager implements RenderingLoop {
setScreen(initialScreen);
initialScreen = null;
}
screen.initialize();
} catch (final Exception e) {
e.printStackTrace();
Engine.getPlatform().exit(0);
WarpPI.getPlatform().exit(0);
}
final Observable<Long> workTimer = Observable.interval(DisplayManager.tickDuration);
var displayRefreshManager = new DisplayRefreshManager(this::onRefresh);
new Timer(DisplayManager.tickDuration, displayRefreshManager::onTick);
graphicEngine.onResize().subscribe(displayRefreshManager::onResize);
final Observable<Integer[]> onResizeObservable = engine.onResize();
Observable<Pair<Long, Integer[]>> refreshObservable;
if (onResizeObservable == null) {
refreshObservable = workTimer.map((l) -> Pair.of(l, null));
} else {
refreshObservable = Observable.combineChanged(workTimer, engine.onResize());
}
refreshObservable.subscribe((pair) -> {
double dt = 0;
final long newtime = System.nanoTime();
if (precTime == -1) {
dt = DisplayManager.tickDuration;
} else {
dt = (newtime - precTime) / 1000d / 1000d;
}
precTime = newtime;
if (pair.getRight() != null) {
final Integer[] windowSize = pair.getRight();
StaticVars.screenSize[0] = windowSize[0];
StaticVars.screenSize[1] = windowSize[1];
}
screen.beforeRender((float) (dt / 1000d));
});
engine.start(getDrawable());
graphicEngine.start(getDrawable());
} catch (final Exception ex) {
ex.printStackTrace();
} finally {}
} finally {
}
}
private void onRefresh(Integer[] windowSize) {
double dt = 0;
final long newtime = System.nanoTime();
if (precTime == -1) {
dt = DisplayManager.tickDuration;
} else {
dt = (newtime - precTime) / 1000d / 1000d;
}
precTime = newtime;
if (windowSize != null) {
display.getDisplaySize()[0] = windowSize[0];
display.getDisplaySize()[1] = windowSize[1];
}
var displaySize = display.getDisplaySize();
var scrWidth = displaySize[0] - hud.getMarginLeft() - hud.getMarginRight();
var scrHeight = displaySize[1] - hud.getMarginTop() - hud.getMarginBottom();
var scrCtx = new ScreenContext(graphicEngine, scrWidth, scrHeight);
screen.beforeRender(scrCtx, (float) (dt / 1000d));
}
public void changeBrightness(final float change) {
@ -487,7 +455,7 @@ public final class DisplayManager implements RenderingLoop {
public void setBrightness(final float newval) {
if (newval >= 0 && newval <= 1) {
brightness = newval;
monitor.setBrightness(brightness);
backlight.setBrightness(brightness);
}
}
@ -523,7 +491,31 @@ public final class DisplayManager implements RenderingLoop {
renderer.glFillRect(x, y, uvX2 - uvX, uvY2 - uvY, uvX, uvY, uvX2 - uvX, uvY2 - uvY);
}
public void waitForExit() {
engine.waitForExit();
public Consumer<TouchEvent> getTouchEventListener() {
return (TouchEvent t) -> {
boolean refresh = false;
if (screen != null && screen.initialized && executeTouchEventOnScreen(t, screen)) {
refresh = true;
} else {
//Default behavior
}
if (refresh) {
forceRefresh = true;
}
};
}
private boolean executeTouchEventOnScreen(TouchEvent t, Screen scr) {
if (t instanceof TouchStartEvent) {
return scr.onTouchStart((TouchStartEvent) t);
} else if (t instanceof TouchMoveEvent) {
return scr.onTouchMove((TouchMoveEvent) t);
} else if (t instanceof TouchEndEvent) {
return scr.onTouchEnd((TouchEndEvent) t);
} else if (t instanceof TouchCancelEvent) {
return scr.onTouchCancel((TouchCancelEvent) t);
} else {
throw new UnsupportedOperationException();
}
}
}

View File

@ -0,0 +1,27 @@
package it.cavallium.warppi.gui;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
public class DisplayRefreshManager {
private final Consumer<Integer[]> refreshConsumer;
private volatile Integer[] size;
public DisplayRefreshManager(Consumer<Integer[]> refreshConsumer) {
this.refreshConsumer = refreshConsumer;
}
public void onTick() {
refreshConsumer.accept(size);
}
public void onResize(Integer[] newSize) {
var oldSize = size;
if (oldSize == null || !Arrays.equals(oldSize, newSize)) {
size = newSize;
refreshConsumer.accept(size);
}
}
}

View File

@ -1,6 +1,6 @@
package it.cavallium.warppi.gui;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.util.Error;
@ -20,9 +20,9 @@ public class GUIErrorMessage {
creationTime = System.currentTimeMillis();
}
public void draw(final GraphicEngine g, final Renderer r, final String msg) {
final int scrW = g.getWidth();
final int scrH = g.getHeight();
public void draw(final DisplayOutputDevice g, final Renderer r, final String msg) {
final int scrW = g.getGraphicEngine().getWidth();
final int scrH = g.getGraphicEngine().getHeight();
final int width = 200;
final int height = 20;
final int margin = 4;

View File

@ -2,14 +2,16 @@ package it.cavallium.warppi.gui;
public interface GraphicalInterface {
void create() throws InterruptedException;
void initialize() throws InterruptedException;
void initializeGraphic(ScreenContext ctx) throws InterruptedException;
void render();
void render(RenderContext ctx);
void renderTopmost();
void renderTopmost(RenderContext ctx);
void beforeRender(float dt);
void beforeRender(ScreenContext ctx, float dt);
boolean mustBeRefreshed();
}

View File

@ -1,8 +1,11 @@
package it.cavallium.warppi.gui;
import it.cavallium.warppi.gui.screens.Screen;
public abstract class HUD implements GraphicalInterface {
public DisplayManager d;
public boolean created = false;
public boolean graphicInitialized = false;
public boolean initialized = false;
public boolean visible = true;
@ -16,6 +19,14 @@ public abstract class HUD implements GraphicalInterface {
}
}
@Override
public void initializeGraphic(ScreenContext ctx) throws InterruptedException {
if (!graphicInitialized) {
graphicInitialized = true;
graphicInitialized();
}
}
@Override
public void create() throws InterruptedException {
if (!created) {
@ -26,20 +37,22 @@ public abstract class HUD implements GraphicalInterface {
public abstract void created() throws InterruptedException;
public abstract void graphicInitialized() throws InterruptedException;
public abstract void initialized() throws InterruptedException;
public abstract void renderBackground();
@Override
public abstract void render();
public abstract void render(RenderContext ctx);
public abstract void renderTopmostBackground();
@Override
public abstract void renderTopmost();
public abstract void renderTopmost(RenderContext ctx);
@Override
public abstract void beforeRender(float dt);
public abstract void beforeRender(ScreenContext ctx, float dt);
@Override
public boolean mustBeRefreshed() {
@ -54,4 +67,11 @@ public abstract class HUD implements GraphicalInterface {
visible = true;
}
public abstract int getMarginLeft();
public abstract int getMarginTop();
public abstract int getMarginRight();
public abstract int getMarginBottom();
}

View File

@ -1,9 +0,0 @@
package it.cavallium.warppi.gui;
public interface HardwareDisplay {
void initialize();
void shutdown();
void setBrightness(double value);
}

View File

@ -0,0 +1,17 @@
package it.cavallium.warppi.gui;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
public class RenderContext extends ScreenContext {
private final Renderer renderer;
public RenderContext(GraphicEngine graphicEngine, Renderer renderer, int width, int height) {
super(graphicEngine, width, height);
this.renderer = renderer;
}
public Renderer getRenderer() {
return renderer;
}
}

View File

@ -0,0 +1,27 @@
package it.cavallium.warppi.gui;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
public class ScreenContext {
private final GraphicEngine graphicEngine;
private final int width;
private final int height;
public ScreenContext(GraphicEngine graphicEngine, int width, int height) {
this.graphicEngine = graphicEngine;
this.width = width;
this.height = height;
}
public GraphicEngine getGraphicEngine() {
return graphicEngine;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}

View File

@ -1,23 +1,28 @@
package it.cavallium.warppi.gui.expression;
import it.cavallium.warppi.gui.expression.blocks.BlockContainer;
import it.cavallium.warppi.gui.expression.blocks.BlockOrContainer;
import it.cavallium.warppi.gui.expression.blocks.BlockPosition;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
public class Caret {
private int pos;
private int remaining;
@NotNull
private BlockPosition pos;
private CaretState state;
private final int[] lastSize;
private final int[] lastLocation;
public Caret(final CaretState state, final int pos) {
public Caret(final CaretState state, final BlockPosition pos) {
this(state, pos, new int[] { 0, 0 }, new int[] { 2, 5 });
}
public Caret(final CaretState state, final int pos, final int[] lastLocation, final int[] lastSize) {
public Caret(final CaretState state, final @NotNull BlockPosition pos, final int[] lastLocation, final int[] lastSize) {
this.state = state;
this.pos = pos;
remaining = pos;
this.lastLocation = lastLocation;
this.lastSize = lastSize;
}
@ -26,26 +31,27 @@ public class Caret {
* Copy
* @param old
*/
public Caret(Caret old) {
this.pos = old.pos;
this.remaining = old.remaining;
public Caret(Caret old, BlockContainer newRoot) {
this.pos = clonePosition(old.pos, newRoot);
this.state = old.state;
this.lastSize = Arrays.copyOf(old.lastSize, old.lastSize.length);
this.lastLocation = Arrays.copyOf(old.lastLocation, old.lastLocation.length);
}
public void skip(final int i) {
remaining -= i;
private BlockPosition clonePosition(BlockPosition pos, BlockContainer newRoot) {
BlockOrContainer el = newRoot;
var url = pos.getURL();
for (int i : url) {
el = el.getAt(i);
}
return new BlockPosition(el);
}
public int getPosition() {
@NotNull
public BlockPosition getPos() {
return pos;
}
public int getRemaining() {
return remaining;
}
public CaretState getState() {
return state;
}
@ -64,12 +70,8 @@ public class Caret {
}
}
public void setPosition(final int i) {
pos = i;
}
public void resetRemaining() {
remaining = pos;
public void setPosition(final BlockPosition pos) {
this.pos = pos;
}
public void setLastLocation(final int x, final int y) {
@ -90,4 +92,7 @@ public class Caret {
return new int[] { lastSize[0], lastSize[1] };
}
public boolean isHere(BlockOrContainer pos) {
return getPos().get() == pos;
}
}

View File

@ -2,11 +2,12 @@ package it.cavallium.warppi.gui.expression;
import java.util.Arrays;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.event.KeyboardEventListener;
import it.cavallium.warppi.gui.expression.blocks.Block;
import it.cavallium.warppi.gui.expression.blocks.BlockContainer;
import it.cavallium.warppi.gui.expression.blocks.BlockVariable;
import it.cavallium.warppi.gui.expression.blocks.TreeContainer;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
public abstract class ExtraMenu<T extends Block> implements KeyboardEventListener {
@ -32,7 +33,7 @@ public abstract class ExtraMenu<T extends Block> implements KeyboardEventListene
protected int height;
protected int[] location;
public abstract void draw(GraphicEngine ge, Renderer r, Caret caret);
public abstract void draw(DisplayOutputDevice ge, Renderer r, Caret caret);
public abstract void open();
@ -46,7 +47,7 @@ public abstract class ExtraMenu<T extends Block> implements KeyboardEventListene
return false;
}
public abstract ExtraMenu<T> clone(final TreeContainer parent, InputContext ic);
public abstract ExtraMenu<T> clone(final BlockContainer parent, InputContext ic);
public abstract ExtraMenu<T> clone(T newBlockVariable);

View File

@ -1,23 +1,23 @@
package it.cavallium.warppi.gui.expression.blocks;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.GraphicalElement;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.ExtraMenu;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.math.MathContext;
import it.cavallium.warppi.math.parser.features.interfaces.Feature;
import it.cavallium.warppi.util.Error;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public abstract class Block implements TreeBlock, GraphicalElement {
public abstract class Block implements TreeBlock, BlockOrContainer, GraphicalElement {
protected boolean small;
protected int width;
protected int height;
protected int line;
protected TreeContainer parent;
protected BlockContainer parent;
public Block() {
@ -27,7 +27,7 @@ public abstract class Block implements TreeBlock, GraphicalElement {
* Copy
* @param b
*/
public Block(TreeContainer parent, Block b) {
public Block(BlockContainer parent, Block b) {
this.small = b.small;
this.width = b.width;
this.height = b.height;
@ -43,15 +43,10 @@ public abstract class Block implements TreeBlock, GraphicalElement {
* Position relative to the window.
* @param y
* Position relative to the window.
* @param small
*/
public abstract void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret);
public abstract void draw(DisplayOutputDevice ge, Renderer r, int x, int y, Caret caret);
public abstract boolean putBlock(Caret caret, Block newBlock);
public abstract boolean delBlock(Caret caret);
public abstract BlockReference<?> getBlock(Caret caret);
public abstract boolean appendBlock(Caret caret, Block newBlock);
/**
* Used only to get inner blocks when deleting the parent block.
@ -64,8 +59,6 @@ public abstract class Block implements TreeBlock, GraphicalElement {
@Override
public abstract void recomputeDimensions();
public abstract int computeCaretMaxBound();
@Override
public int getWidth() {
return width;
@ -81,10 +74,6 @@ public abstract class Block implements TreeBlock, GraphicalElement {
return line;
}
public int getCaretDeltaPositionAfterCreation() {
return 1;
}
public boolean isSmall() {
return small;
}
@ -98,18 +87,66 @@ public abstract class Block implements TreeBlock, GraphicalElement {
public abstract Feature toFeature(MathContext context) throws Error;
@Override
public TreeContainer getParentContainer() {
public BlockContainer getParentContainer() {
return parent;
}
@Override
public BlockContainer getParent() {
return parent;
}
@Override
public BlockOrContainer getAt(int index) {
var ic = getInnerContainers();
return ic.get(index);
}
@Override
public int getIndex() {
return parent != null ? parent.getContentUnsafe().indexOf(this) : -1;
}
@Override
public boolean hasParent() {
return parent != null;
}
public void setParent(final TreeContainer parent) {
public void setParent(final BlockContainer parent) {
this.parent = parent;
}
public abstract Block clone(TreeContainer parent, InputContext ic);
public abstract Block clone(BlockContainer parent, InputContext ic);
public BlockReference<?> getReference() {
if (this.hasParent()) {
return this.parent.getReference(this);
} else {
return null;
}
}
public BlockPosition getLastInnerPosition() {
var innerContainers = getInnerContainers();
if (innerContainers != null && !innerContainers.isEmpty()) {
var lastContainer = innerContainers.get(innerContainers.size() - 1);
var content = lastContainer.getContent();
if (content.isEmpty()) {
return new BlockPosition(lastContainer);
} else {
return new BlockPosition(content.get(content.size() - 1));
}
} else {
return null;
}
}
public BlockPosition getFirstInnerPosition() {
var innerContainers = getInnerContainers();
if (innerContainers != null && !innerContainers.isEmpty()) {
return new BlockPosition(innerContainers.get(0));
} else {
return null;
}
}
}

View File

@ -1,8 +1,8 @@
package it.cavallium.warppi.gui.expression.blocks;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.math.MathContext;
import it.cavallium.warppi.math.parser.features.FeatureChar;
@ -23,33 +23,23 @@ public class BlockChar extends Block {
* @param b
* @param ic
*/
protected BlockChar(final TreeContainer parent, final BlockChar b, InputContext ic) {
protected BlockChar(final BlockContainer parent, final BlockChar b, InputContext ic) {
super(parent, b);
this.ch = b.ch;
}
@Override
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
public void draw(final DisplayOutputDevice ge, final Renderer r, final int x, final int y, final Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
r.glDrawCharLeft(x, y, ch);
}
@Override
public boolean putBlock(final Caret caret, final Block newBlock) {
public boolean appendBlock(final Caret caret, final Block newBlock) {
return false;
}
@Override
public boolean delBlock(final Caret caret) {
return false;
}
@Override
public BlockReference<?> getBlock(final Caret caret) {
return null;
}
@Override
public void recomputeDimensions() {
width = BlockContainer.getDefaultCharWidth(small) - 1;
@ -67,11 +57,6 @@ public class BlockChar extends Block {
return ch;
}
@Override
public int computeCaretMaxBound() {
return 0;
}
@Override
public Feature toFeature(final MathContext context) {
return new FeatureChar(getChar());
@ -88,7 +73,7 @@ public class BlockChar extends Block {
}
@Override
public BlockChar clone(final TreeContainer parent, InputContext ic) {
public BlockChar clone(final BlockContainer parent, InputContext ic) {
return new BlockChar(parent, this, ic);
}

View File

@ -1,14 +1,12 @@
package it.cavallium.warppi.gui.expression.blocks;
import java.util.Arrays;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.GraphicalElement;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.CaretState;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.math.Function;
import it.cavallium.warppi.math.MathContext;
@ -17,9 +15,8 @@ import it.cavallium.warppi.math.parser.features.interfaces.Feature;
import it.cavallium.warppi.util.Error;
import it.cavallium.warppi.util.Errors;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectListIterator;
public class BlockContainer implements TreeContainer, GraphicalElement {
public class BlockContainer implements TreeContainer, BlockOrContainer, GraphicalElement {
private static boolean initialized = false;
@ -32,39 +29,39 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
private int line;
public final boolean withBorder;
private boolean autoMinimums;
private final TreeBlock parent;
private final Block parent;
public BlockContainer() {
this(null, false, BlockContainer.getDefaultCharWidth(false), BlockContainer.getDefaultCharHeight(false), true);
autoMinimums = true;
}
public BlockContainer(final TreeBlock parent) {
public BlockContainer(final Block parent) {
this(parent, false, BlockContainer.getDefaultCharWidth(false), BlockContainer.getDefaultCharHeight(false), true);
autoMinimums = true;
}
public BlockContainer(final TreeBlock parent, final boolean small) {
public BlockContainer(final Block parent, final boolean small) {
this(parent, small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), true);
autoMinimums = true;
}
public BlockContainer(final TreeBlock parent, final boolean small, final ObjectArrayList<Block> content) {
public BlockContainer(final Block parent, final boolean small, final ObjectArrayList<Block> content) {
this(parent, small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), content, true);
autoMinimums = true;
}
public BlockContainer(final TreeBlock parent, final boolean small, final boolean withBorder) {
public BlockContainer(final Block parent, final boolean small, final boolean withBorder) {
this(parent, small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), withBorder);
autoMinimums = true;
}
public BlockContainer(final TreeBlock parent, final boolean small, final int minWidth, final int minHeight, final boolean withBorder) {
public BlockContainer(final Block parent, final boolean small, final int minWidth, final int minHeight, final boolean withBorder) {
this(parent, small, minWidth, minHeight, new ObjectArrayList<>(), withBorder);
autoMinimums = false;
}
public BlockContainer(final TreeBlock parent, final boolean small, final int minWidth, final int minHeight, final ObjectArrayList<Block> content, final boolean withBorder) {
public BlockContainer(final Block parent, final boolean small, final int minWidth, final int minHeight, final ObjectArrayList<Block> content, final boolean withBorder) {
this.parent = parent;
this.small = small;
this.minWidth = minWidth;
@ -79,7 +76,7 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
recomputeDimensions();
}
private BlockContainer(final TreeBlock parent, BlockContainer old, InputContext ic) {
private BlockContainer(final Block parent, BlockContainer old, InputContext ic) {
this.autoMinimums = old.autoMinimums;
this.content = new ObjectArrayList<>();
for (Block b : old.content) {
@ -96,15 +93,30 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
this.withBorder = old.withBorder;
}
public BlockContainer clone(final TreeBlock parent, InputContext ic) {
public BlockContainer clone(final Block parent, InputContext ic) {
return new BlockContainer(parent, this, ic);
}
@Override
public TreeBlock getParentBlock() {
public Block getParentBlock() {
return parent;
}
@Override
public Block getParent() {
return parent;
}
@Override
public BlockOrContainer getAt(int index) {
return content.get(index);
}
@Override
public int getIndex() {
return parent != null ? parent.getInnerContainers().indexOf(this) : -1;
}
@Override
public boolean hasParent() {
return parent != null;
@ -157,7 +169,7 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
public BlockReference<?> getBlockAt(final int i) {
final Block b = content.get(i);
return new BlockReference<>(b, i, this);
return new BlockReference<>(b, i, content, this);
}
public int getSize() {
@ -182,10 +194,10 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
* @param caret
* Position of the caret.
*/
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
public void draw(final DisplayOutputDevice ge, final Renderer r, final int x, final int y, final Caret caret) {
int paddingX = 1;
if (caret.getRemaining() == 0) {
if (caret.isHere(this)) {
if (content.size() > 0) {
BlockContainer.drawCaret(ge, r, caret, small, x, y + line - content.get(0).line, content.get(0).height);
} else {
@ -201,113 +213,39 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
r.glDrawLine(x + paddingX, y + height - 1, x + paddingX + width - 1, y + height - 1);
} else {
for (final Block b : content) {
caret.skip(1);
b.draw(ge, r, x + paddingX, y + line - b.line, caret);
paddingX += b.getWidth();
if (caret.getRemaining() == 0) {
if (caret.isHere(b)) {
BlockContainer.drawCaret(ge, r, caret, small, x + paddingX, y + line - b.line, b.height);
}
paddingX += 1;
}
}
caret.skip(1);
}
public boolean putBlock(final Caret caret, final Block newBlock) {
public boolean appendBlock(final Caret caret, final Block newBlock) {
boolean added = false;
if (caret.getRemaining() == 0) {
if (caret.isHere(this)) {
addBlock(0, newBlock);
added = true;
}
int pos = 0;
for (final Block b : content) {
caret.skip(1);
pos++;
added = added | b.putBlock(caret, newBlock);
if (caret.getRemaining() == 0) {
added = added | b.appendBlock(caret, newBlock);
if (caret.isHere(b)) {
addBlock(pos, newBlock);
added = true;
}
}
caret.skip(1);
if (added) {
recomputeDimensions();
}
return added;
}
public boolean delBlock(final Caret caret) {
boolean removed = false;
int pos = 0;
for (final Block b : content) {
caret.skip(1);
pos++;
final int deltaCaret = caret.getRemaining();
final int caretOldPos = caret.getPosition();
removed = removed | b.delBlock(caret);
if (caret.getRemaining() == 0 || removed == false && deltaCaret >= 0 && caret.getRemaining() < 0) {
ObjectArrayList<Block> blocks = this.getBlockAt(pos - 1).get().getInnerBlocks();
ObjectArrayList<BlockContainer> innerContainers = this.getBlockAt(pos - 1).get().getInnerContainers();
int innerContainersBeforeCaret = 0;
int currentBlockIndex = 0;
if (innerContainers != null) {
for (BlockContainer c : innerContainers) {
currentBlockIndex += c.computeCaretMaxBound();
if (currentBlockIndex > deltaCaret) {
break;
}
innerContainersBeforeCaret++;
}
}
// If the caret is at the end of a block with inner containers don't delete anything and enter into that block.
if (innerContainers == null || (innerContainers.size() - innerContainersBeforeCaret != 0)) {
removeAt(pos - 1);
if (blocks != null) {
ObjectListIterator<Block> blocksIterator = blocks.iterator();
int blockNum = 0;
while (blocksIterator.hasNext()) {
Block block = blocksIterator.next();
addBlockUnsafe(pos - 1 + blockNum, block);
blockNum++;
}
}
caret.setPosition(caretOldPos - innerContainersBeforeCaret);
removed = true;
}
}
}
caret.skip(1);
if (removed) {
recomputeDimensions();
}
return removed;
}
public BlockReference<?> getBlock(final Caret caret) {
BlockReference<?> block = null;
int pos = 0;
for (final Block b : content) {
caret.skip(1);
pos++;
final int deltaCaret = caret.getRemaining();
block = b.getBlock(caret);
if (block != null) {
return block;
}
if (caret.getRemaining() == 0 || deltaCaret >= 0 && caret.getRemaining() < 0) {
block = getBlockAt(pos - 1);
return block;
}
}
caret.skip(1);
return block;
}
@Override
public void recomputeDimensions() {
int l = 0; //Line
@ -377,6 +315,10 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
BlockContainer.initialized = true;
}
public static boolean isInitialized() {
return BlockContainer.initialized;
}
public static BinaryFont getDefaultFont(final boolean small) {
BlockContainer.checkInitialized();
return BlockContainer.defFonts[small ? 1 : 0];
@ -396,7 +338,7 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
return BlockContainer.defFontSizes[b ? 3 : 1];
}
public static void drawCaret(final GraphicEngine ge, final Renderer r, final Caret caret, final boolean small,
public static void drawCaret(final DisplayOutputDevice ge, final Renderer r, final Caret caret, final boolean small,
final int x, final int y, final int height) {
if (caret.getState() == CaretState.VISIBLE_ON) {
r.glColor(BlockContainer.getDefaultColor());
@ -424,18 +366,10 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
private static void checkInitialized() {
if (!BlockContainer.initialized) {
Engine.getPlatform().throwNewExceptionInInitializerError("Please initialize BlockContainer by running the method BlockContainer.initialize(...) first!");
WarpPI.getPlatform().throwNewExceptionInInitializerError("Please initialize BlockContainer by running the method BlockContainer.initialize(...) first!");
}
}
public int computeCaretMaxBound() {
int maxpos = 0;
for (final Block b : content) {
maxpos += 1 + b.computeCaretMaxBound();
}
return maxpos + 1;
}
public Function toFunction(final MathContext context) throws Error {
final ObjectArrayList<Block> blocks = getContent();
final ObjectArrayList<Feature> blockFeatures = new ObjectArrayList<>();
@ -452,4 +386,22 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
return result;
}
public <T extends Block> BlockReference<T> getReference(T block) {
var i = content.indexOf(block);
if (i < 0) return null;
return new BlockReference<>(block, i, content, this);
}
public ObjectArrayList<Block> getContentUnsafe() {
return content;
}
public Block getLastBlock() {
return content.isEmpty() ? null : content.get(content.size() - 1);
}
public BlockPosition getLastPosition() {
var lastBlock = getLastBlock();
return lastBlock != null ? new BlockPosition(lastBlock) : new BlockPosition(this);
}
}

View File

@ -1,15 +1,14 @@
package it.cavallium.warppi.gui.expression.blocks;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.math.Function;
import it.cavallium.warppi.math.MathContext;
import it.cavallium.warppi.math.parser.features.FeatureDivision;
import it.cavallium.warppi.math.parser.features.interfaces.Feature;
import it.cavallium.warppi.util.Error;
import it.unimi.dsi.fastutil.objects.AbstractObjectList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class BlockDivision extends Block {
@ -20,14 +19,19 @@ public class BlockDivision extends Block {
private int paddingLeftUpper;
private int paddingLeftLower;
private int h1;
private ObjectArrayList<BlockContainer> innerContainers;
public BlockDivision() {
containerUp = new BlockContainer(this, false);
containerDown = new BlockContainer(this, false);
recomputeDimensions();
innerContainers = new ObjectArrayList<>(2);
innerContainers.add(containerUp);
innerContainers.add(containerDown);
}
private BlockDivision(final TreeContainer parent, BlockDivision old, InputContext ic) {
private BlockDivision(final BlockContainer parent, BlockDivision old, InputContext ic) {
super(parent, old);
containerUp = old.containerUp.clone(this, ic);
containerDown = old.containerDown.clone(this, ic);
@ -35,10 +39,14 @@ public class BlockDivision extends Block {
paddingLeftUpper = old.paddingLeftUpper;
h1 = old.h1;
System.out.println(String.join(",", ""+h1, ""+old.h1, ""+line, ""+old.line));
innerContainers = new ObjectArrayList<>(2);
innerContainers.add(containerUp);
innerContainers.add(containerDown);
}
@Override
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
public void draw(final DisplayOutputDevice ge, final Renderer r, final int x, final int y, final Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
containerUp.draw(ge, r, x + 1 + paddingLeftUpper, y, caret);
@ -48,38 +56,16 @@ public class BlockDivision extends Block {
}
@Override
public boolean putBlock(final Caret caret, final Block newBlock) {
public boolean appendBlock(final Caret caret, final Block newBlock) {
boolean added = false;
added = added | containerUp.putBlock(caret, newBlock);
added = added | containerDown.putBlock(caret, newBlock);
added = added | containerUp.appendBlock(caret, newBlock);
added = added | containerDown.appendBlock(caret, newBlock);
if (added) {
recomputeDimensions();
}
return added;
}
@Override
public boolean delBlock(final Caret caret) {
boolean removed = false;
removed = removed | containerUp.delBlock(caret);
removed = removed | containerDown.delBlock(caret);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override
public BlockReference<?> getBlock(final Caret caret) {
BlockReference<?> bl = null;
bl = containerUp.getBlock(caret);
if (bl != null) {
return bl;
}
bl = containerDown.getBlock(caret);
return bl;
}
@Override
public void recomputeDimensions() {
final int w1 = containerUp.getWidth();
@ -120,11 +106,6 @@ public class BlockDivision extends Block {
return containerDown;
}
@Override
public int computeCaretMaxBound() {
return containerUp.computeCaretMaxBound() + containerDown.computeCaretMaxBound();
}
@Override
public Feature toFeature(final MathContext context) throws Error {
final Function upper = getUpperContainer().toFunction(context);
@ -141,14 +122,11 @@ public class BlockDivision extends Block {
@Override
public ObjectArrayList<BlockContainer> getInnerContainers() {
ObjectArrayList<BlockContainer> output = new ObjectArrayList<>();
output.add(containerUp);
output.add(containerDown);
return output;
return innerContainers;
}
@Override
public BlockDivision clone(final TreeContainer parent, InputContext ic) {
public BlockDivision clone(final BlockContainer parent, InputContext ic) {
return new BlockDivision(parent, this, ic);
}
}

View File

@ -1,8 +1,8 @@
package it.cavallium.warppi.gui.expression.blocks;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
public class BlockExponentialNotation extends BlockPower {
@ -18,14 +18,14 @@ public class BlockExponentialNotation extends BlockPower {
* @param old
* @param ic
*/
private BlockExponentialNotation(final TreeContainer parent, BlockExponentialNotation old, InputContext ic) {
private BlockExponentialNotation(final BlockContainer parent, BlockExponentialNotation old, InputContext ic) {
super(parent, old, ic);
this.bw = old.bw;
this.bh = old.bh;
}
@Override
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
public void draw(final DisplayOutputDevice ge, final Renderer r, final int x, final int y, final Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
r.glDrawStringLeft(x, y + height - bh, "â„Żâ„®");
@ -41,7 +41,7 @@ public class BlockExponentialNotation extends BlockPower {
}
@Override
public BlockExponentialNotation clone(final TreeContainer parent, InputContext ic) {
public BlockExponentialNotation clone(final BlockContainer parent, InputContext ic) {
return new BlockExponentialNotation(parent, this, ic);
}
}

View File

@ -1,8 +1,8 @@
package it.cavallium.warppi.gui.expression.blocks;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.math.Function;
import it.cavallium.warppi.math.MathContext;
@ -27,11 +27,16 @@ public class BlockLogarithm extends Block implements IParenthesis {
private int schh;
private int nmbh;
private int toph;
private ObjectArrayList<BlockContainer> innerContainers;
public BlockLogarithm() {
containerBase = new BlockContainer(this, true);
containerNumber = new BlockContainer(this, false);
recomputeDimensions();
innerContainers = new ObjectArrayList<>(2);
innerContainers.add(containerBase);
innerContainers.add(containerNumber);
}
public BlockLogarithm(final ObjectArrayList<Block> blocks) {
@ -40,7 +45,7 @@ public class BlockLogarithm extends Block implements IParenthesis {
recomputeDimensions();
}
private BlockLogarithm(final TreeContainer parent, BlockLogarithm old, InputContext ic) {
private BlockLogarithm(final BlockContainer parent, BlockLogarithm old, InputContext ic) {
super(parent, old);
containerBase = old.containerBase.clone(this, ic);
containerNumber = old.containerNumber.clone(this, ic);
@ -56,7 +61,7 @@ public class BlockLogarithm extends Block implements IParenthesis {
}
@Override
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
public void draw(final DisplayOutputDevice ge, final Renderer r, final int x, final int y, final Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
if (prefix != null) {
@ -80,38 +85,16 @@ public class BlockLogarithm extends Block implements IParenthesis {
}
@Override
public boolean putBlock(final Caret caret, final Block newBlock) {
public boolean appendBlock(final Caret caret, final Block newBlock) {
boolean added = false;
added = added | containerBase.putBlock(caret, newBlock);
added = added | containerNumber.putBlock(caret, newBlock);
added = added | containerBase.appendBlock(caret, newBlock);
added = added | containerNumber.appendBlock(caret, newBlock);
if (added) {
recomputeDimensions();
}
return added;
}
@Override
public boolean delBlock(final Caret caret) {
boolean removed = false;
removed = removed | containerBase.delBlock(caret);
removed = removed | containerNumber.delBlock(caret);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override
public BlockReference<?> getBlock(final Caret caret) {
BlockReference<?> bl = null;
bl = containerBase.getBlock(caret);
if (bl != null) {
return bl;
}
bl = containerNumber.getBlock(caret);
return bl;
}
@Override
public void recomputeDimensions() {
if (prefix == null) {
@ -163,11 +146,6 @@ public class BlockLogarithm extends Block implements IParenthesis {
return containerNumber;
}
@Override
public int computeCaretMaxBound() {
return containerBase.computeCaretMaxBound() + containerNumber.computeCaretMaxBound();
}
@Override
public Feature toFeature(final MathContext context) throws Error {
final Function base = getBaseContainer().toFunction(context);
@ -185,14 +163,11 @@ public class BlockLogarithm extends Block implements IParenthesis {
@Override
public ObjectArrayList<BlockContainer> getInnerContainers() {
ObjectArrayList<BlockContainer> output = new ObjectArrayList<>();
output.add(containerBase);
output.add(containerNumber);
return output;
return innerContainers;
}
@Override
public BlockLogarithm clone(final TreeContainer parent, InputContext ic) {
public BlockLogarithm clone(final BlockContainer parent, InputContext ic) {
return new BlockLogarithm(parent, this, ic);
}

View File

@ -8,12 +8,12 @@ public class BlockNumericChar extends BlockChar {
super(ch);
}
private BlockNumericChar(final TreeContainer parent, BlockNumericChar old, InputContext ic) {
private BlockNumericChar(final BlockContainer parent, BlockNumericChar old, InputContext ic) {
super(parent, old, ic);
}
@Override
public BlockNumericChar clone(final TreeContainer parent, InputContext ic) {
public BlockNumericChar clone(final BlockContainer parent, InputContext ic) {
return new BlockNumericChar(parent, this, ic);
}
}

View File

@ -0,0 +1,26 @@
package it.cavallium.warppi.gui.expression.blocks;
import it.cavallium.warppi.gui.GraphicalElement;
public interface BlockOrContainer extends GraphicalElement {
BlockOrContainer getParent();
BlockOrContainer getAt(int index);
default void recomputeDimensionsToRoot() {
var parent = this;
while (parent != null) {
parent.recomputeDimensions();
parent = parent.getParent();
}
}
default BlockContainer getRootContainer() {
var parent = this;
while (parent != null) {
parent = parent.getParent();
}
return (BlockContainer) parent;
}
int getIndex();
}

View File

@ -9,13 +9,15 @@ import it.cavallium.warppi.util.Error;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class BlockParenthesis extends BlockParenthesisAbstract {
private ObjectArrayList<BlockContainer> innerContainersCached;
public BlockParenthesis() {}
public BlockParenthesis(final ObjectArrayList<Block> blocks) {
super(blocks);
}
private BlockParenthesis(final TreeContainer parent, BlockParenthesis old, InputContext ic) {
private BlockParenthesis(final BlockContainer parent, BlockParenthesis old, InputContext ic) {
super(parent, old, ic);
}
@ -31,14 +33,7 @@ public class BlockParenthesis extends BlockParenthesisAbstract {
}
@Override
public ObjectArrayList<BlockContainer> getInnerContainers() {
ObjectArrayList<BlockContainer> output = new ObjectArrayList<>();
output.add(getNumberContainer());
return output;
}
@Override
public BlockParenthesis clone(final TreeContainer parent, InputContext ic) {
public BlockParenthesis clone(final BlockContainer parent, InputContext ic) {
return new BlockParenthesis(parent, this, ic);
}

View File

@ -1,8 +1,8 @@
package it.cavallium.warppi.gui.expression.blocks;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.math.MathContext;
import it.cavallium.warppi.math.parser.features.interfaces.Feature;
@ -14,6 +14,7 @@ public abstract class BlockParenthesisAbstract extends Block implements IParenth
private final BlockContainer containerNumber;
private final String prefix;
private final ObjectArrayList<BlockContainer> innerContainers;
private int prw;
private int chw;
private int chh;
@ -23,12 +24,18 @@ public abstract class BlockParenthesisAbstract extends Block implements IParenth
this.prefix = prefix;
recomputeDimensions();
innerContainers = new ObjectArrayList<>(1);
innerContainers.add(containerNumber);
}
public BlockParenthesisAbstract() {
containerNumber = new BlockContainer(this, false);
prefix = null;
recomputeDimensions();
innerContainers = new ObjectArrayList<>(1);
innerContainers.add(containerNumber);
}
/**
@ -36,27 +43,33 @@ public abstract class BlockParenthesisAbstract extends Block implements IParenth
* @param old
* @param ic
*/
BlockParenthesisAbstract(final TreeContainer parent, BlockParenthesisAbstract old, InputContext ic) {
BlockParenthesisAbstract(final BlockContainer parent, BlockParenthesisAbstract old, InputContext ic) {
super(parent, old);
containerNumber = old.containerNumber.clone(this, ic);
prefix = old.prefix;
prw = old.prw;
chw = old.chw;
chh = old.chh;
innerContainers = new ObjectArrayList<>(1);
innerContainers.add(containerNumber);
}
public BlockParenthesisAbstract(final ObjectArrayList<Block> blocks) {
containerNumber = new BlockContainer(this, false, blocks);
prefix = null;
recomputeDimensions();
innerContainers = new ObjectArrayList<>(1);
innerContainers.add(containerNumber);
}
@Override
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
public void draw(final DisplayOutputDevice ge, final Renderer r, final int x, final int y, final Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
if (prefix != null) {
r.glDrawStringLeft(x + 1, y + line - chh / 2, prefix);
r.glDrawStringLeft(x + 1, y + line - chh / 2f, prefix);
}
r.glDrawCharLeft(x + prw, y, 'â•­');
r.glDrawCharLeft(x + prw, y + height - chh, 'â•°');
@ -73,30 +86,15 @@ public abstract class BlockParenthesisAbstract extends Block implements IParenth
}
@Override
public boolean putBlock(final Caret caret, final Block newBlock) {
public boolean appendBlock(final Caret caret, final Block newBlock) {
boolean added = false;
added = added | containerNumber.putBlock(caret, newBlock);
added = added | containerNumber.appendBlock(caret, newBlock);
if (added) {
recomputeDimensions();
}
return added;
}
@Override
public boolean delBlock(final Caret caret) {
boolean removed = false;
removed = removed | containerNumber.delBlock(caret);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override
public BlockReference<?> getBlock(final Caret caret) {
return containerNumber.getBlock(caret);
}
@Override
public void recomputeDimensions() {
if (prefix == null) {
@ -122,11 +120,6 @@ public abstract class BlockParenthesisAbstract extends Block implements IParenth
return containerNumber;
}
@Override
public int computeCaretMaxBound() {
return containerNumber.computeCaretMaxBound();
}
@Override
public abstract Feature toFeature(MathContext context) throws Error;
@ -139,9 +132,7 @@ public abstract class BlockParenthesisAbstract extends Block implements IParenth
@Override
public ObjectArrayList<BlockContainer> getInnerContainers() {
ObjectArrayList<BlockContainer> output = new ObjectArrayList<>();
output.add(containerNumber);
return output;
return innerContainers;
}
}

View File

@ -0,0 +1,186 @@
package it.cavallium.warppi.gui.expression.blocks;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntCollections;
import org.apache.commons.lang3.NotImplementedException;
import java.util.Collections;
import java.util.Objects;
public final class BlockPosition {
private final BlockOrContainer pos;
public BlockPosition(BlockOrContainer pos) {
this.pos = pos;
}
public BlockPosition(Block block) {
this.pos = block;
}
public BlockPosition(BlockContainer container) {
this.pos = container;
}
public boolean isBlock() {
return pos instanceof Block;
}
public boolean isContainer() {
return pos instanceof BlockContainer;
}
public Block getBlock() {
return (Block) pos;
}
public BlockContainer getContainer() {
return (BlockContainer) pos;
}
public BlockOrContainer get() {
return pos;
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (BlockPosition) obj;
return Objects.equals(this.pos, that.pos);
}
@Override
public int hashCode() {
return Objects.hash(pos);
}
@Override
public String toString() {
return "BlockPosition[" +
"pos=" + pos + ']';
}
public BlockPosition getNext() {
if (pos instanceof BlockContainer) {
var container = (BlockContainer) pos;
var content = container.getContent();
if (content.isEmpty()) {
BlockContainer nextContainer;
if (container.hasParent()) {
var containers = container.getParentBlock().getInnerContainers();
var it = containers.listIterator(containers.indexOf(container) + 1);
nextContainer = it.hasNext() ? it.next() : null;
} else {
nextContainer = null;
}
if (nextContainer != null) {
return new BlockPosition(nextContainer);
} else {
var parentBlock = container.getParentBlock();
return parentBlock != null ? new BlockPosition(parentBlock) : null;
}
} else {
var targetBlock = content.get(0);
var innerContainers = targetBlock.getInnerContainers();
if (innerContainers != null && !innerContainers.isEmpty()) {
return new BlockPosition(innerContainers.get(0));
} else {
return new BlockPosition(targetBlock);
}
}
} else if (pos instanceof Block) {
var block = (Block) pos;
var ref = block.getReference();
var nextBlock = ref.getNextBlock();
if (nextBlock == null) {
var container = block.getParentContainer();
BlockContainer nextContainer;
if (container.hasParent()) {
var containers = container.getParentBlock().getInnerContainers();
var it = containers.listIterator(containers.indexOf(container) + 1);
nextContainer = it.hasNext() ? it.next() : null;
} else {
nextContainer = null;
}
if (nextContainer != null) {
return new BlockPosition(nextContainer);
} else {
var parentBlock = container.getParentBlock();
return parentBlock != null ? new BlockPosition(parentBlock) : null;
}
} else {
var targetBlock = nextBlock.get();
var innerContainers = targetBlock.getInnerContainers();
if (innerContainers != null && !innerContainers.isEmpty()) {
return new BlockPosition(innerContainers.get(0));
} else {
return new BlockPosition(targetBlock);
}
}
} else {
throw new UnsupportedOperationException();
}
}
public BlockPosition getPrevious() {
if (pos instanceof BlockContainer) {
var container = (BlockContainer) pos;
if (container.hasParent()) {
var parentBlock = container.getParentBlock();
var innerContainers = parentBlock.getInnerContainers();
if (innerContainers != null) {
var it = innerContainers.listIterator(innerContainers.indexOf(container));
if (it.hasPrevious()) {
var prevContainer = it.previous();
return prevContainer.getLastPosition();
} else {
var parentContainer = parentBlock.getParentContainer();
var blocks = parentContainer.getContentUnsafe();
var bIt = blocks.listIterator(blocks.indexOf(parentBlock));
if (bIt.hasPrevious()) {
return new BlockPosition(bIt.previous());
} else {
return new BlockPosition(parentContainer);
}
}
} else {
throw new UnsupportedOperationException();
}
} else {
return null;
}
} else if (pos instanceof Block) {
var block = (Block) pos;
var innerContainers = block.getInnerContainers();
if (innerContainers != null) {
var lastContainer = innerContainers.get(innerContainers.size() - 1);
return lastContainer.getLastPosition();
}
var ref = block.getReference();
var prevBlock = ref.getPreviousBlock();
if (prevBlock == null) {
var container = block.getParentContainer();
return new BlockPosition(container);
} else {
var targetBlock = prevBlock.get();
return new BlockPosition(targetBlock);
}
} else {
throw new UnsupportedOperationException();
}
}
public IntArrayList getURL() {
var url = new IntArrayList();
var parent = pos;
while (parent != null) {
var index = parent.getIndex();
if (index == -1) break;
url.add(index);
parent = parent.getParent();
}
Collections.reverse(url);
return url;
}
}

View File

@ -1,8 +1,8 @@
package it.cavallium.warppi.gui.expression.blocks;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.math.Function;
import it.cavallium.warppi.math.MathContext;
@ -14,48 +14,40 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class BlockPower extends Block {
private final BlockContainer containerExponent;
private final ObjectArrayList<BlockContainer> innerContainers;
public BlockPower() {
containerExponent = new BlockContainer(this, true);
recomputeDimensions();
innerContainers = new ObjectArrayList<>(1);
innerContainers.add(containerExponent);
}
protected BlockPower(final TreeContainer parent, BlockPower old, InputContext ic) {
protected BlockPower(final BlockContainer parent, BlockPower old, InputContext ic) {
super(parent, old);
this.containerExponent = old.containerExponent.clone(this, ic);
innerContainers = new ObjectArrayList<>(1);
innerContainers.add(containerExponent);
}
@Override
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
public void draw(final DisplayOutputDevice ge, final Renderer r, final int x, final int y, final Caret caret) {
BlockContainer.getDefaultFont(true).use(ge);
r.glColor(BlockContainer.getDefaultColor());
containerExponent.draw(ge, r, x, y, caret);
}
@Override
public boolean putBlock(final Caret caret, final Block newBlock) {
public boolean appendBlock(final Caret caret, final Block newBlock) {
boolean added = false;
added = added | containerExponent.putBlock(caret, newBlock);
added = added | containerExponent.appendBlock(caret, newBlock);
if (added) {
recomputeDimensions();
}
return added;
}
@Override
public boolean delBlock(Caret caret) {
boolean removed = false;
removed = removed | containerExponent.delBlock(caret);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override
public BlockReference<?> getBlock(final Caret caret) {
return containerExponent.getBlock(caret);
}
@Override
public void recomputeDimensions() {
@ -77,11 +69,6 @@ public class BlockPower extends Block {
return containerExponent;
}
@Override
public int computeCaretMaxBound() {
return containerExponent.computeCaretMaxBound();
}
@Override
public Feature toFeature(final MathContext context) throws Error {
final Function exp = getExponentContainer().toFunction(context);
@ -95,13 +82,11 @@ public class BlockPower extends Block {
@Override
public ObjectArrayList<BlockContainer> getInnerContainers() {
ObjectArrayList<BlockContainer> output = new ObjectArrayList<>();
output.add(containerExponent);
return output;
return innerContainers;
}
@Override
public BlockPower clone(final TreeContainer parent, InputContext ic) {
public BlockPower clone(final BlockContainer parent, InputContext ic) {
return new BlockPower(parent, this, ic);
}
}

View File

@ -1,8 +1,8 @@
package it.cavallium.warppi.gui.expression.blocks;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.math.Function;
import it.cavallium.warppi.math.MathContext;
@ -14,55 +14,42 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class BlockPower2 extends Block {
private final BlockContainer containerExponent;
private final ObjectArrayList<BlockContainer> innerContainers;
public BlockPower2() {
containerExponent = new BlockContainer(this, true);
containerExponent.addBlock(0, new BlockNumericChar('2'));
recomputeDimensions();
innerContainers = new ObjectArrayList<>(1);
innerContainers.add(containerExponent);
}
private BlockPower2(final TreeContainer parent, BlockPower2 old, InputContext ic) {
private BlockPower2(final BlockContainer parent, BlockPower2 old, InputContext ic) {
super(parent, old);
this.containerExponent = old.containerExponent.clone(this, ic);
innerContainers = new ObjectArrayList<>(1);
innerContainers.add(containerExponent);
}
@Override
public int getCaretDeltaPositionAfterCreation() {
return 3;
}
@Override
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
public void draw(final DisplayOutputDevice ge, final Renderer r, final int x, final int y, final Caret caret) {
BlockContainer.getDefaultFont(true).use(ge);
r.glColor(BlockContainer.getDefaultColor());
containerExponent.draw(ge, r, x, y, caret);
}
@Override
public boolean putBlock(final Caret caret, final Block newBlock) {
public boolean appendBlock(final Caret caret, final Block newBlock) {
boolean added = false;
added = added | containerExponent.putBlock(caret, newBlock);
added = added | containerExponent.appendBlock(caret, newBlock);
if (added) {
recomputeDimensions();
}
return added;
}
@Override
public boolean delBlock(final Caret caret) {
boolean removed = false;
removed = removed | containerExponent.delBlock(caret);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override
public BlockReference<?> getBlock(final Caret caret) {
return containerExponent.getBlock(caret);
}
@Override
public void recomputeDimensions() {
final int w2 = containerExponent.getWidth();
@ -83,11 +70,6 @@ public class BlockPower2 extends Block {
return containerExponent;
}
@Override
public int computeCaretMaxBound() {
return containerExponent.computeCaretMaxBound();
}
@Override
public Feature toFeature(final MathContext context) throws Error {
final Function exp = getExponentContainer().toFunction(context);
@ -101,13 +83,11 @@ public class BlockPower2 extends Block {
@Override
public ObjectArrayList<BlockContainer> getInnerContainers() {
ObjectArrayList<BlockContainer> output = new ObjectArrayList<>();
output.add(containerExponent);
return output;
return innerContainers;
}
@Override
public BlockPower2 clone(final TreeContainer parent, InputContext ic) {
public BlockPower2 clone(final BlockContainer parent, InputContext ic) {
return new BlockPower2(parent, this, ic);
}
}

View File

@ -1,13 +1,17 @@
package it.cavallium.warppi.gui.expression.blocks;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class BlockReference<T extends Block> {
private final T block;
private final BlockContainer container;
private final int blockPosition;
private int cachedBlockPosition;
private final ObjectArrayList<Block> containerBlocks;
public BlockReference(final T block, final int blockPosition, final BlockContainer container) {
public BlockReference(final T block, final int cachedBlockPosition, final ObjectArrayList<Block> containerBlocks, final BlockContainer container) {
this.block = block;
this.blockPosition = blockPosition;
this.cachedBlockPosition = cachedBlockPosition;
this.containerBlocks = containerBlocks;
this.container = container;
}
@ -20,23 +24,28 @@ public class BlockReference<T extends Block> {
}
public int getIndex() {
return blockPosition;
if (containerBlocks.size() > cachedBlockPosition && cachedBlockPosition >= 0
&& containerBlocks.get(cachedBlockPosition) == block) {
return cachedBlockPosition;
} else {
return cachedBlockPosition = containerBlocks.indexOf(block);
}
}
public BlockReference<?> getNextBlock() {
return getBlockAtSafe(this.blockPosition + 1);
return getBlockAtSafe(getIndex() + 1);
}
public boolean hasNextBlock() {
return isInsideBounds(this.blockPosition + 1);
return isInsideBounds(getIndex() + 1);
}
public BlockReference<?> getPreviousBlock() {
return getBlockAtSafe(this.blockPosition - 1);
return getBlockAtSafe(getIndex() - 1);
}
public boolean hasPreviousBlock() {
return isInsideBounds(this.blockPosition - 1);
return isInsideBounds(getIndex() - 1);
}
private BlockReference<?> getBlockAtSafe(final int i) {

View File

@ -13,7 +13,7 @@ public class BlockSine extends BlockParenthesisAbstract {
super("SIN");
}
private BlockSine(final TreeContainer parent, BlockSine old, InputContext ic) {
private BlockSine(final BlockContainer parent, BlockSine old, InputContext ic) {
super(parent, old, ic);
}
@ -24,7 +24,7 @@ public class BlockSine extends BlockParenthesisAbstract {
}
@Override
public BlockSine clone(final TreeContainer parent, InputContext ic) {
public BlockSine clone(final BlockContainer parent, InputContext ic) {
return new BlockSine(parent, this, ic);
}
}

View File

@ -1,8 +1,8 @@
package it.cavallium.warppi.gui.expression.blocks;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.math.Function;
import it.cavallium.warppi.math.MathContext;
@ -14,22 +14,27 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class BlockSquareRoot extends Block {
private final BlockContainer containerNumber;
private final ObjectArrayList<BlockContainer> innerContainers;
private int h1;
public BlockSquareRoot() {
containerNumber = new BlockContainer(this, false);
recomputeDimensions();
innerContainers = new ObjectArrayList<>(1);
innerContainers.add(containerNumber);
}
private BlockSquareRoot(final TreeContainer parent, BlockSquareRoot old, InputContext ic) {
private BlockSquareRoot(final BlockContainer parent, BlockSquareRoot old, InputContext ic) {
super(parent, old);
this.containerNumber = old.containerNumber.clone(this, ic);
this.h1 = old.h1;
innerContainers = new ObjectArrayList<>(1);
innerContainers.add(containerNumber);
}
@Override
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
public void draw(final DisplayOutputDevice ge, final Renderer r, final int x, final int y, final Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
r.glDrawLine(x, y + height - 10 + 1, x, y + height - 10 + 2); // /
@ -44,30 +49,15 @@ public class BlockSquareRoot extends Block {
}
@Override
public boolean putBlock(final Caret caret, final Block newBlock) {
public boolean appendBlock(final Caret caret, final Block newBlock) {
boolean added = false;
added = added | containerNumber.putBlock(caret, newBlock);
added = added | containerNumber.appendBlock(caret, newBlock);
if (added) {
recomputeDimensions();
}
return added;
}
@Override
public boolean delBlock(final Caret caret) {
boolean removed = false;
removed = removed | containerNumber.delBlock(caret);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override
public BlockReference<?> getBlock(final Caret caret) {
return containerNumber.getBlock(caret);
}
@Override
public void recomputeDimensions() {
final int w1 = containerNumber.getWidth();
@ -93,11 +83,6 @@ public class BlockSquareRoot extends Block {
return containerNumber;
}
@Override
public int computeCaretMaxBound() {
return containerNumber.computeCaretMaxBound();
}
@Override
public Feature toFeature(final MathContext context) throws Error {
final Function contnt = getNumberContainer().toFunction(context);
@ -119,7 +104,7 @@ public class BlockSquareRoot extends Block {
}
@Override
public BlockSquareRoot clone(final TreeContainer parent, InputContext ic) {
public BlockSquareRoot clone(final BlockContainer parent, InputContext ic) {
return new BlockSquareRoot(parent, this, ic);
}
}

View File

@ -1,8 +1,8 @@
package it.cavallium.warppi.gui.expression.blocks;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.math.MathContext;
import it.cavallium.warppi.math.MathematicalSymbols;
@ -16,32 +16,22 @@ public class BlockUndefined extends Block {
recomputeDimensions();
}
private BlockUndefined(final TreeContainer parent, BlockUndefined old, InputContext ic) {
private BlockUndefined(final BlockContainer parent, BlockUndefined old, InputContext ic) {
super(parent, old);
}
@Override
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
public void draw(final DisplayOutputDevice ge, final Renderer r, final int x, final int y, final Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
r.glDrawStringLeft(x, y, "UNDEFINED");
}
@Override
public boolean putBlock(final Caret caret, final Block newBlock) {
public boolean appendBlock(final Caret caret, final Block newBlock) {
return false;
}
@Override
public boolean delBlock(final Caret caret) {
return false;
}
@Override
public BlockReference<?> getBlock(final Caret caret) {
return null;
}
@Override
public void recomputeDimensions() {
width = BlockContainer.getDefaultFont(small).getStringWidth("UNDEFINED");
@ -55,11 +45,6 @@ public class BlockUndefined extends Block {
recomputeDimensions();
}
@Override
public int computeCaretMaxBound() {
return 0;
}
@Override
public Feature toFeature(final MathContext context) {
return new FeatureChar(MathematicalSymbols.UNDEFINED);
@ -76,7 +61,7 @@ public class BlockUndefined extends Block {
}
@Override
public BlockUndefined clone(final TreeContainer parent, InputContext ic) {
public BlockUndefined clone(final BlockContainer parent, InputContext ic) {
return new BlockUndefined(parent, this, ic);
}

View File

@ -1,15 +1,13 @@
package it.cavallium.warppi.gui.expression.blocks;
import java.util.Arrays;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.event.KeyPressedEvent;
import it.cavallium.warppi.event.KeyReleasedEvent;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.ExtraMenu;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.math.MathContext;
import it.cavallium.warppi.math.functions.Variable.V_TYPE;
@ -45,7 +43,7 @@ public class BlockVariable extends Block {
recomputeDimensions();
}
private BlockVariable(final TreeContainer parent, BlockVariable old, InputContext ic) {
private BlockVariable(final BlockContainer parent, BlockVariable old, InputContext ic) {
super(parent, old);
this.ic = ic;
this.ch = old.ch;
@ -82,7 +80,7 @@ public class BlockVariable extends Block {
}
@Override
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
public void draw(final DisplayOutputDevice ge, final Renderer r, final int x, final int y, final Caret caret) {
if (ic.variableTypeDirtyID != typeDirtyID) {
retrieveValue();
}
@ -108,20 +106,10 @@ public class BlockVariable extends Block {
}
@Override
public boolean putBlock(final Caret caret, final Block newBlock) {
public boolean appendBlock(final Caret caret, final Block newBlock) {
return false;
}
@Override
public boolean delBlock(final Caret caret) {
return false;
}
@Override
public BlockReference<?> getBlock(final Caret caret) {
return null;
}
@Override
public void recomputeDimensions() {
width = BlockContainer.getDefaultCharWidth(small);
@ -139,11 +127,6 @@ public class BlockVariable extends Block {
return ch;
}
@Override
public int computeCaretMaxBound() {
return 0;
}
@Override
public ExtraMenu<?> getExtraMenu() {
return menu;
@ -238,9 +221,9 @@ public class BlockVariable extends Block {
}
@Override
public void draw(final GraphicEngine ge, final Renderer r, final Caret caret) {
public void draw(final DisplayOutputDevice ge, final Renderer r, final Caret caret) {
r.glColor3f(1.0f, 1.0f, 1.0f);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().guiSkin.use(ge);
WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().guiSkin.use(ge);
int popupX = location[0];
int popupY = location[1];
if (popupX < 0) {
@ -249,7 +232,7 @@ public class BlockVariable extends Block {
if (popupY < 0) {
popupY = 0;
}
final int[] screenSize = ge.getSize();
final int[] screenSize = ge.getDisplaySize();
if (popupX + width >= screenSize[0]) {
popupX = screenSize[0] - width - 1;
}
@ -273,7 +256,7 @@ public class BlockVariable extends Block {
}
@Override
public VariableMenu clone(final TreeContainer parent, InputContext ic) {
public VariableMenu clone(final BlockContainer parent, InputContext ic) {
return new VariableMenu(this, block.clone(parent, ic));
}
@ -295,7 +278,7 @@ public class BlockVariable extends Block {
}
@Override
public BlockVariable clone(final TreeContainer parent, InputContext ic) {
public BlockVariable clone(final BlockContainer parent, InputContext ic) {
return new BlockVariable(parent, this, ic);
}
}

View File

@ -3,6 +3,7 @@ package it.cavallium.warppi.gui.expression.containers;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.expression.blocks.Block;
import it.cavallium.warppi.gui.expression.blocks.BlockChar;
import it.cavallium.warppi.gui.expression.blocks.BlockNumericChar;
public class InlineInputContainer extends InputContainer {
@ -30,6 +31,21 @@ public class InlineInputContainer extends InputContainer {
@Override
public Block parseChar(final char c) {
return new BlockChar(c);
switch (c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
return new BlockNumericChar(c);
default:
return new BlockChar(c);
}
}
}

View File

@ -1,16 +1,14 @@
package it.cavallium.warppi.gui.expression.containers;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.event.KeyboardEventListener;
import it.cavallium.warppi.gui.GraphicalElement;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.CaretState;
import it.cavallium.warppi.gui.expression.ExtraMenu;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.expression.blocks.Block;
import it.cavallium.warppi.gui.expression.blocks.BlockContainer;
import it.cavallium.warppi.gui.expression.blocks.BlockReference;
import it.cavallium.warppi.gui.expression.blocks.*;
import it.cavallium.warppi.gui.expression.layouts.InputLayout;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.math.Function;
import it.cavallium.warppi.math.MathContext;
@ -22,7 +20,6 @@ public abstract class InputContainer implements GraphicalElement, InputLayout {
protected Caret caret;
private static final float CARET_DURATION = 0.5f;
private float caretTime;
private int maxPosition = 0;
private boolean parsed = false;
private ExtraMenu<?> extra;
protected InputContext inputContext;
@ -49,8 +46,8 @@ public abstract class InputContainer implements GraphicalElement, InputLayout {
public InputContainer(final InputContext ic, final boolean small, final int minWidth, final int minHeight) {
inputContext = ic;
caret = new Caret(CaretState.VISIBLE_ON, 0);
root = new BlockContainer(null, small, false);
caret = new Caret(CaretState.VISIBLE_ON, new BlockPosition(root));
}
/**
@ -61,10 +58,9 @@ public abstract class InputContainer implements GraphicalElement, InputLayout {
protected InputContainer(InputContainer old, InputContext ic) {
this.caretTime = old.caretTime;
this.extra = old.extra == null ? null : old.extra.clone(null, ic);
this.maxPosition = old.maxPosition;
this.caret = old.caret == null ? null : new Caret(old.caret);
this.inputContext = ic;
this.root = old.root == null ? null : old.root.clone(null, ic);
this.caret = old.caret == null ? null : new Caret(old.caret, root);
this.parsed = old.parsed;
}
@ -75,10 +71,9 @@ public abstract class InputContainer implements GraphicalElement, InputLayout {
public void typeBlock(final Block b) {
if (b != null) {
caret.resetRemaining();
if (root.putBlock(caret, b)) {
caret.setPosition(caret.getPosition() + b.getCaretDeltaPositionAfterCreation());
maxPosition = root.computeCaretMaxBound();
if (root.appendBlock(caret, b)) {
var innerPos = b.getFirstInnerPosition();
caret.setPosition(innerPos == null ? new BlockPosition(b) : innerPos);
root.recomputeDimensions();
}
closeExtra();
@ -92,13 +87,65 @@ public abstract class InputContainer implements GraphicalElement, InputLayout {
}
public void del() {
caret.resetRemaining();
if (root.delBlock(caret)) {
root.recomputeDimensions();
var pos = caret.getPos();
BlockOrContainer currentElementToRecompute;
boolean removed;
if (pos.isBlock()) {
var block = pos.getBlock();
var lastInnerPosition = block.getLastInnerPosition();
if (lastInnerPosition != null) {
caret.setPosition(lastInnerPosition);
currentElementToRecompute = null;
removed = false;
} else {
caret.setPosition(pos.getPrevious());
var parent = block.getParentContainer();
parent.removeBlockUnsafe(block);
currentElementToRecompute = parent;
removed = true;
}
} else if (pos.isContainer()) {
var container = pos.getContainer();
if (container == root) {
currentElementToRecompute = null;
removed = false;
} else if (!container.hasParent()) {
throw new IllegalStateException();
} else {
var block = container.getParentBlock();
var containers = block.getInnerContainers();
BlockContainer prevContainer;
if (containers == null) {
prevContainer = null;
} else {
var containerIt = containers.listIterator(containers.indexOf(container));
if (containerIt.hasPrevious()) {
prevContainer = containerIt.previous();
} else {
prevContainer = null;
}
}
if (prevContainer != null) {
var lastPosition = prevContainer.getLastPosition();
caret.setPosition(lastPosition);
currentElementToRecompute = null;
removed = false;
} else {
caret.setPosition(pos.getPrevious());
var parentContainer = block.getParentContainer();
parentContainer.removeBlockUnsafe(block);
currentElementToRecompute = parentContainer;
removed = true;
}
}
} else {
throw new UnsupportedOperationException();
}
if (caret.getPosition() > 0) {
caret.setPosition(caret.getPosition() - 1);
maxPosition = root.computeCaretMaxBound();
if (removed) {
while (currentElementToRecompute != null) {
currentElementToRecompute.recomputeDimensions();
currentElementToRecompute = currentElementToRecompute.getParent();
}
}
caret.turnOn();
caretTime = 0;
@ -106,46 +153,25 @@ public abstract class InputContainer implements GraphicalElement, InputLayout {
}
public BlockReference<?> getSelectedBlock() {
caret.resetRemaining();
final BlockReference<?> selectedBlock = root.getBlock(caret);
return selectedBlock;
}
public BlockReference<?> getBlockAtCaretPosition(final int i) {
final BlockReference<?> selectedBlock = root.getBlock(new Caret(CaretState.HIDDEN, i));
return selectedBlock;
var pos = caret.getPos();
if (pos.isBlock()) {
return pos.getBlock().getReference();
} else {
var container = pos.getContainer();
if (container.hasParent()) {
return container.getParentBlock().getReference();
} else {
return null;
}
}
}
public void moveLeft() {
final int curPos = caret.getPosition();
if (curPos > 0) {
caret.setPosition(curPos - 1);
var prev = caret.getPos().getPrevious();
if (prev != null) {
caret.setPosition(prev);
} else {
caret.setPosition(maxPosition - 1);
}
caret.turnOn();
caretTime = 0;
closeExtra();
}
public void moveRight(final int delta) {
final int curPos = caret.getPosition();
if (curPos + delta < maxPosition) {
caret.setPosition(curPos + delta);
} else {
caret.setPosition(0);
}
caret.turnOn();
caretTime = 0;
closeExtra();
}
public void moveTo(final int position) {
if (position < maxPosition) {
caret.setPosition(position);
} else {
caret.setPosition(0);
caret.setPosition(root.getLastPosition());
}
caret.turnOn();
caretTime = 0;
@ -153,7 +179,22 @@ public abstract class InputContainer implements GraphicalElement, InputLayout {
}
public void moveRight() {
moveRight(1);
var prev = caret.getPos().getNext();
if (prev != null) {
caret.setPosition(prev);
} else {
caret.setPosition(new BlockPosition(root));
}
caret.turnOn();
caretTime = 0;
closeExtra();
}
public void moveTo(final BlockPosition position) {
caret.setPosition(position);
caret.turnOn();
caretTime = 0;
closeExtra();
}
@Override
@ -211,8 +252,7 @@ public abstract class InputContainer implements GraphicalElement, InputLayout {
* @param y
* Position relative to the window.
*/
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y) {
caret.resetRemaining();
public void draw(final DisplayOutputDevice ge, final Renderer r, final int x, final int y) {
root.draw(ge, r, x, y, caret);
if (extra != null) {
extra.draw(ge, r, caret);
@ -220,27 +260,13 @@ public abstract class InputContainer implements GraphicalElement, InputLayout {
}
public void clear() {
caret = new Caret(CaretState.VISIBLE_ON, 0);
caret = new Caret(CaretState.VISIBLE_ON, new BlockPosition(root));
root.clear();
maxPosition = root.computeCaretMaxBound();
recomputeDimensions();
}
public boolean isEmpty() {
return maxPosition <= 1;
}
public int getCaretMaxPosition() {
return maxPosition;
}
public void setCaretPosition(final int pos) {
if (pos > 0 && pos < maxPosition) {
caret.setPosition(pos);
}
caret.turnOn();
caretTime = 0;
closeExtra();
return root.getSize() == 0;
}
public void setParsed(final boolean parsed) {

View File

@ -3,22 +3,12 @@ package it.cavallium.warppi.gui.expression.containers;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.CaretState;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.expression.blocks.Block;
import it.cavallium.warppi.gui.expression.blocks.BlockChar;
import it.cavallium.warppi.gui.expression.blocks.BlockContainer;
import it.cavallium.warppi.gui.expression.blocks.BlockDivision;
import it.cavallium.warppi.gui.expression.blocks.BlockLogarithm;
import it.cavallium.warppi.gui.expression.blocks.BlockNumericChar;
import it.cavallium.warppi.gui.expression.blocks.BlockParenthesis;
import it.cavallium.warppi.gui.expression.blocks.BlockPower;
import it.cavallium.warppi.gui.expression.blocks.BlockPower2;
import it.cavallium.warppi.gui.expression.blocks.BlockReference;
import it.cavallium.warppi.gui.expression.blocks.BlockSine;
import it.cavallium.warppi.gui.expression.blocks.BlockSquareRoot;
import it.cavallium.warppi.gui.expression.blocks.BlockVariable;
import it.cavallium.warppi.gui.expression.blocks.IParenthesis;
import it.cavallium.warppi.gui.expression.blocks.*;
import it.cavallium.warppi.math.MathematicalSymbols;
import java.util.ArrayList;
import java.util.List;
public class NormalInputContainer extends InputContainer {
@Deprecated()
@ -43,7 +33,6 @@ public class NormalInputContainer extends InputContainer {
/**
* Copy
* @param userInput
* @param ic
*/
public NormalInputContainer(InputContainer old, InputContext ic) {
@ -106,36 +95,24 @@ public class NormalInputContainer extends InputContainer {
switch (c) {
case MathematicalSymbols.PARENTHESIS_CLOSE: {
final BlockReference<?> ref = getSelectedBlock();
if (ref == null) {
BlockParenthesisAbstract parenthesis = findParenthesis(ref.get());
if (parenthesis == null) {
break;
} else {
final Caret newCaret = new Caret(CaretState.HIDDEN, caret.getPosition());
BlockContainer currentContainer;
BlockReference<?> newRef = ref;
int safeExit = 0;
do {
currentContainer = (BlockContainer) newRef.get().getParentContainer();
final int initialRelativeIndex = currentContainer.getContent().indexOf(newRef.get());
final int newIndex = newCaret.getPosition() + currentContainer.getContent().size() - initialRelativeIndex;
newRef = getBlockAtCaretPosition(newIndex);
newCaret.setPosition(newIndex);
safeExit++;
} while (newRef != null && newRef.get() instanceof IParenthesis == false && currentContainer != null && safeExit < 100000);
if (safeExit >= 100000) {
System.err.println("Error 0x001030: Infinite loop");
}
if (newRef != null) {
moveTo(newCaret.getPosition());
}
moveTo(new BlockPosition(parenthesis));
}
break;
}
case MathematicalSymbols.POWER_OF_TWO:
moveTo(new BlockPosition(getSelectedBlock().get()));
break;
case MathematicalSymbols.DIVISION: {
@SuppressWarnings("unchecked")
final BlockReference<BlockDivision> ref = (BlockReference<BlockDivision>) getSelectedBlock();
@SuppressWarnings("unused")
final BlockContainer parentContainer = ref.getContainer();
BlockReference<?> currentBlock = ref;
List<Block> blocksToMove = new ArrayList<>();
boolean groupedBefore = false;
int before = 0;
while (true) {
@ -148,28 +125,39 @@ public class NormalInputContainer extends InputContainer {
if (!groupedBefore) {
groupedBefore = true;
}
blocksToMove.add(b);
before++;
} else {
break;
}
}
if (groupedBefore) {
moveLeft();
for (int i = 0; i < before; i++) {
final BlockReference<?> b = getSelectedBlock();
del();
moveRight();
typeBlock(b.get());
moveLeft();
moveLeft();
var div = ref.get();
var upperContainer = div.getUpperContainer();
for (int i = blocksToMove.size() - 1; i >= 0; i--) {
var b = blocksToMove.get(i);
b.getParentContainer().removeBlockUnsafe(b);
upperContainer.appendBlock(b);
}
for (int i = 0; i < before + 1; i++) {
moveRight();
}
moveRight();// Move to the divisor
div.recomputeDimensionsToRoot();
moveTo(new BlockPosition(div.getLowerContainer()));
}
break;
}
}
}
private BlockParenthesisAbstract findParenthesis(Block o) {
while (!(o instanceof BlockParenthesisAbstract)) {
var pc = o.getParentContainer();
if (!pc.hasParent()) {
return null;
}
o = pc.getParentBlock();
if (o == null) {
return null;
}
}
return (BlockParenthesisAbstract) o;
}
}

View File

@ -1,33 +1,40 @@
package it.cavallium.warppi.gui.expression.containers;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.GraphicalElement;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.CaretState;
import it.cavallium.warppi.gui.expression.blocks.Block;
import it.cavallium.warppi.gui.expression.blocks.BlockContainer;
import it.cavallium.warppi.gui.expression.blocks.BlockPosition;
import it.cavallium.warppi.gui.expression.layouts.OutputLayout;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public abstract class OutputContainer implements GraphicalElement, OutputLayout {
private static final long serialVersionUID = -5714825964892683571L;
public final ObjectArrayList<BlockContainer> roots;
private final Caret caret = new Caret(CaretState.HIDDEN, 0);
private final Caret caret;
public OutputContainer() {
roots = new ObjectArrayList<>();
roots.add(new BlockContainer());
var root = new BlockContainer();
roots.add(root);
caret = new Caret(CaretState.HIDDEN, new BlockPosition(root));
}
public OutputContainer(final boolean small) {
roots = new ObjectArrayList<>();
roots.add(new BlockContainer(null, small));
var root = new BlockContainer(null, small);
roots.add(root);
caret = new Caret(CaretState.HIDDEN, new BlockPosition(root));
}
public OutputContainer(final boolean small, final int minWidth, final int minHeight) {
roots = new ObjectArrayList<>();
roots.add(new BlockContainer(null, small));
var root = new BlockContainer(null, small);
roots.add(root);
caret = new Caret(CaretState.HIDDEN, new BlockPosition(root));
}
public void setContentAsSingleGroup(final ObjectArrayList<Block> blocks) {
@ -119,7 +126,7 @@ public abstract class OutputContainer implements GraphicalElement, OutputLayout
* @param y
* Position relative to the window.
*/
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y) {
public void draw(final DisplayOutputDevice ge, final Renderer r, final int x, final int y) {
int offset = 0;
for (final BlockContainer root : roots) {
root.draw(ge, r, x, y + offset, caret);

View File

@ -1,29 +1,32 @@
package it.cavallium.warppi.gui.graphicengine;
import it.cavallium.warppi.util.EventSubscriber;
import java.io.IOException;
import java.util.List;
import it.cavallium.warppi.flow.Observable;
import java.util.function.Consumer;
public interface GraphicEngine {
int[] getSize();
boolean isSupported();
boolean isInitialized();
void setTitle(String title);
void setResizable(boolean r);
void setDisplayMode(final int ww, final int wh);
void setDisplayMode(int ww, int wh);
void create(Runnable object);
default void create() {
create(null);
};
void create(Runnable object);
Observable<Integer[]> onResize();
EventSubscriber<Integer[]> onResize();
int getWidth();
@ -43,10 +46,6 @@ public interface GraphicEngine {
Skin loadSkin(String file) throws IOException;
void waitForExit();
boolean isSupported();
boolean doesRefreshPauses();
default boolean supportsFontRegistering() {

View File

@ -1,5 +1,7 @@
package it.cavallium.warppi.gui.graphicengine;
import it.cavallium.warppi.gui.graphicengine.impl.common.ReboundedRenderer;
public interface Renderer {
void glColor3i(int r, int gg, int b);
@ -42,4 +44,8 @@ public interface Renderer {
void glClearSkin();
BinaryFont getCurrentFont();
default Renderer getBoundedInstance(int dx, int dy, int width, int height) {
return new ReboundedRenderer(this, dx, dy, width, height);
}
}

View File

@ -1,5 +1,5 @@
package it.cavallium.warppi.gui.graphicengine;
public interface RenderingLoop {
void refresh();
void refresh(boolean force);
}

View File

@ -3,17 +3,27 @@ package it.cavallium.warppi.gui.graphicengine;
import java.io.IOException;
import java.net.URISyntaxException;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
public interface Skin {
void load(String file) throws IOException, URISyntaxException;
void initialize(GraphicEngine d);
void initialize(DisplayOutputDevice d);
boolean isInitialized();
void use(GraphicEngine d);
void use(DisplayOutputDevice d);
/**
* May not be available before initialization
* @return skin width
*/
int getSkinWidth();
/**
* May not be available before initialization
* @return skin height
*/
int getSkinHeight();
}

View File

@ -3,9 +3,9 @@ package it.cavallium.warppi.gui.graphicengine.impl.common;
import java.io.File;
import java.io.IOException;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.Platform.ImageUtils.ImageReader;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.graphicengine.Skin;
public abstract class PngSkin implements Skin {
@ -25,7 +25,7 @@ public abstract class PngSkin implements Skin {
if (!file.startsWith("/")) {
file = "/" + file;
}
final ImageReader r = Engine.getPlatform().getImageUtils().load(Engine.getPlatform().getStorageUtils().getResourceStream(file));
final ImageReader r = WarpPI.getPlatform().getImageUtils().load(WarpPI.getPlatform().getPlatformStorage().getResourceStream(file));
if (r == null) {
skinData = new int[0];
skinSize = new int[] { 0, 0 };
@ -37,7 +37,7 @@ public abstract class PngSkin implements Skin {
}
@Override
public void initialize(final GraphicEngine d) {
public void initialize(final DisplayOutputDevice d) {
// TODO Auto-generated method stub
}

View File

@ -1,17 +1,13 @@
package it.cavallium.warppi.gui.graphicengine.impl.common;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.Platform.ConsoleUtils;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.util.Utils;
public abstract class RFTFont implements BinaryFont {
@ -62,7 +58,7 @@ public abstract class RFTFont implements BinaryFont {
}
private void load(final String path, final boolean onlyRaw) throws IOException {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN + 1, "Loading font " + path);
WarpPI.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN + 1, "Loading font " + path);
loadFont(path);
if (!onlyRaw) {
chars32 = new int[intervalsTotalSize * charIntCount];
@ -94,14 +90,14 @@ public abstract class RFTFont implements BinaryFont {
}
}
Engine.getPlatform().gc();
WarpPI.getPlatform().gc();
}
private void loadFont(String string) throws IOException {
if (!string.startsWith("/")) {
string = "/" + string;
}
InputStream res = Engine.getPlatform().getStorageUtils().getResourceStream(string);
InputStream res = WarpPI.getPlatform().getPlatformStorage().getResourceStream(string);
final int[] file = Utils.realBytes(Utils.convertStreamToByteArray(res, res.available()));
final int filelength = file.length;
if (filelength >= 16) {
@ -140,7 +136,7 @@ public abstract class RFTFont implements BinaryFont {
} catch (final Exception ex) {
ex.printStackTrace();
System.out.println(string);
Engine.getPlatform().exit(-1);
WarpPI.getPlatform().exit(-1);
}
}
} else {
@ -266,7 +262,7 @@ public abstract class RFTFont implements BinaryFont {
}
@Override
public void initialize(final GraphicEngine d) {}
public void initialize(final DisplayOutputDevice d) {}
@Override
public int getStringWidth(final String text) {
@ -314,7 +310,7 @@ public abstract class RFTFont implements BinaryFont {
}
@Override
public void use(final GraphicEngine d) {
public void use(final DisplayOutputDevice d) {
}

View File

@ -0,0 +1,130 @@
package it.cavallium.warppi.gui.graphicengine.impl.common;
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
import it.cavallium.warppi.gui.graphicengine.Renderer;
public class ReboundedRenderer implements Renderer {
private final Renderer renderer;
private final int dx;
private final int dy;
private final int width;
private final int height;
public ReboundedRenderer(Renderer renderer, int dx, int dy, int width, int height) {
this.renderer = renderer;
this.dx = dx;
this.dy = dy;
this.width = width;
this.height = height;
}
@Override
public void glColor3i(int r, int gg, int b) {
renderer.glColor3i(r, gg, b);
}
@Override
public void glColor(int c) {
renderer.glColor(c);
}
@Override
public void glColor4i(int red, int green, int blue, int alpha) {
renderer.glColor4i(red, green, blue, alpha);
}
@Override
public void glColor3f(float red, float green, float blue) {
renderer.glColor3f(red, green, blue);
}
@Override
public void glColor4f(float red, float green, float blue, float alpha) {
renderer.glColor4f(red, green, blue, alpha);
}
@Override
public void glClearColor4i(int red, int green, int blue, int alpha) {
renderer.glClearColor4i(red, green, blue, alpha);
}
@Override
public void glClearColor4f(float red, float green, float blue, float alpha) {
renderer.glClearColor4f(red, green, blue, alpha);
}
@Override
public int glGetClearColor() {
return renderer.glGetClearColor();
}
@Override
public void glClearColor(int c) {
renderer.glClearColor(c);
}
@Override
public void glClear(int screenWidth, int screenHeight) {
renderer.glClear(screenWidth, screenHeight);
}
@Override
public void glDrawLine(float x0, float y0, float x1, float y1) {
renderer.glDrawLine(this.dx + x0, this.dy + y0, this.dx + x1, this.dy + y1);
}
@Override
public void glFillRect(float x, float y, float width, float height, float uvX, float uvY, float uvWidth, float uvHeight) {
renderer.glFillRect(this.dx + x, this.dy + y, width, height, uvX, uvY, uvWidth, uvHeight);
}
@Override
public void glFillColor(float x, float y, float width, float height) {
renderer.glFillColor(this.dx + x, this.dy + y, width, height);
}
@Override
public void glDrawCharLeft(int x, int y, char ch) {
renderer.glDrawCharLeft(this.dx + x, this.dy + y, ch);
}
@Override
public void glDrawCharCenter(int x, int y, char ch) {
renderer.glDrawCharCenter(this.dx + x, this.dy + y, ch);
}
@Override
public void glDrawCharRight(int x, int y, char ch) {
renderer.glDrawCharRight(this.dx + x, this.dy + y, ch);
}
@Override
public void glDrawStringLeft(float x, float y, String text) {
renderer.glDrawStringLeft(this.dx + x, this.dy + y, text);
}
@Override
public void glDrawStringCenter(float x, float y, String text) {
renderer.glDrawStringCenter(this.dx + x, this.dy + y, text);
}
@Override
public void glDrawStringRight(float x, float y, String text) {
renderer.glDrawStringRight(this.dx + x, this.dy + y, text);
}
@Override
public void glClearSkin() {
renderer.glClearSkin();
}
@Override
public BinaryFont getCurrentFont() {
return renderer.getCurrentFont();
}
@Override
public Renderer getBoundedInstance(int dx, int dy, int width, int height) {
return renderer.getBoundedInstance(this.dx + dx, this.dy + dy, width, height);
}
}

View File

@ -2,19 +2,20 @@ package it.cavallium.warppi.gui.graphicengine.impl.nogui;
import java.io.IOException;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.Platform.Semaphore;
import it.cavallium.warppi.flow.Observable;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.gui.graphicengine.RenderingLoop;
import it.cavallium.warppi.gui.graphicengine.Skin;
import it.cavallium.warppi.util.EventSubmitter;
import it.cavallium.warppi.util.EventSubscriber;
public class NoGuiEngine implements GraphicEngine {
private boolean initialized;
public Semaphore exitSemaphore = Engine.getPlatform().newSemaphore(0);
@Override
public int[] getSize() {
@ -44,7 +45,7 @@ public class NoGuiEngine implements GraphicEngine {
}
@Override
public Observable<Integer[]> onResize() {
public EventSubscriber<Integer[]> onResize() {
return null;
}
@ -61,7 +62,6 @@ public class NoGuiEngine implements GraphicEngine {
@Override
public void destroy() {
initialized = false;
exitSemaphore.release();
}
@Override
@ -140,6 +140,11 @@ public class NoGuiEngine implements GraphicEngine {
public BinaryFont getCurrentFont() {
return null;
}
@Override
public Renderer getBoundedInstance(int dx, int dy, int width, int height) {
return getRenderer();
}
};
}
@ -147,7 +152,7 @@ public class NoGuiEngine implements GraphicEngine {
public BinaryFont loadFont(final String fontName) throws IOException {
return new BinaryFont() {
@Override
public void use(final GraphicEngine d) {}
public void use(final DisplayOutputDevice d) {}
@Override
public void load(final String file) throws IOException {}
@ -158,7 +163,7 @@ public class NoGuiEngine implements GraphicEngine {
}
@Override
public void initialize(final GraphicEngine d) {}
public void initialize(final DisplayOutputDevice d) {}
@Override
public int getStringWidth(final String text) {
@ -193,7 +198,7 @@ public class NoGuiEngine implements GraphicEngine {
public BinaryFont loadFont(final String path, final String fontName) throws IOException {
return new BinaryFont() {
@Override
public void use(final GraphicEngine d) {}
public void use(final DisplayOutputDevice d) {}
@Override
public void load(final String file) throws IOException {}
@ -204,7 +209,7 @@ public class NoGuiEngine implements GraphicEngine {
}
@Override
public void initialize(final GraphicEngine d) {}
public void initialize(final DisplayOutputDevice d) {}
@Override
public int getStringWidth(final String text) {
@ -239,7 +244,7 @@ public class NoGuiEngine implements GraphicEngine {
public Skin loadSkin(final String file) throws IOException {
return new Skin() {
@Override
public void use(final GraphicEngine d) {}
public void use(final DisplayOutputDevice d) {}
@Override
public void load(final String file) throws IOException {}
@ -250,7 +255,7 @@ public class NoGuiEngine implements GraphicEngine {
}
@Override
public void initialize(final GraphicEngine d) {}
public void initialize(final DisplayOutputDevice d) {}
@Override
public int getSkinWidth() {
@ -266,13 +271,6 @@ public class NoGuiEngine implements GraphicEngine {
};
}
@Override
public void waitForExit() {
try {
exitSemaphore.acquire();
} catch (final InterruptedException e) {}
}
@Override
public boolean isSupported() {
return true;

View File

@ -1,9 +1,12 @@
package it.cavallium.warppi.gui.screens;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.StaticVars;
import it.cavallium.warppi.event.KeyPressedEvent;
import it.cavallium.warppi.gui.HistoryBehavior;
import it.cavallium.warppi.gui.RenderContext;
import it.cavallium.warppi.gui.ScreenContext;
import it.cavallium.warppi.math.Function;
import it.cavallium.warppi.math.functions.Variable.VariableValue;
import it.cavallium.warppi.util.Utils;
@ -28,26 +31,29 @@ public class ChooseVariableValueScreen extends Screen {
public void initialized() throws InterruptedException {}
@Override
public void render() {
Utils.getFont(false, true).use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor4i(0, 0, 0, 64);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringCenter(StaticVars.screenSize[0] / 2 + 1, StaticVars.screenSize[1] / 2 - 20, "WORK IN PROGRESS.");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringCenter(StaticVars.screenSize[0] / 2, StaticVars.screenSize[1] / 2 - 20 + 1, "WORK IN PROGRESS.");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringCenter(StaticVars.screenSize[0] / 2 + 1, StaticVars.screenSize[1] / 2 - 20 + 1, "WORK IN PROGRESS.");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor3i(255, 0, 0);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringCenter(StaticVars.screenSize[0] / 2, StaticVars.screenSize[1] / 2 - 20, "WORK IN PROGRESS.");
public void graphicInitialized(ScreenContext ctx) throws InterruptedException {}
Utils.getFont(false, false).use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor4i(0, 0, 0, 64);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringCenter(StaticVars.screenSize[0] / 2 + 1, StaticVars.screenSize[1] / 2, "THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringCenter(StaticVars.screenSize[0] / 2, StaticVars.screenSize[1] / 2 + 1, "THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringCenter(StaticVars.screenSize[0] / 2 + 1, StaticVars.screenSize[1] / 2 + 1, "THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor3i(255, 0, 0);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringCenter(StaticVars.screenSize[0] / 2, StaticVars.screenSize[1] / 2, "THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
@Override
public void render(RenderContext ctx) {
Utils.getFont(false, true).use(WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().display);
ctx.getRenderer().glColor4i(0, 0, 0, 64);
ctx.getRenderer().glDrawStringCenter(ctx.getWidth() / 2 + 1, ctx.getHeight() / 2 - 20, "WORK IN PROGRESS.");
ctx.getRenderer().glDrawStringCenter(ctx.getWidth() / 2, ctx.getHeight() / 2 - 20 + 1, "WORK IN PROGRESS.");
ctx.getRenderer().glDrawStringCenter(ctx.getWidth() / 2 + 1, ctx.getHeight() / 2 - 20 + 1, "WORK IN PROGRESS.");
ctx.getRenderer().glColor3i(255, 0, 0);
ctx.getRenderer().glDrawStringCenter(ctx.getWidth() / 2, ctx.getHeight() / 2 - 20, "WORK IN PROGRESS.");
Utils.getFont(false, false).use(WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().display);
ctx.getRenderer().glColor4i(0, 0, 0, 64);
ctx.getRenderer().glDrawStringCenter(ctx.getWidth() / 2 + 1, ctx.getHeight() / 2, "THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
ctx.getRenderer().glDrawStringCenter(ctx.getWidth() / 2, ctx.getHeight() / 2 + 1, "THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
ctx.getRenderer().glDrawStringCenter(ctx.getWidth() / 2 + 1, ctx.getHeight() / 2 + 1, "THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
ctx.getRenderer().glColor3i(255, 0, 0);
ctx.getRenderer().glDrawStringCenter(ctx.getWidth() / 2, ctx.getHeight() / 2, "THIS SCREEN MUST HAVE A GUI TO SELECT THE VARIABLE TO SOLVE.");
}
@Override
public void beforeRender(final float dt) {
public void beforeRender(ScreenContext ctx, final float dt) {
}

View File

@ -1,6 +1,8 @@
package it.cavallium.warppi.gui.screens;
import it.cavallium.warppi.gui.HistoryBehavior;
import it.cavallium.warppi.gui.RenderContext;
import it.cavallium.warppi.gui.ScreenContext;
public class EmptyScreen extends Screen {
@ -20,13 +22,16 @@ public class EmptyScreen extends Screen {
public void initialized() throws InterruptedException {}
@Override
public void render() {
public void graphicInitialized(ScreenContext ctx) throws InterruptedException {}
@Override
public void render(RenderContext ctx) {
// TODO Auto-generated method stub
}
@Override
public void beforeRender(final float dt) {
public void beforeRender(ScreenContext ctx, final float dt) {
}

View File

@ -1,10 +1,12 @@
package it.cavallium.warppi.gui.screens;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.StaticVars;
import it.cavallium.warppi.event.KeyPressedEvent;
import it.cavallium.warppi.event.KeyReleasedEvent;
import it.cavallium.warppi.gui.HistoryBehavior;
import it.cavallium.warppi.gui.RenderContext;
import it.cavallium.warppi.gui.ScreenContext;
import it.cavallium.warppi.gui.graphicengine.Renderer;
public class KeyboardDebugScreen extends Screen {
@ -28,20 +30,23 @@ public class KeyboardDebugScreen extends Screen {
public void initialized() throws InterruptedException {}
@Override
public void render() {
final Renderer renderer = Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer;
Engine.INSTANCE.getHardwareDevice().getDisplayManager().fonts[2].use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
public void graphicInitialized(ScreenContext ctx) throws InterruptedException {}
@Override
public void render(RenderContext ctx) {
final Renderer renderer = WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().renderer;
WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().fonts[2].use(WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().display);
renderer.glColor4f(0.75f, 0.0f, 0.0f, 1.0f);
renderer.glDrawStringRight(StaticVars.screenSize[0] - 10, 30, "-" + keyevent.toUpperCase() + "-");
renderer.glDrawStringRight(ctx.getWidth() - 10, 30, "-" + keyevent.toUpperCase() + "-");
if (keyevent != "NONE") {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().fonts[2].use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().fonts[2].use(WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().display);
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
renderer.glDrawStringLeft(10, 30, "Key position");
renderer.glDrawStringLeft(10, 45, "X: " + KeyboardDebugScreen.keyX + ", Y:" + KeyboardDebugScreen.keyY);
renderer.glDrawStringLeft(10, 65, "Key value");
renderer.glDrawStringLeft(10, 80, key);
}
Engine.INSTANCE.getHardwareDevice().getDisplayManager().fonts[3].use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().fonts[3].use(WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().display);
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
for (int i = 0; i < 5; i++) {
if (KeyboardDebugScreen.log[i] != null) {
@ -53,10 +58,10 @@ public class KeyboardDebugScreen extends Screen {
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
renderer.glFillColor(-80 + 100 + 200, 90, 5, 5);
renderer.glFillColor(-80 + 100, 100, 200, 70);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().fonts[2].use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().fonts[2].use(WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().display);
renderer.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
renderer.glDrawStringCenter(-80 + 100 + 200 / 2, 100 + 70 / 2 - renderer.getCurrentFont().getCharacterHeight() / 2, "FROM SERIAL");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().fonts[3].use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().fonts[3].use(WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().display);
renderer.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
for (int i = 0; i < 8; i++) {
if (KeyboardDebugScreen.pinsA[i] == 1) {
@ -99,10 +104,10 @@ public class KeyboardDebugScreen extends Screen {
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
renderer.glFillColor(150 + 90, 200, 5, 5);
renderer.glFillColor(150 + 100, 100, 200, 70);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().fonts[2].use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().fonts[2].use(WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().display);
renderer.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
renderer.glDrawStringCenter(150 + 100 + 200 / 2, 100 + 70 / 2 - renderer.getCurrentFont().getCharacterHeight() / 2, "TO SERIAL");
Engine.INSTANCE.getHardwareDevice().getDisplayManager().fonts[3].use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().fonts[3].use(WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().display);
renderer.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
for (int i = 15; i >= 8; i--) {
if (KeyboardDebugScreen.pinsB[i] == 1) {
@ -173,7 +178,7 @@ public class KeyboardDebugScreen extends Screen {
}
@Override
public void beforeRender(final float dt) {
public void beforeRender(ScreenContext ctx, final float dt) {
if (System.currentTimeMillis() - beforetime >= 1000) {
keyevent = "NONE";
KeyboardDebugScreen.keyX = 0;

View File

@ -1,9 +1,13 @@
package it.cavallium.warppi.gui.screens;
import it.cavallium.warppi.Engine;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.device.display.DisplayOutputDevice;
import it.cavallium.warppi.StaticVars;
import it.cavallium.warppi.extra.mario.MarioScreen;
import it.cavallium.warppi.gui.GraphicUtils;
import it.cavallium.warppi.gui.HistoryBehavior;
import it.cavallium.warppi.gui.RenderContext;
import it.cavallium.warppi.gui.ScreenContext;
public class LoadingScreen extends Screen {
@ -21,7 +25,7 @@ public class LoadingScreen extends Screen {
@Override
public void created() throws InterruptedException {
Engine.INSTANCE.isLoaded().subscribe((loaded) -> {
WarpPI.INSTANCE.isLoaded().subscribe((loaded) -> {
this.loaded = loaded;
});
endLoading = 0;
@ -29,34 +33,43 @@ public class LoadingScreen extends Screen {
@Override
public void initialized() throws InterruptedException {
previousZoomValue = StaticVars.windowZoomFunction.apply(StaticVars.windowZoom.getLastValue());
Engine.INSTANCE.getHardwareDevice().getDisplayManager().getHUD().hide();
StaticVars.windowZoom.onNext(1f);
float lastZoomValue = StaticVars.windowZoom.getLastValue();
previousZoomValue = lastZoomValue;
WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().getHUD().hide();
if (lastZoomValue != 1.0f) {
StaticVars.windowZoom.submit(1f);
}
}
@Override
public void graphicInitialized(ScreenContext ctx) throws InterruptedException {}
@Override
public void beforeRender(final float dt) {
public void beforeRender(ScreenContext ctx, final float dt) {
loadingTextTranslation = GraphicUtils.sinDeg(endLoading * 90f) * 10f;
endLoading += dt;
if (!ended && loaded && (Engine.getPlatform().getSettings().isDebugEnabled() || endLoading >= 3.5f)) {
if (!ended && loaded && ((WarpPI.getPlatform().getSettings().isDebugEnabled() && endLoading >= 1.5f) || endLoading >= 3.5f)) {
ended = true;
StaticVars.windowZoom.onNext(previousZoomValue);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().getHUD().show();
Engine.INSTANCE.getHardwareDevice().getDisplayManager().setScreen(new MathInputScreen());
if (previousZoomValue != 1.0f) {
StaticVars.windowZoom.submit(previousZoomValue);
}
WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().getHUD().show();
WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().setScreen(new MathInputScreen());
}
mustRefresh = true;
}
@Override
public void render() {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().guiSkin.use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor3i(255, 255, 255);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillRect(StaticVars.screenSize[0] / 2f - 80, StaticVars.screenSize[1] / 2f - 64, 160, 48, 0, 32, 160, 48);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillRect(StaticVars.screenSize[0] / 2f - 24, StaticVars.screenSize[1] / 2f - loadingTextTranslation, 48, 48, 160, 32, 48, 48);
public void render(RenderContext ctx) {
DisplayOutputDevice display = d.display;
WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().guiSkin.use(display);
ctx.getRenderer().glColor3i(255, 255, 255);
ctx.getRenderer().glFillRect(ctx.getWidth() / 2f - 80, ctx.getHeight() / 2f - 64, 160, 48, 0, 32, 160, 48);
ctx.getRenderer().glFillRect(ctx.getWidth() / 2f - 24, ctx.getHeight() / 2f - loadingTextTranslation, 48, 48, 160, 32, 48, 48);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillRect(StaticVars.screenSize[0] - 224, StaticVars.screenSize[1] - 48, 224, 48, 0, 80, 224, 48);
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillRect(StaticVars.screenSize[0] - 160 - 24 - 224, StaticVars.screenSize[1] - 48, 160, 48, 224, 80, 160, 48);
ctx.getRenderer().glFillRect(ctx.getWidth() - 224, ctx.getHeight() - 48, 224, 48, 0, 80, 224, 48);
ctx.getRenderer().glFillRect(ctx.getWidth() - 160 - 24 - 224, ctx.getHeight() - 48, 160, 48, 224, 80, 160, 48);
}

Some files were not shown because too many files have changed in this diff Show More