diff --git a/app_pojavlauncher/build.gradle b/app_pojavlauncher/build.gradle
index 034ff33b6..7efbff153 100644
--- a/app_pojavlauncher/build.gradle
+++ b/app_pojavlauncher/build.gradle
@@ -227,5 +227,5 @@ dependencies {
// implementation 'net.sourceforge.streamsupport:streamsupport-cfuture:1.7.0'
- implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
}
diff --git a/app_pojavlauncher/libs/SDL3-3.1.9.aar b/app_pojavlauncher/libs/SDL3-3.1.9.aar
new file mode 100644
index 000000000..c13c06ebc
Binary files /dev/null and b/app_pojavlauncher/libs/SDL3-3.1.9.aar differ
diff --git a/app_pojavlauncher/src/main/assets/components/arc_dns_injector/arc_dns_injector.jar b/app_pojavlauncher/src/main/assets/components/arc_dns_injector/arc_dns_injector.jar
index 447ec038b..16d8c3eb9 100644
Binary files a/app_pojavlauncher/src/main/assets/components/arc_dns_injector/arc_dns_injector.jar and b/app_pojavlauncher/src/main/assets/components/arc_dns_injector/arc_dns_injector.jar differ
diff --git a/app_pojavlauncher/src/main/assets/components/arc_dns_injector/version b/app_pojavlauncher/src/main/assets/components/arc_dns_injector/version
index 02de90fae..68e9f6406 100644
--- a/app_pojavlauncher/src/main/assets/components/arc_dns_injector/version
+++ b/app_pojavlauncher/src/main/assets/components/arc_dns_injector/version
@@ -1 +1 @@
-1687691695196
\ No newline at end of file
+1736466767190
\ No newline at end of file
diff --git a/app_pojavlauncher/src/main/assets/components/forge_installer/forge_installer.jar b/app_pojavlauncher/src/main/assets/components/forge_installer/forge_installer.jar
index c540bee9c..0992cbb11 100644
Binary files a/app_pojavlauncher/src/main/assets/components/forge_installer/forge_installer.jar and b/app_pojavlauncher/src/main/assets/components/forge_installer/forge_installer.jar differ
diff --git a/app_pojavlauncher/src/main/assets/components/forge_installer/version b/app_pojavlauncher/src/main/assets/components/forge_installer/version
index 50f426278..28053889d 100644
--- a/app_pojavlauncher/src/main/assets/components/forge_installer/version
+++ b/app_pojavlauncher/src/main/assets/components/forge_installer/version
@@ -1 +1 @@
-1692525087345
\ No newline at end of file
+1736466767180
\ No newline at end of file
diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-glfw-classes.jar b/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-glfw-classes.jar
index 4141a08bb..4282de7ee 100644
Binary files a/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-glfw-classes.jar and b/app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-glfw-classes.jar differ
diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/version b/app_pojavlauncher/src/main/assets/components/lwjgl3/version
index a4b0232d5..ae0486753 100644
--- a/app_pojavlauncher/src/main/assets/components/lwjgl3/version
+++ b/app_pojavlauncher/src/main/assets/components/lwjgl3/version
@@ -1 +1 @@
-1732218529630
\ No newline at end of file
+1736466767185
\ No newline at end of file
diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java
index bfabd8f36..b8e85ce08 100644
--- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java
+++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java
@@ -24,13 +24,12 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
-import android.provider.DocumentsContract;
import android.util.Log;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
-import android.webkit.MimeTypeMap;
+import android.view.WindowInsets;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
@@ -66,12 +65,14 @@ import net.kdt.pojavlaunch.value.MinecraftAccount;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
+import org.libsdl.app.SDLActivityComponent;
+import org.libsdl.app.SDLComponentReceiver;
import org.lwjgl.glfw.CallbackBridge;
import java.io.File;
import java.io.IOException;
-public class MainActivity extends BaseActivity implements ControlButtonMenuListener, EditorExitable, ServiceConnection {
+public class MainActivity extends BaseActivity implements ControlButtonMenuListener, EditorExitable, ServiceConnection, SDLComponentReceiver, View.OnSystemUiVisibilityChangeListener {
public static volatile ClipboardManager GLOBAL_CLIPBOARD;
public static final String INTENT_MINECRAFT_VERSION = "intent_version";
@@ -98,9 +99,16 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
private QuickSettingSideDialog mQuickSettingSideDialog;
+ private SDLActivityComponent sdlActivityComponent;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+
+ sdlActivityComponent = new SDLActivityComponent(this);
+ sdlActivityComponent.setLibraries(new String[] { "SDL3" });
+ sdlActivityComponent.onCreate();
+
minecraftProfile = LauncherProfiles.getCurrentProfile();
MCOptionUtils.load(Tools.getGameDirPath(minecraftProfile).getAbsolutePath());
@@ -281,24 +289,32 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
mQuickSettingSideDialog.cancel();
}
CallbackBridge.nativeSetWindowAttrib(LwjglGlfwKeycode.GLFW_HOVERED, 0);
+
+ sdlActivityComponent.onPause();
super.onPause();
}
@Override
protected void onStart() {
+ sdlActivityComponent.onStart();
super.onStart();
+
CallbackBridge.nativeSetWindowAttrib(LwjglGlfwKeycode.GLFW_VISIBLE, 1);
}
@Override
protected void onStop() {
CallbackBridge.nativeSetWindowAttrib(LwjglGlfwKeycode.GLFW_VISIBLE, 0);
+
+ sdlActivityComponent.onStop();
super.onStop();
}
@Override
protected void onDestroy() {
+ sdlActivityComponent.onDestroy();
super.onDestroy();
+
CallbackBridge.removeGrabListener(touchpad);
CallbackBridge.removeGrabListener(minecraftGLView);
ContextExecutor.clearActivity();
@@ -306,6 +322,7 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
+ sdlActivityComponent.onConfigurationChanged(newConfig);
super.onConfigurationChanged(newConfig);
if(mGyroControl != null) mGyroControl.updateOrientation();
@@ -330,6 +347,7 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ sdlActivityComponent.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
@@ -421,6 +439,10 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
+ if (!sdlActivityComponent.dispatchKeyEvent(event)) {
+ return false;
+ }
+
if(isInEditor) {
if(event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if(event.getAction() == KeyEvent.ACTION_DOWN) mControlLayout.askToExit(this);
@@ -570,4 +592,39 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
return minecraftGLView.dispatchCapturedPointerEvent(ev);
else return super.dispatchTrackballEvent(ev);
}
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ sdlActivityComponent.onWindowFocusChanged(hasFocus);
+ super.onWindowFocusChanged(hasFocus);
+ }
+
+ @Override
+ public void onTrimMemory(int level) {
+ sdlActivityComponent.onTrimMemory(level);
+ super.onTrimMemory(level);
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (sdlActivityComponent.onBackPressed()) {
+ super.onBackPressed();
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ sdlActivityComponent.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ }
+
+ @Override
+ public void onSystemUiVisibilityChange(int visibility) {
+ sdlActivityComponent.onSystemUiVisibilityChange(visibility);
+ }
+
+ @Override
+ public void superOnBackPressed() {
+ super.onBackPressed();
+ }
}
diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java
index dd9f5f10f..50f42b3e8 100644
--- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java
+++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java
@@ -1,6 +1,7 @@
package net.kdt.pojavlaunch;
import static net.kdt.pojavlaunch.MainActivity.touchCharInput;
+import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_GAMEPAD_PASSTHRU;
import static net.kdt.pojavlaunch.utils.MCOptionUtils.getMcScale;
import static org.lwjgl.glfw.CallbackBridge.sendMouseButton;
import static org.lwjgl.glfw.CallbackBridge.windowHeight;
@@ -214,7 +215,7 @@ public class MinecraftGLSurface extends View implements GrabListener {
public boolean dispatchGenericMotionEvent(MotionEvent event) {
int mouseCursorIndex = -1;
- if(Gamepad.isGamepadEvent(event)){
+ if(Gamepad.isGamepadEvent(event) && !PREF_GAMEPAD_PASSTHRU){
if(mGamepad == null) createGamepad(this, event.getDevice());
mInputManager.handleMotionEventInput(getContext(), event, mGamepad);
@@ -252,6 +253,10 @@ public class MinecraftGLSurface extends View implements GrabListener {
/** The event for keyboard/ gamepad button inputs */
public boolean processKeyEvent(KeyEvent event) {
+ if (PREF_GAMEPAD_PASSTHRU) {
+ return false;
+ }
+
//Log.i("KeyEvent", event.toString());
//Filtering useless events by order of probability
diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java
index 49fccca08..99a95b7bd 100644
--- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java
+++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java
@@ -43,6 +43,7 @@ import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTI
import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTION_WEST;
import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.isJoystickEvent;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_DEADZONE_SCALE;
+import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_GAMEPAD_PASSTHRU;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_SCALE_FACTOR;
import static net.kdt.pojavlaunch.utils.MCOptionUtils.getMcScale;
import static org.lwjgl.glfw.CallbackBridge.sendKeyPress;
@@ -89,6 +90,10 @@ public class Gamepad implements GrabListener, GamepadHandler {
private final GamepadDataProvider mMapProvider;
public Gamepad(View contextView, InputDevice inputDevice, GamepadDataProvider mapProvider, boolean showCursor){
+ if (PREF_GAMEPAD_PASSTHRU) {
+ throw new IllegalStateException("Gamepad should never have been constructed if passthru is on.");
+ }
+
Settings.setDeadzoneScale(PREF_DEADZONE_SCALE);
mScreenChoreographer = Choreographer.getInstance();
@@ -190,14 +195,14 @@ public class Gamepad implements GrabListener, GamepadHandler {
}
public static boolean isGamepadEvent(MotionEvent event){
- return isJoystickEvent(event);
+ return isJoystickEvent(event) && !PREF_GAMEPAD_PASSTHRU;
}
public static boolean isGamepadEvent(KeyEvent event){
boolean isGamepad = ((event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD)
|| ((event.getDevice() != null) && ((event.getDevice().getSources() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD));
- return isGamepad && GamepadDpad.isDpadEvent(event);
+ return isGamepad && GamepadDpad.isDpadEvent(event) && !PREF_GAMEPAD_PASSTHRU;
}
/**
diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java
index b5480596f..f17cca734 100644
--- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java
+++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java
@@ -37,6 +37,7 @@ public class LauncherPreferences {
public static final String PREF_VERSION_REPOS = "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json";
public static boolean PREF_CHECK_LIBRARY_SHA = true;
public static boolean PREF_DISABLE_GESTURES = false;
+ public static boolean PREF_GAMEPAD_PASSTHRU = false;
public static boolean PREF_DISABLE_SWAP_HAND = false;
public static float PREF_MOUSESPEED = 1f;
public static int PREF_RAM_ALLOCATION;
@@ -84,6 +85,7 @@ public class LauncherPreferences {
PREF_FORCE_ENGLISH = DEFAULT_PREF.getBoolean("force_english", false);
PREF_CHECK_LIBRARY_SHA = DEFAULT_PREF.getBoolean("checkLibraries",true);
PREF_DISABLE_GESTURES = DEFAULT_PREF.getBoolean("disableGestures",false);
+ PREF_GAMEPAD_PASSTHRU = DEFAULT_PREF.getBoolean("gamepadPassthru",false);
PREF_DISABLE_SWAP_HAND = DEFAULT_PREF.getBoolean("disableDoubleTap", false);
PREF_RAM_ALLOCATION = DEFAULT_PREF.getInt("allocation", findBestRAMAllocation(ctx));
PREF_CUSTOM_JAVA_ARGS = DEFAULT_PREF.getString("javaArgs", "");
diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java
index 1b9a2cd2b..6c52450dc 100644
--- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java
+++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java
@@ -30,6 +30,8 @@ import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.multirt.Runtime;
import net.kdt.pojavlaunch.plugins.FFmpegPlugin;
import net.kdt.pojavlaunch.prefs.*;
+
+import org.libsdl.app.SDLActivityComponent;
import org.lwjgl.glfw.*;
import javax.microedition.khronos.egl.EGL10;
diff --git a/app_pojavlauncher/src/main/jni/Android.mk b/app_pojavlauncher/src/main/jni/Android.mk
index a820a902a..e7919525b 100644
--- a/app_pojavlauncher/src/main/jni/Android.mk
+++ b/app_pojavlauncher/src/main/jni/Android.mk
@@ -15,11 +15,13 @@ include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := tinywrapper
-LOCAL_SHARED_LIBRARIES := angle_gles2
+LOCAL_SHARED_LIBRARIES := angle_gles2 SDL3 SDL3-Headers
LOCAL_SRC_FILES := tinywrapper/main.c tinywrapper/string_utils.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/tinywrapper
include $(BUILD_SHARED_LIBRARY)
+$(call import-add-path,/out)
+$(call import-module,prefab/SDL3)
$(call import-module,prefab/bytehook)
LOCAL_PATH := $(HERE_PATH)
diff --git a/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libjnidispatch.so b/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libjnidispatch.so
index b58816595..cd7e6716f 100644
Binary files a/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libjnidispatch.so and b/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libjnidispatch.so differ
diff --git a/app_pojavlauncher/src/main/jniLibs/armeabi-v7a/libjnidispatch.so b/app_pojavlauncher/src/main/jniLibs/armeabi-v7a/libjnidispatch.so
index 1d02dca9d..603883efa 100644
Binary files a/app_pojavlauncher/src/main/jniLibs/armeabi-v7a/libjnidispatch.so and b/app_pojavlauncher/src/main/jniLibs/armeabi-v7a/libjnidispatch.so differ
diff --git a/app_pojavlauncher/src/main/jniLibs/x86/libjnidispatch.so b/app_pojavlauncher/src/main/jniLibs/x86/libjnidispatch.so
index 336aad7b9..e9094b68b 100644
Binary files a/app_pojavlauncher/src/main/jniLibs/x86/libjnidispatch.so and b/app_pojavlauncher/src/main/jniLibs/x86/libjnidispatch.so differ
diff --git a/app_pojavlauncher/src/main/jniLibs/x86_64/libjnidispatch.so b/app_pojavlauncher/src/main/jniLibs/x86_64/libjnidispatch.so
index 4af42fc52..e594b8882 100644
Binary files a/app_pojavlauncher/src/main/jniLibs/x86_64/libjnidispatch.so and b/app_pojavlauncher/src/main/jniLibs/x86_64/libjnidispatch.so differ
diff --git a/app_pojavlauncher/src/main/res/values/strings.xml b/app_pojavlauncher/src/main/res/values/strings.xml
index 8814ef333..26c58e4e5 100644
--- a/app_pojavlauncher/src/main/res/values/strings.xml
+++ b/app_pojavlauncher/src/main/res/values/strings.xml
@@ -162,6 +162,8 @@
Library %s is damaged and will be redownloaded
Library %s can\'t be checked, have to assume it\'s good
Library %s is fine and usable
+ Gamepad passthrough
+ Designed for controller mods like Controlify; when enabled, Pojav does no controller to keyboard/mouse emulation and allows the game to process controllers.
Disable gestures
Disables gestures, such as hold to break block, and tap to place a block.
Disable double tap to swap hands
diff --git a/app_pojavlauncher/src/main/res/xml/pref_control.xml b/app_pojavlauncher/src/main/res/xml/pref_control.xml
index 0d2778e17..fab2e5e4a 100644
--- a/app_pojavlauncher/src/main/res/xml/pref_control.xml
+++ b/app_pojavlauncher/src/main/res/xml/pref_control.xml
@@ -13,6 +13,13 @@
+
+