Use native input for controls (#524)
* WIP feature: native input * Fixes: 1.13+, jar installer input What's left: fix hotbar position * Fix broken hotbar --------- Co-authored-by: Duy Tran Khanh <[email protected]>
This commit is contained in:
1 parent
31906e33b7
commit
57ecfbf096
9 files changed
+399
-611
No files matched your search
@@ -89,36 +89,6 @@ public class UIKit {
|
||||
method.invoke(null, new Object[]{new String[]{}});
|
||||
}
|
||||
|
||||
public static void callback_SurfaceViewController_onTouch(int event, float x, float y) {
|
||||
switch (event) {
|
||||
case ACTION_DOWN:
|
||||
case ACTION_UP:
|
||||
if (!GLFW.mGLFWIsGrabbing) {
|
||||
CallbackBridge.mouseX = x;
|
||||
CallbackBridge.mouseY = y;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTION_MOVE:
|
||||
if (GLFW.mGLFWIsGrabbing) {
|
||||
CallbackBridge.mouseX += x - CallbackBridge.mouseLastX;
|
||||
CallbackBridge.mouseY += y - CallbackBridge.mouseLastY;
|
||||
} else {
|
||||
CallbackBridge.mouseX = x;
|
||||
CallbackBridge.mouseY = y;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTION_MOVE_MOTION:
|
||||
CallbackBridge.mouseX += x;
|
||||
CallbackBridge.mouseY += y;
|
||||
}
|
||||
CallbackBridge.mouseLastX = x;
|
||||
CallbackBridge.mouseLastY = y;
|
||||
|
||||
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
|
||||
}
|
||||
|
||||
public static void updateMCGuiScale() {
|
||||
MCOptionUtils.load();
|
||||
String str = MCOptionUtils.get("guiScale");
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
package org.lwjgl.glfw;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import android.util.*;
|
||||
|
||||
import net.kdt.pojavlaunch.*;
|
||||
import net.kdt.pojavlaunch.uikit.UIKit;
|
||||
import net.kdt.pojavlaunch.utils.MCOptionUtils;
|
||||
|
||||
public class CallbackBridge {
|
||||
public static final int CLIPBOARD_COPY = 2000;
|
||||
@@ -20,210 +13,38 @@ public class CallbackBridge {
|
||||
public static final int EVENT_TYPE_KEY = 1005;
|
||||
public static final int EVENT_TYPE_MOUSE_BUTTON = 1006;
|
||||
public static final int EVENT_TYPE_SCROLL = 1007;
|
||||
public static final int EVENT_TYPE_WINDOW_POS = 1008;
|
||||
public static final int EVENT_TYPE_WINDOW_SIZE = 1009;
|
||||
public static final int EVENT_TYPE_WINDOW_SIZE = 1008;
|
||||
|
||||
public static final int ANDROID_TYPE_GRAB_STATE = 0;
|
||||
|
||||
// Should pending events be limited?
|
||||
volatile public static List<Object[]> PENDING_EVENT_LIST = new ArrayList<>();
|
||||
volatile public static boolean PENDING_EVENT_READY = false;
|
||||
|
||||
public static final boolean INPUT_DEBUG_ENABLED;
|
||||
|
||||
private static boolean inputReady;
|
||||
|
||||
// TODO send grab state event to Android
|
||||
|
||||
static {
|
||||
System.load(System.getenv("BUNDLE_PATH") + "/PojavLauncher");
|
||||
|
||||
// Forge 1.17+ initialize their very own space (both Java and JNI) so we re-init stuff here
|
||||
MCOptionUtils.load();
|
||||
Tools.mGLFWWindowWidth = Integer.parseInt(MCOptionUtils.get("overrideWidth"));
|
||||
Tools.mGLFWWindowHeight = Integer.parseInt(MCOptionUtils.get("overrideHeight"));
|
||||
MCOptionUtils.save(); // Free the loaded data
|
||||
CallbackBridge.setClass();
|
||||
try {
|
||||
Class.forName("net.kdt.pojavlaunch.uikit.UIKit");
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
INPUT_DEBUG_ENABLED = Boolean.parseBoolean(System.getProperty("glfwstub.debugInput", "false"));
|
||||
}
|
||||
|
||||
// BEGIN launcher side
|
||||
public static float mouseX, mouseY, mouseLastX, mouseLastY;
|
||||
public static boolean mouseLeft;
|
||||
//public static StringBuilder DEBUG_STRING = new StringBuilder();
|
||||
|
||||
public static boolean nativeIsGrabbing() {
|
||||
return GLFW.mGLFWIsGrabbing;
|
||||
}
|
||||
|
||||
private static void nativeSendCursorPos(float x, float y) {
|
||||
if (!inputReady) return;
|
||||
GLFW.mGLFWCursorX = x + GLFW.internalGetWindow(GLFW.mainContext).x;
|
||||
GLFW.mGLFWCursorY = y + GLFW.internalGetWindow(GLFW.mainContext).y;
|
||||
}
|
||||
private static void nativeSendKeycode(int keycode, char keychar, int scancode, int action, int mods) {
|
||||
if (!inputReady) return;
|
||||
// TODO keycode
|
||||
// PENDING_EVENT_LIST.add(new Integer[]{EVENR_TYPE_CHAR_MODS});
|
||||
}
|
||||
private static void nativeSendMouseButton(int button, int action, int mods) {
|
||||
if (!inputReady) return;
|
||||
PENDING_EVENT_LIST.add(new Object[]{EVENT_TYPE_MOUSE_BUTTON, button, action, mods, 0});
|
||||
}
|
||||
private static void nativeSendScroll(double xoffset, double yoffset) {
|
||||
if (!inputReady) return;
|
||||
PENDING_EVENT_LIST.add(new Object[]{EVENT_TYPE_SCROLL, (int) xoffset, (int) yoffset, 0, 0});
|
||||
}
|
||||
private static void nativeSendScreenSize(int width, int height) {
|
||||
if (!inputReady) return;
|
||||
PENDING_EVENT_LIST.add(new Object[]{EVENT_TYPE_FRAMEBUFFER_SIZE, width, height, 0, 0});
|
||||
PENDING_EVENT_LIST.add(new Object[]{EVENT_TYPE_WINDOW_SIZE, width, height, 0, 0});
|
||||
}
|
||||
private static void nativeSendWindowPos(int x, int y) {
|
||||
if (!inputReady) return;
|
||||
PENDING_EVENT_LIST.add(new Object[]{EVENT_TYPE_WINDOW_POS, x, y, 0, 0});
|
||||
}
|
||||
|
||||
// volatile private static boolean isGrabbing = false;
|
||||
public static class PusherRunnable implements Runnable {
|
||||
int button; float x; float y;
|
||||
public PusherRunnable(int button, float x, float y) {
|
||||
this.button = button;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
putMouseEventWithCoords(button, 1, x, y);
|
||||
try { Thread.sleep(40); } catch (InterruptedException e) {}
|
||||
putMouseEventWithCoords(button, 0, x, y);
|
||||
}
|
||||
}
|
||||
public static void putMouseEventWithCoords(int button, float x, float y /* , int dz, long nanos */) {
|
||||
new Thread(new PusherRunnable(button,x,y)).run();
|
||||
}
|
||||
|
||||
public static void putMouseEventWithCoords(int button, int state, float x, float y /* , int dz, long nanos */) {
|
||||
sendCursorPos(x, y);
|
||||
sendMouseKeycode(button, CallbackBridge.getCurrentMods(), state == 1);
|
||||
}
|
||||
|
||||
private static boolean threadAttached;
|
||||
public static void sendCursorPos(float x, float y) {
|
||||
if (!threadAttached) {
|
||||
threadAttached = true; // CallbackBridge.nativeAttachThreadToOther(true, true /* TODO BaseMainActivity.isInputStackCall */);
|
||||
}
|
||||
|
||||
//DEBUG_STRING.append("CursorPos=" + x + ", " + y + "\n");
|
||||
mouseX = x;
|
||||
mouseY = y;
|
||||
nativeSendCursorPos(x, y);
|
||||
}
|
||||
|
||||
public static void sendKeycode(int keycode, char keychar, int scancode, int modifiers, boolean isDown) {
|
||||
//DEBUG_STRING.append("KeyCode=" + keycode + ", Char=" + keychar);
|
||||
// TODO CHECK: This may cause input issue, not receive input!
|
||||
/*
|
||||
if (!nativeSendCharMods((int) keychar, modifiers) || !nativeSendChar(keychar)) {
|
||||
nativeSendKey(keycode, 0, isDown ? 1 : 0, modifiers);
|
||||
}
|
||||
*/
|
||||
|
||||
nativeSendKeycode(keycode, keychar, scancode, isDown ? 1 : 0, modifiers);
|
||||
|
||||
// sendData(JRE_TYPE_KEYCODE_CONTROL, keycode, Character.toString(keychar), Boolean.toString(isDown), modifiers);
|
||||
}
|
||||
|
||||
public static void sendMouseKeycode(int button, int modifiers, boolean isDown) {
|
||||
//DEBUG_STRING.append("MouseKey=" + button + ", down=" + isDown + "\n");
|
||||
// if (isGrabbing()) DEBUG_STRING.append("MouseGrabStrace: " + android.util.Log.getStackTraceString(new Throwable()) + "\n");
|
||||
nativeSendMouseButton(button, isDown ? 1 : 0, modifiers);
|
||||
}
|
||||
|
||||
public static void sendMouseKeycode(int keycode) {
|
||||
sendMouseKeycode(keycode, CallbackBridge.getCurrentMods(), true);
|
||||
sendMouseKeycode(keycode, CallbackBridge.getCurrentMods(), false);
|
||||
}
|
||||
|
||||
public static void sendScroll(double xoffset, double yoffset) {
|
||||
//DEBUG_STRING.append("ScrollX=" + xoffset + ",ScrollY=" + yoffset);
|
||||
nativeSendScroll(xoffset, yoffset);
|
||||
}
|
||||
|
||||
public static void sendUpdateWindowSize(int w, int h) {
|
||||
nativeSendScreenSize(w, h);
|
||||
}
|
||||
|
||||
public static boolean isGrabbing() {
|
||||
return nativeIsGrabbing();
|
||||
}
|
||||
|
||||
public static boolean holdingAlt, holdingCapslock, holdingCtrl,
|
||||
holdingNumlock, holdingShift;
|
||||
public static int getCurrentMods() {
|
||||
int currMods = 0;
|
||||
if (holdingAlt) {
|
||||
currMods &= LWJGLGLFWKeycode.GLFW_MOD_ALT;
|
||||
} if (holdingCapslock) {
|
||||
currMods &= LWJGLGLFWKeycode.GLFW_MOD_CAPS_LOCK;
|
||||
} if (holdingCtrl) {
|
||||
currMods &= LWJGLGLFWKeycode.GLFW_MOD_CONTROL;
|
||||
} if (holdingNumlock) {
|
||||
currMods &= LWJGLGLFWKeycode.GLFW_MOD_NUM_LOCK;
|
||||
} if (holdingShift) {
|
||||
currMods &= LWJGLGLFWKeycode.GLFW_MOD_SHIFT;
|
||||
}
|
||||
return currMods;
|
||||
}
|
||||
// END launcher side
|
||||
|
||||
public static void sendGrabbing(boolean grab, float xset, float yset) {
|
||||
// sendData(ANDROID_TYPE_GRAB_STATE, Boolean.toString(grab));
|
||||
|
||||
if (grab) {
|
||||
UIKit.updateMCGuiScale();
|
||||
/*
|
||||
if (isDebugEnabled) {
|
||||
//try {
|
||||
//debugEventStream = new PrintStream(new File(System.getProperty("user.dir"), "glfwstub_inputeventlog.txt"));
|
||||
debugEventStream = System.out;
|
||||
//} catch (FileNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
//}
|
||||
}
|
||||
|
||||
mouseX = xset;
|
||||
mouseY = yset;
|
||||
|
||||
GLFW.mGLFWIsGrabbing = grab;
|
||||
nativeSetGrabbing(grab, xset, yset);
|
||||
|
||||
//Quick and dirty: debul all key inputs to System.out
|
||||
*/
|
||||
}
|
||||
|
||||
// Called from native code
|
||||
public static void receiveCallback(int type, float i1, float i2, int i3, int i4) {
|
||||
/*
|
||||
if (INPUT_DEBUG_ENABLED) {
|
||||
System.out.println("LWJGL GLFW Callback received type=" + Integer.toString(type) + ", data=" + i1 + ", " + i2 + ", " + i3 + ", " + i4);
|
||||
}
|
||||
*/
|
||||
if (PENDING_EVENT_READY) {
|
||||
if (type == EVENT_TYPE_CURSOR_POS) {
|
||||
GLFW.mGLFWCursorX = (double) i1;
|
||||
GLFW.mGLFWCursorY = (double) i2;
|
||||
} else if (type == EVENT_TYPE_SCROLL) {
|
||||
PENDING_EVENT_LIST.add(new Object[]{type, i1, i2, i3, i4});
|
||||
} else {
|
||||
PENDING_EVENT_LIST.add(new Object[]{type, (int)i1, (int)i2, i3, i4});
|
||||
}
|
||||
} // else System.out.println("Event input is not ready yet!");
|
||||
|
||||
|
||||
public static void sendData(int type, String data) {
|
||||
nativeSendData(false, type, data);
|
||||
}
|
||||
|
||||
// public static native void nativeSendData(boolean isAndroid, int type, String data);
|
||||
public static boolean nativeSetInputReady(boolean ready) {
|
||||
inputReady = ready;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static native String nativeClipboard(int action, String copy);
|
||||
private static native void nativeSetGrabbing(boolean grab, float xset, float yset);
|
||||
public static native void setClass();
|
||||
public static native void nativeSendData(boolean isAndroid, int type, String data);
|
||||
public static native boolean nativeSetInputReady(boolean ready);
|
||||
public static native String nativeClipboard(int action, byte[] copy);
|
||||
public static native void nativeSetGrabbing(boolean grab);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,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();
|
||||
@@ -345,7 +347,7 @@ public class GLFW
|
||||
|
||||
/**
|
||||
* The omni-directional resize cursor/move shape.
|
||||
*
|
||||
*
|
||||
* <p>This is usually either a combined horizontal and vertical double-headed arrow or a grabbing hand.</p>
|
||||
*/
|
||||
public static final int GLFW_RESIZE_ALL_CURSOR = 0x36009;
|
||||
@@ -431,7 +433,7 @@ public class GLFW
|
||||
|
||||
/**
|
||||
* Specifies whether to allow access to the window menu via the Alt+Space and Alt-and-then-Space keyboard shortcuts.
|
||||
*
|
||||
*
|
||||
* <p>This is ignored on other platforms.</p>
|
||||
*/
|
||||
public static final int GLFW_WIN32_KEYBOARD_MENU = 0x25001;
|
||||
@@ -488,43 +490,46 @@ public class GLFW
|
||||
/* volatile */ public static GLFWWindowRefreshCallback mGLFWWindowRefreshCallback;
|
||||
/* volatile */ public static GLFWWindowSizeCallback mGLFWWindowSizeCallback;
|
||||
|
||||
volatile public static double mGLFWCursorX, mGLFWCursorY, mGLFWCursorLastX, mGLFWCursorLastY;
|
||||
|
||||
volatile public static int mGLFWWindowWidth, mGLFWWindowHeight;
|
||||
|
||||
private static GLFWGammaRamp mGLFWGammaRamp;
|
||||
private static Map<Integer, String> mGLFWKeyCodes;
|
||||
private static GLFWVidMode mGLFWVideoMode;
|
||||
private static long mGLFWWindowMonitor;
|
||||
|
||||
private static double mGLFWInitialTime;
|
||||
|
||||
private static ArrayMap<Long, GLFWWindowProperties> mGLFWWindowMap;
|
||||
|
||||
public static boolean mGLFWIsGrabbing, mGLFWIsInputReady, mGLFWIsUseStackQueue = false;
|
||||
public static final byte[] keyDownBuffer = new byte[317];
|
||||
private static double mGLFWInitialTime;
|
||||
|
||||
private static ArrayMap<Long, GLFWWindowProperties> mGLFWWindowMap;
|
||||
public static boolean mGLFWIsInputReady;
|
||||
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;
|
||||
|
||||
static {
|
||||
try {
|
||||
System.load(System.getenv("BUNDLE_PATH") + "/PojavLauncher");
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
mGLFWWindowWidth = Tools.mGLFWWindowWidth;
|
||||
mGLFWWindowHeight = Tools.mGLFWWindowHeight;
|
||||
|
||||
// Minecraft triggers a glfwPollEvents() on splash screen, so update window size there.
|
||||
// note: these calls are required, otherwise mouse input will break
|
||||
CallbackBridge.receiveCallback(CallbackBridge.EVENT_TYPE_FRAMEBUFFER_SIZE, Tools.mGLFWWindowWidth, Tools.mGLFWWindowHeight, 0, 0);
|
||||
CallbackBridge.receiveCallback(CallbackBridge.EVENT_TYPE_WINDOW_SIZE, Tools.mGLFWWindowWidth, Tools.mGLFWWindowHeight, 0, 0);
|
||||
// CallbackBridge.receiveCallback(CallbackBridge.EVENT_TYPE_FRAMEBUFFER_SIZE, mGLFWWindowWidth, mGLFWWindowHeight, 0, 0);
|
||||
// CallbackBridge.receiveCallback(CallbackBridge.EVENT_TYPE_WINDOW_SIZE, mGLFWWindowWidth, mGLFWWindowHeight, 0, 0);
|
||||
|
||||
mGLFWErrorCallback = GLFWErrorCallback.createPrint();
|
||||
mGLFWKeyCodes = new ArrayMap<>();
|
||||
|
||||
mGLFWWindowMap = new ArrayMap<>();
|
||||
|
||||
mGLFWVideoMode = new GLFWVidMode(ByteBuffer.allocateDirect(GLFWVidMode.SIZEOF));
|
||||
internalChangeMonitorSize(Tools.mGLFWWindowWidth, Tools.mGLFWWindowHeight);
|
||||
|
||||
memPutInt(mGLFWVideoMode.address() + (long) mGLFWVideoMode.REDBITS, 8);
|
||||
memPutInt(mGLFWVideoMode.address() + (long) mGLFWVideoMode.GREENBITS, 8);
|
||||
memPutInt(mGLFWVideoMode.address() + (long) mGLFWVideoMode.BLUEBITS, 8);
|
||||
mGLFWWindowMap = new ArrayMap<>();
|
||||
|
||||
mGLFWVideoMode = new GLFWVidMode(ByteBuffer.allocateDirect(GLFWVidMode.SIZEOF));
|
||||
memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.WIDTH, mGLFWWindowWidth);
|
||||
memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.HEIGHT, mGLFWWindowHeight);
|
||||
memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.REDBITS, 8);
|
||||
memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.GREENBITS, 8);
|
||||
memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.BLUEBITS, 8);
|
||||
memPutInt(mGLFWVideoMode.address() + (long) mGLFWVideoMode.REFRESHRATE, Integer.parseInt(System.getProperty("UIScreen.maximumFramesPerSecond")));
|
||||
|
||||
// A way to generate key code names
|
||||
@@ -533,9 +538,9 @@ public class GLFW
|
||||
for (Field thisField : thisFieldArr) {
|
||||
if (thisField.getName().startsWith("GLFW_KEY_")) {
|
||||
mGLFWKeyCodes.put(
|
||||
(int) thisField.get(null),
|
||||
thisField.getName().substring(9, 10).toUpperCase() +
|
||||
thisField.getName().substring(10).replace("_", " ").toLowerCase()
|
||||
(int) thisField.get(null),
|
||||
thisField.getName().substring(9, 10).toUpperCase() +
|
||||
thisField.getName().substring(10).replace("_", " ").toLowerCase()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -552,11 +557,10 @@ public class GLFW
|
||||
private static native long nglfwSetKeyCallback(long window, long ptr);
|
||||
private static native long nglfwSetMouseButtonCallback(long window, long ptr);
|
||||
private static native long nglfwSetScrollCallback(long window, long ptr);
|
||||
private static native long nglfwSetWindowPosCallback(long window, long ptr);
|
||||
private static native long nglfwSetWindowSizeCallback(long window, long ptr);
|
||||
// private static native void nglfwSetInputReady();
|
||||
private static native void nglfwSetShowingWindow(long window);
|
||||
|
||||
|
||||
/*
|
||||
private static void priGlfwSetError(int error) {
|
||||
mGLFW_currentError = error;
|
||||
@@ -583,43 +587,40 @@ public class GLFW
|
||||
|
||||
/** Function address. */
|
||||
public static final long
|
||||
Init = apiGetFunctionAddress(GLFW, "pojavInit"),
|
||||
CreateContext = apiGetFunctionAddress(GLFW, "pojavCreateContext"),
|
||||
GetCurrentContext = apiGetFunctionAddress(GLFW, "pojavGetCurrentContext"),
|
||||
//DetachOnCurrentThread = apiGetFunctionAddress(GLFW, "pojavDetachOnCurrentThread"),
|
||||
MakeContextCurrent = apiGetFunctionAddress(GLFW, "pojavMakeCurrent"),
|
||||
Terminate = apiGetFunctionAddress(GLFW, "pojavTerminate"),
|
||||
SetWindowHint = apiGetFunctionAddress(GLFW, "pojavSetWindowHint"),
|
||||
SwapBuffers = apiGetFunctionAddress(GLFW, "pojavSwapBuffers"),
|
||||
SwapInterval = apiGetFunctionAddress(GLFW, "pojavSwapInterval");
|
||||
Init = apiGetFunctionAddress(GLFW, "pojavInit"),
|
||||
CreateContext = apiGetFunctionAddress(GLFW, "pojavCreateContext"),
|
||||
GetCurrentContext = apiGetFunctionAddress(GLFW, "pojavGetCurrentContext"),
|
||||
//DetachOnCurrentThread = apiGetFunctionAddress(GLFW, "pojavDetachOnCurrentThread"),
|
||||
MakeContextCurrent = apiGetFunctionAddress(GLFW, "pojavMakeCurrent"),
|
||||
Terminate = apiGetFunctionAddress(GLFW, "pojavTerminate"),
|
||||
SetWindowHint = apiGetFunctionAddress(GLFW, "pojavSetWindowHint"),
|
||||
SwapBuffers = apiGetFunctionAddress(GLFW, "pojavSwapBuffers"),
|
||||
SwapInterval = apiGetFunctionAddress(GLFW, "pojavSwapInterval"),
|
||||
PumpEvents = apiGetFunctionAddress(GLFW, "pojavPumpEvents"),
|
||||
RewindEvents = apiGetFunctionAddress(GLFW, "pojavRewindEvents");
|
||||
}
|
||||
|
||||
public static SharedLibrary getLibrary() {
|
||||
return GLFW;
|
||||
}
|
||||
|
||||
|
||||
public static void internalChangeMonitorSize(int width, int height) {
|
||||
Tools.mGLFWWindowWidth = width;
|
||||
Tools.mGLFWWindowHeight = height;
|
||||
memPutInt(mGLFWVideoMode.address() + (long) mGLFWVideoMode.WIDTH, Tools.mGLFWWindowWidth);
|
||||
memPutInt(mGLFWVideoMode.address() + (long) mGLFWVideoMode.HEIGHT, Tools.mGLFWWindowHeight);
|
||||
mGLFWWindowWidth = width;
|
||||
mGLFWWindowHeight = height;
|
||||
if (mGLFWVideoMode == null) return;
|
||||
memPutInt(mGLFWVideoMode.address() + (long) mGLFWVideoMode.WIDTH, mGLFWWindowWidth);
|
||||
memPutInt(mGLFWVideoMode.address() + (long) mGLFWVideoMode.HEIGHT, mGLFWWindowHeight);
|
||||
}
|
||||
|
||||
|
||||
public static GLFWWindowProperties internalGetWindow(long window) {
|
||||
GLFWWindowProperties win = mGLFWWindowMap.get(window);
|
||||
if (win == null) {
|
||||
System.err.println("GLFW: No window pointer found: " + window);
|
||||
win = mGLFWWindowMap.get(mainContext);
|
||||
// throw new IllegalArgumentException("No window pointer found: " + window);
|
||||
}
|
||||
if (win == null) {
|
||||
System.err.println("GLFW: Stills no window pointer found: " + window);
|
||||
win = mGLFWWindowMap.valueAt(0);
|
||||
throw new IllegalArgumentException("No window pointer found: " + window);
|
||||
}
|
||||
return win;
|
||||
}
|
||||
|
||||
// Generated stub callback methods
|
||||
// Generated stub callback methods
|
||||
public static GLFWCharCallback glfwSetCharCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWcharfun") GLFWCharCallbackI cbfun) {
|
||||
GLFWCharCallback lastCallback = mGLFWCharCallback;
|
||||
if (cbfun == null) mGLFWCharCallback = null;
|
||||
@@ -651,7 +652,7 @@ public class GLFW
|
||||
|
||||
return lastCallback;
|
||||
}
|
||||
|
||||
|
||||
public static GLFWDropCallback glfwSetDropCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWdropfun") GLFWDropCallbackI cbfun) {
|
||||
GLFWDropCallback lastCallback = mGLFWDropCallback;
|
||||
if (cbfun == null) mGLFWDropCallback = null;
|
||||
@@ -792,7 +793,7 @@ public class GLFW
|
||||
public static void glfwTerminate() {
|
||||
mGLFWIsInputReady = false;
|
||||
CallbackBridge.nativeSetInputReady(false);
|
||||
|
||||
|
||||
long __functionAddress = Functions.Terminate;
|
||||
invokeV(__functionAddress);
|
||||
}
|
||||
@@ -847,21 +848,18 @@ public class GLFW
|
||||
|
||||
xpos.put(0);
|
||||
ypos.put(0);
|
||||
width.put(Tools.mGLFWWindowWidth);
|
||||
height.put(Tools.mGLFWWindowHeight);
|
||||
width.put(mGLFWWindowWidth);
|
||||
height.put(mGLFWWindowHeight);
|
||||
}
|
||||
|
||||
@NativeType("GLFWmonitor *")
|
||||
public static long glfwGetWindowMonitor(@NativeType("GLFWwindow *") long window) {
|
||||
return internalGetWindow(window).monitor;
|
||||
return mGLFWWindowMonitor;
|
||||
}
|
||||
|
||||
public static void glfwSetWindowMonitor(@NativeType("GLFWwindow *") long window, @NativeType("GLFWmonitor *") long monitor, int xpos, int ypos, int width, int height, int refreshRate) {
|
||||
GLFWWindowProperties properties = internalGetWindow(window);
|
||||
properties.monitor = monitor;
|
||||
properties.x = xpos;
|
||||
properties.y = ypos;
|
||||
internalChangeMonitorSize(width, height);
|
||||
// weird calculation to fake pointer
|
||||
mGLFWWindowMonitor = window * monitor;
|
||||
}
|
||||
|
||||
public static int glfwGetWindowAttrib(@NativeType("GLFWwindow *") long window, int attrib) {
|
||||
@@ -878,7 +876,7 @@ public class GLFW
|
||||
checkSafe(minor, 1);
|
||||
checkSafe(rev, 1);
|
||||
}
|
||||
|
||||
|
||||
major.put(GLFW_VERSION_MAJOR);
|
||||
minor.put(GLFW_VERSION_MINOR);
|
||||
rev.put(GLFW_VERSION_REVISION);
|
||||
@@ -895,12 +893,13 @@ public class GLFW
|
||||
@Nullable
|
||||
@NativeType("GLFWvidmode const *")
|
||||
public static GLFWVidMode.Buffer glfwGetVideoModes(@NativeType("GLFWmonitor *") long monitor) {
|
||||
MemoryStack stack = stackGet();
|
||||
int stackPointer = stack.getPointer();
|
||||
MemoryStack stack = stackGet(); int stackPointer = stack.getPointer();
|
||||
try {
|
||||
// long __result = nglfwGetVideoModes(monitor, memAddress(count));
|
||||
long __result = glfwGetVideoMode(monitor).address();
|
||||
return GLFWVidMode.createSafe(__result, 1);
|
||||
GLFWVidMode.Buffer buffer = GLFWVidMode.createSafe(__result, 1);
|
||||
buffer.put(glfwGetVideoMode(monitor));
|
||||
return buffer;
|
||||
} finally {
|
||||
stack.setPointer(stackPointer);
|
||||
}
|
||||
@@ -939,34 +938,35 @@ public class GLFW
|
||||
// System.out.println("glfwGetTime");
|
||||
return (System.nanoTime() - mGLFWInitialTime) / 1.e9;
|
||||
}
|
||||
|
||||
|
||||
public static void glfwSetTime(double time) {
|
||||
mGLFWInitialTime = System.nanoTime() - (long) time;
|
||||
}
|
||||
|
||||
|
||||
public static long glfwGetTimerValue() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
public static long glfwGetTimerFrequency() {
|
||||
// FIXME set correct value!!
|
||||
return 60;
|
||||
}
|
||||
|
||||
|
||||
// GLFW Window functions
|
||||
public static long nglfwCreateContext(long share) {
|
||||
return invokePP(share, Functions.CreateContext);
|
||||
}
|
||||
public static long glfwCreateWindow(int width, int height, CharSequence title, long monitor, long share) {
|
||||
EventLoop.OffScreen.check();
|
||||
// Create an ACTUAL EGL context
|
||||
// Create an ACTUAL EGL context
|
||||
long ptr = nglfwCreateContext(share);
|
||||
//nativeEglMakeCurrent(ptr);
|
||||
GLFWWindowProperties win = new GLFWWindowProperties();
|
||||
// win.width = width;
|
||||
// win.height = height;
|
||||
|
||||
win.width = width;
|
||||
win.height = height;
|
||||
|
||||
win.width = mGLFWWindowWidth;
|
||||
win.height = mGLFWWindowHeight;
|
||||
win.title = title;
|
||||
|
||||
win.windowAttribs.put(GLFW_HOVERED, 1);
|
||||
@@ -980,8 +980,13 @@ public class GLFW
|
||||
|
||||
public static void glfwDestroyWindow(long window) {
|
||||
// Check window exists
|
||||
internalGetWindow(window);
|
||||
mGLFWWindowMap.remove(window);
|
||||
try {
|
||||
internalGetWindow(window);
|
||||
mGLFWWindowMap.remove(window);
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("GLFW: Warning: failed to remove window " + window);
|
||||
e.printStackTrace();
|
||||
}
|
||||
nglfwSetShowingWindow(mGLFWWindowMap.size() == 0 ? 0 : mGLFWWindowMap.keyAt(mGLFWWindowMap.size() - 1));
|
||||
}
|
||||
|
||||
@@ -998,21 +1003,15 @@ public class GLFW
|
||||
internalGetWindow(window).x = x;
|
||||
internalGetWindow(window).y = y;
|
||||
}
|
||||
|
||||
|
||||
public static void glfwSetWindowSize(long window, int width, int height) {
|
||||
try {
|
||||
internalChangeMonitorSize(width, height);
|
||||
internalGetWindow(window).width = width;
|
||||
internalGetWindow(window).height = height;
|
||||
System.out.println("GLFW: Set size for window " + window + ", width=" + width + ", height=" + height);
|
||||
} catch (Throwable th) {
|
||||
System.err.println("Unable to set window size for window " + window);
|
||||
th.printStackTrace();
|
||||
}
|
||||
internalGetWindow(window).width = width;
|
||||
internalGetWindow(window).height = height;
|
||||
|
||||
System.out.println("GLFW: Set size for window " + window + ", width=" + width + ", height=" + height);
|
||||
}
|
||||
|
||||
public static void glfwShowWindow(long window) {
|
||||
System.out.println("GLFW: Showing window " + window + ", " + internalGetWindow(window).toString());
|
||||
nglfwSetShowingWindow(window);
|
||||
}
|
||||
public static void glfwWindowHint(int hint, int value) {
|
||||
@@ -1030,91 +1029,33 @@ public class GLFW
|
||||
public static void glfwSetWindowShouldClose(long window, boolean close) {
|
||||
internalGetWindow(window).shouldClose = close;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void glfwSetWindowTitle(@NativeType("GLFWwindow *") long window, @NativeType("char const *") ByteBuffer title) {
|
||||
|
||||
|
||||
}
|
||||
public static void glfwSetWindowTitle(@NativeType("GLFWwindow *") long window, @NativeType("char const *") CharSequence title) {
|
||||
internalGetWindow(window).title = title;
|
||||
}
|
||||
|
||||
|
||||
public static void glfwSetWindowIcon(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWimage const *") GLFWImage.Buffer images) {}
|
||||
|
||||
public static void glfwPollEvents() {
|
||||
if (!mGLFWIsInputReady) {
|
||||
mGLFWIsInputReady = true;
|
||||
mGLFWIsUseStackQueue = CallbackBridge.nativeSetInputReady(true);
|
||||
CallbackBridge.nativeSetInputReady(true);
|
||||
}
|
||||
|
||||
if (!CallbackBridge.PENDING_EVENT_READY) {
|
||||
CallbackBridge.PENDING_EVENT_READY = true;
|
||||
// nglfwSetInputReady();
|
||||
}
|
||||
|
||||
// Indirect event
|
||||
while (CallbackBridge.PENDING_EVENT_LIST.size() > 0) {
|
||||
Object[] dataArr = CallbackBridge.PENDING_EVENT_LIST.remove(0);
|
||||
|
||||
for (Long ptr : mGLFWWindowMap.keySet()) {
|
||||
switch ((int)dataArr[0]) {
|
||||
case CallbackBridge.EVENT_TYPE_CHAR:
|
||||
if (mGLFWCharCallback != null) {
|
||||
mGLFWCharCallback.invoke(ptr, (int)dataArr[1]);
|
||||
}
|
||||
break;
|
||||
case CallbackBridge.EVENT_TYPE_CHAR_MODS:
|
||||
if (mGLFWCharModsCallback != null) {
|
||||
mGLFWCharModsCallback.invoke(ptr, (int)dataArr[1], (int)dataArr[2]);
|
||||
}
|
||||
break;
|
||||
case CallbackBridge.EVENT_TYPE_CURSOR_ENTER:
|
||||
if (mGLFWCursorEnterCallback != null) {
|
||||
mGLFWCursorEnterCallback.invoke(ptr, (int)dataArr[1] == 1);
|
||||
}
|
||||
break;
|
||||
case CallbackBridge.EVENT_TYPE_KEY:
|
||||
if (mGLFWKeyCallback != null) {
|
||||
keyDownBuffer[Math.max(0, (int)dataArr[1]-31)]=(byte)(int)dataArr[3];
|
||||
mGLFWKeyCallback.invoke(ptr, (int)dataArr[1], (int)dataArr[2], (int)dataArr[3], (int)dataArr[4]);
|
||||
}
|
||||
break;
|
||||
case CallbackBridge.EVENT_TYPE_MOUSE_BUTTON:
|
||||
if (mGLFWMouseButtonCallback != null) {
|
||||
mGLFWMouseButtonCallback.invoke(ptr, (int)dataArr[1], (int)dataArr[2], (int)dataArr[3]);
|
||||
}
|
||||
break;
|
||||
case CallbackBridge.EVENT_TYPE_SCROLL:
|
||||
if (mGLFWScrollCallback != null) {
|
||||
mGLFWScrollCallback.invoke(ptr, (float)dataArr[1], (float)dataArr[2]);
|
||||
}
|
||||
break;
|
||||
case CallbackBridge.EVENT_TYPE_WINDOW_POS:
|
||||
glfwSetWindowPos(ptr, (int)dataArr[1], (int)dataArr[2]);
|
||||
break;
|
||||
case CallbackBridge.EVENT_TYPE_FRAMEBUFFER_SIZE:
|
||||
case CallbackBridge.EVENT_TYPE_WINDOW_SIZE:
|
||||
glfwSetWindowSize(ptr, (int)dataArr[1], (int)dataArr[2]);
|
||||
if ((int)dataArr[0] == CallbackBridge.EVENT_TYPE_FRAMEBUFFER_SIZE && mGLFWFramebufferSizeCallback != null) {
|
||||
mGLFWFramebufferSizeCallback.invoke(ptr, Tools.mGLFWWindowWidth, Tools.mGLFWWindowHeight);
|
||||
} else if ((int)dataArr[0] == CallbackBridge.EVENT_TYPE_WINDOW_SIZE && mGLFWWindowSizeCallback != null) {
|
||||
mGLFWWindowSizeCallback.invoke(ptr, Tools.mGLFWWindowWidth, Tools.mGLFWWindowHeight);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
System.err.println("GLFWEvent: unknown callback type " + (int)dataArr[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((mGLFWCursorX != mGLFWCursorLastX || mGLFWCursorY != mGLFWCursorLastY) && mGLFWCursorPosCallback != null) {
|
||||
mGLFWCursorLastX = mGLFWCursorX;
|
||||
mGLFWCursorLastY = mGLFWCursorY;
|
||||
for (Long ptr : mGLFWWindowMap.keySet()) {
|
||||
mGLFWCursorPosCallback.invoke(ptr, mGLFWCursorX, mGLFWCursorY);
|
||||
}
|
||||
//System.out.println("CursorPos updated to x=" + mGLFWCursorX + ",y=" + mGLFWCursorY);
|
||||
for (Long ptr : mGLFWWindowMap.keySet()) callJV(ptr, Functions.PumpEvents);
|
||||
callV(Functions.RewindEvents);
|
||||
}
|
||||
|
||||
public static void internalWindowSizeChanged(long window, int w, int h) {
|
||||
try {
|
||||
internalChangeMonitorSize(w, h);
|
||||
glfwSetWindowSize(window, mGLFWWindowWidth, mGLFWWindowHeight);
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1123,12 +1064,12 @@ public class GLFW
|
||||
public static void glfwWaitEventsTimeout(double timeout) {
|
||||
// Boardwalk: this isn't how you do a frame limiter, but oh well
|
||||
// System.out.println("Frame limiter");
|
||||
|
||||
/*
|
||||
try {
|
||||
Thread.sleep((long)(timeout * 1000));
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
|
||||
*/
|
||||
// System.out.println("Out of the frame limiter");
|
||||
|
||||
}
|
||||
@@ -1143,12 +1084,13 @@ public class GLFW
|
||||
if (mode == GLFW_CURSOR) {
|
||||
switch (value) {
|
||||
case GLFW_CURSOR_DISABLED:
|
||||
CallbackBridge.sendGrabbing(true, (int) mGLFWCursorX, (int) mGLFWCursorY);
|
||||
net.kdt.pojavlaunch.uikit.UIKit.updateMCGuiScale();
|
||||
CallbackBridge.nativeSetGrabbing(true);
|
||||
break;
|
||||
default: CallbackBridge.sendGrabbing(false, (int) mGLFWCursorX, (int) mGLFWCursorY);
|
||||
default: CallbackBridge.nativeSetGrabbing(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internalGetWindow(window).inputModes.put(mode, value);
|
||||
}
|
||||
public static String glfwGetKeyName(int key, int scancode) {
|
||||
@@ -1161,30 +1103,31 @@ 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) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void glfwGetCursorPos(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("double *") DoubleBuffer xpos, @Nullable @NativeType("double *") DoubleBuffer ypos) {
|
||||
if (CHECKS) {
|
||||
checkSafe(xpos, 1);
|
||||
checkSafe(ypos, 1);
|
||||
}
|
||||
|
||||
xpos.put(mGLFWCursorX);
|
||||
ypos.put(mGLFWCursorY);
|
||||
nglfwGetCursorPos(window, xpos, ypos);
|
||||
}
|
||||
|
||||
public static void glfwSetCursorPos(@NativeType("GLFWwindow *") long window, double xpos, double ypos) {
|
||||
|
||||
|
||||
public static native void nglfwGetCursorPos(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("double *") DoubleBuffer xpos, @Nullable @NativeType("double *") DoubleBuffer ypos);
|
||||
public static native void nglfwGetCursorPosA(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("double *") double[] xpos, @Nullable @NativeType("double *") double[] ypos);
|
||||
|
||||
public static native void glfwSetCursorPos(@NativeType("GLFWwindow *") long window, double xpos, double ypos); /*{
|
||||
mGLFWCursorX = mGLFWCursorLastX = xpos;
|
||||
mGLFWCursorY = mGLFWCursorLastY = ypos;
|
||||
|
||||
|
||||
CallbackBridge.sendGrabbing(mGLFWIsGrabbing, (int) xpos, (int) ypos);
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
public static long glfwCreateCursor(@NativeType("const GLFWimage *") GLFWImage image, int xhot, int yhot) {
|
||||
return 4L;
|
||||
}
|
||||
@@ -1193,20 +1136,22 @@ public class GLFW
|
||||
}
|
||||
public static void glfwDestroyCursor(@NativeType("GLFWcursor *") long cursor) {}
|
||||
public static void glfwSetCursor(@NativeType("GLFWwindow *") long window, @NativeType("GLFWcursor *") long cursor) {}
|
||||
|
||||
|
||||
public static boolean glfwRawMouseMotionSupported() {
|
||||
// Should be not supported?
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static void glfwSetClipboardString(@NativeType("GLFWwindow *") long window, @NativeType("char const *") ByteBuffer string) {
|
||||
glfwSetClipboardString(window, memUTF8Safe(string));
|
||||
byte[] arr = new byte[string.remaining()];
|
||||
string.get(arr);
|
||||
CallbackBridge.nativeClipboard(CallbackBridge.CLIPBOARD_COPY, arr);
|
||||
}
|
||||
|
||||
public static void glfwSetClipboardString(@NativeType("GLFWwindow *") long window, @NativeType("char const *") CharSequence string) {
|
||||
CallbackBridge.nativeClipboard(CallbackBridge.CLIPBOARD_COPY, string.toString());
|
||||
glfwSetClipboardString(window, memUTF8Safe(string));
|
||||
}
|
||||
|
||||
|
||||
public static String glfwGetClipboardString(@NativeType("GLFWwindow *") long window) {
|
||||
return CallbackBridge.nativeClipboard(CallbackBridge.CLIPBOARD_PASTE, null);
|
||||
}
|
||||
@@ -1252,7 +1197,7 @@ public class GLFW
|
||||
|
||||
}
|
||||
public static boolean glfwUpdateGamepadMappings(ByteBuffer string) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
public static String glfwGetGamepadName(int jid) {
|
||||
return null;
|
||||
@@ -1296,8 +1241,8 @@ return false;
|
||||
|
||||
xpos[0] = 0;
|
||||
ypos[0] = 0;
|
||||
width[0] = Tools.mGLFWWindowWidth;
|
||||
height[0] = Tools.mGLFWWindowHeight;
|
||||
width[0] = mGLFWWindowWidth;
|
||||
height[0] = mGLFWWindowHeight;
|
||||
}
|
||||
|
||||
/** Array version of: {@link #glfwGetMonitorPhysicalSize GetMonitorPhysicalSize} */
|
||||
@@ -1305,7 +1250,7 @@ return false;
|
||||
public static void glfwGetMonitorPhysicalSize(@NativeType("GLFWmonitor *") long monitor, @Nullable @NativeType("int *") int[] widthMM, @Nullable @NativeType("int *") int[] heightMM) {
|
||||
long __functionAddress = Functions.GetMonitorPhysicalSize;
|
||||
if (CHECKS) {
|
||||
check(monitor);
|
||||
// check(monitor);
|
||||
checkSafe(widthMM, 1);
|
||||
checkSafe(heightMM, 1);
|
||||
}
|
||||
@@ -1318,7 +1263,7 @@ return false;
|
||||
public static void glfwGetMonitorContentScale(@NativeType("GLFWmonitor *") long monitor, @Nullable @NativeType("float *") float[] xscale, @Nullable @NativeType("float *") float[] yscale) {
|
||||
long __functionAddress = Functions.GetMonitorContentScale;
|
||||
if (CHECKS) {
|
||||
check(monitor);
|
||||
// check(monitor);
|
||||
checkSafe(xscale, 1);
|
||||
checkSafe(yscale, 1);
|
||||
}
|
||||
@@ -1378,7 +1323,7 @@ return false;
|
||||
public static void glfwGetWindowContentScale(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("float *") float[] xscale, @Nullable @NativeType("float *") float[] yscale) {
|
||||
long __functionAddress = Functions.GetWindowContentScale;
|
||||
if (CHECKS) {
|
||||
check(window);
|
||||
// check(window);
|
||||
checkSafe(xscale, 1);
|
||||
checkSafe(yscale, 1);
|
||||
}
|
||||
@@ -1393,8 +1338,7 @@ return false;
|
||||
checkSafe(xpos, 1);
|
||||
checkSafe(ypos, 1);
|
||||
}
|
||||
xpos[0] = mGLFWCursorX;
|
||||
ypos[0] = mGLFWCursorY;
|
||||
nglfwGetCursorPosA(window, xpos, ypos);
|
||||
}
|
||||
|
||||
@NativeType("int")
|
||||
|
||||
@@ -191,6 +191,7 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) {
|
||||
|
||||
rgbArray = calloc(4, (size_t) (windowWidth * windowHeight));
|
||||
|
||||
setenv("POJAV_SKIP_JNI_GLFW", "1", 1);
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
launchJVM(nil, self.filepath, windowWidth, windowHeight, 8);
|
||||
});
|
||||
|
||||
@@ -489,12 +489,12 @@ BOOL slideableHotbar;
|
||||
virtualMouseFrame.origin.y = clamp(virtualMouseFrame.origin.y, 0, self.surfaceView.frame.size.height);
|
||||
lastVirtualMousePoint = location;
|
||||
self.mousePointerView.frame = virtualMouseFrame;
|
||||
callback_SurfaceViewController_onTouch(event, virtualMouseFrame.origin.x * screenScale, virtualMouseFrame.origin.y * screenScale);
|
||||
CallbackBridge_nativeSendCursorPos(event, virtualMouseFrame.origin.x * screenScale, virtualMouseFrame.origin.y * screenScale);
|
||||
return;
|
||||
}
|
||||
lastVirtualMousePoint = location;
|
||||
}
|
||||
callback_SurfaceViewController_onTouch(event, location.x * screenScale, location.y * screenScale);
|
||||
CallbackBridge_nativeSendCursorPos(event, location.x * screenScale, location.y * screenScale);
|
||||
}
|
||||
|
||||
#pragma mark - Input: on-surface functions
|
||||
@@ -547,7 +547,7 @@ BOOL slideableHotbar;
|
||||
|
||||
if (touchEvent == self.primaryTouch) {
|
||||
if ([self isTouchInactive:self.primaryTouch]) return; // FIXME: should be? ACTION_UP will never be sent
|
||||
if (event == ACTION_MOVE) {
|
||||
if (event == ACTION_MOVE && isGrabbing) {
|
||||
event = ACTION_MOVE_MOTION;
|
||||
CGPoint prevLocationInView = [touchEvent previousLocationInView:self.rootView];
|
||||
locationInView.x -= prevLocationInView.x;
|
||||
|
||||
@@ -75,8 +75,6 @@ void* egl_make_current(void* window);
|
||||
#define RENDERER_VIRGL 3
|
||||
#define RENDERER_VULKAN 4
|
||||
|
||||
int config_renderer;
|
||||
|
||||
typedef jint RegalMakeCurrent_func(EGLContext context);
|
||||
|
||||
// Called from JNI_OnLoad of liblwjgl_opengl, TODO: check if unused
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// Created by maks on 24.09.2022.
|
||||
//
|
||||
|
||||
#ifndef POJAVLAUNCHER_ENVIRON_H
|
||||
#define POJAVLAUNCHER_ENVIRON_H
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include "jni.h"
|
||||
|
||||
typedef struct {
|
||||
short type;
|
||||
short i1;
|
||||
short i2;
|
||||
short i3;
|
||||
short i4;
|
||||
} GLFWInputEvent;
|
||||
|
||||
typedef void GLFW_invoke_Char_func(void* window, unsigned int codepoint);
|
||||
typedef void GLFW_invoke_CharMods_func(void* window, unsigned int codepoint, int mods);
|
||||
typedef void GLFW_invoke_CursorEnter_func(void* window, int entered);
|
||||
typedef void GLFW_invoke_CursorPos_func(void* window, double xpos, double ypos);
|
||||
typedef void GLFW_invoke_FramebufferSize_func(void* window, int width, int height);
|
||||
typedef void GLFW_invoke_Key_func(void* window, int key, int scancode, int action, int mods);
|
||||
typedef void GLFW_invoke_MouseButton_func(void* window, int button, int action, int mods);
|
||||
typedef void GLFW_invoke_Scroll_func(void* window, double xoffset, double yoffset);
|
||||
typedef void GLFW_invoke_WindowPos_func(void* window, int x, int y);
|
||||
typedef void GLFW_invoke_WindowSize_func(void* window, int width, int height);
|
||||
|
||||
//struct pojav_environ_s {
|
||||
//struct ANativeWindow* pojavWindow;
|
||||
//render_window_t* mainWindowBundle;
|
||||
int config_renderer;
|
||||
//BOOL force_vsync;
|
||||
atomic_size_t eventCounter;
|
||||
GLFWInputEvent events[8000];
|
||||
double cursorX, cursorY, cLastX, cLastY;
|
||||
//jmethodID method_accessAndroidClipboard;
|
||||
//jmethodID method_onGrabStateChanged;
|
||||
jmethodID method_glfwSetWindowAttrib;
|
||||
jmethodID method_internalWindowSizeChanged;
|
||||
jclass bridgeClazz;
|
||||
jclass vmGlfwClass;
|
||||
jboolean isGrabbing;
|
||||
jbyte* keyDownBuffer;
|
||||
JavaVM* runtimeJavaVMPtr;
|
||||
JNIEnv* runtimeJNIEnvPtr;
|
||||
//JavaVM* dalvikJavaVMPtr;
|
||||
//JNIEnv* dalvikJNIEnvPtr_ANDROID;
|
||||
long showingWindow;
|
||||
bool isInputReady, isCursorEntered, isUseStackQueueCall;
|
||||
//int savedWidth, savedHeight;
|
||||
int windowWidth, windowHeight;
|
||||
int physicalWidth, physicalHeight;
|
||||
#define ADD_CALLBACK_WWIN(NAME) \
|
||||
GLFW_invoke_##NAME##_func* GLFW_invoke_##NAME;
|
||||
ADD_CALLBACK_WWIN(Char);
|
||||
ADD_CALLBACK_WWIN(CharMods);
|
||||
ADD_CALLBACK_WWIN(CursorEnter);
|
||||
ADD_CALLBACK_WWIN(CursorPos);
|
||||
ADD_CALLBACK_WWIN(FramebufferSize);
|
||||
ADD_CALLBACK_WWIN(Key);
|
||||
ADD_CALLBACK_WWIN(MouseButton);
|
||||
ADD_CALLBACK_WWIN(Scroll);
|
||||
ADD_CALLBACK_WWIN(WindowPos);
|
||||
ADD_CALLBACK_WWIN(WindowSize);
|
||||
|
||||
#undef ADD_CALLBACK_WWIN
|
||||
//};
|
||||
|
||||
float resolutionScale;
|
||||
BOOL virtualMouseEnabled;
|
||||
BOOL isControlModifiable;
|
||||
|
||||
#endif //POJAVLAUNCHER_ENVIRON_H
|
||||
+168
-177
@@ -5,9 +5,6 @@
|
||||
* - Active development
|
||||
* - Works with some bugs:
|
||||
* + Modded versions gives broken stuff..
|
||||
*
|
||||
* TODO:
|
||||
* - Implements glfwSetCursorPos() to handle grab camera pos correctly.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
@@ -18,6 +15,7 @@
|
||||
#include <dlfcn.h>
|
||||
#include <libgen.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "glfw_keycodes.h"
|
||||
@@ -28,25 +26,6 @@
|
||||
|
||||
jint (*orig_ProcessImpl_forkAndExec)(JNIEnv *env, jobject process, jint mode, jbyteArray helperpath, jbyteArray prog, jbyteArray argBlock, jint argc, jbyteArray envBlock, jint envc, jbyteArray dir, jintArray std_fds, jboolean redirectErrorStream);
|
||||
|
||||
typedef void GLFW_invoke_Char_func(void* window, unsigned int codepoint);
|
||||
typedef void GLFW_invoke_CharMods_func(void* window, unsigned int codepoint, int mods);
|
||||
typedef void GLFW_invoke_CursorEnter_func(void* window, int entered);
|
||||
typedef void GLFW_invoke_CursorPos_func(void* window, double xpos, double ypos);
|
||||
typedef void GLFW_invoke_FramebufferSize_func(void* window, int width, int height);
|
||||
typedef void GLFW_invoke_Key_func(void* window, int key, int scancode, int action, int mods);
|
||||
typedef void GLFW_invoke_MouseButton_func(void* window, int button, int action, int mods);
|
||||
typedef void GLFW_invoke_Scroll_func(void* window, double xoffset, double yoffset);
|
||||
typedef void GLFW_invoke_WindowSize_func(void* window, int width, int height);
|
||||
typedef void GLFW_invoke_WindowPos_func(void* window, int x, int y);
|
||||
|
||||
CGFloat grabCursorX, grabCursorY, lastCursorX, lastCursorY;
|
||||
|
||||
jclass inputBridgeClass_ANDROID;
|
||||
jmethodID inputBridgeMethod_ANDROID;
|
||||
|
||||
jclass uikitBridgeClass;
|
||||
jmethodID uikitBridgeTouchMethod;
|
||||
|
||||
NSString* processPath(NSString* path) {
|
||||
if ([path hasPrefix:@"file:"]) {
|
||||
path = [path substringFromIndex:5].stringByRemovingPercentEncoding.stringByResolvingSymlinksInPath;
|
||||
@@ -110,28 +89,57 @@ hooked_ProcessImpl_forkAndExec(JNIEnv *env, jobject process, jint mode, jbyteArr
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hookExec(JNIEnv *env) {
|
||||
void hookExec() {
|
||||
jclass cls;
|
||||
orig_ProcessImpl_forkAndExec = dlsym(RTLD_DEFAULT, "Java_java_lang_UNIXProcess_forkAndExec");
|
||||
if (!orig_ProcessImpl_forkAndExec) {
|
||||
orig_ProcessImpl_forkAndExec = dlsym(RTLD_DEFAULT, "Java_java_lang_ProcessImpl_forkAndExec");
|
||||
cls = (*env)->FindClass(env, "java/lang/ProcessImpl");
|
||||
cls = (*runtimeJNIEnvPtr)->FindClass(runtimeJNIEnvPtr, "java/lang/ProcessImpl");
|
||||
} else {
|
||||
cls = (*env)->FindClass(env, "java/lang/UNIXProcess");
|
||||
cls = (*runtimeJNIEnvPtr)->FindClass(runtimeJNIEnvPtr, "java/lang/UNIXProcess");
|
||||
}
|
||||
JNINativeMethod methods[] = {
|
||||
{"forkAndExec", "(I[B[B[BI[BI[B[IZ)I", (void *)&hooked_ProcessImpl_forkAndExec}
|
||||
};
|
||||
(*env)->RegisterNatives(env, cls, methods, 1);
|
||||
(*runtimeJNIEnvPtr)->RegisterNatives(runtimeJNIEnvPtr, cls, methods, 1);
|
||||
}
|
||||
|
||||
// JNI_OnLoad
|
||||
void JNI_OnLoadGLFW() {
|
||||
vmGlfwClass = (*runtimeJNIEnvPtr)->NewGlobalRef(runtimeJNIEnvPtr, (*runtimeJNIEnvPtr)->FindClass(runtimeJNIEnvPtr, "org/lwjgl/glfw/GLFW"));
|
||||
method_glfwSetWindowAttrib = (*runtimeJNIEnvPtr)->GetStaticMethodID(runtimeJNIEnvPtr, vmGlfwClass, "glfwSetWindowAttrib", "(JII)V");
|
||||
method_internalWindowSizeChanged = (*runtimeJNIEnvPtr)->GetStaticMethodID(runtimeJNIEnvPtr, vmGlfwClass, "internalWindowSizeChanged", "(JII)V");
|
||||
jfieldID field_keyDownBuffer = (*runtimeJNIEnvPtr)->GetStaticFieldID(runtimeJNIEnvPtr, vmGlfwClass, "keyDownBuffer", "Ljava/nio/ByteBuffer;");
|
||||
jobject keyDownBufferJ = (*runtimeJNIEnvPtr)->GetStaticObjectField(runtimeJNIEnvPtr, vmGlfwClass, field_keyDownBuffer);
|
||||
keyDownBuffer = (*runtimeJNIEnvPtr)->GetDirectBufferAddress(runtimeJNIEnvPtr, keyDownBufferJ);
|
||||
}
|
||||
/*
|
||||
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
JNIEnv *env;
|
||||
(*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_4);
|
||||
hookExec(env);
|
||||
|
||||
runtimeJavaVMPtr = vm;
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
(*runtimeJavaVMPtr)->AttachCurrentThread(runtimeJavaVMPtr, &runtimeJNIEnvPtr, NULL);
|
||||
if (!getenv("POJAV_SKIP_JNI_GLFW")) {
|
||||
JNI_OnLoadGLFW();
|
||||
}
|
||||
hookExec();
|
||||
});
|
||||
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
*/
|
||||
|
||||
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
runtimeJavaVMPtr = vm;
|
||||
|
||||
(*runtimeJavaVMPtr)->GetEnv(runtimeJavaVMPtr, (void **)&runtimeJNIEnvPtr, JNI_VERSION_1_4);
|
||||
hookExec();
|
||||
if (getenv("POJAV_SKIP_JNI_GLFW")) {
|
||||
runtimeJNIEnvPtr = nil;
|
||||
} else {
|
||||
JNI_OnLoadGLFW();
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
@@ -141,39 +149,106 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) {
|
||||
}
|
||||
|
||||
#define ADD_CALLBACK_WWIN(NAME) \
|
||||
GLFW_invoke_##NAME##_func* GLFW_invoke_##NAME; \
|
||||
JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSet##NAME##Callback(JNIEnv * env, jclass cls, jlong window, jlong callbackptr) { \
|
||||
void** oldCallback = (void**) &GLFW_invoke_##NAME; \
|
||||
GLFW_invoke_##NAME = (GLFW_invoke_##NAME##_func*) (uintptr_t) callbackptr; \
|
||||
return (jlong) (uintptr_t) *oldCallback; \
|
||||
}
|
||||
|
||||
ADD_CALLBACK_WWIN(Char);
|
||||
ADD_CALLBACK_WWIN(CharMods);
|
||||
ADD_CALLBACK_WWIN(CursorEnter);
|
||||
ADD_CALLBACK_WWIN(CursorPos);
|
||||
ADD_CALLBACK_WWIN(FramebufferSize);
|
||||
ADD_CALLBACK_WWIN(Key);
|
||||
ADD_CALLBACK_WWIN(MouseButton);
|
||||
ADD_CALLBACK_WWIN(Scroll);
|
||||
ADD_CALLBACK_WWIN(WindowSize);
|
||||
ADD_CALLBACK_WWIN(WindowPos);
|
||||
ADD_CALLBACK_WWIN(Char)
|
||||
ADD_CALLBACK_WWIN(CharMods)
|
||||
ADD_CALLBACK_WWIN(CursorEnter)
|
||||
ADD_CALLBACK_WWIN(CursorPos)
|
||||
ADD_CALLBACK_WWIN(FramebufferSize)
|
||||
ADD_CALLBACK_WWIN(Key)
|
||||
ADD_CALLBACK_WWIN(MouseButton)
|
||||
ADD_CALLBACK_WWIN(Scroll)
|
||||
ADD_CALLBACK_WWIN(WindowPos)
|
||||
ADD_CALLBACK_WWIN(WindowSize)
|
||||
|
||||
#undef ADD_CALLBACK_WWIN
|
||||
|
||||
void sendData(int type, CGFloat i1, CGFloat i2, int i3, int i4) {
|
||||
//NSDebugLog(@"Debug: Send data, jnienv.isNull=%d, bridgeClass.isNull=%d\n", runtimeJNIEnvPtr == NULL, inputBridgeClass_ANDROID == NULL);
|
||||
if (runtimeJNIEnvPtr == NULL) {
|
||||
(*runtimeJavaVMPtr)->AttachCurrentThread(runtimeJavaVMPtr, &runtimeJNIEnvPtr, NULL);
|
||||
void handleFramebufferSizeJava(void* window, int w, int h) {
|
||||
if(GLFW_invoke_CursorEnter)GLFW_invoke_CursorEnter(window, 1);
|
||||
if(GLFW_invoke_WindowPos)GLFW_invoke_WindowPos(window, 0, 0);
|
||||
(*runtimeJNIEnvPtr)->CallStaticVoidMethod(runtimeJNIEnvPtr, vmGlfwClass, method_internalWindowSizeChanged, (long)window, w, h);
|
||||
}
|
||||
|
||||
void pojavPumpEvents(void* window) {
|
||||
//__android_log_print(ANDROID_LOG_INFO, "input_bridge_v3", "pojavPumpevents %d", eventCounter);
|
||||
size_t counter = atomic_load_explicit(&eventCounter, memory_order_acquire);
|
||||
if((cLastX != cursorX || cLastY != cursorY) && GLFW_invoke_CursorPos) {
|
||||
cLastX = cursorX;
|
||||
cLastY = cursorY;
|
||||
if (isUseStackQueueCall)
|
||||
GLFW_invoke_CursorPos(window, cursorX, cursorY);
|
||||
}
|
||||
if(inputBridgeClass_ANDROID == NULL) return;
|
||||
(*runtimeJNIEnvPtr)->CallStaticVoidMethod(
|
||||
runtimeJNIEnvPtr,
|
||||
inputBridgeClass_ANDROID,
|
||||
inputBridgeMethod_ANDROID,
|
||||
type,
|
||||
(jfloat)i1, (jfloat)i2, i3, i4
|
||||
);
|
||||
for(size_t i = 0; i < counter; 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);
|
||||
break;
|
||||
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(window, event.i1, event.i2);
|
||||
if(GLFW_invoke_FramebufferSize) GLFW_invoke_FramebufferSize(window, event.i1, event.i2);
|
||||
break;
|
||||
case EVENT_TYPE_WINDOW_SIZE:
|
||||
handleFramebufferSizeJava(window, event.i1, event.i2);
|
||||
if(GLFW_invoke_WindowSize) GLFW_invoke_WindowSize(window, event.i1, event.i2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
atomic_store_explicit(&eventCounter, counter, memory_order_release);
|
||||
}
|
||||
void pojavRewindEvents() {
|
||||
atomic_store_explicit(&eventCounter, 0, memory_order_release);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_lwjgl_glfw_GLFW_nglfwGetCursorPos(JNIEnv *env, jclass clazz, jlong window, jobject xpos,
|
||||
jobject ypos) {
|
||||
*(double*)(*env)->GetDirectBufferAddress(env, xpos) = cursorX;
|
||||
*(double*)(*env)->GetDirectBufferAddress(env, ypos) = cursorY;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_lwjgl_glfw_GLFW_nglfwGetCursorPosA(JNIEnv *env, jclass clazz, jlong window,
|
||||
jdoubleArray xpos, jdoubleArray ypos) {
|
||||
(*env)->SetDoubleArrayRegion(env, xpos, 0,1, &cursorX);
|
||||
(*env)->SetDoubleArrayRegion(env, ypos, 0,1, &cursorY);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_lwjgl_glfw_GLFW_glfwSetCursorPos(JNIEnv *env, jclass clazz, jlong window, jdouble xpos,
|
||||
jdouble ypos) {
|
||||
cLastX = cursorX = xpos;
|
||||
cLastY = cursorY = ypos;
|
||||
}
|
||||
|
||||
void sendData(short type, short i1, short i2, short i3, short i4) {
|
||||
size_t counter = atomic_load_explicit(&eventCounter, memory_order_acquire);
|
||||
if (counter < 7999) {
|
||||
GLFWInputEvent *event = &events[counter++];
|
||||
event->type = type;
|
||||
event->i1 = i1;
|
||||
event->i2 = i2;
|
||||
event->i3 = i3;
|
||||
event->i4 = i4;
|
||||
}
|
||||
atomic_store_explicit(&eventCounter, counter, memory_order_release);
|
||||
}
|
||||
|
||||
void closeGLFWWindow() {
|
||||
@@ -194,47 +269,6 @@ void closeGLFWWindow() {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
void callback_SurfaceViewController_launchMinecraft(int width, int height) {
|
||||
NSDebugLog(@"Received SurfaceViewController callback, width=%d, height=%d\n", width, height);
|
||||
|
||||
// Because UI init after JVM init, this should not be null
|
||||
assert(runtimeJNIEnvPtr != NULL);
|
||||
|
||||
if (!uikitBridgeClass) {
|
||||
uikitBridgeClass = (*runtimeJNIEnvPtr)->FindClass(runtimeJNIEnvPtr, "net/kdt/pojavlaunch/uikit/UIKit");
|
||||
assert(uikitBridgeClass != NULL);
|
||||
}
|
||||
|
||||
jstring rendererLibStr = (*runtimeJNIEnvPtr)->NewStringUTF(runtimeJNIEnvPtr, getenv("POJAV_RENDERER"));
|
||||
|
||||
jmethodID method = (*runtimeJNIEnvPtr)->GetStaticMethodID(runtimeJNIEnvPtr, uikitBridgeClass, "callback_SurfaceViewController_launchMinecraft", "(IILjava/lang/String;)V");
|
||||
assert(method != NULL);
|
||||
|
||||
(*runtimeJNIEnvPtr)->CallStaticVoidMethod(
|
||||
runtimeJNIEnvPtr,
|
||||
uikitBridgeClass, method,
|
||||
width, height,
|
||||
rendererLibStr
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
void callback_SurfaceViewController_onTouch(int event, CGFloat x, CGFloat y) {
|
||||
if (!isInputReady) return;
|
||||
|
||||
if (!runtimeJNIEnvPtr) {
|
||||
(*runtimeJavaVMPtr)->AttachCurrentThread(runtimeJavaVMPtr, &runtimeJNIEnvPtr, NULL);
|
||||
}
|
||||
|
||||
|
||||
(*runtimeJNIEnvPtr)->CallStaticVoidMethod(
|
||||
runtimeJNIEnvPtr,
|
||||
uikitBridgeClass, uikitBridgeTouchMethod,
|
||||
event, (jfloat)x, (jfloat)y
|
||||
);
|
||||
}
|
||||
|
||||
const int hotbarKeys[9] = {
|
||||
GLFW_KEY_1, GLFW_KEY_2, GLFW_KEY_3,
|
||||
GLFW_KEY_4, GLFW_KEY_5, GLFW_KEY_6,
|
||||
@@ -272,30 +306,26 @@ JNIEXPORT jstring JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(JNI
|
||||
JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetInputReady(JNIEnv* env, jclass clazz, jboolean inputReady) {
|
||||
//NSDebugLog(@"Debug: Changing input state, isReady=%d, isUseStackQueueCall=%d\n", inputReady, isUseStackQueueCall);
|
||||
isInputReady = inputReady;
|
||||
if (isUseStackQueueCall) {
|
||||
sendData(EVENT_TYPE_FRAMEBUFFER_SIZE, windowWidth, windowHeight, 0, 0);
|
||||
sendData(EVENT_TYPE_WINDOW_SIZE, windowWidth, windowHeight, 0, 0);
|
||||
}
|
||||
return isUseStackQueueCall;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetGrabbing(JNIEnv* env, jclass clazz, jboolean grabbing, jfloat xset, jfloat yset) {
|
||||
isGrabbing = grabbing;
|
||||
if (isGrabbing == JNI_TRUE) {
|
||||
grabCursorX = xset; // savedWidth / 2;
|
||||
grabCursorY = yset; // savedHeight / 2;
|
||||
isPrepareGrabPos = true;
|
||||
|
||||
CGRect screenBounds = [[UIScreen mainScreen] bounds];
|
||||
virtualMouseFrame.origin.x = screenBounds.size.width / 2;
|
||||
virtualMouseFrame.origin.y = screenBounds.size.height / 2;
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
UIView *surfaceView = ((SurfaceViewController *)currentWindow().rootViewController).surfaceView;
|
||||
SurfaceViewController *vc = ((SurfaceViewController *)currentWindow().rootViewController);
|
||||
UIView *surfaceView = vc.surfaceView;
|
||||
if (isGrabbing == JNI_TRUE) {
|
||||
CGFloat screenScale = [[UIScreen mainScreen] scale] * resolutionScale;
|
||||
callback_SurfaceViewController_onTouch(ACTION_DOWN, lastVirtualMousePoint.x * screenScale, lastVirtualMousePoint.y * screenScale);
|
||||
((SurfaceViewController *)currentWindow().rootViewController).mousePointerView.frame = virtualMouseFrame;
|
||||
CallbackBridge_nativeSendCursorPos(ACTION_DOWN, lastVirtualMousePoint.x * screenScale, lastVirtualMousePoint.y * screenScale);//TODO
|
||||
vc.mousePointerView.frame = virtualMouseFrame;
|
||||
}
|
||||
((SurfaceViewController *)currentWindow().rootViewController).scrollPanGesture.enabled = !isGrabbing;
|
||||
((SurfaceViewController *)currentWindow().rootViewController).mousePointerView.hidden = isGrabbing || !virtualMouseEnabled;
|
||||
vc.scrollPanGesture.enabled = !isGrabbing;
|
||||
vc.mousePointerView.hidden = isGrabbing || !virtualMouseEnabled;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -334,46 +364,36 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorEnter(
|
||||
}
|
||||
}
|
||||
*/
|
||||
void CallbackBridge_nativeSendCursorPos(CGFloat x, CGFloat y) {
|
||||
if (GLFW_invoke_CursorPos && isInputReady) {
|
||||
if (!isCursorEntered) {
|
||||
if (GLFW_invoke_CursorEnter) {
|
||||
isCursorEntered = true;
|
||||
if (isUseStackQueueCall) {
|
||||
sendData(EVENT_TYPE_CURSOR_ENTER, 1, 0, 0, 0);
|
||||
} else {
|
||||
GLFW_invoke_CursorEnter((void*) showingWindow, 1);
|
||||
}
|
||||
} else if (isGrabbing) {
|
||||
// Some Minecraft versions does not use GLFWCursorEnterCallback
|
||||
// This is a smart check, as Minecraft will not in grab mode if already not.
|
||||
isCursorEntered = true;
|
||||
void CallbackBridge_nativeSendCursorPos(char event, CGFloat x, CGFloat y) {
|
||||
if (!GLFW_invoke_CursorPos || !isInputReady) return;
|
||||
|
||||
switch (event) {
|
||||
case ACTION_DOWN:
|
||||
case ACTION_UP:
|
||||
if (!isGrabbing) {
|
||||
cursorX = x;
|
||||
cursorY = y;
|
||||
}
|
||||
}
|
||||
|
||||
if (isGrabbing) {
|
||||
if (!isPrepareGrabPos) {
|
||||
grabCursorX += x - lastCursorX;
|
||||
grabCursorY += y - lastCursorY;
|
||||
break;
|
||||
|
||||
case ACTION_MOVE:
|
||||
if (isGrabbing) {
|
||||
cursorX += x - cLastX;
|
||||
cursorY += y - cLastY;
|
||||
} else {
|
||||
cursorX = x;
|
||||
cursorY = y;
|
||||
}
|
||||
|
||||
lastCursorX = x;
|
||||
lastCursorY = y;
|
||||
|
||||
if (isPrepareGrabPos) {
|
||||
isPrepareGrabPos = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isUseStackQueueCall) {
|
||||
GLFW_invoke_CursorPos((void*) showingWindow, (double) (x), (double) (y));
|
||||
} else {
|
||||
sendData(EVENT_TYPE_CURSOR_POS, (isGrabbing ? grabCursorX : x), (isGrabbing ? grabCursorY : y), 0, 0);
|
||||
}
|
||||
|
||||
lastCursorX = x;
|
||||
lastCursorY = y;
|
||||
break;
|
||||
|
||||
case ACTION_MOVE_MOTION:
|
||||
cursorX += x;
|
||||
cursorY += y;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isUseStackQueueCall) {
|
||||
GLFW_invoke_CursorPos((void*) showingWindow, (double) cursorX, (double) cursorY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,6 +429,7 @@ char getKeyModifiers(int key, int action) {
|
||||
|
||||
void CallbackBridge_nativeSendKey(int key, int scancode, int action, int mods) {
|
||||
if (GLFW_invoke_Key && isInputReady) {
|
||||
keyDownBuffer[MAX(0, key-31)]=(jbyte)action;
|
||||
if (mods == 0) {
|
||||
mods = getKeyModifiers(key, action);
|
||||
}
|
||||
@@ -424,8 +445,6 @@ void CallbackBridge_nativeSendKey(int key, int scancode, int action, int mods) {
|
||||
void CallbackBridge_nativeSendMouseButton(int button, int action, int mods) {
|
||||
if (isInputReady) {
|
||||
if (button == -1) {
|
||||
// Notify to prepare set new grab pos
|
||||
isPrepareGrabPos = true;
|
||||
} else if (GLFW_invoke_MouseButton) {
|
||||
if (mods == 0) {
|
||||
mods = getKeyModifiers(0, action);
|
||||
@@ -474,16 +493,6 @@ void CallbackBridge_nativeSendScroll(CGFloat xoffset, CGFloat yoffset) {
|
||||
}
|
||||
}
|
||||
|
||||
void CallbackBridge_nativeSendWindowPos(int x, int y) {
|
||||
if (GLFW_invoke_WindowPos && isInputReady) {
|
||||
if (isUseStackQueueCall) {
|
||||
sendData(EVENT_TYPE_WINDOW_POS, x, y, 0, 0);
|
||||
} else {
|
||||
GLFW_invoke_WindowPos((void*) showingWindow, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetShowingWindow(JNIEnv* env, jclass clazz, jlong window) {
|
||||
showingWindow = (long) window;
|
||||
}
|
||||
@@ -495,27 +504,9 @@ void CallbackBridge_setWindowAttrib(int attrib, int value) {
|
||||
return;
|
||||
}
|
||||
|
||||
jclass glfwClazz = (*runtimeJNIEnvPtr)->FindClass(runtimeJNIEnvPtr, "org/lwjgl/glfw/GLFW");
|
||||
assert(glfwClazz != NULL);
|
||||
jmethodID glfwMethod = (*runtimeJNIEnvPtr)->GetStaticMethodID(runtimeJNIEnvPtr, glfwClazz, "glfwSetWindowAttrib", "(JII)V");
|
||||
assert(glfwMethod != NULL);
|
||||
|
||||
(*runtimeJNIEnvPtr)->CallStaticVoidMethod(
|
||||
runtimeJNIEnvPtr,
|
||||
glfwClazz, glfwMethod,
|
||||
vmGlfwClass, method_glfwSetWindowAttrib,
|
||||
(jlong) showingWindow, attrib, value
|
||||
);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_lwjgl_glfw_CallbackBridge_setClass(JNIEnv *env, jclass clazz) {
|
||||
inputBridgeMethod_ANDROID = (*env)->GetStaticMethodID(env, clazz, "receiveCallback", "(IFFII)V");
|
||||
assert(inputBridgeMethod_ANDROID != NULL);
|
||||
inputBridgeClass_ANDROID = (*env)->NewGlobalRef(env, clazz);
|
||||
assert(inputBridgeClass_ANDROID != NULL);
|
||||
|
||||
uikitBridgeClass = (*env)->NewGlobalRef(env, (*env)->FindClass(env, "net/kdt/pojavlaunch/uikit/UIKit"));
|
||||
assert(uikitBridgeClass != NULL);
|
||||
uikitBridgeTouchMethod = (*env)->GetStaticMethodID(env, uikitBridgeClass, "callback_SurfaceViewController_onTouch", "(IFF)V");
|
||||
assert(uikitBridgeTouchMethod != NULL);
|
||||
}
|
||||
+4
-16
@@ -3,10 +3,11 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "environ.h"
|
||||
#include "jni.h"
|
||||
|
||||
// Remove date + time from NSLog, unneeded
|
||||
#define NSLog(args...) customNSLog(__FILE__,__LINE__,__PRETTY_FUNCTION__,args);
|
||||
#define NSLog(args...) customNSLog(__FILE__,__LINE__,__PRETTY_FUNCTION__,args);
|
||||
|
||||
// Control button actions
|
||||
#define ACTION_DOWN 0
|
||||
@@ -50,8 +51,6 @@
|
||||
#define NSDebugLog(...) if (debugLogEnabled) { NSLog(__VA_ARGS__); }
|
||||
BOOL debugBoundsEnabled, debugLogEnabled;
|
||||
|
||||
JavaVM* runtimeJavaVMPtr;
|
||||
JNIEnv* runtimeJNIEnvPtr;
|
||||
//__weak UIViewController *viewController;
|
||||
|
||||
#define CS_DEBUGGED 0x10000000
|
||||
@@ -59,15 +58,6 @@ int csops(pid_t pid, unsigned int ops, void *useraddr, size_t usersize);
|
||||
BOOL isJITEnabled(BOOL checkCSOps);
|
||||
|
||||
void* gbuffer; // OSMesa framebuffer
|
||||
long showingWindow;
|
||||
int windowWidth, windowHeight;
|
||||
int physicalWidth, physicalHeight;
|
||||
BOOL isInputReady, isCursorEntered, isPrepareGrabPos, isUseStackQueueCall;
|
||||
jboolean isGrabbing;
|
||||
BOOL virtualMouseEnabled;
|
||||
|
||||
float resolutionScale;
|
||||
BOOL isControlModifiable;
|
||||
|
||||
// Init functions
|
||||
void init_hookFunctions();
|
||||
@@ -97,21 +87,19 @@ void _CGDataProviderReleaseBytePointerCallback(void *info,const void *pointer);
|
||||
|
||||
jboolean attachThread(bool isAndroid, JNIEnv** secondJNIEnvPtr);
|
||||
|
||||
void sendData(int type, CGFloat i1, CGFloat i2, int i3, int i4);
|
||||
void sendData(short type, short i1, short i2, short i3, short i4);
|
||||
|
||||
void closeGLFWWindow();
|
||||
void callback_LauncherViewController_installMinecraft();
|
||||
void callback_SurfaceViewController_launchMinecraft(int width, int height);
|
||||
void callback_SurfaceViewController_onTouch(int event, CGFloat x, CGFloat y);
|
||||
int callback_SurfaceViewController_touchHotbar(CGFloat x, CGFloat y);
|
||||
|
||||
BOOL CallbackBridge_nativeSendChar(jchar codepoint /* jint codepoint */);
|
||||
BOOL CallbackBridge_nativeSendCharMods(jchar codepoint, int mods);
|
||||
void CallbackBridge_nativeSendCursorPos(CGFloat x, CGFloat y);
|
||||
void CallbackBridge_nativeSendCursorPos(char event, CGFloat x, CGFloat y);
|
||||
void CallbackBridge_nativeSendKey(int key, int scancode, int action, int mods);
|
||||
void CallbackBridge_nativeSendMouseButton(int button, int action, int mods);
|
||||
void CallbackBridge_nativeSendScreenSize(int width, int height);
|
||||
void CallbackBridge_nativeSendScroll(CGFloat xoffset, CGFloat yoffset);
|
||||
void CallbackBridge_nativeSendWindowPos(jint x, jint y);
|
||||
void CallbackBridge_sendKeycode(int keycode, jchar keychar, int scancode, int modifiers, BOOL isDown);
|
||||
void CallbackBridge_setWindowAttrib(int attrib, int value);
|
||||
Reference in new issue
Block a user