.
- * Unless required by applicable law or agreed to in writing, software distributed under
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
- * ANY KIND, either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
- */
-
-package org.badvision.outlaweditor.test;
-
-import java.util.concurrent.CountDownLatch;
-
-import javax.swing.SwingUtilities;
-
-import javafx.application.Platform;
-import javafx.embed.swing.JFXPanel;
-
-import org.junit.Rule;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-/**
- * A JUnit {@link Rule} for running tests on the JavaFX thread and performing
- * JavaFX initialization. To include in your test case, add the following code:
- *
- *
- * {@literal @}Rule
- * public JavaFXThreadingRule jfxRule = new JavaFXThreadingRule();
- *
- *
- * @author Andy Till
- *
- */
-public class JavaFXThreadingRule implements TestRule {
-
- /**
- * Flag for setting up the JavaFX, we only need to do this once for all tests.
- */
- private static boolean jfxIsSetup;
-
- @Override
- public Statement apply(Statement statement, Description description) {
-
- return new OnJFXThreadStatement(statement);
- }
-
- private static class OnJFXThreadStatement extends Statement {
-
- private final Statement statement;
-
- public OnJFXThreadStatement(Statement aStatement) {
- statement = aStatement;
- }
-
- private Throwable rethrownException = null;
-
- @Override
- public void evaluate() throws Throwable {
-
- if(!jfxIsSetup) {
- setupJavaFX();
-
- jfxIsSetup = true;
- }
-
- final CountDownLatch countDownLatch = new CountDownLatch(1);
-
- Platform.runLater(() -> {
- try {
- statement.evaluate();
- } catch (Throwable e) {
- rethrownException = e;
- }
- countDownLatch.countDown();
- });
-
- countDownLatch.await();
-
- // if an exception was thrown by the statement during evaluation,
- // then re-throw it to fail the test
- if(rethrownException != null) {
- throw rethrownException;
- }
- }
-
- protected void setupJavaFX() throws InterruptedException {
-
- long timeMillis = System.currentTimeMillis();
-
- final CountDownLatch latch = new CountDownLatch(1);
-
- SwingUtilities.invokeLater(() -> {
- // initializes JavaFX environment
- new JFXPanel();
-
- latch.countDown();
- });
-
- System.out.println("javafx initialising...");
- latch.await();
- System.out.println("javafx is initialised in " + (System.currentTimeMillis() - timeMillis) + "ms");
- }
-
- }
-}
\ No newline at end of file
diff --git a/OutlawEditor/src/test/java/org/badvision/outlaweditor/test/TestMythosEditor.java b/OutlawEditor/src/test/java/org/badvision/outlaweditor/test/TestMythosEditor.java
deleted file mode 100644
index 953fc88b..00000000
--- a/OutlawEditor/src/test/java/org/badvision/outlaweditor/test/TestMythosEditor.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
- * (the "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at .
- * Unless required by applicable law or agreed to in writing, software distributed under
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
- * ANY KIND, either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
- */
-
-package org.badvision.outlaweditor.test;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.StringWriter;
-import javax.xml.bind.JAXB;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Marshaller;
-import org.badvision.outlaweditor.data.xml.Block;
-import org.badvision.outlaweditor.data.xml.GameData;
-import org.badvision.outlaweditor.data.xml.Map;
-import org.badvision.outlaweditor.data.xml.Scripts;
-import org.badvision.outlaweditor.data.xml.Script;
-import org.junit.Test;
-import static org.junit.Assert.*;
-
-/**
- * Various sanity checks of the Mythos script editing feature
- *
- * @author blurry
- */
-public class TestMythosEditor {
-
- static public final String[] testData = {"testData/blocklytest1.xml", "testData/blocklytest2.xml"};
- static public final String XML_HEADER = "\n";
-
- @Test
- public void deserializeTest() throws Exception {
- for (String path : testData) {
- System.out.println("testing " + path);
- Block theBlock = getBlock(path);
- assertNotNull(theBlock);
- }
- }
-
- @Test
- public void roundtripTest() throws Exception {
- JAXBContext context = JAXBContext.newInstance("org.badvision.outlaweditor.data.xml");
- Marshaller m = context.createMarshaller();
- m.setProperty(Marshaller.JAXB_FRAGMENT, true);
- for (String path : testData) {
- System.out.println("testing " + path);
- Block theBlock = getBlock(path);
- StringWriter testWriter = new StringWriter();
-
- GameData d = new GameData();
- Map map = new Map();
- d.getMap().add(map);
- Script script = new Script();
- script.setName("name");
- script.setDescription("description");
- script.setBlock(theBlock);
- map.setScripts(new Scripts());
- map.getScripts().getScript().add(script);
- m.marshal(d, testWriter);
- String testOutput = testWriter.getBuffer().toString();
- assertNotNull(testOutput);
-// assertSimilar(XML_HEADER + testOutput, getFileContents(path));
- }
- }
-
- public String getFileContents(String path) throws IOException {
- BufferedInputStream data = (BufferedInputStream) getClass().getClassLoader().getResource(path).getContent();
- byte[] buf = new byte[1024];
- StringBuilder contents = new StringBuilder();
- while (data.available() > 0) {
- int len = data.read(buf);
- if (len > 0) {
- String append = new String(buf, 0, len);
- contents.append(append);
- }
- }
- return contents.toString();
- }
-
- public void assertSimilar(String s1, String s2) {
- s1 = s1.replaceAll("\\s", "");
- s1 = s1.replaceAll("\\n", "");
- s2 = s2.replaceAll("\\s", "");
- s2 = s2.replaceAll("\\n", "");
- assertEquals(s1, s2);
- }
-
- public Block getBlock(String resourcePath) throws IOException {
- BufferedInputStream data = (BufferedInputStream) getClass().getClassLoader().getResource(resourcePath).getContent();
- assertNotNull(data);
- GameData gd = JAXB.unmarshal(data, GameData.class);
- assertNotNull(gd);
- assertNotNull(gd.getMap());
- assertEquals(1, gd.getMap().size());
- Scripts s = gd.getMap().get(0).getScripts();
- assertNotNull(s);
- assertNotNull(s.getScript());
- assertTrue(s.getScript().size() > 0);
- Script scr = (Script) s.getScript().get(0);
- return scr.getBlock();
- }
-}
diff --git a/Platform/Apple/tools/jace/pom.xml b/Platform/Apple/tools/jace/pom.xml
index 7b76897b..ee9ce579 100644
--- a/Platform/Apple/tools/jace/pom.xml
+++ b/Platform/Apple/tools/jace/pom.xml
@@ -43,7 +43,7 @@
com.gluonhq
gluonfx-maven-plugin
- 1.0.18
+ 1.0.19
jace.LawlessLegends
@@ -178,5 +178,15 @@
18
jar
+
+ org.lwjgl
+ lwjgl-openal
+ 3.3.2
+
+
+ javazoom
+ jlayer
+ 1.0.1
+
diff --git a/Platform/Apple/tools/jace/src/main/java/jace/apple2e/Speaker.java b/Platform/Apple/tools/jace/src/main/java/jace/apple2e/Speaker.java
index 23b96631..d78f6c77 100644
--- a/Platform/Apple/tools/jace/src/main/java/jace/apple2e/Speaker.java
+++ b/Platform/Apple/tools/jace/src/main/java/jace/apple2e/Speaker.java
@@ -27,8 +27,6 @@ import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.sound.sampled.SourceDataLine;
-
import jace.Emulator;
import jace.LawlessLegends;
import jace.config.ConfigurableField;
@@ -106,10 +104,6 @@ public class Speaker extends SoundGeneratorDevice {
*/
@ConfigurableField(name = "Idle cycles before sleep", shortName = "idle")
public static int MAX_IDLE_CYCLES = 2000000;
- /**
- * Java sound output
- */
- private SourceDataLine sdl;
/**
* Manifestation of the apple speaker softswitch
*/
diff --git a/Platform/Apple/tools/jace/src/main/java/jace/config/InvokableActionRegistryImpl.java b/Platform/Apple/tools/jace/src/main/java/jace/config/InvokableActionRegistryImpl.java
index 5b8d3053..cf98968e 100644
--- a/Platform/Apple/tools/jace/src/main/java/jace/config/InvokableActionRegistryImpl.java
+++ b/Platform/Apple/tools/jace/src/main/java/jace/config/InvokableActionRegistryImpl.java
@@ -1,5 +1,6 @@
package jace.config;
+import java.io.IOException;
import java.util.logging.Level;
// NOTE: This is generated code. Do not edit.
@@ -68,7 +69,7 @@ public class InvokableActionRegistryImpl extends InvokableActionRegistry {
putStaticAction(annotation.name(), jace.EmulatorUILogic.class, annotation, (b) -> {
try {
jace.EmulatorUILogic.saveScreenshotRaw();
- } catch (Exception ex) {
+ } catch (IOException ex) {
logger.log(Level.SEVERE, "Error invoking jace.EmulatorUILogic.saveScreenshotRaw", ex);
}
});
@@ -116,7 +117,7 @@ public class InvokableActionRegistryImpl extends InvokableActionRegistry {
putStaticAction(annotation.name(), jace.EmulatorUILogic.class, annotation, (b) -> {
try {
jace.EmulatorUILogic.saveScreenshot();
- } catch (Exception ex) {
+ } catch (IOException ex) {
logger.log(Level.SEVERE, "Error invoking jace.EmulatorUILogic.saveScreenshot", ex);
}
});
diff --git a/Platform/Apple/tools/jace/src/main/java/jace/core/SoundMixer.java b/Platform/Apple/tools/jace/src/main/java/jace/core/SoundMixer.java
index 059d3bbe..6823347d 100644
--- a/Platform/Apple/tools/jace/src/main/java/jace/core/SoundMixer.java
+++ b/Platform/Apple/tools/jace/src/main/java/jace/core/SoundMixer.java
@@ -18,14 +18,13 @@
*/
package jace.core;
-import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.DataLine;
-import javax.sound.sampled.LineUnavailableException;
-import javax.sound.sampled.SourceDataLine;
+import org.lwjgl.openal.AL;
+import org.lwjgl.openal.ALC;
+import org.lwjgl.openal.ALC10;
+import org.lwjgl.openal.ALCCapabilities;
+import org.lwjgl.openal.ALCapabilities;
import jace.config.ConfigurableField;
@@ -53,37 +52,42 @@ public class SoundMixer extends Device {
@ConfigurableField(name = "Mute", shortName = "mute")
public static boolean MUTE = false;
+ private final String defaultDeviceName;
+ private long audioDevice;
+ private long audioContext;
+ private ALCCapabilities audioCapabilities;
+ private ALCapabilities audioLibCapabilities;
public SoundMixer(Computer computer) {
super(computer);
+ defaultDeviceName = ALC10.alcGetString(0, ALC10.ALC_DEFAULT_DEVICE_SPECIFIER);
}
- /**
- * Get a javafx media sourcedataline for stereo 44.1KHz 16-bit signed PCM data.
- * Confirm the line is open before using it.
- *
- * @return
- */
- public SourceDataLine getLine() {
- if (MUTE) {
- return null;
+ // Lots of inspiration from https://www.youtube.com/watch?v=dLrqBTeipwg
+ @Override
+ public void attach() {
+ super.attach();
+ audioDevice = ALC10.alcOpenDevice(defaultDeviceName);
+ // TODO: Other attributes?
+ audioContext = ALC10.alcCreateContext(audioDevice, new int[]{0});
+ ALC10.alcMakeContextCurrent(audioContext);
+ audioCapabilities = ALC.createCapabilities(audioDevice);
+ audioLibCapabilities = AL.createCapabilities(audioCapabilities);
+ if (!audioLibCapabilities.OpenAL10) {
+ Logger.getLogger(SoundMixer.class.getName()).warning("OpenAL 1.0 not supported");
+ detach();
}
-
- SourceDataLine line = null;
- try {
- // WAV is a little endian format, so it makes sense to stick with that.
- AudioFormat format = new AudioFormat(RATE, BITS, 2, true, false);
- DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
- line = (SourceDataLine) AudioSystem.getLine(info);
- line.open(format);
- line.start();
-// Logger.getLogger(getClass().getName()).log(Level.INFO, "Obtained source data line: %s, buffer size %d".formatted(line.getFormat(), line.getBufferSize()));
- } catch (IllegalArgumentException | LineUnavailableException e) {
- Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Error getting sound line: {0}", e.getMessage());
- }
- return line;
- }
+ }
@Override
+ public void detach() {
+ ALC10.alcDestroyContext(audioContext);
+ ALC10.alcCloseDevice(audioDevice);
+ MUTE = true;
+ super.detach();
+ }
+
+ @Override
+
public String getDeviceName() {
return "Sound Output";
}
@@ -93,17 +97,16 @@ public class SoundMixer extends Device {
return "mixer";
}
+
@Override
public synchronized void reconfigure() {
if (MUTE) {
detach();
+ } else {
+ attach();
}
}
- public byte randomByte() {
- return (byte) (Math.random() * 256);
- }
-
@Override
public void tick() {
}
diff --git a/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessComputer.java b/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessComputer.java
index 50ee946a..4c0e1011 100644
--- a/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessComputer.java
+++ b/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessComputer.java
@@ -117,7 +117,7 @@ public class LawlessComputer extends Apple2e {
private void renderWithMask(int... mask) throws InterruptedException {
RAM128k ram = (RAM128k) getMemory();
byte[] framebuffer = getBootScreen();
- int maskOffset = 0;
+ int maskOffset;
for (int i = 0; i < 0x02000; i += 2) {
int y = Video.identifyHiresRow(i + 0x02000);
int x = i - Video.calculateHiresOffset(y);
diff --git a/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessHacks.java b/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessHacks.java
index dacf9d6e..4db838cb 100644
--- a/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessHacks.java
+++ b/Platform/Apple/tools/jace/src/main/java/jace/lawless/LawlessHacks.java
@@ -3,16 +3,14 @@ package jace.lawless;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.net.URISyntaxException;
import java.net.URL;
+import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -132,17 +130,18 @@ public class LawlessHacks extends Cheats {
private Media getAudioTrack(int number) {
String filename = getSongName(number);
String pathStr = "/jace/data/sound/" + filename;
-// System.out.println("looking in "+pathStr);
URL path = getClass().getResource(pathStr);
if (path == null) {
return null;
}
- try {
- return new Media(path.toURI().toString());
- } catch (URISyntaxException e) {
- Logger.getLogger(getClass().getName()).log(Level.WARNING, "Unable to load audio track " + number + " from " + pathStr, e);
- return null;
+ String resourcePath = path.toString();
+ System.out.println("Playing " + resourcePath);
+ if (resourcePath.startsWith("resource:")) {
+ resourcePath = Paths.get(resourcePath).toFile().getAbsolutePath();
+ System.out.println("Playing " + resourcePath);
}
+ // Log path
+ return new Media(resourcePath);
}
private void playMusic(int track, boolean switchScores) {
diff --git a/Platform/Apple/tools/jace/src/main/java/module-info.java b/Platform/Apple/tools/jace/src/main/java/module-info.java
index c9cb640a..4613b630 100644
--- a/Platform/Apple/tools/jace/src/main/java/module-info.java
+++ b/Platform/Apple/tools/jace/src/main/java/module-info.java
@@ -36,6 +36,8 @@ module lawlesslegends {
requires javafx.mediaEmpty;
requires javafx.media;
requires jdk.jsobject;
+ requires org.lwjgl.openal;
+
// requires org.reflections;
opens jace to javafx.graphics, javafx.fxml, javafx.controls;
diff --git a/Platform/Apple/tools/jace/src/main/resources/META-INF/native-image/jni-config.json b/Platform/Apple/tools/jace/src/main/resources/META-INF/native-image/jni-config.json
index c3ab1d90..43715d50 100644
--- a/Platform/Apple/tools/jace/src/main/resources/META-INF/native-image/jni-config.json
+++ b/Platform/Apple/tools/jace/src/main/resources/META-INF/native-image/jni-config.json
@@ -381,9 +381,67 @@
{"name":"skip","parameterTypes":["long"] }
]
},
+{
+ "name":"com.sun.media.sound.DirectAudioDevice",
+ "methods":[
+ {
+ "name":"addFormat",
+ "parameterTypes":[
+ "java.util.Vector",
+ "int",
+ "int",
+ "int",
+ "float",
+ "int",
+ "boolean",
+ "boolean"
+ ]
+ }
+ ]
+},
+{
+ "name":"com.sun.media.sound.DirectAudioDeviceProvider$DirectAudioDeviceInfo",
+ "methods":[
+ {
+ "name":"",
+ "parameterTypes":[
+ "int",
+ "int",
+ "int",
+ "java.lang.String",
+ "java.lang.String",
+ "java.lang.String",
+ "java.lang.String"
+ ]
+ }
+ ]
+},
+{
+ "name":"com.sun.media.sound.PortMixerProvider$PortMixerInfo",
+ "methods":[
+ {
+ "name":"",
+ "parameterTypes":[
+ "int",
+ "java.lang.String",
+ "java.lang.String",
+ "java.lang.String",
+ "java.lang.String"
+ ]
+ }
+ ]
+},
{
"name":"java.lang.Boolean",
- "methods":[{"name":"booleanValue","parameterTypes":[] }]
+ "methods":[
+ {
+ "name":"getBoolean",
+ "parameterTypes":[
+ "java.lang.String"
+ ]
+ },
+ {"name":"booleanValue","parameterTypes":[] }
+ ]
},
{
"name":"java.lang.Class",
diff --git a/Platform/Apple/tools/jace/src/main/resources/META-INF/native-image/resource-config.json b/Platform/Apple/tools/jace/src/main/resources/META-INF/native-image/resource-config.json
index 663a4ff3..48381a13 100644
--- a/Platform/Apple/tools/jace/src/main/resources/META-INF/native-image/resource-config.json
+++ b/Platform/Apple/tools/jace/src/main/resources/META-INF/native-image/resource-config.json
@@ -1,36 +1,30 @@
{
"resources":{
- "includes":[
- {
- "pattern":"\\Qjace\\E"
- },
- {
- "pattern":"^codemirror.*$"
- },
- {
- "pattern":"^jace.*$"
- },
- {
- "pattern":"^jace.data..*$"
- },
- {
- "pattern":"^jace.data.sound..*$"
- }
- ]},
- "bundles":[
- {
- "name":"com.sun.javafx.tk.quantum.QuantumMessagesBundle",
- "locales":[
- "",
- "und"
- ]
- },
- {
- "name":"com/sun/javafx/scene/control/skin/resources/controls",
- "locales":[
- "",
- "und"
- ]
- }
- ]
-}
+ "includes":[
+ {"pattern": ".*\\.bin$"},
+ {"pattern": ".*\\.rom$"},
+ {"pattern": ".*\\.mp3$"},
+ {"pattern": ".*\\.png$"},
+ {"pattern": ".*\\.jpg$"},
+ {"pattern": ".*\\.jpeg$"},
+ {"pattern": ".*\\.gif$"},
+ {"pattern": ".*\\.bmp$"},
+ {"pattern": ".*\\.ttf$"},
+ {"pattern": ".*\\.raw$"},
+ {"pattern": ".*\\.xml$"},
+ {"pattern": ".*\\.fxml$"},
+ {"pattern": ".*\\.css$"},
+ {"pattern": ".*\\.gls$"},
+ {"pattern": ".*\\.json$"},
+ {"pattern": ".*\\.dat$"},
+ {"pattern": ".*\\.license$"},
+ {"pattern": ".*\\.frag$"},
+ {"pattern": ".*\\.vert$"},
+ {"pattern": ".*\\.obj$"},
+ {"pattern": ".*\\.mtl$"},
+ {"pattern": ".*\\.js$"},
+ {"pattern": ".*\\.html$"},
+ {"pattern": ".*\\.txt$"}
+ ]
+ }
+}
\ No newline at end of file
diff --git a/Platform/Apple/tools/jace/src/main/resources/META-INF/substrate/config/jniconfig.json b/Platform/Apple/tools/jace/src/main/resources/META-INF/substrate/config/jniconfig.json
new file mode 100644
index 00000000..43715d50
--- /dev/null
+++ b/Platform/Apple/tools/jace/src/main/resources/META-INF/substrate/config/jniconfig.json
@@ -0,0 +1,519 @@
+[
+{
+ "name":"[Lcom.sun.glass.ui.Screen;"
+},
+{
+ "name":"[Ljava.lang.String;"
+},
+{
+ "name":"com.sun.glass.ui.Application",
+ "methods":[
+ {"name":"notifyDidBecomeActive","parameterTypes":[] },
+ {"name":"notifyDidFinishLaunching","parameterTypes":[] },
+ {"name":"notifyDidHide","parameterTypes":[] },
+ {"name":"notifyDidResignActive","parameterTypes":[] },
+ {"name":"notifyDidUnhide","parameterTypes":[] },
+ {"name":"notifyOpenFiles","parameterTypes":["java.lang.String[]"] },
+ {"name":"notifyWillBecomeActive","parameterTypes":[] },
+ {"name":"notifyWillFinishLaunching","parameterTypes":[] },
+ {"name":"notifyWillHide","parameterTypes":[] },
+ {"name":"notifyWillResignActive","parameterTypes":[] },
+ {"name":"notifyWillUnhide","parameterTypes":[] }
+ ]
+},
+{
+ "name":"com.sun.glass.ui.CommonDialogs$ExtensionFilter",
+ "methods":[
+ {"name":"extensionsToArray","parameterTypes":[] },
+ {"name":"getDescription","parameterTypes":[] }
+ ]
+},
+{
+ "name":"com.sun.glass.ui.CommonDialogs$FileChooserResult",
+ "methods":[{"name":"","parameterTypes":["java.util.List","com.sun.glass.ui.CommonDialogs$ExtensionFilter"] }]
+},
+{
+ "name":"com.sun.glass.ui.EventLoop",
+ "methods":[
+ {"name":"","parameterTypes":[] },
+ {"name":"enter","parameterTypes":[] },
+ {"name":"leave","parameterTypes":["java.lang.Object"] }
+ ]
+},
+{
+ "name":"com.sun.glass.ui.Menu",
+ "methods":[
+ {"name":"notifyMenuClosed","parameterTypes":[] },
+ {"name":"notifyMenuOpening","parameterTypes":[] }
+ ]
+},
+{
+ "name":"com.sun.glass.ui.MenuItem$Callback",
+ "methods":[
+ {"name":"action","parameterTypes":[] },
+ {"name":"validate","parameterTypes":[] }
+ ]
+},
+{
+ "name":"com.sun.glass.ui.Screen",
+ "methods":[
+ {"name":"","parameterTypes":["long","int","int","int","int","int","int","int","int","int","int","int","int","int","int","int","float","float","float","float"] },
+ {"name":"notifySettingsChanged","parameterTypes":[] }
+ ]
+},
+{
+ "name":"com.sun.glass.ui.Size",
+ "methods":[{"name":"","parameterTypes":["int","int"] }]
+},
+{
+ "name":"com.sun.glass.ui.View",
+ "fields":[{"name":"ptr"}],
+ "methods":[
+ {"name":"getAccessible","parameterTypes":[] },
+ {"name":"notifyDragDrop","parameterTypes":["int","int","int","int","int"] },
+ {"name":"notifyDragEnd","parameterTypes":["int"] },
+ {"name":"notifyDragEnter","parameterTypes":["int","int","int","int","int"] },
+ {"name":"notifyDragLeave","parameterTypes":[] },
+ {"name":"notifyDragOver","parameterTypes":["int","int","int","int","int"] },
+ {"name":"notifyInputMethod","parameterTypes":["java.lang.String","int[]","int[]","byte[]","int","int","int"] },
+ {"name":"notifyInputMethodCandidatePosRequest","parameterTypes":["int"] },
+ {"name":"notifyKey","parameterTypes":["int","int","char[]","int"] },
+ {"name":"notifyMenu","parameterTypes":["int","int","int","int","boolean"] },
+ {"name":"notifyMouse","parameterTypes":["int","int","int","int","int","int","int","boolean","boolean"] },
+ {"name":"notifyRepaint","parameterTypes":["int","int","int","int"] },
+ {"name":"notifyResize","parameterTypes":["int","int"] },
+ {"name":"notifyView","parameterTypes":["int"] }
+ ]
+},
+{
+ "name":"com.sun.javafx.font.coretext.CGAffineTransform",
+ "fields":[
+ {"name":"a"},
+ {"name":"b"},
+ {"name":"c"},
+ {"name":"d"},
+ {"name":"tx"},
+ {"name":"ty"}
+ ],
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "name":"com.sun.javafx.font.coretext.CGPoint",
+ "fields":[
+ {"name":"x"},
+ {"name":"y"}
+ ],
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "name":"com.sun.javafx.font.coretext.CGRect",
+ "fields":[
+ {"name":"origin"},
+ {"name":"size"}
+ ],
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "name":"com.sun.javafx.font.coretext.CGSize",
+ "fields":[
+ {"name":"height"},
+ {"name":"width"}
+ ],
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "name":"com.sun.javafx.iio.common.ImageLoaderImpl",
+ "methods":[{"name":"emitWarning","parameterTypes":["java.lang.String"] }]
+},
+{
+ "name":"com.sun.javafx.iio.jpeg.JPEGImageLoader",
+ "methods":[
+ {"name":"setInputAttributes","parameterTypes":["int","int","int","int","int","byte[]"] },
+ {"name":"setOutputAttributes","parameterTypes":["int","int"] },
+ {"name":"updateImageProgress","parameterTypes":["int"] }
+ ]
+},
+{
+ "name":"com.sun.media.jfxmedia.locator.Locator",
+ "methods":[{"name":"getStringLocation","parameterTypes":[] }]
+},
+{
+ "name":"com.sun.media.jfxmedia.logging.Logger",
+ "methods":[
+ {"name":"logMsg","parameterTypes":["int","java.lang.String"] },
+ {"name":"logMsg","parameterTypes":["int","java.lang.String","java.lang.String","java.lang.String"] }
+ ]
+},
+{
+ "name":"com.sun.media.jfxmediaimpl.NativeMediaPlayer",
+ "methods":[
+ {"name":"sendAudioSpectrumEvent","parameterTypes":["double","double","boolean"] },
+ {"name":"sendAudioTrack","parameterTypes":["boolean","long","java.lang.String","int","java.lang.String","int","int","float"] },
+ {"name":"sendBufferProgressEvent","parameterTypes":["double","long","long","long"] },
+ {"name":"sendDurationUpdateEvent","parameterTypes":["double"] },
+ {"name":"sendFrameSizeChangedEvent","parameterTypes":["int","int"] },
+ {"name":"sendMarkerEvent","parameterTypes":["java.lang.String","double"] },
+ {"name":"sendNewFrameEvent","parameterTypes":["long"] },
+ {"name":"sendPlayerHaltEvent","parameterTypes":["java.lang.String","double"] },
+ {"name":"sendPlayerMediaErrorEvent","parameterTypes":["int"] },
+ {"name":"sendPlayerStateEvent","parameterTypes":["int","double"] },
+ {"name":"sendSubtitleTrack","parameterTypes":["boolean","long","java.lang.String","int","java.lang.String"] },
+ {"name":"sendVideoTrack","parameterTypes":["boolean","long","java.lang.String","int","int","int","float","boolean"] },
+ {"name":"sendWarning","parameterTypes":["int","java.lang.String"] }
+ ]
+},
+{
+ "name":"com.sun.media.jfxmediaimpl.platform.osx.OSXMediaPlayer"
+},
+{
+ "name":"com.sun.media.sound.DirectAudioDevice",
+ "methods":[{"name":"addFormat","parameterTypes":["java.util.Vector","int","int","int","float","int","boolean","boolean"] }]
+},
+{
+ "name":"com.sun.media.sound.DirectAudioDeviceProvider$DirectAudioDeviceInfo",
+ "methods":[{"name":"","parameterTypes":["int","int","int","java.lang.String","java.lang.String","java.lang.String","java.lang.String"] }]
+},
+{
+ "name":"com.sun.media.sound.PortMixerProvider$PortMixerInfo",
+ "methods":[{"name":"","parameterTypes":["int","java.lang.String","java.lang.String","java.lang.String","java.lang.String"] }]
+},
+{
+ "name":"com.sun.webkit.BackForwardList",
+ "methods":[{"name":"notifyChanged","parameterTypes":[] }]
+},
+{
+ "name":"com.sun.webkit.BackForwardList$Entry",
+ "methods":[
+ {"name":"","parameterTypes":["long","long"] },
+ {"name":"notifyItemChanged","parameterTypes":[] },
+ {"name":"notifyItemDestroyed","parameterTypes":[] }
+ ]
+},
+{
+ "name":"com.sun.webkit.CursorManager",
+ "methods":[
+ {"name":"getCursorManager","parameterTypes":[] },
+ {"name":"getPredefinedCursorID","parameterTypes":["int"] }
+ ]
+},
+{
+ "name":"com.sun.webkit.FileSystem",
+ "methods":[
+ {"name":"fwkFileExists","parameterTypes":["java.lang.String"] },
+ {"name":"fwkMakeAllDirectories","parameterTypes":["java.lang.String"] },
+ {"name":"fwkPathByAppendingComponent","parameterTypes":["java.lang.String","java.lang.String"] }
+ ]
+},
+{
+ "name":"com.sun.webkit.MainThread",
+ "methods":[{"name":"fwkScheduleDispatchFunctions","parameterTypes":[] }]
+},
+{
+ "name":"com.sun.webkit.Timer",
+ "methods":[
+ {"name":"fwkSetFireTime","parameterTypes":["double"] },
+ {"name":"fwkStopTimer","parameterTypes":[] }
+ ]
+},
+{
+ "name":"com.sun.webkit.WCWidget",
+ "methods":[
+ {"name":"fwkDestroy","parameterTypes":[] },
+ {"name":"fwkRequestFocus","parameterTypes":[] },
+ {"name":"fwkSetBounds","parameterTypes":["int","int","int","int"] },
+ {"name":"fwkSetCursor","parameterTypes":["long"] },
+ {"name":"fwkSetVisible","parameterTypes":["boolean"] }
+ ]
+},
+{
+ "name":"com.sun.webkit.WebPage",
+ "methods":[
+ {"name":"fwkAddMessageToConsole","parameterTypes":["java.lang.String","int","java.lang.String"] },
+ {"name":"fwkAlert","parameterTypes":["java.lang.String"] },
+ {"name":"fwkCanRunBeforeUnloadConfirmPanel","parameterTypes":[] },
+ {"name":"fwkChooseFile","parameterTypes":["java.lang.String","boolean","java.lang.String"] },
+ {"name":"fwkCloseWindow","parameterTypes":[] },
+ {"name":"fwkConfirm","parameterTypes":["java.lang.String"] },
+ {"name":"fwkCreateWindow","parameterTypes":["boolean","boolean","boolean","boolean"] },
+ {"name":"fwkDidClearWindowObject","parameterTypes":["long","long"] },
+ {"name":"fwkFireLoadEvent","parameterTypes":["long","int","java.lang.String","java.lang.String","double","int"] },
+ {"name":"fwkFireResourceLoadEvent","parameterTypes":["long","int","int","java.lang.String","double","int"] },
+ {"name":"fwkFrameCreated","parameterTypes":["long"] },
+ {"name":"fwkFrameDestroyed","parameterTypes":["long"] },
+ {"name":"fwkGetPageBounds","parameterTypes":[] },
+ {"name":"fwkGetWindowBounds","parameterTypes":[] },
+ {"name":"fwkPermitAcceptResourceAction","parameterTypes":["long","java.lang.String"] },
+ {"name":"fwkPermitEnableScriptsAction","parameterTypes":["long","java.lang.String"] },
+ {"name":"fwkPermitNavigateAction","parameterTypes":["long","java.lang.String"] },
+ {"name":"fwkPermitNewWindowAction","parameterTypes":["long","java.lang.String"] },
+ {"name":"fwkPermitRedirectAction","parameterTypes":["long","java.lang.String"] },
+ {"name":"fwkPermitSubmitDataAction","parameterTypes":["long","java.lang.String","java.lang.String","boolean"] },
+ {"name":"fwkPrompt","parameterTypes":["java.lang.String","java.lang.String"] },
+ {"name":"fwkRemoveRequestURL","parameterTypes":["long","int"] },
+ {"name":"fwkRepaint","parameterTypes":["int","int","int","int"] },
+ {"name":"fwkRunBeforeUnloadConfirmPanel","parameterTypes":["java.lang.String"] },
+ {"name":"fwkScreenToWindow","parameterTypes":["com.sun.webkit.graphics.WCPoint"] },
+ {"name":"fwkSetCursor","parameterTypes":["long"] },
+ {"name":"fwkSetFocus","parameterTypes":["boolean"] },
+ {"name":"fwkSetRequestURL","parameterTypes":["long","int","java.lang.String"] },
+ {"name":"fwkSetScrollbarsVisible","parameterTypes":["boolean"] },
+ {"name":"fwkSetStatusbarText","parameterTypes":["java.lang.String"] },
+ {"name":"fwkSetTooltip","parameterTypes":["java.lang.String"] },
+ {"name":"fwkSetWindowBounds","parameterTypes":["int","int","int","int"] },
+ {"name":"fwkShowWindow","parameterTypes":[] },
+ {"name":"fwkTransferFocus","parameterTypes":["boolean"] },
+ {"name":"fwkWindowToScreen","parameterTypes":["com.sun.webkit.graphics.WCPoint"] },
+ {"name":"getHostWindow","parameterTypes":[] },
+ {"name":"getPage","parameterTypes":[] },
+ {"name":"getRenderTheme","parameterTypes":[] },
+ {"name":"setInputMethodState","parameterTypes":["boolean"] }
+ ]
+},
+{
+ "name":"com.sun.webkit.dom.JSObject",
+ "fields":[{"name":"UNDEFINED"}],
+ "methods":[{"name":"","parameterTypes":["long","int"] }]
+},
+{
+ "name":"com.sun.webkit.graphics.Ref",
+ "methods":[
+ {"name":"getID","parameterTypes":[] },
+ {"name":"ref","parameterTypes":[] }
+ ]
+},
+{
+ "name":"com.sun.webkit.graphics.ScrollBarTheme",
+ "methods":[{"name":"getThickness","parameterTypes":[] }]
+},
+{
+ "name":"com.sun.webkit.graphics.WCFont",
+ "methods":[
+ {"name":"getAscent","parameterTypes":[] },
+ {"name":"getCapHeight","parameterTypes":[] },
+ {"name":"getDescent","parameterTypes":[] },
+ {"name":"getGlyphBoundingBox","parameterTypes":["int"] },
+ {"name":"getGlyphCodes","parameterTypes":["char[]"] },
+ {"name":"getGlyphWidth","parameterTypes":["int"] },
+ {"name":"getLineGap","parameterTypes":[] },
+ {"name":"getLineSpacing","parameterTypes":[] },
+ {"name":"getTextRuns","parameterTypes":["java.lang.String"] },
+ {"name":"getXHeight","parameterTypes":[] },
+ {"name":"hasUniformLineMetrics","parameterTypes":[] },
+ {"name":"hashCode","parameterTypes":[] }
+ ]
+},
+{
+ "name":"com.sun.webkit.graphics.WCGraphicsManager",
+ "methods":[
+ {"name":"createWCPath","parameterTypes":[] },
+ {"name":"getGraphicsManager","parameterTypes":[] },
+ {"name":"getWCFont","parameterTypes":["java.lang.String","boolean","boolean","float"] }
+ ]
+},
+{
+ "name":"com.sun.webkit.graphics.WCPoint",
+ "methods":[
+ {"name":"","parameterTypes":["float","float"] },
+ {"name":"getX","parameterTypes":[] },
+ {"name":"getY","parameterTypes":[] }
+ ]
+},
+{
+ "name":"com.sun.webkit.graphics.WCRectangle",
+ "fields":[
+ {"name":"h"},
+ {"name":"w"},
+ {"name":"x"},
+ {"name":"y"}
+ ]
+},
+{
+ "name":"com.sun.webkit.graphics.WCRenderQueue",
+ "methods":[
+ {"name":"fwkAddBuffer","parameterTypes":["java.nio.ByteBuffer"] },
+ {"name":"fwkDisposeGraphics","parameterTypes":[] },
+ {"name":"refFloatArr","parameterTypes":["float[]"] },
+ {"name":"refIntArr","parameterTypes":["int[]"] }
+ ]
+},
+{
+ "name":"com.sun.webkit.graphics.WCTextRun",
+ "methods":[
+ {"name":"getCharOffset","parameterTypes":["int"] },
+ {"name":"getEnd","parameterTypes":[] },
+ {"name":"getGlyph","parameterTypes":["int"] },
+ {"name":"getGlyphCount","parameterTypes":[] },
+ {"name":"getGlyphPosAndAdvance","parameterTypes":["int"] },
+ {"name":"getStart","parameterTypes":[] },
+ {"name":"isLeftToRight","parameterTypes":[] }
+ ]
+},
+{
+ "name":"com.sun.webkit.network.FormDataElement",
+ "methods":[
+ {"name":"fwkCreateFromByteArray","parameterTypes":["byte[]"] },
+ {"name":"fwkCreateFromFile","parameterTypes":["java.lang.String"] }
+ ]
+},
+{
+ "name":"com.sun.webkit.network.NetworkContext",
+ "methods":[
+ {"name":"canHandleURL","parameterTypes":["java.lang.String"] },
+ {"name":"fwkGetMaximumHTTPConnectionCountPerHost","parameterTypes":[] },
+ {"name":"fwkLoad","parameterTypes":["com.sun.webkit.WebPage","boolean","java.lang.String","java.lang.String","java.lang.String","com.sun.webkit.network.FormDataElement[]","long"] }
+ ]
+},
+{
+ "name":"com.sun.webkit.network.URLLoaderBase",
+ "methods":[{"name":"fwkCancel","parameterTypes":[] }]
+},
+{
+ "name":"jace.ide.Program"
+},
+{
+ "name":"java.io.File",
+ "methods":[{"name":"","parameterTypes":["java.lang.String"] }]
+},
+{
+ "name":"java.io.InputStream",
+ "methods":[
+ {"name":"read","parameterTypes":["byte[]","int","int"] },
+ {"name":"skip","parameterTypes":["long"] }
+ ]
+},
+{
+ "name":"com.sun.media.sound.DirectAudioDevice",
+ "methods":[
+ {
+ "name":"addFormat",
+ "parameterTypes":[
+ "java.util.Vector",
+ "int",
+ "int",
+ "int",
+ "float",
+ "int",
+ "boolean",
+ "boolean"
+ ]
+ }
+ ]
+},
+{
+ "name":"com.sun.media.sound.DirectAudioDeviceProvider$DirectAudioDeviceInfo",
+ "methods":[
+ {
+ "name":"",
+ "parameterTypes":[
+ "int",
+ "int",
+ "int",
+ "java.lang.String",
+ "java.lang.String",
+ "java.lang.String",
+ "java.lang.String"
+ ]
+ }
+ ]
+},
+{
+ "name":"com.sun.media.sound.PortMixerProvider$PortMixerInfo",
+ "methods":[
+ {
+ "name":"",
+ "parameterTypes":[
+ "int",
+ "java.lang.String",
+ "java.lang.String",
+ "java.lang.String",
+ "java.lang.String"
+ ]
+ }
+ ]
+},
+{
+ "name":"java.lang.Boolean",
+ "methods":[
+ {
+ "name":"getBoolean",
+ "parameterTypes":[
+ "java.lang.String"
+ ]
+ },
+ {"name":"booleanValue","parameterTypes":[] }
+ ]
+},
+{
+ "name":"java.lang.Class",
+ "methods":[
+ {"name":"forName","parameterTypes":["java.lang.String","boolean","java.lang.ClassLoader"] },
+ {"name":"isArray","parameterTypes":[] }
+ ]
+},
+{
+ "name":"java.lang.ClassLoader",
+ "methods":[
+ {"name":"getPlatformClassLoader","parameterTypes":[] },
+ {"name":"loadClass","parameterTypes":["java.lang.String"] }
+ ]
+},
+{
+ "name":"java.lang.Integer",
+ "methods":[
+ {"name":"","parameterTypes":["int"] },
+ {"name":"intValue","parameterTypes":[] }
+ ]
+},
+{
+ "name":"java.lang.Long",
+ "methods":[{"name":"longValue","parameterTypes":[] }]
+},
+{
+ "name":"java.lang.Number"
+},
+{
+ "name":"java.lang.Object",
+ "methods":[{"name":"getClass","parameterTypes":[] }]
+},
+{
+ "name":"java.lang.Runnable",
+ "methods":[{"name":"run","parameterTypes":[] }]
+},
+{
+ "name":"java.lang.String",
+ "methods":[
+ {"name":"lastIndexOf","parameterTypes":["int"] },
+ {"name":"substring","parameterTypes":["int"] }
+ ]
+},
+{
+ "name":"java.lang.System",
+ "methods":[
+ {"name":"getProperty","parameterTypes":["java.lang.String"] },
+ {"name":"setProperty","parameterTypes":["java.lang.String","java.lang.String"] }
+ ]
+},
+{
+ "name":"java.util.ArrayList",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "name":"java.util.List",
+ "methods":[{"name":"add","parameterTypes":["java.lang.Object"] }]
+},
+{
+ "name":"java.util.Map",
+ "methods":[{"name":"get","parameterTypes":["java.lang.Object"] }]
+},
+{
+ "name":"jdk.internal.loader.ClassLoaders$PlatformClassLoader"
+},
+{
+ "name":"org.graalvm.jniutils.JNIExceptionWrapperEntryPoints",
+ "methods":[{"name":"getClassName","parameterTypes":["java.lang.Class"] }]
+},
+{
+ "name":"sun.launcher.LauncherHelper$FXHelper",
+ "methods":[{"name":"main","parameterTypes":["java.lang.String[]"] }]
+}
+]
diff --git a/Platform/Apple/tools/jace/src/main/resources/META-INF/substrate/config/reflectionconfig.json b/Platform/Apple/tools/jace/src/main/resources/META-INF/substrate/config/reflectionconfig.json
new file mode 100644
index 00000000..214d5b09
--- /dev/null
+++ b/Platform/Apple/tools/jace/src/main/resources/META-INF/substrate/config/reflectionconfig.json
@@ -0,0 +1,1141 @@
+[
+{
+ "name":"[D"
+},
+{
+ "name":"apple.security.AppleProvider",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "name":"com.sun.crypto.provider.AESCipher$General",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "name":"com.sun.crypto.provider.ARCFOURCipher",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "name":"com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "name":"com.sun.crypto.provider.DESCipher",
+ "methods":[{"name":"