mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-14 07:05:40 -04:00
Feat[gamepad]: direct input
This commit is contained in:
parent
99c8ea2bfd
commit
c5d1739877
Binary file not shown.
@ -1 +1 @@
|
|||||||
1732218529630
|
1735293224932
|
@ -29,6 +29,7 @@ import androidx.annotation.RequiresApi;
|
|||||||
import net.kdt.pojavlaunch.customcontrols.ControlLayout;
|
import net.kdt.pojavlaunch.customcontrols.ControlLayout;
|
||||||
import net.kdt.pojavlaunch.customcontrols.gamepad.DefaultDataProvider;
|
import net.kdt.pojavlaunch.customcontrols.gamepad.DefaultDataProvider;
|
||||||
import net.kdt.pojavlaunch.customcontrols.gamepad.Gamepad;
|
import net.kdt.pojavlaunch.customcontrols.gamepad.Gamepad;
|
||||||
|
import net.kdt.pojavlaunch.customcontrols.gamepad.direct.DirectGamepad;
|
||||||
import net.kdt.pojavlaunch.customcontrols.mouse.AbstractTouchpad;
|
import net.kdt.pojavlaunch.customcontrols.mouse.AbstractTouchpad;
|
||||||
import net.kdt.pojavlaunch.customcontrols.mouse.AndroidPointerCapture;
|
import net.kdt.pojavlaunch.customcontrols.mouse.AndroidPointerCapture;
|
||||||
import net.kdt.pojavlaunch.customcontrols.mouse.InGUIEventProcessor;
|
import net.kdt.pojavlaunch.customcontrols.mouse.InGUIEventProcessor;
|
||||||
@ -40,6 +41,7 @@ import net.kdt.pojavlaunch.utils.MCOptionUtils;
|
|||||||
|
|
||||||
import org.lwjgl.glfw.CallbackBridge;
|
import org.lwjgl.glfw.CallbackBridge;
|
||||||
|
|
||||||
|
import fr.spse.gamepad_remapper.GamepadHandler;
|
||||||
import fr.spse.gamepad_remapper.RemapperManager;
|
import fr.spse.gamepad_remapper.RemapperManager;
|
||||||
import fr.spse.gamepad_remapper.RemapperView;
|
import fr.spse.gamepad_remapper.RemapperView;
|
||||||
|
|
||||||
@ -48,7 +50,7 @@ import fr.spse.gamepad_remapper.RemapperView;
|
|||||||
*/
|
*/
|
||||||
public class MinecraftGLSurface extends View implements GrabListener {
|
public class MinecraftGLSurface extends View implements GrabListener {
|
||||||
/* Gamepad object for gamepad inputs, instantiated on need */
|
/* Gamepad object for gamepad inputs, instantiated on need */
|
||||||
private Gamepad mGamepad = null;
|
private GamepadHandler mGamepadHandler;
|
||||||
/* The RemapperView.Builder object allows you to set which buttons to remap */
|
/* The RemapperView.Builder object allows you to set which buttons to remap */
|
||||||
private final RemapperManager mInputManager = new RemapperManager(getContext(), new RemapperView.Builder(null)
|
private final RemapperManager mInputManager = new RemapperManager(getContext(), new RemapperView.Builder(null)
|
||||||
.remapA(true)
|
.remapA(true)
|
||||||
@ -203,7 +205,11 @@ public class MinecraftGLSurface extends View implements GrabListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createGamepad(View contextView, InputDevice inputDevice) {
|
private void createGamepad(View contextView, InputDevice inputDevice) {
|
||||||
mGamepad = new Gamepad(contextView, inputDevice, DefaultDataProvider.INSTANCE, true);
|
if(LauncherPreferences.PREF_DIRECT_CONTROLLER) {
|
||||||
|
mGamepadHandler = new DirectGamepad();
|
||||||
|
}else {
|
||||||
|
mGamepadHandler = new Gamepad(contextView, inputDevice, DefaultDataProvider.INSTANCE, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,9 +221,9 @@ public class MinecraftGLSurface extends View implements GrabListener {
|
|||||||
int mouseCursorIndex = -1;
|
int mouseCursorIndex = -1;
|
||||||
|
|
||||||
if(Gamepad.isGamepadEvent(event)){
|
if(Gamepad.isGamepadEvent(event)){
|
||||||
if(mGamepad == null) createGamepad(this, event.getDevice());
|
if(mGamepadHandler == null) createGamepad(this, event.getDevice());
|
||||||
|
|
||||||
mInputManager.handleMotionEventInput(getContext(), event, mGamepad);
|
mInputManager.handleMotionEventInput(getContext(), event, mGamepadHandler);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,9 +293,9 @@ public class MinecraftGLSurface extends View implements GrabListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Gamepad.isGamepadEvent(event)){
|
if(Gamepad.isGamepadEvent(event)){
|
||||||
if(mGamepad == null) createGamepad(this, event.getDevice());
|
if(mGamepadHandler == null) createGamepad(this, event.getDevice());
|
||||||
|
|
||||||
mInputManager.handleKeyEventInput(getContext(), event, mGamepad);
|
mInputManager.handleKeyEventInput(getContext(), event, mGamepadHandler);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ import androidx.core.math.MathUtils;
|
|||||||
import net.kdt.pojavlaunch.GrabListener;
|
import net.kdt.pojavlaunch.GrabListener;
|
||||||
import net.kdt.pojavlaunch.LwjglGlfwKeycode;
|
import net.kdt.pojavlaunch.LwjglGlfwKeycode;
|
||||||
import net.kdt.pojavlaunch.R;
|
import net.kdt.pojavlaunch.R;
|
||||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
|
||||||
import net.kdt.pojavlaunch.utils.MCOptionUtils;
|
import net.kdt.pojavlaunch.utils.MCOptionUtils;
|
||||||
|
|
||||||
import org.lwjgl.glfw.CallbackBridge;
|
import org.lwjgl.glfw.CallbackBridge;
|
||||||
|
@ -0,0 +1,74 @@
|
|||||||
|
package net.kdt.pojavlaunch.customcontrols.gamepad.direct;
|
||||||
|
|
||||||
|
import static android.view.MotionEvent.AXIS_HAT_X;
|
||||||
|
import static android.view.MotionEvent.AXIS_HAT_Y;
|
||||||
|
import static org.lwjgl.glfw.CallbackBridge.sGamepadAxisBuffer;
|
||||||
|
import static org.lwjgl.glfw.CallbackBridge.sGamepadButtonBuffer;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import fr.spse.gamepad_remapper.GamepadHandler;
|
||||||
|
|
||||||
|
public class DirectGamepad implements GamepadHandler {
|
||||||
|
@Override
|
||||||
|
public void handleGamepadInput(int keycode, float value) {
|
||||||
|
int gKeycode = -1, gAxis = -1;
|
||||||
|
switch (keycode) {
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_A: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_A; break;
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_B: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_B; break;
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_X: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_X; break;
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_Y: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_Y; break;
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_L1: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER; break;
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_R1: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER; break;
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_L2:
|
||||||
|
case MotionEvent.AXIS_LTRIGGER:
|
||||||
|
gAxis = GamepadKeycodes.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER;
|
||||||
|
break;
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_R2:
|
||||||
|
case MotionEvent.AXIS_RTRIGGER:
|
||||||
|
gAxis = GamepadKeycodes.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER;
|
||||||
|
break;
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_THUMBL: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_LEFT_THUMB; break;
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_THUMBR: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB; break;
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_START: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_START; break;
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_SELECT: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_BACK; break;
|
||||||
|
case KeyEvent.KEYCODE_DPAD_UP: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_DPAD_UP; break;
|
||||||
|
case KeyEvent.KEYCODE_DPAD_DOWN: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_DPAD_DOWN; break;
|
||||||
|
case KeyEvent.KEYCODE_DPAD_LEFT: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_DPAD_LEFT; break;
|
||||||
|
case KeyEvent.KEYCODE_DPAD_RIGHT: gKeycode = GamepadKeycodes.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT; break;
|
||||||
|
case KeyEvent.KEYCODE_DPAD_CENTER: break; // TODO
|
||||||
|
case MotionEvent.AXIS_X: gAxis = GamepadKeycodes.GLFW_GAMEPAD_AXIS_LEFT_X; break;
|
||||||
|
case MotionEvent.AXIS_Y: gAxis = GamepadKeycodes.GLFW_GAMEPAD_AXIS_LEFT_Y; break;
|
||||||
|
case MotionEvent.AXIS_Z: gAxis = GamepadKeycodes.GLFW_GAMEPAD_AXIS_RIGHT_X; break;
|
||||||
|
case MotionEvent.AXIS_RZ: gAxis = GamepadKeycodes.GLFW_GAMEPAD_AXIS_RIGHT_Y; break;
|
||||||
|
case AXIS_HAT_X:
|
||||||
|
sGamepadButtonBuffer.put(
|
||||||
|
GamepadKeycodes.GLFW_GAMEPAD_BUTTON_DPAD_LEFT,
|
||||||
|
value < -0.85 ? GamepadKeycodes.GLFW_PRESS : GamepadKeycodes.GLFW_RELEASE
|
||||||
|
);
|
||||||
|
sGamepadButtonBuffer.put(
|
||||||
|
GamepadKeycodes.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT,
|
||||||
|
value > 0.85 ? GamepadKeycodes.GLFW_PRESS : GamepadKeycodes.GLFW_RELEASE
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
case AXIS_HAT_Y:
|
||||||
|
sGamepadButtonBuffer.put(
|
||||||
|
GamepadKeycodes.GLFW_GAMEPAD_BUTTON_DPAD_UP,
|
||||||
|
value < -0.85 ? GamepadKeycodes.GLFW_PRESS : GamepadKeycodes.GLFW_RELEASE
|
||||||
|
);
|
||||||
|
sGamepadButtonBuffer.put(
|
||||||
|
GamepadKeycodes.GLFW_GAMEPAD_BUTTON_DPAD_DOWN,
|
||||||
|
value > 0.85 ? GamepadKeycodes.GLFW_PRESS : GamepadKeycodes.GLFW_RELEASE
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(gKeycode != -1) {
|
||||||
|
sGamepadButtonBuffer.put(gKeycode, value > 0.85 ? GamepadKeycodes.GLFW_PRESS : GamepadKeycodes.GLFW_RELEASE);
|
||||||
|
}
|
||||||
|
if(gAxis != -1) {
|
||||||
|
sGamepadAxisBuffer.put(gAxis, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package net.kdt.pojavlaunch.customcontrols.gamepad.direct;
|
||||||
|
|
||||||
|
public class GamepadKeycodes {
|
||||||
|
public static final byte GLFW_RELEASE = 0;
|
||||||
|
public static final byte GLFW_PRESS = 1;
|
||||||
|
public static int NUM_KEYCODES = 0;
|
||||||
|
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_A = 0;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_B = 1;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_X = 2;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_Y = 3;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_LEFT_BUMPER = 4;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER = 5;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_BACK = 6;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_START = 7;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_GUIDE = 8;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_LEFT_THUMB = 9;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_RIGHT_THUMB = 10;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_DPAD_UP = 11;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_DPAD_RIGHT = 12;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_DPAD_DOWN = 13;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_DPAD_LEFT = 14;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_LAST = GLFW_GAMEPAD_BUTTON_DPAD_LEFT;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_CROSS = GLFW_GAMEPAD_BUTTON_A;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_CIRCLE = GLFW_GAMEPAD_BUTTON_B;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_SQUARE = GLFW_GAMEPAD_BUTTON_X;
|
||||||
|
public static final short GLFW_GAMEPAD_BUTTON_TRIANGLE = GLFW_GAMEPAD_BUTTON_Y;
|
||||||
|
|
||||||
|
public static final short GLFW_GAMEPAD_AXIS_LEFT_X = 0;
|
||||||
|
public static final short GLFW_GAMEPAD_AXIS_LEFT_Y = 1;
|
||||||
|
public static final short GLFW_GAMEPAD_AXIS_RIGHT_X = 2;
|
||||||
|
public static final short GLFW_GAMEPAD_AXIS_RIGHT_Y = 3;
|
||||||
|
public static final short GLFW_GAMEPAD_AXIS_LEFT_TRIGGER = 4;
|
||||||
|
public static final short GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER = 5;
|
||||||
|
public static final short GLFW_GAMEPAD_AXIS_LAST = GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER;
|
||||||
|
}
|
@ -67,6 +67,7 @@ public class LauncherPreferences {
|
|||||||
public static String PREF_DOWNLOAD_SOURCE = "default";
|
public static String PREF_DOWNLOAD_SOURCE = "default";
|
||||||
public static boolean PREF_SKIP_NOTIFICATION_PERMISSION_CHECK = false;
|
public static boolean PREF_SKIP_NOTIFICATION_PERMISSION_CHECK = false;
|
||||||
public static boolean PREF_VSYNC_IN_ZINK = true;
|
public static boolean PREF_VSYNC_IN_ZINK = true;
|
||||||
|
public static boolean PREF_DIRECT_CONTROLLER = false;
|
||||||
|
|
||||||
|
|
||||||
public static void loadPreferences(Context ctx) {
|
public static void loadPreferences(Context ctx) {
|
||||||
@ -109,6 +110,7 @@ public class LauncherPreferences {
|
|||||||
PREF_VERIFY_MANIFEST = DEFAULT_PREF.getBoolean("verifyManifest", true);
|
PREF_VERIFY_MANIFEST = DEFAULT_PREF.getBoolean("verifyManifest", true);
|
||||||
PREF_SKIP_NOTIFICATION_PERMISSION_CHECK = DEFAULT_PREF.getBoolean(PREF_KEY_SKIP_NOTIFICATION_CHECK, false);
|
PREF_SKIP_NOTIFICATION_PERMISSION_CHECK = DEFAULT_PREF.getBoolean(PREF_KEY_SKIP_NOTIFICATION_CHECK, false);
|
||||||
PREF_VSYNC_IN_ZINK = DEFAULT_PREF.getBoolean("vsync_in_zink", true);
|
PREF_VSYNC_IN_ZINK = DEFAULT_PREF.getBoolean("vsync_in_zink", true);
|
||||||
|
PREF_DIRECT_CONTROLLER = DEFAULT_PREF.getBoolean("directController", false);
|
||||||
|
|
||||||
String argLwjglLibname = "-Dorg.lwjgl.opengl.libname=";
|
String argLwjglLibname = "-Dorg.lwjgl.opengl.libname=";
|
||||||
for (String arg : JREUtils.parseJavaArguments(PREF_CUSTOM_JAVA_ARGS)) {
|
for (String arg : JREUtils.parseJavaArguments(PREF_CUSTOM_JAVA_ARGS)) {
|
||||||
|
@ -89,6 +89,7 @@ public class LauncherPreferenceControlFragment extends LauncherPreferenceFragmen
|
|||||||
requirePreference("gyroInvertX").setVisible(LauncherPreferences.PREF_ENABLE_GYRO);
|
requirePreference("gyroInvertX").setVisible(LauncherPreferences.PREF_ENABLE_GYRO);
|
||||||
requirePreference("gyroInvertY").setVisible(LauncherPreferences.PREF_ENABLE_GYRO);
|
requirePreference("gyroInvertY").setVisible(LauncherPreferences.PREF_ENABLE_GYRO);
|
||||||
requirePreference("gyroSmoothing").setVisible(LauncherPreferences.PREF_ENABLE_GYRO);
|
requirePreference("gyroSmoothing").setVisible(LauncherPreferences.PREF_ENABLE_GYRO);
|
||||||
|
requirePreference("_frag_changeKeyBindings").setVisible(!LauncherPreferences.PREF_DIRECT_CONTROLLER);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,9 @@ import android.view.Choreographer;
|
|||||||
import androidx.annotation.Keep;
|
import androidx.annotation.Keep;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import dalvik.annotation.optimization.CriticalNative;
|
import dalvik.annotation.optimization.CriticalNative;
|
||||||
@ -27,6 +30,9 @@ public class CallbackBridge {
|
|||||||
public volatile static boolean holdingAlt, holdingCapslock, holdingCtrl,
|
public volatile static boolean holdingAlt, holdingCapslock, holdingCtrl,
|
||||||
holdingNumlock, holdingShift;
|
holdingNumlock, holdingShift;
|
||||||
|
|
||||||
|
public static final ByteBuffer sGamepadButtonBuffer;
|
||||||
|
public static final FloatBuffer sGamepadAxisBuffer;
|
||||||
|
|
||||||
public static void putMouseEventWithCoords(int button, float x, float y) {
|
public static void putMouseEventWithCoords(int button, float x, float y) {
|
||||||
putMouseEventWithCoords(button, true, x, y);
|
putMouseEventWithCoords(button, true, x, y);
|
||||||
sChoreographer.postFrameCallbackDelayed(l -> putMouseEventWithCoords(button, false, x, y), 33);
|
sChoreographer.postFrameCallbackDelayed(l -> putMouseEventWithCoords(button, false, x, y), 33);
|
||||||
@ -193,6 +199,11 @@ public class CallbackBridge {
|
|||||||
grabListeners.remove(listener);
|
grabListeners.remove(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static FloatBuffer createGamepadAxisBuffer() {
|
||||||
|
ByteBuffer axisByteBuffer = nativeCreateGamepadAxisBuffer();
|
||||||
|
// NOTE: hardcoded order (also in jre_lwjgl3glfw CallbackBridge)
|
||||||
|
return axisByteBuffer.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
@Keep @CriticalNative public static native void nativeSetUseInputStackQueue(boolean useInputStackQueue);
|
@Keep @CriticalNative public static native void nativeSetUseInputStackQueue(boolean useInputStackQueue);
|
||||||
|
|
||||||
@ -206,8 +217,12 @@ public class CallbackBridge {
|
|||||||
@Keep @CriticalNative private static native void nativeSendScroll(double xoffset, double yoffset);
|
@Keep @CriticalNative private static native void nativeSendScroll(double xoffset, double yoffset);
|
||||||
@Keep @CriticalNative private static native void nativeSendScreenSize(int width, int height);
|
@Keep @CriticalNative private static native void nativeSendScreenSize(int width, int height);
|
||||||
public static native void nativeSetWindowAttrib(int attrib, int value);
|
public static native void nativeSetWindowAttrib(int attrib, int value);
|
||||||
|
private static native ByteBuffer nativeCreateGamepadButtonBuffer();
|
||||||
|
private static native ByteBuffer nativeCreateGamepadAxisBuffer();
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("pojavexec");
|
System.loadLibrary("pojavexec");
|
||||||
|
sGamepadButtonBuffer = nativeCreateGamepadButtonBuffer();
|
||||||
|
sGamepadAxisBuffer = createGamepadAxisBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,11 @@ typedef void GLFW_invoke_Key_func(void* window, int key, int scancode, int actio
|
|||||||
typedef void GLFW_invoke_MouseButton_func(void* window, int button, 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_Scroll_func(void* window, double xoffset, double yoffset);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char buttons [15];
|
||||||
|
float axes[6];
|
||||||
|
} GLFWgamepadstate;
|
||||||
|
|
||||||
struct pojav_environ_s {
|
struct pojav_environ_s {
|
||||||
struct ANativeWindow* pojavWindow;
|
struct ANativeWindow* pojavWindow;
|
||||||
basic_render_window_t* mainWindowBundle;
|
basic_render_window_t* mainWindowBundle;
|
||||||
@ -58,6 +63,7 @@ struct pojav_environ_s {
|
|||||||
bool isInputReady, isCursorEntered, isUseStackQueueCall, shouldUpdateMouse;
|
bool isInputReady, isCursorEntered, isUseStackQueueCall, shouldUpdateMouse;
|
||||||
bool shouldUpdateMonitorSize, monitorSizeConsumed;
|
bool shouldUpdateMonitorSize, monitorSizeConsumed;
|
||||||
int savedWidth, savedHeight;
|
int savedWidth, savedHeight;
|
||||||
|
GLFWgamepadstate gamepadState;
|
||||||
#define ADD_CALLBACK_WWIN(NAME) \
|
#define ADD_CALLBACK_WWIN(NAME) \
|
||||||
GLFW_invoke_##NAME##_func* GLFW_invoke_##NAME;
|
GLFW_invoke_##NAME##_func* GLFW_invoke_##NAME;
|
||||||
ADD_CALLBACK_WWIN(Char);
|
ADD_CALLBACK_WWIN(Char);
|
||||||
|
@ -40,9 +40,10 @@ jint JNI_OnLoad(JavaVM* vm, __attribute__((unused)) void* reserved) {
|
|||||||
//Save dalvik global JavaVM pointer
|
//Save dalvik global JavaVM pointer
|
||||||
pojav_environ->dalvikJavaVMPtr = vm;
|
pojav_environ->dalvikJavaVMPtr = vm;
|
||||||
(*vm)->GetEnv(vm, (void**) &pojav_environ->dalvikJNIEnvPtr_ANDROID, JNI_VERSION_1_4);
|
(*vm)->GetEnv(vm, (void**) &pojav_environ->dalvikJNIEnvPtr_ANDROID, JNI_VERSION_1_4);
|
||||||
pojav_environ->bridgeClazz = (*pojav_environ->dalvikJNIEnvPtr_ANDROID)->NewGlobalRef(pojav_environ->dalvikJNIEnvPtr_ANDROID,(*pojav_environ->dalvikJNIEnvPtr_ANDROID) ->FindClass(pojav_environ->dalvikJNIEnvPtr_ANDROID,"org/lwjgl/glfw/CallbackBridge"));
|
JNIEnv *env = pojav_environ->dalvikJNIEnvPtr_ANDROID;
|
||||||
pojav_environ->method_accessAndroidClipboard = (*pojav_environ->dalvikJNIEnvPtr_ANDROID)->GetStaticMethodID(pojav_environ->dalvikJNIEnvPtr_ANDROID, pojav_environ->bridgeClazz, "accessAndroidClipboard", "(ILjava/lang/String;)Ljava/lang/String;");
|
pojav_environ->bridgeClazz = (*env)->NewGlobalRef(env,(*env) ->FindClass(env,"org/lwjgl/glfw/CallbackBridge"));
|
||||||
pojav_environ->method_onGrabStateChanged = (*pojav_environ->dalvikJNIEnvPtr_ANDROID)->GetStaticMethodID(pojav_environ->dalvikJNIEnvPtr_ANDROID, pojav_environ->bridgeClazz, "onGrabStateChanged", "(Z)V");
|
pojav_environ->method_accessAndroidClipboard = (*env)->GetStaticMethodID(env, pojav_environ->bridgeClazz, "accessAndroidClipboard", "(ILjava/lang/String;)Ljava/lang/String;");
|
||||||
|
pojav_environ->method_onGrabStateChanged = (*env)->GetStaticMethodID(env, pojav_environ->bridgeClazz, "onGrabStateChanged", "(Z)V");
|
||||||
pojav_environ->isUseStackQueueCall = JNI_FALSE;
|
pojav_environ->isUseStackQueueCall = JNI_FALSE;
|
||||||
} else if (pojav_environ->dalvikJavaVMPtr != vm) {
|
} else if (pojav_environ->dalvikJavaVMPtr != vm) {
|
||||||
__android_log_print(ANDROID_LOG_INFO, "Native", "Saving JVM environ...");
|
__android_log_print(ANDROID_LOG_INFO, "Native", "Saving JVM environ...");
|
||||||
@ -644,3 +645,18 @@ static void registerFunctions(JNIEnv *env) {
|
|||||||
use_critical_cc ? critical_fcns : noncritical_fcns,
|
use_critical_cc ? critical_fcns : noncritical_fcns,
|
||||||
sizeof(critical_fcns)/sizeof(critical_fcns[0]));
|
sizeof(critical_fcns)/sizeof(critical_fcns[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL
|
||||||
|
Java_org_lwjgl_glfw_GLFW_internalGetGamepadDataPointer(JNIEnv *env, jclass clazz) {
|
||||||
|
return (jlong) &pojav_environ->gamepadState;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL
|
||||||
|
Java_org_lwjgl_glfw_CallbackBridge_nativeCreateGamepadButtonBuffer(JNIEnv *env, jclass clazz) {
|
||||||
|
return (*env)->NewDirectByteBuffer(env, &pojav_environ->gamepadState.buttons, sizeof(pojav_environ->gamepadState.buttons));
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jobject JNICALL
|
||||||
|
Java_org_lwjgl_glfw_CallbackBridge_nativeCreateGamepadAxisBuffer(JNIEnv *env, jclass clazz) {
|
||||||
|
return (*env)->NewDirectByteBuffer(env, &pojav_environ->gamepadState.axes, sizeof(pojav_environ->gamepadState.axes));
|
||||||
|
}
|
@ -422,4 +422,6 @@
|
|||||||
<string name="local_login_bad_username_title">Unsuitable username</string>
|
<string name="local_login_bad_username_title">Unsuitable username</string>
|
||||||
<string name="local_login_bad_username_text">The username must be between 3–16 characters long, and must only contain latin letters, arabic numerals and underscores.</string>
|
<string name="local_login_bad_username_text">The username must be between 3–16 characters long, and must only contain latin letters, arabic numerals and underscores.</string>
|
||||||
<string name="quick_setting_title">Quick settings</string>
|
<string name="quick_setting_title">Quick settings</string>
|
||||||
|
<string name="preference_direct_controller_title">Use direct controller input</string>
|
||||||
|
<string name="preference_direct_controller_description">Disables keyboard/mouse emulation and lets the game use gamepad inputs directly.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -144,7 +144,13 @@
|
|||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="@string/preference_category_controller_settings"
|
android:title="@string/preference_category_controller_settings"
|
||||||
>
|
>
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="directController"
|
||||||
|
android:title="@string/preference_direct_controller_title"
|
||||||
|
android:summary="@string/preference_direct_controller_description"
|
||||||
|
/>
|
||||||
<Preference
|
<Preference
|
||||||
|
android:key="_frag_changeKeyBindings"
|
||||||
android:title="@string/preference_remap_controller_title"
|
android:title="@string/preference_remap_controller_title"
|
||||||
android:summary="@string/preference_remap_controller_description"
|
android:summary="@string/preference_remap_controller_description"
|
||||||
android:fragment="net.kdt.pojavlaunch.fragments.GamepadMapperFragment"/>
|
android:fragment="net.kdt.pojavlaunch.fragments.GamepadMapperFragment"/>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
package org.lwjgl.glfw;
|
package org.lwjgl.glfw;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class CallbackBridge {
|
public class CallbackBridge {
|
||||||
@ -47,5 +48,7 @@ public class CallbackBridge {
|
|||||||
public static native boolean nativeSetInputReady(boolean ready);
|
public static native boolean nativeSetInputReady(boolean ready);
|
||||||
public static native String nativeClipboard(int action, byte[] copy);
|
public static native String nativeClipboard(int action, byte[] copy);
|
||||||
public static native void nativeSetGrabbing(boolean grab);
|
public static native void nativeSetGrabbing(boolean grab);
|
||||||
|
public static native ByteBuffer nativeCreateGamepadButtonBuffer();
|
||||||
|
public static native ByteBuffer nativeCreateGamepadAxisBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import javax.annotation.*;
|
|||||||
|
|
||||||
import org.lwjgl.*;
|
import org.lwjgl.*;
|
||||||
import org.lwjgl.system.*;
|
import org.lwjgl.system.*;
|
||||||
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL20.*;
|
import static org.lwjgl.opengl.GL20.*;
|
||||||
import static org.lwjgl.system.APIUtil.*;
|
import static org.lwjgl.system.APIUtil.*;
|
||||||
@ -24,8 +25,9 @@ import java.util.*;
|
|||||||
|
|
||||||
public class GLFW
|
public class GLFW
|
||||||
{
|
{
|
||||||
static FloatBuffer joystickData = (FloatBuffer)FloatBuffer.allocate(8).flip();
|
static FloatBuffer joystickAxisData;
|
||||||
static ByteBuffer buttonData = (ByteBuffer)ByteBuffer.allocate(8).flip();
|
static ByteBuffer joystickButtonData;
|
||||||
|
static ByteBuffer empty = (ByteBuffer)ByteBuffer.allocate(0);
|
||||||
/** The major version number of the GLFW library. This is incremented when the API is changed in non-compatible ways. */
|
/** The major version number of the GLFW library. This is incremented when the API is changed in non-compatible ways. */
|
||||||
public static final int GLFW_VERSION_MAJOR = 3;
|
public static final int GLFW_VERSION_MAJOR = 3;
|
||||||
|
|
||||||
@ -515,6 +517,7 @@ public class GLFW
|
|||||||
private static final String PROP_WINDOW_WIDTH = "glfwstub.windowWidth";
|
private static final String PROP_WINDOW_WIDTH = "glfwstub.windowWidth";
|
||||||
private static final String PROP_WINDOW_HEIGHT= "glfwstub.windowHeight";
|
private static final String PROP_WINDOW_HEIGHT= "glfwstub.windowHeight";
|
||||||
public static long mainContext = 0;
|
public static long mainContext = 0;
|
||||||
|
private static long gamepadDataPointer;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
@ -636,6 +639,8 @@ public class GLFW
|
|||||||
return win;
|
return win;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static native long internalGetGamepadDataPointer();
|
||||||
|
|
||||||
// Generated stub callback methods
|
// Generated stub callback methods
|
||||||
public static GLFWCharCallback glfwSetCharCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWcharfun") GLFWCharCallbackI cbfun) {
|
public static GLFWCharCallback glfwSetCharCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWcharfun") GLFWCharCallbackI cbfun) {
|
||||||
GLFWCharCallback lastCallback = mGLFWCharCallback;
|
GLFWCharCallback lastCallback = mGLFWCharCallback;
|
||||||
@ -805,6 +810,10 @@ public class GLFW
|
|||||||
mGLFWInitialTime = (double) System.nanoTime();
|
mGLFWInitialTime = (double) System.nanoTime();
|
||||||
long __functionAddress = Functions.Init;
|
long __functionAddress = Functions.Init;
|
||||||
isGLFWReady = invokeI(__functionAddress) != 0;
|
isGLFWReady = invokeI(__functionAddress) != 0;
|
||||||
|
gamepadDataPointer = internalGetGamepadDataPointer();
|
||||||
|
// NOTE: hardcoded order (also in android CallbackBridge)
|
||||||
|
joystickAxisData = CallbackBridge.nativeCreateGamepadAxisBuffer().order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
|
||||||
|
joystickButtonData = CallbackBridge.nativeCreateGamepadButtonBuffer();
|
||||||
}
|
}
|
||||||
return isGLFWReady;
|
return isGLFWReady;
|
||||||
}
|
}
|
||||||
@ -1201,50 +1210,59 @@ public class GLFW
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean glfwJoystickPresent(int jid) {
|
public static boolean glfwJoystickPresent(int jid) {
|
||||||
if(jid == 0) {
|
if(jid == GLFW_JOYSTICK_1) {
|
||||||
return true;
|
return true;
|
||||||
}else return false;
|
}else return false;
|
||||||
}
|
}
|
||||||
public static String glfwGetJoystickName(int jid) {
|
public static String glfwGetJoystickName(int jid) {
|
||||||
if(jid == 0) {
|
if(jid == GLFW_JOYSTICK_1) {
|
||||||
return "AIC event bus controller";
|
return "Pojav XBOX 360 compatible gamepad";
|
||||||
}else return null;
|
}else return null;
|
||||||
}
|
}
|
||||||
public static FloatBuffer glfwGetJoystickAxes(int jid) {
|
public static FloatBuffer glfwGetJoystickAxes(int jid) {
|
||||||
if(jid == 0) {
|
if(jid == GLFW_JOYSTICK_1) {
|
||||||
return joystickData;
|
return joystickAxisData;
|
||||||
}else return null;
|
}else return null;
|
||||||
}
|
}
|
||||||
public static ByteBuffer glfwGetJoystickButtons(int jid) {
|
public static ByteBuffer glfwGetJoystickButtons(int jid) {
|
||||||
if(jid == 0) {
|
if(jid == GLFW_JOYSTICK_1) {
|
||||||
return buttonData;
|
return joystickButtonData;
|
||||||
}else return null;
|
}else return null;
|
||||||
}
|
}
|
||||||
public static ByteBuffer glfwGetjoystickHats(int jid) {
|
public static ByteBuffer glfwGetJoystickHats(int jid) {
|
||||||
return null;
|
if(jid == GLFW_JOYSTICK_1) {
|
||||||
|
return empty; // Maybe implement this later?
|
||||||
|
}else return null;
|
||||||
}
|
}
|
||||||
public static boolean glfwJoystickIsGamepad(int jid) {
|
public static boolean glfwJoystickIsGamepad(int jid) {
|
||||||
if(jid == 0) return true;
|
if(jid == GLFW_JOYSTICK_1) return true;
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
public static String glfwGetJoystickGUID(int jid) {
|
public static String glfwGetJoystickGUID(int jid) {
|
||||||
if(jid == 0) return "aio0";
|
// 16 8-bit characters to be compatible with SDL_GUID
|
||||||
|
if(jid == GLFW_JOYSTICK_1) return "AAAAAAAAAAAAAAAA";
|
||||||
else return null;
|
else return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static long mUserPointer;
|
||||||
|
|
||||||
public static long glfwGetJoystickUserPointer(int jid) {
|
public static long glfwGetJoystickUserPointer(int jid) {
|
||||||
return 0;
|
return mUserPointer;
|
||||||
}
|
}
|
||||||
public static void glfwSetJoystickUserPointer(int jid, long pointer) {
|
public static void glfwSetJoystickUserPointer(int jid, long pointer) {
|
||||||
|
mUserPointer = pointer;
|
||||||
}
|
}
|
||||||
public static boolean glfwUpdateGamepadMappings(ByteBuffer string) {
|
public static boolean glfwUpdateGamepadMappings(ByteBuffer string) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public static String glfwGetGamepadName(int jid) {
|
public static String glfwGetGamepadName(int jid) {
|
||||||
return null;
|
if(jid == GLFW_JOYSTICK_1) return "Pojav XBOX 360 compatible gamepad";
|
||||||
|
else return null;
|
||||||
}
|
}
|
||||||
public static boolean glfwGetGamepadState(int jid, GLFWGamepadState state) {
|
public static boolean glfwGetGamepadState(int jid, GLFWGamepadState state) {
|
||||||
return false;
|
if(jid != 0) return false;
|
||||||
|
MemoryUtil.memCopy(gamepadDataPointer, state.address(), state.sizeof());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Array version of: {@link #glfwGetVersion GetVersion} */
|
/** Array version of: {@link #glfwGetVersion GetVersion} */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user