diff --git a/app/src/main/java/net/kdt/pojavlaunch/FakeURLClassLoader.java b/app/src/main/java/net/kdt/pojavlaunch/FakeURLClassLoader.java deleted file mode 100644 index 94fd49e94..000000000 --- a/app/src/main/java/net/kdt/pojavlaunch/FakeURLClassLoader.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.kdt.pojavlaunch; -import java.net.*; -import java.io.*; -import dalvik.system.*; - -public class FakeURLClassLoader extends URLClassLoader -{ - private DexClassLoader m; - public FakeURLClassLoader(java.lang.String dexPath, java.lang.String optimizedDirectory, java.lang.String librarySearchPath, java.lang.ClassLoader parent) throws MalformedURLException { - super(new URL[] { new File("test.jar").toURI().toURL() }, null); - - m = new DexClassLoader(dexPath, optimizedDirectory, librarySearchPath, parent); - } - - @Override - public java.lang.String findLibrary(String name) { - return m.findLibrary(name); - } - - @Override - public Class loadClass(String name) throws ClassNotFoundException - { - return m.loadClass(name); - } -} diff --git a/app/src/main/java/net/kdt/pojavlaunch/InstallModActivity.java b/app/src/main/java/net/kdt/pojavlaunch/InstallModActivity.java index 6c34118f5..d8d91f965 100644 --- a/app/src/main/java/net/kdt/pojavlaunch/InstallModActivity.java +++ b/app/src/main/java/net/kdt/pojavlaunch/InstallModActivity.java @@ -8,9 +8,12 @@ import com.oracle.dalvik.*; import java.io.*; import java.lang.reflect.*; import java.util.*; +import org.lwjgl.glfw.*; public class InstallModActivity extends LoggableActivity { + public static volatile boolean IS_JRE_RUNNING; + private TextureView mTextureView; private LinearLayout contentLog; private TextView textLog; @@ -32,7 +35,7 @@ public class InstallModActivity extends LoggableActivity logFile.delete(); logFile.createNewFile(); logStream = new PrintStream(logFile.getAbsolutePath()); - this.contentLog = (LinearLayout) findViewById(R.id.content_log_layout); + this.contentLog = findViewById(R.id.content_log_layout); this.contentScroll = (ScrollView) findViewById(R.id.content_log_scroll); this.textLog = (TextView) contentScroll.getChildAt(0); this.toggleLog = (ToggleButton) findViewById(R.id.content_log_toggle_log); @@ -55,24 +58,32 @@ public class InstallModActivity extends LoggableActivity mTextureView = findViewById(R.id.installmod_surfaceview); mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener(){ + private boolean isAvailableCalled = false; @Override - public void onSurfaceTextureAvailable(SurfaceTexture tex, int w, int h) { - try { - Surface surface = new Surface(tex); - Field field = surface.getClass().getDeclaredField("mNativeObject"); - field.setAccessible(true); - JREUtils.setupBridgeSurfaceAWT((long) field.get(surface)); - } catch (Throwable th) { - Tools.showError(InstallModActivity.this, th, true); - } + public void onSurfaceTextureAvailable(SurfaceTexture tex, final int w, final int h) { + if (!isAvailableCalled) { + isAvailableCalled = true; + } else return; + + // final Surface surface = new Surface(tex); + new Thread(new Runnable(){ + @Override + public void run() { + while (IS_JRE_RUNNING) { + Canvas canvas = mTextureView.lockCanvas(); + JREUtils.renderAWTScreenFrame(canvas, w, h); + mTextureView.unlockCanvasAndPost(canvas); + } + } + }, "AWTSurfaceUpdater").start(); new Thread(new Runnable(){ - @Override - public void run() { - launchJavaRuntime(modFile, javaArgs); - // finish(); - } - }).start(); + @Override + public void run() { + launchJavaRuntime(modFile, javaArgs); + + } + }, "JREMainThread").start(); } @Override @@ -128,6 +139,8 @@ public class InstallModActivity extends LoggableActivity javaArgList.add("-Xbootclasspath/a" + libStr.toString()); } + javaArgList.add("-Dcacio.managed.screensize=" + CallbackBridge.windowWidth + "x" + CallbackBridge.windowHeight); + File cacioArgOverrideFile = new File(cacioAwtLibPath, "overrideargs.txt"); if (cacioArgOverrideFile.exists()) { javaArgList.addAll(Arrays.asList(Tools.read(cacioArgOverrideFile.getAbsolutePath()).split(" "))); diff --git a/app/src/main/java/net/kdt/pojavlaunch/JREUtils.java b/app/src/main/java/net/kdt/pojavlaunch/JREUtils.java index 95bd04e35..caa9d7787 100644 --- a/app/src/main/java/net/kdt/pojavlaunch/JREUtils.java +++ b/app/src/main/java/net/kdt/pojavlaunch/JREUtils.java @@ -208,7 +208,7 @@ public class JREUtils public static native void setupBridgeWindow(Object surface); // TODO AWT Android port - public static native void setupBridgeSurfaceAWT(long surface); + public static native void renderAWTScreenFrame(Object canvas, int width, int height); // BEFORE Load and execute PIE binary using dlopen and dlsym("main") // AFTER: [Deprecated] diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk index 6865edaad..8bdde262e 100644 --- a/app/src/main/jni/Android.mk +++ b/app/src/main/jni/Android.mk @@ -9,6 +9,7 @@ LOCAL_MODULE := pojavexec LOCAL_CFLAGS += -DDEBUG # -DGLES_TEST LOCAL_SRC_FILES := \ + awt_bridge.c \ egl_bridge.c \ input_bridge_v3.c \ jre_launcher.c \ diff --git a/app/src/main/jni/awt_bridge.c b/app/src/main/jni/awt_bridge.c new file mode 100644 index 000000000..6785a329d --- /dev/null +++ b/app/src/main/jni/awt_bridge.c @@ -0,0 +1,44 @@ +#include +#include "utils.h" + +// jclass class_awt; +// jmethodID method_awt; + +// TODO: check for memory leaks +JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_JREUtils_renderAWTScreenFrame(JNIEnv* env, jclass clazz, jobject canvas, jint width, jint height) { + if (runtimeJNIEnvPtr_ANDROID == NULL) return; + + int *rgbArray; + jintArray jreRgbArray, androidRgbArray; + + jclass class_awt = (*runtimeJNIEnvPtr_ANDROID)->FindClass(runtimeJNIEnvPtr_ANDROID, "net/java/openjdk/cacio/ctc/CTCScreen"); + jmethodID method_awt = (*runtimeJNIEnvPtr_ANDROID)->GetStaticMethodID(runtimeJNIEnvPtr_ANDROID, class_awt, "getCurrentScreenRGB"); + jreRgbArray = (jintArray) (*runtimeJNIEnvPtr_ANDROID)->CallStaticObjectMethod( + runtimeJNIEnvPtr_ANDROID, + class_awt, + method_awt + ); + + // Copy JRE RGB array memory to Android. + int arrayLength = (*runtimeJNIEnvPtr_ANDROID)->GetArrayLength(runtimeJNIEnvPtr_ANDROID, jreRgbArray); + rgbArray = (*runtimeJNIEnvPtr_ANDROID)->GetIntArrayElements(runtimeJNIEnvPtr_ANDROID, jreRgbArray, 0); + androidRgbArray = (*runtimeJNIEnvPtr_ANDROID)->NewIntArray(runtimeJNIEnvPtr_ANDROID, arrayLength); + (*runtimeJNIEnvPtr_ANDROID)->SetIntArrayRegion(runtimeJNIEnvPtr_ANDROID, androidRgbArray, 0, arrayLength, rgbArray); + + // Maybe use Skia lib instead? + jclass class_canvas = (*dalvikJNIEnvPtr_ANDROID)->GetObjectClass(dalvikJNIEnvPtr_ANDROID, canvas); + jmethodID method_canvas = (*dalvikJNIEnvPtr_ANDROID)->GetMethodID(dalvikJNIEnvPtr_ANDROID, class_canvas, "drawBitmap", "[IIIFFIIZLandroid/graphics/Paint;"); + (*runtimeJNIEnvPtr_ANDROID)->CallVoidMethod( + runtimeJNIEnvPtr_ANDROID, + canvas, + method_canvas, + rgbArray, 0, width, 0, 0, width, height, JNI_TRUE, NULL + ); + + // android_graphics_Canvas_native_drawBitmap + + (*runtimeJNIEnvPtr_ANDROID)->ReleaseIntArrayElements(runtimeJNIEnvPtr_ANDROID, jreRgbArray, rgbArray); + (*dalvikJNIEnvPtr_ANDROID)->DeleteLocalRef(dalvikJNIEnvPtr_ANDROID, androidRgbArray); + // free(rgbArray); +} + diff --git a/app/src/main/jni/egl_bridge.c b/app/src/main/jni/egl_bridge.c index 8582de6fc..92dc852e9 100644 --- a/app/src/main/jni/egl_bridge.c +++ b/app/src/main/jni/egl_bridge.c @@ -34,10 +34,6 @@ EGLConfig config; typedef jint RegalMakeCurrent_func(EGLContext context); -JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_JREUtils_setupBridgeWindow(JNIEnv* env, jclass clazz, jobject surface) { - potatoBridge.androidWindow = ANativeWindow_fromSurface(env, surface); -} - // Called from JNI_OnLoad of liblwjgl_opengl void pojav_openGLOnLoad() {