From b77a5361ad69c3289a502feb0f9d243c2a01a6de Mon Sep 17 00:00:00 2001 From: isXander Date: Wed, 1 Feb 2023 15:04:18 +0000 Subject: [PATCH] better binding api and look sensitivity --- .../dev/isxander/controlify/Controlify.java | 12 +++-- .../controlify/bindings/BindingSupplier.java | 8 +++ .../bindings/ControllerBindings.java | 50 ++++++++++--------- .../compatibility/screen/ScreenProcessor.java | 6 +-- .../screen/component/ComponentProcessor.java | 3 ++ .../component/SliderComponentProcessor.java | 5 ++ .../controlify/config/gui/YACLHelper.java | 6 +++ .../controller/ControllerConfig.java | 2 + .../controlify/event/ControlifyEvents.java | 6 +-- .../controlify/ingame/InGameInputHandler.java | 2 +- 10 files changed, 64 insertions(+), 36 deletions(-) create mode 100644 src/main/java/dev/isxander/controlify/bindings/BindingSupplier.java diff --git a/src/main/java/dev/isxander/controlify/Controlify.java b/src/main/java/dev/isxander/controlify/Controlify.java index 93987b9..642bba3 100644 --- a/src/main/java/dev/isxander/controlify/Controlify.java +++ b/src/main/java/dev/isxander/controlify/Controlify.java @@ -1,5 +1,6 @@ package dev.isxander.controlify; +import com.mojang.logging.LogUtils; import dev.isxander.controlify.compatibility.screen.ScreenProcessorProvider; import dev.isxander.controlify.config.ControlifyConfig; import dev.isxander.controlify.controller.Controller; @@ -9,8 +10,10 @@ import dev.isxander.controlify.ingame.InGameInputHandler; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.minecraft.client.Minecraft; import org.lwjgl.glfw.GLFW; +import org.slf4j.Logger; public class Controlify { + public static final Logger LOGGER = LogUtils.getLogger(); private static Controlify instance = null; private Controller currentController; @@ -22,7 +25,7 @@ public class Controlify { for (int i = 0; i < GLFW.GLFW_JOYSTICK_LAST; i++) { if (GLFW.glfwJoystickPresent(i)) { setCurrentController(Controller.byId(i)); - System.out.println("Connected: " + currentController.name()); + LOGGER.info("Controller found: " + currentController.name()); this.setCurrentInputMode(InputMode.CONTROLLER); } } @@ -32,18 +35,17 @@ public class Controlify { // listen for new controllers GLFW.glfwSetJoystickCallback((jid, event) -> { - System.out.println("Event: " + event); if (event == GLFW.GLFW_CONNECTED) { setCurrentController(Controller.byId(jid)); - System.out.println("Connected: " + currentController.name()); + LOGGER.info("Controller connected: " + currentController.name()); this.setCurrentInputMode(InputMode.CONTROLLER); ControlifyConfig.load(); // load config again if a configuration already exists for this controller ControlifyConfig.save(); // save config if it doesn't exist } else if (event == GLFW.GLFW_DISCONNECTED) { - Controller.CONTROLLERS.remove(jid); + var controller = Controller.CONTROLLERS.remove(jid); setCurrentController(Controller.CONTROLLERS.values().stream().filter(Controller::connected).findFirst().orElse(null)); - System.out.println("Disconnected: " + jid); + LOGGER.info("Controller disconnected: " + controller.name()); this.setCurrentInputMode(currentController == null ? InputMode.KEYBOARD_MOUSE : InputMode.CONTROLLER); } }); diff --git a/src/main/java/dev/isxander/controlify/bindings/BindingSupplier.java b/src/main/java/dev/isxander/controlify/bindings/BindingSupplier.java new file mode 100644 index 0000000..1786522 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/bindings/BindingSupplier.java @@ -0,0 +1,8 @@ +package dev.isxander.controlify.bindings; + +import dev.isxander.controlify.controller.Controller; + +@FunctionalInterface +public interface BindingSupplier { + ControllerBinding get(Controller controller); +} diff --git a/src/main/java/dev/isxander/controlify/bindings/ControllerBindings.java b/src/main/java/dev/isxander/controlify/bindings/ControllerBindings.java index 4bea672..e90fab7 100644 --- a/src/main/java/dev/isxander/controlify/bindings/ControllerBindings.java +++ b/src/main/java/dev/isxander/controlify/bindings/ControllerBindings.java @@ -8,54 +8,56 @@ import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.resources.ResourceLocation; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; public class ControllerBindings { public final ControllerBinding JUMP, SNEAK, ATTACK, USE, SPRINT, NEXT_SLOT, PREV_SLOT, PAUSE, INVENTORY, CHANGE_PERSPECTIVE, OPEN_CHAT; - private final List registry = new ArrayList<>(); + private final Map registry = new HashMap<>(); public ControllerBindings(Controller controller) { var options = Minecraft.getInstance().options; - JUMP = register(new ControllerBinding(controller, Bind.A_BUTTON, new ResourceLocation("controlify", "jump"), options.keyJump)); - SNEAK = register(new ControllerBinding(controller, Bind.RIGHT_STICK, new ResourceLocation("controlify", "sneak"), options.keyShift)); - ATTACK = register(new ControllerBinding(controller, Bind.RIGHT_TRIGGER, new ResourceLocation("controlify", "attack"), options.keyAttack)); - USE = register(new ControllerBinding(controller, Bind.LEFT_TRIGGER, new ResourceLocation("controlify", "use"), options.keyUse)); - SPRINT = register(new ControllerBinding(controller, Bind.LEFT_STICK, new ResourceLocation("controlify", "sprint"), options.keySprint)); - NEXT_SLOT = register(new ControllerBinding(controller, Bind.RIGHT_BUMPER, new ResourceLocation("controlify", "next_slot"), null)); - PREV_SLOT = register(new ControllerBinding(controller, Bind.LEFT_BUMPER, new ResourceLocation("controlify", "prev_slot"), null)); - PAUSE = register(new ControllerBinding(controller, Bind.START, new ResourceLocation("controlify", "pause"), null)); - INVENTORY = register(new ControllerBinding(controller, Bind.Y_BUTTON, new ResourceLocation("controlify", "inventory"), options.keyInventory)); - CHANGE_PERSPECTIVE = register(new ControllerBinding(controller, Bind.BACK, new ResourceLocation("controlify", "change_perspective"), options.keyTogglePerspective)); - OPEN_CHAT = register(new ControllerBinding(controller, Bind.DPAD_UP, new ResourceLocation("controlify", "open_chat"), options.keyChat)); + register(JUMP = new ControllerBinding(controller, Bind.A_BUTTON, new ResourceLocation("controlify", "jump"), options.keyJump)); + register(SNEAK = new ControllerBinding(controller, Bind.RIGHT_STICK, new ResourceLocation("controlify", "sneak"), options.keyShift)); + register(ATTACK = new ControllerBinding(controller, Bind.RIGHT_TRIGGER, new ResourceLocation("controlify", "attack"), options.keyAttack)); + register(USE = new ControllerBinding(controller, Bind.LEFT_TRIGGER, new ResourceLocation("controlify", "use"), options.keyUse)); + register(SPRINT = new ControllerBinding(controller, Bind.LEFT_STICK, new ResourceLocation("controlify", "sprint"), options.keySprint)); + register(NEXT_SLOT = new ControllerBinding(controller, Bind.RIGHT_BUMPER, new ResourceLocation("controlify", "next_slot"), null)); + register(PREV_SLOT = new ControllerBinding(controller, Bind.LEFT_BUMPER, new ResourceLocation("controlify", "prev_slot"), null)); + register(PAUSE = new ControllerBinding(controller, Bind.START, new ResourceLocation("controlify", "pause"), null)); + register(INVENTORY = new ControllerBinding(controller, Bind.Y_BUTTON, new ResourceLocation("controlify", "inventory"), options.keyInventory)); + register(CHANGE_PERSPECTIVE = new ControllerBinding(controller, Bind.BACK, new ResourceLocation("controlify", "change_perspective"), options.keyTogglePerspective)); + register(OPEN_CHAT = new ControllerBinding(controller, Bind.DPAD_UP, new ResourceLocation("controlify", "open_chat"), options.keyChat)); - ControlifyEvents.CONTROLLER_BIND_REGISTRY.invoker().onRegisterControllerBinds(this); + ControlifyEvents.CONTROLLER_BIND_REGISTRY.invoker().onRegisterControllerBinds(this, controller); ControlifyEvents.CONTROLLER_STATE_UPDATED.register(this::imitateVanillaClick); } - public ControllerBinding register(ControllerBinding binding) { - registry.add(binding); - return binding; + public BindingSupplier register(ControllerBinding binding) { + registry.put(binding.id(), binding); + return controller -> controller.bindings().get(binding.id()); } - public List registry() { - return Collections.unmodifiableList(registry); + public ControllerBinding get(ResourceLocation id) { + return registry.get(id); + } + + public Map registry() { + return Collections.unmodifiableMap(registry); } public JsonObject toJson() { JsonObject json = new JsonObject(); - for (var binding : registry()) { + for (var binding : registry().values()) { json.addProperty(binding.id().toString(), binding.currentBind().identifier()); } return json; } public void fromJson(JsonObject json) { - for (var binding : registry()) { + for (var binding : registry().values()) { var bind = json.get(binding.id().toString()); if (bind == null) continue; binding.setCurrentBind(Bind.fromIdentifier(bind.getAsString())); @@ -63,7 +65,7 @@ public class ControllerBindings { } private void imitateVanillaClick(Controller controller) { - for (var binding : registry()) { + for (var binding : registry().values()) { KeyMapping vanillaKey = binding.override(); if (vanillaKey == null) continue; diff --git a/src/main/java/dev/isxander/controlify/compatibility/screen/ScreenProcessor.java b/src/main/java/dev/isxander/controlify/compatibility/screen/ScreenProcessor.java index 421d52d..532b4a7 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/screen/ScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/compatibility/screen/ScreenProcessor.java @@ -4,7 +4,6 @@ import dev.isxander.controlify.Controlify; import dev.isxander.controlify.InputMode; import dev.isxander.controlify.compatibility.screen.component.ComponentProcessorProvider; import dev.isxander.controlify.controller.Controller; -import dev.isxander.controlify.controller.ControllerState; import dev.isxander.controlify.mixins.ScreenAccessor; import net.minecraft.client.gui.ComponentPath; import net.minecraft.client.gui.navigation.FocusNavigationEvent; @@ -28,7 +27,7 @@ public class ScreenProcessor { handleButtons(controller); } - private void handleComponentNavigation(Controller controller) { + protected void handleComponentNavigation(Controller controller) { if (screen.getFocused() != null) { var focused = screen.getFocused(); var processor = ComponentProcessorProvider.provide(focused); @@ -67,12 +66,13 @@ public class ScreenProcessor { ComponentPath path = screen.nextFocusPath(event); if (path != null) { accessor.invokeChangeFocus(path); + ComponentProcessorProvider.provide(path.component()).onNavigateTo(this, controller); lastMoved = repeatEventAvailable ? INITIAL_REPEAT_DELAY - REPEAT_DELAY : 0; } } } - private void handleButtons(Controller controller) { + protected void handleButtons(Controller controller) { if (screen.getFocused() != null) { var focused = screen.getFocused(); var processor = ComponentProcessorProvider.provide(focused); diff --git a/src/main/java/dev/isxander/controlify/compatibility/screen/component/ComponentProcessor.java b/src/main/java/dev/isxander/controlify/compatibility/screen/component/ComponentProcessor.java index ee32ba4..70bb213 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/screen/component/ComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/compatibility/screen/component/ComponentProcessor.java @@ -23,4 +23,7 @@ public class ComponentProcessor { public boolean overrideControllerButtons(ScreenProcessor screen, Controller controller) { return false; } + + public void onNavigateTo(ScreenProcessor screen, Controller controller) { + } } diff --git a/src/main/java/dev/isxander/controlify/compatibility/screen/component/SliderComponentProcessor.java b/src/main/java/dev/isxander/controlify/compatibility/screen/component/SliderComponentProcessor.java index 4df1352..fa96ee3 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/screen/component/SliderComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/compatibility/screen/component/SliderComponentProcessor.java @@ -62,4 +62,9 @@ public class SliderComponentProcessor extends ComponentProcessor config.lookSensitivity, v -> config.lookSensitivity = v) + .controller(opt -> new FloatSliderController(opt, 0.1f, 2f, 0.05f, v -> Component.literal(String.format("%.0f%%", v*100)))) + .build()) .option(Option.createBuilder(float.class) .name(Component.translatable("controlify.gui.left_stick_deadzone")) .tooltip(Component.translatable("controlify.gui.left_stick_deadzone.tooltip")) diff --git a/src/main/java/dev/isxander/controlify/controller/ControllerConfig.java b/src/main/java/dev/isxander/controlify/controller/ControllerConfig.java index ba15e18..735dcc2 100644 --- a/src/main/java/dev/isxander/controlify/controller/ControllerConfig.java +++ b/src/main/java/dev/isxander/controlify/controller/ControllerConfig.java @@ -5,6 +5,8 @@ import dev.isxander.controlify.config.ControlifyConfig; public class ControllerConfig { public static final ControllerConfig DEFAULT = new ControllerConfig(); + public float lookSensitivity = 1f; + public float leftStickDeadzone = 0.2f; public float rightStickDeadzone = 0.2f; diff --git a/src/main/java/dev/isxander/controlify/event/ControlifyEvents.java b/src/main/java/dev/isxander/controlify/event/ControlifyEvents.java index 6ac0a53..7ad8402 100644 --- a/src/main/java/dev/isxander/controlify/event/ControlifyEvents.java +++ b/src/main/java/dev/isxander/controlify/event/ControlifyEvents.java @@ -19,9 +19,9 @@ public class ControlifyEvents { } }); - public static final Event CONTROLLER_BIND_REGISTRY = EventFactory.createArrayBacked(ControllerBindRegistry.class, callbacks -> bindings -> { + public static final Event CONTROLLER_BIND_REGISTRY = EventFactory.createArrayBacked(ControllerBindRegistry.class, callbacks -> (bindings, controller) -> { for (ControllerBindRegistry callback : callbacks) { - callback.onRegisterControllerBinds(bindings); + callback.onRegisterControllerBinds(bindings, controller); } }); @@ -37,6 +37,6 @@ public class ControlifyEvents { @FunctionalInterface public interface ControllerBindRegistry { - void onRegisterControllerBinds(ControllerBindings bindings); + void onRegisterControllerBinds(ControllerBindings bindings, Controller controller); } } diff --git a/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java b/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java index c573707..562c433 100644 --- a/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java +++ b/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java @@ -55,7 +55,7 @@ public class InGameInputHandler { var delta = time - deltaTime; deltaTime = time; - var sensitivity = 1f * 8f + 2f; + var sensitivity = controller.config().lookSensitivity * 8f + 2f; var sensCubed = sensitivity * sensitivity * sensitivity; var dx = accumulatedDX * delta;