From 834b7e9f6fe8772b197a82c16e630e3f67595fa9 Mon Sep 17 00:00:00 2001 From: isXander Date: Fri, 5 May 2023 17:16:15 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Lazily=20ask=20for=20vibra?= =?UTF-8?q?tion=20natives=20once=20controller=20plugged=20in=20(close=20#6?= =?UTF-8?q?3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/isxander/controlify/Controlify.java | 66 ++++++++++++------- .../controlify/debug/DebugProperties.java | 2 +- .../controlify/driver/GamepadDrivers.java | 2 +- .../controlify/driver/SteamDeckDriver.java | 14 ++-- 4 files changed, 56 insertions(+), 28 deletions(-) diff --git a/src/main/java/dev/isxander/controlify/Controlify.java b/src/main/java/dev/isxander/controlify/Controlify.java index e11e20b..d2914b8 100644 --- a/src/main/java/dev/isxander/controlify/Controlify.java +++ b/src/main/java/dev/isxander/controlify/Controlify.java @@ -40,9 +40,10 @@ import org.lwjgl.glfw.GLFW; import org.slf4j.Logger; import java.util.ArrayDeque; -import java.util.Objects; import java.util.Optional; import java.util.Queue; +import java.util.concurrent.CompletableFuture; +import java.util.stream.IntStream; public class Controlify implements ControlifyApi { public static final Logger LOGGER = LogUtils.getLogger(); @@ -57,6 +58,8 @@ public class Controlify implements ControlifyApi { private InputMode currentInputMode = InputMode.KEYBOARD_MOUSE; private ControllerHIDService controllerHIDService; + private CompletableFuture vibrationOnboardingFuture = null; + private final ControlifyConfig config = new ControlifyConfig(this); private final Queue> calibrationQueue = new ArrayDeque<>(); @@ -73,17 +76,49 @@ public class Controlify implements ControlifyApi { config().load(); - if (!config().globalSettings().vibrationOnboarded) { - minecraft.setScreen(new VibrationOnboardingScreen( - minecraft.screen, - answer -> this.initializeControllers() - )); - } else { - this.initializeControllers(); + var controllersConnected = IntStream.range(0, GLFW.GLFW_JOYSTICK_LAST + 1).anyMatch(GLFW::glfwJoystickPresent); + if (controllersConnected) { + askVibrationNatives().whenComplete((loaded, th) -> discoverControllers()); } + + // listen for new controllers + GLFW.glfwSetJoystickCallback((jid, event) -> { + try { + this.askVibrationNatives().whenComplete((loaded, th) -> { + if (event == GLFW.GLFW_CONNECTED) { + this.onControllerHotplugged(jid); + } else if (event == GLFW.GLFW_DISCONNECTED) { + this.onControllerDisconnect(jid); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + }); } - private void initializeControllers() { + private CompletableFuture askVibrationNatives() { + if (vibrationOnboardingFuture != null) return vibrationOnboardingFuture; + + if (config().globalSettings().vibrationOnboarded) { + return CompletableFuture.completedFuture(config().globalSettings().loadVibrationNatives); + } + + vibrationOnboardingFuture = new CompletableFuture<>(); + + minecraft.setScreen(new VibrationOnboardingScreen( + minecraft.screen, + answer -> { + if (answer) + SDL2NativesManager.initialise(); + vibrationOnboardingFuture.complete(answer); + } + )); + + return vibrationOnboardingFuture; + } + + private void discoverControllers() { DebugLog.log("Discovering and initializing controllers..."); if (config().globalSettings().loadVibrationNatives) @@ -123,19 +158,6 @@ public class Controlify implements ControlifyApi { config().saveIfDirty(); } - // listen for new controllers - GLFW.glfwSetJoystickCallback((jid, event) -> { - try { - if (event == GLFW.GLFW_CONNECTED) { - this.onControllerHotplugged(jid); - } else if (event == GLFW.GLFW_DISCONNECTED) { - this.onControllerDisconnect(jid); - } - } catch (Exception e) { - e.printStackTrace(); - } - }); - ClientTickEvents.START_CLIENT_TICK.register(this::tick); FabricLoader.getInstance().getEntrypoints("controlify", ControlifyEntrypoint.class).forEach(entrypoint -> { diff --git a/src/main/java/dev/isxander/controlify/debug/DebugProperties.java b/src/main/java/dev/isxander/controlify/debug/DebugProperties.java index 67930d5..9e0dba6 100644 --- a/src/main/java/dev/isxander/controlify/debug/DebugProperties.java +++ b/src/main/java/dev/isxander/controlify/debug/DebugProperties.java @@ -19,7 +19,7 @@ public class DebugProperties { /* Print gyro data if supported */ public static final boolean PRINT_GYRO = boolProp("controlify.debug.print_gyro", false, false); /* Print what drivers are being used */ - public static final boolean PRINT_DRIVER = boolProp("controlify.debug.print_driver", false, true); + public static final boolean PRINT_DRIVER = boolProp("controlify.debug.print_driver", true, true); public static void printProperties() { if (properties.stream().noneMatch(DebugProperty::enabled)) diff --git a/src/main/java/dev/isxander/controlify/driver/GamepadDrivers.java b/src/main/java/dev/isxander/controlify/driver/GamepadDrivers.java index babc224..3ee6ebe 100644 --- a/src/main/java/dev/isxander/controlify/driver/GamepadDrivers.java +++ b/src/main/java/dev/isxander/controlify/driver/GamepadDrivers.java @@ -36,7 +36,7 @@ public record GamepadDrivers(BasicGamepadInputDriver basicGamepadInputDriver, Gy } // broken - if (hid.isPresent() && SteamDeckDriver.isSteamDeck(hid.get()) && false) { + if (hid.isPresent() && SteamDeckDriver.isSteamDeck(hid.get())) { gyroDriver = new SteamDeckDriver(hid.get()); } diff --git a/src/main/java/dev/isxander/controlify/driver/SteamDeckDriver.java b/src/main/java/dev/isxander/controlify/driver/SteamDeckDriver.java index 51a22e6..2581efb 100644 --- a/src/main/java/dev/isxander/controlify/driver/SteamDeckDriver.java +++ b/src/main/java/dev/isxander/controlify/driver/SteamDeckDriver.java @@ -5,12 +5,15 @@ import dev.isxander.controlify.controller.gamepad.GamepadState; import dev.isxander.controlify.controller.hid.HIDIdentifier; import org.hid4java.HidDevice; +import java.util.Arrays; + public class SteamDeckDriver implements GyroDriver, BasicGamepadInputDriver { private static final int cInputRecordLen = 8; // Number of bytes that are read from the hid device per 1 byte of HID private static final int cByteposInput = 4; // Position in the raw hid data where HID data byte is private static final byte[] startMarker = new byte[] { 0x01, 0x00, 0x09, 0x40 }; // Beginning of every Steam deck HID frame private final HidDevice hidDevice; + private int interval = 0; private GamepadState.GyroState gyroDelta = GamepadState.GyroState.ORIGIN; private BasicGamepadState basicGamepadState = new BasicGamepadState(GamepadState.AxesState.EMPTY, GamepadState.ButtonState.EMPTY); @@ -23,7 +26,9 @@ public class SteamDeckDriver implements GyroDriver, BasicGamepadInputDriver { @Override public void update() { - sendSomething(); + if (interval == 0) + keepAlive(); + interval = (interval + 1) % 120; byte[] data = new byte[64]; int readCnt = hidDevice.read(data); @@ -35,6 +40,8 @@ public class SteamDeckDriver implements GyroDriver, BasicGamepadInputDriver { Controlify.LOGGER.warn("Error reading data."); } + System.out.println(Arrays.toString(data)); + if (!checkData(data, readCnt)) return; Frame frame = Frame.fromBytes(data); @@ -42,9 +49,8 @@ public class SteamDeckDriver implements GyroDriver, BasicGamepadInputDriver { readFrame(frame); } - private void sendSomething() { - hidDevice.getFeatureReport(new byte[]{ (byte) 0x89 }, (byte) 0x0); - hidDevice.write(new byte[]{ (byte) 0x89 }, 2, (byte) 0x0); + private void keepAlive() { + hidDevice.sendFeatureReport(new byte[0], (byte) 8); } private void readFrame(Frame frame) {