Feat[gamepad]: direct input

This commit is contained in:
artdeell 2024-12-27 12:58:48 +03:00
parent 99c8ea2bfd
commit c5d1739877
15 changed files with 212 additions and 28 deletions

View File

@ -1 +1 @@
1732218529630
1735293224932

View File

@ -29,6 +29,7 @@ import androidx.annotation.RequiresApi;
import net.kdt.pojavlaunch.customcontrols.ControlLayout;
import net.kdt.pojavlaunch.customcontrols.gamepad.DefaultDataProvider;
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.AndroidPointerCapture;
import net.kdt.pojavlaunch.customcontrols.mouse.InGUIEventProcessor;
@ -40,6 +41,7 @@ import net.kdt.pojavlaunch.utils.MCOptionUtils;
import org.lwjgl.glfw.CallbackBridge;
import fr.spse.gamepad_remapper.GamepadHandler;
import fr.spse.gamepad_remapper.RemapperManager;
import fr.spse.gamepad_remapper.RemapperView;
@ -48,7 +50,7 @@ import fr.spse.gamepad_remapper.RemapperView;
*/
public class MinecraftGLSurface extends View implements GrabListener {
/* 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 */
private final RemapperManager mInputManager = new RemapperManager(getContext(), new RemapperView.Builder(null)
.remapA(true)
@ -203,7 +205,11 @@ public class MinecraftGLSurface extends View implements GrabListener {
}
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;
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;
}
@ -287,9 +293,9 @@ public class MinecraftGLSurface extends View implements GrabListener {
}
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;
}

View File

@ -26,7 +26,6 @@ import androidx.core.math.MathUtils;
import net.kdt.pojavlaunch.GrabListener;
import net.kdt.pojavlaunch.LwjglGlfwKeycode;
import net.kdt.pojavlaunch.R;
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
import net.kdt.pojavlaunch.utils.MCOptionUtils;
import org.lwjgl.glfw.CallbackBridge;

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -67,6 +67,7 @@ public class LauncherPreferences {
public static String PREF_DOWNLOAD_SOURCE = "default";
public static boolean PREF_SKIP_NOTIFICATION_PERMISSION_CHECK = false;
public static boolean PREF_VSYNC_IN_ZINK = true;
public static boolean PREF_DIRECT_CONTROLLER = false;
public static void loadPreferences(Context ctx) {
@ -109,6 +110,7 @@ public class LauncherPreferences {
PREF_VERIFY_MANIFEST = DEFAULT_PREF.getBoolean("verifyManifest", true);
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_DIRECT_CONTROLLER = DEFAULT_PREF.getBoolean("directController", false);
String argLwjglLibname = "-Dorg.lwjgl.opengl.libname=";
for (String arg : JREUtils.parseJavaArguments(PREF_CUSTOM_JAVA_ARGS)) {

View File

@ -89,6 +89,7 @@ public class LauncherPreferenceControlFragment extends LauncherPreferenceFragmen
requirePreference("gyroInvertX").setVisible(LauncherPreferences.PREF_ENABLE_GYRO);
requirePreference("gyroInvertY").setVisible(LauncherPreferences.PREF_ENABLE_GYRO);
requirePreference("gyroSmoothing").setVisible(LauncherPreferences.PREF_ENABLE_GYRO);
requirePreference("_frag_changeKeyBindings").setVisible(!LauncherPreferences.PREF_DIRECT_CONTROLLER);
}
}

View File

@ -8,6 +8,9 @@ import android.view.Choreographer;
import androidx.annotation.Keep;
import androidx.annotation.Nullable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import dalvik.annotation.optimization.CriticalNative;
@ -27,6 +30,9 @@ public class CallbackBridge {
public volatile static boolean holdingAlt, holdingCapslock, holdingCtrl,
holdingNumlock, holdingShift;
public static final ByteBuffer sGamepadButtonBuffer;
public static final FloatBuffer sGamepadAxisBuffer;
public static void putMouseEventWithCoords(int button, float x, float y) {
putMouseEventWithCoords(button, true, x, y);
sChoreographer.postFrameCallbackDelayed(l -> putMouseEventWithCoords(button, false, x, y), 33);
@ -193,6 +199,11 @@ public class CallbackBridge {
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);
@ -206,8 +217,12 @@ public class CallbackBridge {
@Keep @CriticalNative private static native void nativeSendScroll(double xoffset, double yoffset);
@Keep @CriticalNative private static native void nativeSendScreenSize(int width, int height);
public static native void nativeSetWindowAttrib(int attrib, int value);
private static native ByteBuffer nativeCreateGamepadButtonBuffer();
private static native ByteBuffer nativeCreateGamepadAxisBuffer();
static {
System.loadLibrary("pojavexec");
sGamepadButtonBuffer = nativeCreateGamepadButtonBuffer();
sGamepadAxisBuffer = createGamepadAxisBuffer();
}
}

View File

@ -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_Scroll_func(void* window, double xoffset, double yoffset);
typedef struct {
unsigned char buttons [15];
float axes[6];
} GLFWgamepadstate;
struct pojav_environ_s {
struct ANativeWindow* pojavWindow;
basic_render_window_t* mainWindowBundle;
@ -58,6 +63,7 @@ struct pojav_environ_s {
bool isInputReady, isCursorEntered, isUseStackQueueCall, shouldUpdateMouse;
bool shouldUpdateMonitorSize, monitorSizeConsumed;
int savedWidth, savedHeight;
GLFWgamepadstate gamepadState;
#define ADD_CALLBACK_WWIN(NAME) \
GLFW_invoke_##NAME##_func* GLFW_invoke_##NAME;
ADD_CALLBACK_WWIN(Char);

View File

@ -40,9 +40,10 @@ jint JNI_OnLoad(JavaVM* vm, __attribute__((unused)) void* reserved) {
//Save dalvik global JavaVM pointer
pojav_environ->dalvikJavaVMPtr = vm;
(*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"));
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->method_onGrabStateChanged = (*pojav_environ->dalvikJNIEnvPtr_ANDROID)->GetStaticMethodID(pojav_environ->dalvikJNIEnvPtr_ANDROID, pojav_environ->bridgeClazz, "onGrabStateChanged", "(Z)V");
JNIEnv *env = pojav_environ->dalvikJNIEnvPtr_ANDROID;
pojav_environ->bridgeClazz = (*env)->NewGlobalRef(env,(*env) ->FindClass(env,"org/lwjgl/glfw/CallbackBridge"));
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;
} else if (pojav_environ->dalvikJavaVMPtr != vm) {
__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,
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));
}

View File

@ -422,4 +422,6 @@
<string name="local_login_bad_username_title">Unsuitable username</string>
<string name="local_login_bad_username_text">The username must be between 316 characters long, and must only contain latin letters, arabic numerals and underscores.</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>

View File

@ -144,7 +144,13 @@
<PreferenceCategory
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
android:key="_frag_changeKeyBindings"
android:title="@string/preference_remap_controller_title"
android:summary="@string/preference_remap_controller_description"
android:fragment="net.kdt.pojavlaunch.fragments.GamepadMapperFragment"/>

View File

@ -1,4 +1,5 @@
package org.lwjgl.glfw;
import java.nio.ByteBuffer;
import java.util.*;
public class CallbackBridge {
@ -47,5 +48,7 @@ public class CallbackBridge {
public static native boolean nativeSetInputReady(boolean ready);
public static native String nativeClipboard(int action, byte[] copy);
public static native void nativeSetGrabbing(boolean grab);
public static native ByteBuffer nativeCreateGamepadButtonBuffer();
public static native ByteBuffer nativeCreateGamepadAxisBuffer();
}

View File

@ -13,6 +13,7 @@ import javax.annotation.*;
import org.lwjgl.*;
import org.lwjgl.system.*;
import org.lwjgl.system.MemoryUtil;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.system.APIUtil.*;
@ -24,8 +25,9 @@ import java.util.*;
public class GLFW
{
static FloatBuffer joystickData = (FloatBuffer)FloatBuffer.allocate(8).flip();
static ByteBuffer buttonData = (ByteBuffer)ByteBuffer.allocate(8).flip();
static FloatBuffer joystickAxisData;
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. */
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_HEIGHT= "glfwstub.windowHeight";
public static long mainContext = 0;
private static long gamepadDataPointer;
static {
try {
@ -636,6 +639,8 @@ public class GLFW
return win;
}
private static native long internalGetGamepadDataPointer();
// Generated stub callback methods
public static GLFWCharCallback glfwSetCharCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWcharfun") GLFWCharCallbackI cbfun) {
GLFWCharCallback lastCallback = mGLFWCharCallback;
@ -805,6 +810,10 @@ public class GLFW
mGLFWInitialTime = (double) System.nanoTime();
long __functionAddress = Functions.Init;
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;
}
@ -1201,50 +1210,59 @@ public class GLFW
}
public static boolean glfwJoystickPresent(int jid) {
if(jid == 0) {
if(jid == GLFW_JOYSTICK_1) {
return true;
}else return false;
}
public static String glfwGetJoystickName(int jid) {
if(jid == 0) {
return "AIC event bus controller";
if(jid == GLFW_JOYSTICK_1) {
return "Pojav XBOX 360 compatible gamepad";
}else return null;
}
public static FloatBuffer glfwGetJoystickAxes(int jid) {
if(jid == 0) {
return joystickData;
if(jid == GLFW_JOYSTICK_1) {
return joystickAxisData;
}else return null;
}
public static ByteBuffer glfwGetJoystickButtons(int jid) {
if(jid == 0) {
return buttonData;
if(jid == GLFW_JOYSTICK_1) {
return joystickButtonData;
}else return null;
}
public static ByteBuffer glfwGetjoystickHats(int jid) {
return null;
public static ByteBuffer glfwGetJoystickHats(int jid) {
if(jid == GLFW_JOYSTICK_1) {
return empty; // Maybe implement this later?
}else return null;
}
public static boolean glfwJoystickIsGamepad(int jid) {
if(jid == 0) return true;
if(jid == GLFW_JOYSTICK_1) return true;
else return false;
}
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;
}
private static long mUserPointer;
public static long glfwGetJoystickUserPointer(int jid) {
return 0;
return mUserPointer;
}
public static void glfwSetJoystickUserPointer(int jid, long pointer) {
mUserPointer = pointer;
}
public static boolean glfwUpdateGamepadMappings(ByteBuffer string) {
return false;
}
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) {
return false;
if(jid != 0) return false;
MemoryUtil.memCopy(gamepadDataPointer, state.address(), state.sizeof());
return true;
}
/** Array version of: {@link #glfwGetVersion GetVersion} */