diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-glfw-classes.jar b/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-glfw-classes.jar index 2e21d87bc..667561942 100644 Binary files a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-glfw-classes.jar and b/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-glfw-classes.jar differ diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/version b/app_pojavlauncher/src/main/assets/components/lwjgl3/version index 18b03e5b5..b7cfa66b4 100644 --- a/app_pojavlauncher/src/main/assets/components/lwjgl3/version +++ b/app_pojavlauncher/src/main/assets/components/lwjgl3/version @@ -1 +1 @@ -1665886806915 \ No newline at end of file +1668936448354 \ No newline at end of file diff --git a/app_pojavlauncher/src/main/jni/input_bridge_v3.c b/app_pojavlauncher/src/main/jni/input_bridge_v3.c index b3fdff771..35f6d1082 100644 --- a/app_pojavlauncher/src/main/jni/input_bridge_v3.c +++ b/app_pojavlauncher/src/main/jni/input_bridge_v3.c @@ -49,9 +49,12 @@ jmethodID inputBridgeMethod_ANDROID, inputBridgeMethod_JRE; jmethodID method_accessAndroidClipboard; jmethodID method_onGrabStateChanged; jmethodID method_glftSetWindowAttrib; +jmethodID method_internalWindowSizeChanged; +jmethodID method_fallbackWriteKey = NULL; jclass bridgeClazz; jclass vmGlfwClass; jboolean isGrabbing; +jbyte* keyDownBuffer; jint JNI_OnLoad(JavaVM* vm, void* reserved) { if (dalvikJavaVMPtr == NULL) { @@ -67,7 +70,11 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) { (*vm)->GetEnv(vm, (void**) &runtimeJNIEnvPtr_JRE, JNI_VERSION_1_4); vmGlfwClass = (*runtimeJNIEnvPtr_JRE)->NewGlobalRef(runtimeJNIEnvPtr_JRE, (*runtimeJNIEnvPtr_JRE)->FindClass(runtimeJNIEnvPtr_JRE, "org/lwjgl/glfw/GLFW")); method_glftSetWindowAttrib = (*runtimeJNIEnvPtr_JRE)->GetStaticMethodID(runtimeJNIEnvPtr_JRE, vmGlfwClass, "glfwSetWindowAttrib", "(JII)V"); - hookExec(); + method_internalWindowSizeChanged = (*runtimeJNIEnvPtr_JRE)->GetStaticMethodID(runtimeJNIEnvPtr_JRE, vmGlfwClass, "internalWindowSizeChanged", "(JII)V"); + jfieldID field_keyDownBuffer = (*runtimeJNIEnvPtr_JRE)->GetStaticFieldID(runtimeJNIEnvPtr_JRE, vmGlfwClass, "keyDownBuffer", "Ljava/nio/ByteBuffer;"); + jobject keyDownBufferJ = (*runtimeJNIEnvPtr_JRE)->GetStaticObjectField(runtimeJNIEnvPtr_JRE, vmGlfwClass, field_keyDownBuffer); + keyDownBuffer = (*runtimeJNIEnvPtr_JRE)->GetDirectBufferAddress(runtimeJNIEnvPtr_JRE, keyDownBufferJ); + hookExec(); } isGrabbing = JNI_FALSE; @@ -127,6 +134,56 @@ jboolean attachThread(bool isAndroid, JNIEnv** secondJNIEnvPtr) { return JNI_FALSE; } +typedef struct { + int type; + int i1; + int i2; + int i3; + int i4; +} GLFWInputEvent; +static size_t eventCounter = 0; +static GLFWInputEvent events[500]; + +void handleFramebufferSizeJava(long window, int w, int h) { + (*runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod(runtimeJNIEnvPtr_JRE, vmGlfwClass, method_internalWindowSizeChanged, (long)window, w, h); +} + +void pojavPumpEvents(void* window) { + //__android_log_print(ANDROID_LOG_INFO, "input_bridge_v3", "pojavPumpEvents %d", eventCounter); + + for(size_t i = 0; i < eventCounter; i++) { + GLFWInputEvent event = events[i]; + switch(event.type) { + case EVENT_TYPE_CHAR: + if(GLFW_invoke_Char) GLFW_invoke_Char(window, event.i1); + break; + case EVENT_TYPE_CHAR_MODS: + if(GLFW_invoke_CharMods) GLFW_invoke_CharMods(window, event.i1, event.i2); + break; + case EVENT_TYPE_KEY: + if(GLFW_invoke_Key) GLFW_invoke_Key(window, event.i1, event.i2, event.i3, event.i4); + case EVENT_TYPE_MOUSE_BUTTON: + if(GLFW_invoke_MouseButton) GLFW_invoke_MouseButton(window, event.i1, event.i2, event.i3); + break; + case EVENT_TYPE_SCROLL: + if(GLFW_invoke_Scroll) GLFW_invoke_Scroll(window, event.i1, event.i2); + break; + case EVENT_TYPE_FRAMEBUFFER_SIZE: + handleFramebufferSizeJava(showingWindow, event.i1, event.i2); + if(GLFW_invoke_FramebufferSize) GLFW_invoke_FramebufferSize(window, event.i1, event.i2); + break; + case EVENT_TYPE_WINDOW_SIZE: + handleFramebufferSizeJava(showingWindow, event.i1, event.i2); + if(GLFW_invoke_WindowSize) GLFW_invoke_WindowSize(window, event.i1, event.i2); + break; + } + } +} +void pojavRewindEvents() { + eventCounter = 0; +} + + void sendData(int type, int i1, int i2, int i3, int i4) { #ifdef DEBUG LOGD("Debug: Send data, jnienv.isNull=%d\n", runtimeJNIEnvPtr_ANDROID == NULL); @@ -136,13 +193,24 @@ void sendData(int type, int i1, int i2, int i3, int i4) { return; } if(inputBridgeClass_ANDROID == NULL) return; - (*runtimeJNIEnvPtr_ANDROID)->CallStaticVoidMethod( - runtimeJNIEnvPtr_ANDROID, - inputBridgeClass_ANDROID, - inputBridgeMethod_ANDROID, - type, - i1, i2, i3, i4 - ); + if(type == EVENT_TYPE_CURSOR_POS) { + (*runtimeJNIEnvPtr_ANDROID)->CallStaticVoidMethod( + runtimeJNIEnvPtr_ANDROID, + inputBridgeClass_ANDROID, + inputBridgeMethod_ANDROID, + type, + i1, i2, i3, i4 + ); + }else { + if (eventCounter < 499) { + GLFWInputEvent *event = &events[eventCounter++]; + event->type = type; + event->i1 = i1; + event->i2 = i2; + event->i3 = i3; + event->i4 = i4; + } + } } void closeGLFWWindow() { @@ -356,10 +424,14 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorPos(JN lastCursorY = y; } } - +#define max(a,b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a > _b ? _a : _b; }) JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(JNIEnv* env, jclass clazz, jint key, jint scancode, jint action, jint mods) { if (GLFW_invoke_Key && isInputReady) { if (isUseStackQueueCall) { + keyDownBuffer[max(0, key-31)]=(jbyte)action; sendData(EVENT_TYPE_KEY, key, scancode, action, mods); } else { GLFW_invoke_Key((void*) showingWindow, key, scancode, action, mods); diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java index 247732615..40040006a 100644 --- a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java @@ -21,6 +21,8 @@ import static org.lwjgl.system.MemoryStack.*; import static org.lwjgl.system.MemoryUtil.*; import java.util.*; +import sun.misc.Unsafe; + public class GLFW { static FloatBuffer joystickData = (FloatBuffer)FloatBuffer.allocate(8).flip(); @@ -496,7 +498,7 @@ public class GLFW private static ArrayMap mGLFWWindowMap; public static boolean mGLFWIsGrabbing, mGLFWIsInputReady, mGLFWIsUseStackQueue = false; - public static final byte[] keyDownBuffer = new byte[317]; + public static final ByteBuffer keyDownBuffer = ByteBuffer.allocateDirect(317); private static final String PROP_WINDOW_WIDTH = "glfwstub.windowWidth"; private static final String PROP_WINDOW_HEIGHT= "glfwstub.windowHeight"; public static long mainContext = 0; @@ -612,7 +614,9 @@ public class GLFW MakeContextCurrent = apiGetFunctionAddress(GLFW, "pojavMakeCurrent"), Terminate = apiGetFunctionAddress(GLFW, "pojavTerminate"), SwapBuffers = apiGetFunctionAddress(GLFW, "pojavSwapBuffers"), - SwapInterval = apiGetFunctionAddress(GLFW, "pojavSwapInterval"); + SwapInterval = apiGetFunctionAddress(GLFW, "pojavSwapInterval"), + PumpEvents = apiGetFunctionAddress(GLFW, "pojavPumpEvents"), + RewindEvents = apiGetFunctionAddress(GLFW, "pojavRewindEvents"); } public static SharedLibrary getLibrary() { @@ -1057,69 +1061,8 @@ public class GLFW CallbackBridge.PENDING_EVENT_READY = true; } - // Indirect event - while (CallbackBridge.PENDING_EVENT_LIST.size() > 0) { - Integer[] dataArr = CallbackBridge.PENDING_EVENT_LIST.remove(0); - for (Long ptr : mGLFWWindowMap.keySet()) { - try { - switch (dataArr[0]) { - case CallbackBridge.EVENT_TYPE_CHAR: - if (mGLFWCharCallback != null) { - mGLFWCharCallback.invoke(ptr, dataArr[1]); - } - break; - case CallbackBridge.EVENT_TYPE_CHAR_MODS: - if (mGLFWCharModsCallback != null) { - mGLFWCharModsCallback.invoke(ptr, dataArr[1], dataArr[2]); - } - break; - case CallbackBridge.EVENT_TYPE_CURSOR_ENTER: - if (mGLFWCursorEnterCallback != null) { - mGLFWCursorEnterCallback.invoke(ptr, dataArr[1] == 1); - } - break; - case CallbackBridge.EVENT_TYPE_KEY: - if (mGLFWKeyCallback != null) { - keyDownBuffer[Math.max(0, dataArr[1]-31)]=(byte)(int)dataArr[3]; - mGLFWKeyCallback.invoke(ptr, dataArr[1], dataArr[2], dataArr[3], dataArr[4]); - } - break; - case CallbackBridge.EVENT_TYPE_MOUSE_BUTTON: - if (mGLFWMouseButtonCallback != null) { - mGLFWMouseButtonCallback.invoke(ptr, dataArr[1], dataArr[2], dataArr[3]); - } - break; - case CallbackBridge.EVENT_TYPE_SCROLL: - if (mGLFWScrollCallback != null) { - mGLFWScrollCallback.invoke(ptr, dataArr[1], dataArr[2]); - } - break; - case CallbackBridge.EVENT_TYPE_FRAMEBUFFER_SIZE: - case CallbackBridge.EVENT_TYPE_WINDOW_SIZE: - try { - internalChangeMonitorSize(dataArr[1], dataArr[2]); - glfwSetWindowSize(ptr, mGLFWWindowWidth, mGLFWWindowHeight); - if (dataArr[0] == CallbackBridge.EVENT_TYPE_FRAMEBUFFER_SIZE && mGLFWFramebufferSizeCallback != null) { - mGLFWFramebufferSizeCallback.invoke(ptr, mGLFWWindowWidth, mGLFWWindowHeight); - } else if (dataArr[0] == CallbackBridge.EVENT_TYPE_WINDOW_SIZE && mGLFWWindowSizeCallback != null) { - mGLFWWindowSizeCallback.invoke(ptr, mGLFWWindowWidth, mGLFWWindowHeight); - } - } catch (Throwable th) { - // Some Minecraft versions cause a NPE when setting size, so we will have to ignore them to make game alive - th.printStackTrace(); - } - break; - default: - System.err.println("GLFWEvent: unknown callback type " + dataArr[0]); - break; - } - }catch (Throwable throwable){ - throwable.printStackTrace(); - } - - } - } - + for (Long ptr : mGLFWWindowMap.keySet()) callJV(ptr, Functions.PumpEvents); + callV(Functions.RewindEvents); if ((mGLFWCursorX != mGLFWCursorLastX || mGLFWCursorY != mGLFWCursorLastY) && mGLFWCursorPosCallback != null) { mGLFWCursorLastX = mGLFWCursorX; mGLFWCursorLastY = mGLFWCursorY; @@ -1138,6 +1081,15 @@ public class GLFW } } + public static void internalWindowSizeChanged(long window, int w, int h) { + try { + internalChangeMonitorSize(w, h); + glfwSetWindowSize(window, mGLFWWindowWidth, mGLFWWindowHeight); + }catch (Exception e) { + e.printStackTrace(); + } + } + public static void glfwWaitEvents() {} public static void glfwWaitEventsTimeout(double timeout) { @@ -1181,7 +1133,7 @@ public class GLFW } public static int glfwGetKey(@NativeType("GLFWwindow *") long window, int key) { - return keyDownBuffer[Math.max(0, key-31)]; + return keyDownBuffer.get(Math.max(0, key-31)); } public static int glfwGetMouseButton(@NativeType("GLFWwindow *") long window, int button) {