From 8eb851059085ebfa42d3791d9fa4004d01681fd4 Mon Sep 17 00:00:00 2001 From: isXander Date: Sat, 15 Apr 2023 13:12:45 +0100 Subject: [PATCH] lots of API docs and fix sources jar --- build.gradle.kts | 16 +++++-- .../dev/isxander/controlify/Controlify.java | 34 ++++++++++---- .../controlify/api/ControlifyApi.java | 7 ++- .../api/bind/ControllerBinding.java | 27 ++++++++++- .../api/buttonguide/ButtonGuidePredicate.java | 2 + .../api/event/ControlifyEvents.java | 21 ++++++++- .../api/ingameguide/IngameGuideContext.java | 9 ++++ .../api/ingameinput/LookInputModifier.java | 34 ++++++++++++++ .../bindings/ControllerBindings.java | 2 +- .../config/gui/ControllerBindHandler.java | 21 +++++++++ .../config/gui/GamepadBindController.java | 30 +++++++++--- .../config/gui/JoystickBindController.java | 46 ++++++++++++++----- .../controller/joystick/JoystickState.java | 27 +++++------ .../controlify/debug/DebugProperties.java | 2 +- .../mixins/core/MinecraftMixin.java | 2 +- .../mixins/feature/guide/ingame/GuiMixin.java | 12 ++--- 16 files changed, 233 insertions(+), 59 deletions(-) create mode 100644 src/main/java/dev/isxander/controlify/config/gui/ControllerBindHandler.java diff --git a/build.gradle.kts b/build.gradle.kts index 18f4adb..f0be9a2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,5 @@ import com.github.breadmoirai.githubreleaseplugin.GithubReleaseTask +import org.gradle.jvm.tasks.Jar plugins { java @@ -118,6 +119,11 @@ blossom { replaceToken("", libs.versions.sdl2.jni.get(), sdl2ManagerClass) } +java { + withSourcesJar() + withJavadocJar() +} + tasks { processResources { val modId: String by project @@ -152,6 +158,10 @@ tasks { archiveClassifier.set("fabric-$minecraftVersion-sources") } + named("javadocJar") { + archiveClassifier.set("fabric-$minecraftVersion-javadoc") + } + register("releaseMod") { group = "mod" @@ -163,10 +173,6 @@ tasks { } } -java { - withSourcesJar() -} - val changelogText = file("changelogs/${project.version}.md").takeIf { it.exists() }?.readText() ?: "No changelog provided." val modrinthId: String by project @@ -233,6 +239,8 @@ publishing { artifactId = base.archivesName.get() from(components["java"]) + artifact(tasks["remapSourcesJar"]) + artifact(tasks["javadocJar"]) } } diff --git a/src/main/java/dev/isxander/controlify/Controlify.java b/src/main/java/dev/isxander/controlify/Controlify.java index 31ed3f2..222104f 100644 --- a/src/main/java/dev/isxander/controlify/Controlify.java +++ b/src/main/java/dev/isxander/controlify/Controlify.java @@ -4,6 +4,7 @@ import com.mojang.blaze3d.Blaze3D; import com.mojang.logging.LogUtils; import dev.isxander.controlify.api.ControlifyApi; import dev.isxander.controlify.api.entrypoint.ControlifyEntrypoint; +import dev.isxander.controlify.config.gui.ControllerBindHandler; import dev.isxander.controlify.controller.Controller; import dev.isxander.controlify.controller.ControllerState; import dev.isxander.controlify.controller.joystick.CompoundJoystickController; @@ -37,6 +38,7 @@ import org.lwjgl.glfw.GLFW; import org.slf4j.Logger; import java.util.ArrayDeque; +import java.util.Optional; import java.util.Queue; public class Controlify implements ControlifyApi { @@ -160,6 +162,8 @@ public class Controlify implements ControlifyApi { controllerHIDService = new ControllerHIDService(); controllerHIDService.start(); + ControllerBindHandler.setup(); + FabricLoader.getInstance().getEntrypoints("controlify", ControlifyEntrypoint.class).forEach(entrypoint -> { try { entrypoint.onControlifyPreInit(this); @@ -187,6 +191,7 @@ public class Controlify implements ControlifyApi { wrapControllerError(controller::updateState, "Updating controller state", controller); else wrapControllerError(controller::clearState, "Clearing controller state", controller); + ControlifyEvents.CONTROLLER_STATE_UPDATE.invoker().onControllerStateUpdate(controller); } if (switchableController != null && Blaze3D.getTime() - askSwitchTime <= 10000) { @@ -233,11 +238,11 @@ public class Controlify implements ControlifyApi { ScreenProcessorProvider.provide(minecraft.screen).onControllerUpdate(controller); } if (minecraft.level != null) { - this.inGameInputHandler().inputTick(); + this.inGameInputHandler().ifPresent(InGameInputHandler::inputTick); } this.virtualMouseHandler().handleControllerInput(controller); - ControlifyEvents.CONTROLLER_STATE_UPDATED.invoker().onControllerStateUpdate(controller); + ControlifyEvents.ACTIVE_CONTROLLER_TICKED.invoker().onControllerStateUpdate(controller); } public static void wrapControllerError(Runnable runnable, String errorTitle, Controller controller) { @@ -335,10 +340,12 @@ public class Controlify implements ControlifyApi { return currentController; } - public void setCurrentController(Controller controller) { - if (controller == null) - controller = Controller.DUMMY; + @Override + public @NotNull Optional> getCurrentController() { + return Optional.ofNullable(currentController); + } + public void setCurrentController(Controller controller) { if (this.currentController == controller) return; this.currentController = controller; @@ -347,6 +354,15 @@ public class Controlify implements ControlifyApi { switchableController = null; } + if (controller == null) { + this.setInputMode(InputMode.KEYBOARD_MOUSE); + this.inGameInputHandler = null; + this.inGameButtonGuide = null; + DebugLog.log("Updated current controller to null"); + config().save(); + return; + } + DebugLog.log("Updated current controller to {}({})", controller.name(), controller.uid()); if (!config().currentControllerUid().equals(controller.uid())) { @@ -362,12 +378,12 @@ public class Controlify implements ControlifyApi { calibrationQueue.add(controller); } - public InGameInputHandler inGameInputHandler() { - return inGameInputHandler; + public Optional inGameInputHandler() { + return Optional.ofNullable(inGameInputHandler); } - public InGameButtonGuide inGameButtonGuide() { - return inGameButtonGuide; + public Optional inGameButtonGuide() { + return Optional.ofNullable(inGameButtonGuide); } public VirtualMouseHandler virtualMouseHandler() { diff --git a/src/main/java/dev/isxander/controlify/api/ControlifyApi.java b/src/main/java/dev/isxander/controlify/api/ControlifyApi.java index f89aabb..b79756b 100644 --- a/src/main/java/dev/isxander/controlify/api/ControlifyApi.java +++ b/src/main/java/dev/isxander/controlify/api/ControlifyApi.java @@ -2,10 +2,11 @@ package dev.isxander.controlify.api; import dev.isxander.controlify.Controlify; import dev.isxander.controlify.InputMode; -import dev.isxander.controlify.api.bind.ControlifyBindingsApi; import dev.isxander.controlify.controller.Controller; import org.jetbrains.annotations.NotNull; +import java.util.Optional; + /** * Interface with Controlify in a manner where you don't need to worry about updates * breaking! This is the recommended way to interact with Controlify. @@ -17,10 +18,14 @@ import org.jetbrains.annotations.NotNull; */ public interface ControlifyApi { /** + * @deprecated Use {@link #getCurrentController()} instead. * @return the controller currently in use. If disabled, this will return {@link Controller#DUMMY} */ + @Deprecated @NotNull Controller currentController(); + @NotNull Optional> getCurrentController(); + /** * Get the current input mode for the game. */ diff --git a/src/main/java/dev/isxander/controlify/api/bind/ControllerBinding.java b/src/main/java/dev/isxander/controlify/api/bind/ControllerBinding.java index 1318755..0a0ef1c 100644 --- a/src/main/java/dev/isxander/controlify/api/bind/ControllerBinding.java +++ b/src/main/java/dev/isxander/controlify/api/bind/ControllerBinding.java @@ -5,17 +5,39 @@ import dev.isxander.yacl.api.Option; import net.minecraft.client.KeyMapping; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.Nullable; import java.util.function.BooleanSupplier; public interface ControllerBinding { + /** + * @return the current analogue state of the binding. + */ float state(); + + /** + * @return the analogue state of the binding last tick. + */ float prevState(); + /** + * @return if the binding is currently held. + */ boolean held(); + + /** + * @return if the binding was held last tick. + */ boolean prevHeld(); + /** + * @return if the binding is held this tick but not the previous tick + */ boolean justPressed(); + + /** + * @return if the binding is not held this tick but was held last tick + */ boolean justReleased(); Component name(); @@ -24,7 +46,10 @@ public interface ControllerBinding { ResourceLocation id(); - KeyMappingOverride override(); + /** + * The vanilla override of the binding. Null if there is no override. + */ + @Nullable KeyMappingOverride override(); void resetBind(); boolean isUnbound(); diff --git a/src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuidePredicate.java b/src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuidePredicate.java index b40163e..05cc2c7 100644 --- a/src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuidePredicate.java +++ b/src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuidePredicate.java @@ -8,6 +8,8 @@ import net.minecraft.client.gui.screens.Screen; public interface ButtonGuidePredicate { boolean shouldDisplay(T button); + /** Only display the button guide when the button is focused. */ ButtonGuidePredicate FOCUS_ONLY = AbstractWidget::isFocused; + /** Always display the button guide. */ ButtonGuidePredicate ALWAYS = btn -> true; } diff --git a/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java b/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java index 137d8d9..e4a87e7 100644 --- a/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java +++ b/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java @@ -21,7 +21,22 @@ public final class ControlifyEvents { /** * Triggers every tick when the current controller state has been updated. */ - public static final Event CONTROLLER_STATE_UPDATED = EventFactory.createArrayBacked(ControllerStateUpdate.class, callbacks -> controller -> { + public static final Event ACTIVE_CONTROLLER_TICKED = EventFactory.createArrayBacked(ControllerStateUpdate.class, callbacks -> controller -> { + for (ControllerStateUpdate callback : callbacks) { + callback.onControllerStateUpdate(controller); + } + }); + + /** + * @deprecated Use {@link #ACTIVE_CONTROLLER_TICKED} instead. + */ + @Deprecated + public static final Event CONTROLLER_STATE_UPDATED = ACTIVE_CONTROLLER_TICKED; + + /** + * Triggers every tick when any connected controller's state has been updated before the active controller is ticked. + */ + public static final Event CONTROLLER_STATE_UPDATE = EventFactory.createArrayBacked(ControllerStateUpdate.class, callbacks -> controller -> { for (ControllerStateUpdate callback : callbacks) { callback.onControllerStateUpdate(controller); } @@ -45,6 +60,10 @@ public final class ControlifyEvents { } }); + /** + * Allows you to modify the look input before it is applied to the player. + * These modifiers are called before the look input is multiplied by the sensitivity. + */ public static final Event LOOK_INPUT_MODIFIER = EventFactory.createArrayBacked(LookInputModifier.class, callbacks -> new LookInputModifier() { @Override public float modifyX(float x, Controller controller) { diff --git a/src/main/java/dev/isxander/controlify/api/ingameguide/IngameGuideContext.java b/src/main/java/dev/isxander/controlify/api/ingameguide/IngameGuideContext.java index debf423..a9f761e 100644 --- a/src/main/java/dev/isxander/controlify/api/ingameguide/IngameGuideContext.java +++ b/src/main/java/dev/isxander/controlify/api/ingameguide/IngameGuideContext.java @@ -6,6 +6,15 @@ import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.world.phys.HitResult; +/** + * All information available to a guide entry. + * This may be added over time. + * @param client the minecraft client + * @param player local player + * @param level the current world + * @param hitResult where the player is currently looking + * @param controller the controller for this guide renderer + */ public record IngameGuideContext(Minecraft client, LocalPlayer player, ClientLevel level, diff --git a/src/main/java/dev/isxander/controlify/api/ingameinput/LookInputModifier.java b/src/main/java/dev/isxander/controlify/api/ingameinput/LookInputModifier.java index a7f813a..7c0b6c1 100644 --- a/src/main/java/dev/isxander/controlify/api/ingameinput/LookInputModifier.java +++ b/src/main/java/dev/isxander/controlify/api/ingameinput/LookInputModifier.java @@ -6,15 +6,49 @@ import dev.isxander.controlify.ingame.InGameInputHandler; import java.util.function.BiFunction; import java.util.function.BooleanSupplier; +/** + * Allows dependants to modify controller look input. + * + * Implementing classes must provide methods for modifying the x + * and y axis values of the controller's look input. + */ public interface LookInputModifier { + + /** + * Modifies the x axis value of the controller's look input. + * + * @param x the current value of the x axis, typically in the range 0-1 but can be higher from gyro input + * @param controller the current active controller + * @return the modified value of the x axis + */ float modifyX(float x, Controller controller); + /** + * Modifies the y axis value of the controller's look input. + * + * @param y the current value of the y axis, typically in the range 0-1 but can be higher from gyro input + * @param controller the current active controller + * @return the modified value of the y axis + */ float modifyY(float y, Controller controller); + /** + * Creates a new LookInputModifier using the given x and y axis modifying functions. + * + * @param x the function for modifying the x axis + * @param y the function for modifying the y axis + * @return the new LookInputModifier object + */ static LookInputModifier functional(BiFunction, Float> x, BiFunction, Float> y) { return new InGameInputHandler.FunctionalLookInputModifier(x, y); } + /** + * Creates a new LookInputModifier that sets the x and y axis to zero if the given condition is true. + * + * @param condition the condition that determines whether to set the axis values to zero + * @return the new LookInputModifier object + */ static LookInputModifier zeroIf(BooleanSupplier condition) { return functional((x, controller) -> condition.getAsBoolean() ? 0 : x, (y, controller) -> condition.getAsBoolean() ? 0 : y); } diff --git a/src/main/java/dev/isxander/controlify/bindings/ControllerBindings.java b/src/main/java/dev/isxander/controlify/bindings/ControllerBindings.java index ede91f6..448000a 100644 --- a/src/main/java/dev/isxander/controlify/bindings/ControllerBindings.java +++ b/src/main/java/dev/isxander/controlify/bindings/ControllerBindings.java @@ -339,7 +339,7 @@ public class ControllerBindings { registerModdedKeybinds(); - ControlifyEvents.CONTROLLER_STATE_UPDATED.register(this::onControllerUpdate); + ControlifyEvents.CONTROLLER_STATE_UPDATE.register(this::onControllerUpdate); ControlifyEvents.INPUT_MODE_CHANGED.register(mode -> KeyMapping.releaseAll()); } diff --git a/src/main/java/dev/isxander/controlify/config/gui/ControllerBindHandler.java b/src/main/java/dev/isxander/controlify/config/gui/ControllerBindHandler.java new file mode 100644 index 0000000..6d96f2b --- /dev/null +++ b/src/main/java/dev/isxander/controlify/config/gui/ControllerBindHandler.java @@ -0,0 +1,21 @@ +package dev.isxander.controlify.config.gui; + +import dev.isxander.controlify.api.event.ControlifyEvents; + +public class ControllerBindHandler { + public static ControlifyEvents.ControllerStateUpdate CURRENT_BIND_LISTENER = controller -> {}; + + public static void setBindListener(ControlifyEvents.ControllerStateUpdate listener) { + CURRENT_BIND_LISTENER = listener; + } + + public static void clearBindListener() { + CURRENT_BIND_LISTENER = controller -> {}; + } + + public static void setup() { + ControlifyEvents.CONTROLLER_STATE_UPDATE.register(controller -> { + CURRENT_BIND_LISTENER.onControllerStateUpdate(controller); + }); + } +} diff --git a/src/main/java/dev/isxander/controlify/config/gui/GamepadBindController.java b/src/main/java/dev/isxander/controlify/config/gui/GamepadBindController.java index b0c340a..965805f 100644 --- a/src/main/java/dev/isxander/controlify/config/gui/GamepadBindController.java +++ b/src/main/java/dev/isxander/controlify/config/gui/GamepadBindController.java @@ -1,6 +1,7 @@ package dev.isxander.controlify.config.gui; import com.mojang.blaze3d.vertex.PoseStack; +import dev.isxander.controlify.api.event.ControlifyEvents; import dev.isxander.controlify.bindings.GamepadBind; import dev.isxander.controlify.bindings.GamepadBinds; import dev.isxander.controlify.bindings.IBind; @@ -42,8 +43,9 @@ public class GamepadBindController implements Controller> { return new BindButtonWidget(this, yaclScreen, dimension); } - public static class BindButtonWidget extends ControllerWidget implements ComponentProcessor { + public static class BindButtonWidget extends ControllerWidget implements ComponentProcessor, ControlifyEvents.ControllerStateUpdate { private boolean awaitingControllerInput = false; + private boolean justTookInput = false; private final Component awaitingText = Component.translatable("controlify.gui.bind_input_awaiting").withStyle(ChatFormatting.ITALIC); public BindButtonWidget(GamepadBindController control, YACLScreen screen, Dimension dim) { @@ -64,6 +66,7 @@ public class GamepadBindController implements Controller> { public boolean keyPressed(int keyCode, int scanCode, int modifiers) { if (isFocused() && keyCode == GLFW.GLFW_KEY_ENTER && !awaitingControllerInput) { awaitingControllerInput = true; + ControllerBindHandler.setBindListener(this); return true; } @@ -74,6 +77,7 @@ public class GamepadBindController implements Controller> { public boolean mouseClicked(double mouseX, double mouseY, int button) { if (getDimension().isPointInside((int)mouseX, (int)mouseY)) { awaitingControllerInput = true; + ControllerBindHandler.setBindListener(this); return true; } @@ -85,10 +89,23 @@ public class GamepadBindController implements Controller> { if (controller != control.controller) return true; if (controller.bindings().GUI_PRESS.justPressed() && !awaitingControllerInput) { + ControllerBindHandler.setBindListener(this); return awaitingControllerInput = true; } - if (!awaitingControllerInput) return false; + if (justTookInput) { + justTookInput = false; + return true; + } + + return false; + } + + @Override + public void onControllerStateUpdate(dev.isxander.controlify.controller.Controller controller) { + if (controller != control.controller) return; + + if (!awaitingControllerInput) return; var gamepad = control.controller; @@ -97,17 +114,16 @@ public class GamepadBindController implements Controller> { if (bind.held(gamepad.state()) && !bind.held(gamepad.prevState())) { control.option().requestSet(bind); awaitingControllerInput = false; - gamepad.consumeButtonState(); - return true; + justTookInput = true; + ControllerBindHandler.clearBindListener(); + return; } } - - return false; } @Override public boolean overrideControllerNavigation(ScreenProcessor screen, dev.isxander.controlify.controller.Controller controller) { - return awaitingControllerInput; + return awaitingControllerInput || justTookInput; } @Override diff --git a/src/main/java/dev/isxander/controlify/config/gui/JoystickBindController.java b/src/main/java/dev/isxander/controlify/config/gui/JoystickBindController.java index 837380a..7489b3c 100644 --- a/src/main/java/dev/isxander/controlify/config/gui/JoystickBindController.java +++ b/src/main/java/dev/isxander/controlify/config/gui/JoystickBindController.java @@ -1,6 +1,7 @@ package dev.isxander.controlify.config.gui; import com.mojang.blaze3d.vertex.PoseStack; +import dev.isxander.controlify.api.event.ControlifyEvents; import dev.isxander.controlify.bindings.*; import dev.isxander.controlify.controller.joystick.JoystickController; import dev.isxander.controlify.controller.joystick.SingleJoystickController; @@ -41,8 +42,9 @@ public class JoystickBindController implements Controller> return new BindButtonWidget(this, yaclScreen, dimension); } - public static class BindButtonWidget extends ControllerWidget implements ComponentProcessor { + public static class BindButtonWidget extends ControllerWidget implements ComponentProcessor, ControlifyEvents.ControllerStateUpdate { private boolean awaitingControllerInput = false; + private boolean justTookInput = false; private final Component awaitingText = Component.translatable("controlify.gui.bind_input_awaiting").withStyle(ChatFormatting.ITALIC); public BindButtonWidget(JoystickBindController control, YACLScreen screen, Dimension dim) { @@ -63,6 +65,7 @@ public class JoystickBindController implements Controller> public boolean keyPressed(int keyCode, int scanCode, int modifiers) { if (isFocused() && keyCode == GLFW.GLFW_KEY_ENTER && !awaitingControllerInput) { awaitingControllerInput = true; + ControllerBindHandler.setBindListener(this); return true; } @@ -73,6 +76,7 @@ public class JoystickBindController implements Controller> public boolean mouseClicked(double mouseX, double mouseY, int button) { if (getDimension().isPointInside((int)mouseX, (int)mouseY)) { awaitingControllerInput = true; + ControllerBindHandler.setBindListener(this); return true; } @@ -83,11 +87,25 @@ public class JoystickBindController implements Controller> public boolean overrideControllerButtons(ScreenProcessor screen, dev.isxander.controlify.controller.Controller controller) { if (controller != control.controller) return true; - if (controller.bindings().GUI_PRESS.justPressed() && !awaitingControllerInput) { - return awaitingControllerInput = true; + if (justTookInput) { + justTookInput = false; + return true; } - if (!awaitingControllerInput) return false; + if (controller.bindings().GUI_PRESS.justPressed() && !awaitingControllerInput) { + awaitingControllerInput = true; + ControllerBindHandler.setBindListener(this); + return true; + } + + return awaitingControllerInput; + } + + @Override + public void onControllerStateUpdate(dev.isxander.controlify.controller.Controller controller) { + if (controller != control.controller) return; + + if (!awaitingControllerInput) return; var joystick = control.controller; @@ -98,7 +116,9 @@ public class JoystickBindController implements Controller> if (state.buttons().get(i) && !prevState.buttons().get(i)) { control.option().requestSet(new JoystickButtonBind(joystick, i)); awaitingControllerInput = false; - return true; + justTookInput = true; + ControllerBindHandler.clearBindListener(); + return; } } @@ -111,11 +131,15 @@ public class JoystickBindController implements Controller> if (axis > activationThreshold) { control.option().requestSet(new JoystickAxisBind(joystick, i, JoystickAxisBind.AxisDirection.POSITIVE)); awaitingControllerInput = false; - return true; + justTookInput = true; + ControllerBindHandler.clearBindListener(); + return; } else if (axis < -activationThreshold) { control.option().requestSet(new JoystickAxisBind(joystick, i, JoystickAxisBind.AxisDirection.NEGATIVE)); awaitingControllerInput = false; - return true; + justTookInput = true; + ControllerBindHandler.clearBindListener(); + return; } } } @@ -127,16 +151,16 @@ public class JoystickBindController implements Controller> if (prevHat.isCentered() && !hat.isCentered()) { control.option().requestSet(new JoystickHatBind(joystick, i, hat)); awaitingControllerInput = false; - return true; + justTookInput = true; + ControllerBindHandler.clearBindListener(); + return; } } - - return false; } @Override public boolean overrideControllerNavigation(ScreenProcessor screen, dev.isxander.controlify.controller.Controller controller) { - return awaitingControllerInput; + return awaitingControllerInput || justTookInput; } @Override diff --git a/src/main/java/dev/isxander/controlify/controller/joystick/JoystickState.java b/src/main/java/dev/isxander/controlify/controller/joystick/JoystickState.java index 330101c..e2cf962 100644 --- a/src/main/java/dev/isxander/controlify/controller/joystick/JoystickState.java +++ b/src/main/java/dev/isxander/controlify/controller/joystick/JoystickState.java @@ -73,15 +73,8 @@ public class JoystickState implements ControllerState { } public static JoystickState fromJoystick(JoystickController joystick, int joystickId) { - if (DebugProperties.PRINT_JOY_INPUT_COUNT) - Controlify.LOGGER.info("Printing joy input for " + joystick.name()); - FloatBuffer axesBuffer = GLFW.glfwGetJoystickAxes(joystickId); float[] inAxes = new float[axesBuffer.limit()]; - - if (DebugProperties.PRINT_JOY_INPUT_COUNT) - Controlify.LOGGER.info("Axes count = " + inAxes.length); - { int i = 0; while (axesBuffer.hasRemaining()) { @@ -92,10 +85,6 @@ public class JoystickState implements ControllerState { ByteBuffer buttonBuffer = GLFW.glfwGetJoystickButtons(joystickId); boolean[] inButtons = new boolean[buttonBuffer.limit()]; - - if (DebugProperties.PRINT_JOY_INPUT_COUNT) - Controlify.LOGGER.info("Button count = " + inButtons.length); - { int i = 0; while (buttonBuffer.hasRemaining()) { @@ -106,10 +95,6 @@ public class JoystickState implements ControllerState { ByteBuffer hatBuffer = GLFW.glfwGetJoystickHats(joystickId); HatState[] inHats = new HatState[hatBuffer.limit()]; - - if (DebugProperties.PRINT_JOY_INPUT_COUNT) - Controlify.LOGGER.info("Hat count = " + inHats.length); - { int i = 0; while (hatBuffer.hasRemaining()) { @@ -139,12 +124,22 @@ public class JoystickState implements ControllerState { var axis = axes[i]; float state = axis.getAxis(data); rawAxes.add(state); - deadzoneAxes.add(axis.requiresDeadzone() ? ControllerUtils.deadzone(state, i) : state); + deadzoneAxes.add(axis.requiresDeadzone() + ? ControllerUtils.deadzone(state, joystick.config().getDeadzone(i)) + : state + ); } List buttons = Arrays.stream(mapping.buttons()).map(button -> button.isPressed(data)).toList(); List hats = Arrays.stream(mapping.hats()).map(hat -> hat.getHatState(data)).toList(); + if (DebugProperties.PRINT_JOY_STATE) { + Controlify.LOGGER.info("Printing joystick state for controller {}", joystick); + Controlify.LOGGER.info(Arrays.stream(axes).map(axis -> axis.name().getString() + ": " + axis.getAxis(data)).toList().toString()); + Controlify.LOGGER.info(Arrays.stream(mapping.buttons()).map(button -> button.name().getString() + ": " + button.isPressed(data)).toList().toString()); + Controlify.LOGGER.info(Arrays.stream(mapping.hats()).map(hat -> hat.name().getString() + ": " + hat.getHatState(data)).toList().toString()); + } + return new JoystickState(joystick.mapping(), deadzoneAxes, rawAxes, buttons, hats); } diff --git a/src/main/java/dev/isxander/controlify/debug/DebugProperties.java b/src/main/java/dev/isxander/controlify/debug/DebugProperties.java index 6e50f34..85a57cd 100644 --- a/src/main/java/dev/isxander/controlify/debug/DebugProperties.java +++ b/src/main/java/dev/isxander/controlify/debug/DebugProperties.java @@ -15,7 +15,7 @@ public class DebugProperties { /* Forces all gamepads to be treated as a regular joystick */ public static final boolean FORCE_JOYSTICK = boolProp("controlify.debug.force_joystick", false, false); /* Prints joystick input counts for making joystick mappings */ - public static final boolean PRINT_JOY_INPUT_COUNT = boolProp("controlify.debug.print_joy_input_count", false, false); + public static final boolean PRINT_JOY_STATE = boolProp("controlify.debug.print_joy_state", false, false); /* Print gyro data if supported */ public static final boolean PRINT_GYRO = boolProp("controlify.debug.print_gyro", false, false); diff --git a/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java b/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java index 344cf19..ec76b57 100644 --- a/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java @@ -50,7 +50,7 @@ public abstract class MinecraftMixin { @Inject(method = "runTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MouseHandler;turnPlayer()V")) private void doPlayerLook(boolean tick, CallbackInfo ci) { - Controlify.instance().inGameInputHandler().processPlayerLook(getDeltaFrameTime()); + Controlify.instance().inGameInputHandler().ifPresent(ih -> ih.processPlayerLook(getDeltaFrameTime())); } @Inject(method = "", at = @At("TAIL")) diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/guide/ingame/GuiMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/guide/ingame/GuiMixin.java index bec29bb..ff1334e 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/guide/ingame/GuiMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/guide/ingame/GuiMixin.java @@ -2,6 +2,8 @@ package dev.isxander.controlify.mixins.feature.guide.ingame; import com.mojang.blaze3d.vertex.PoseStack; import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.ingame.InGameInputHandler; +import dev.isxander.controlify.ingame.guide.InGameButtonGuide; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import org.spongepowered.asm.mixin.Final; @@ -20,17 +22,15 @@ public class GuiMixin { @Inject(method = "render", at = @At(value = "CONSTANT", args = "stringValue=chat")) private void renderButtonGuide(PoseStack matrices, float tickDelta, CallbackInfo ci) { - if (Controlify.instance().inGameButtonGuide() != null) { + Controlify.instance().inGameButtonGuide().ifPresent(guide -> { minecraft.getProfiler().push("controlify_button_guide"); - Controlify.instance().inGameButtonGuide().renderHud(matrices, tickDelta, screenWidth, screenHeight); + guide.renderHud(matrices, tickDelta, screenWidth, screenHeight); minecraft.getProfiler().pop(); - } + }); } @Inject(method = "tick()V", at = @At("RETURN")) private void tickButtonGuide(CallbackInfo ci) { - if (Controlify.instance().inGameButtonGuide() != null) { - Controlify.instance().inGameButtonGuide().tick(); - } + Controlify.instance().inGameButtonGuide().ifPresent(InGameButtonGuide::tick); } }