1
0
forked from Clones/Controlify

✏️ Lazily ask for vibration natives once controller plugged in (close #63)

This commit is contained in:
isXander
2023-05-05 17:16:15 +01:00
parent 63c3816a21
commit 834b7e9f6f
4 changed files with 56 additions and 28 deletions

View File

@ -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<Boolean> vibrationOnboardingFuture = null;
private final ControlifyConfig config = new ControlifyConfig(this);
private final Queue<Controller<?, ?>> 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<Boolean> 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 -> {

View File

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

View File

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

View File

@ -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) {