1
0
forked from Clones/Controlify

better binding api and look sensitivity

This commit is contained in:
isXander
2023-02-01 15:04:18 +00:00
parent 4ea05b9dbf
commit b77a5361ad
10 changed files with 64 additions and 36 deletions

View File

@ -1,5 +1,6 @@
package dev.isxander.controlify; package dev.isxander.controlify;
import com.mojang.logging.LogUtils;
import dev.isxander.controlify.compatibility.screen.ScreenProcessorProvider; import dev.isxander.controlify.compatibility.screen.ScreenProcessorProvider;
import dev.isxander.controlify.config.ControlifyConfig; import dev.isxander.controlify.config.ControlifyConfig;
import dev.isxander.controlify.controller.Controller; 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.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import org.slf4j.Logger;
public class Controlify { public class Controlify {
public static final Logger LOGGER = LogUtils.getLogger();
private static Controlify instance = null; private static Controlify instance = null;
private Controller currentController; private Controller currentController;
@ -22,7 +25,7 @@ public class Controlify {
for (int i = 0; i < GLFW.GLFW_JOYSTICK_LAST; i++) { for (int i = 0; i < GLFW.GLFW_JOYSTICK_LAST; i++) {
if (GLFW.glfwJoystickPresent(i)) { if (GLFW.glfwJoystickPresent(i)) {
setCurrentController(Controller.byId(i)); setCurrentController(Controller.byId(i));
System.out.println("Connected: " + currentController.name()); LOGGER.info("Controller found: " + currentController.name());
this.setCurrentInputMode(InputMode.CONTROLLER); this.setCurrentInputMode(InputMode.CONTROLLER);
} }
} }
@ -32,18 +35,17 @@ public class Controlify {
// listen for new controllers // listen for new controllers
GLFW.glfwSetJoystickCallback((jid, event) -> { GLFW.glfwSetJoystickCallback((jid, event) -> {
System.out.println("Event: " + event);
if (event == GLFW.GLFW_CONNECTED) { if (event == GLFW.GLFW_CONNECTED) {
setCurrentController(Controller.byId(jid)); setCurrentController(Controller.byId(jid));
System.out.println("Connected: " + currentController.name()); LOGGER.info("Controller connected: " + currentController.name());
this.setCurrentInputMode(InputMode.CONTROLLER); this.setCurrentInputMode(InputMode.CONTROLLER);
ControlifyConfig.load(); // load config again if a configuration already exists for this controller ControlifyConfig.load(); // load config again if a configuration already exists for this controller
ControlifyConfig.save(); // save config if it doesn't exist ControlifyConfig.save(); // save config if it doesn't exist
} else if (event == GLFW.GLFW_DISCONNECTED) { } 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)); 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); this.setCurrentInputMode(currentController == null ? InputMode.KEYBOARD_MOUSE : InputMode.CONTROLLER);
} }
}); });

View File

@ -0,0 +1,8 @@
package dev.isxander.controlify.bindings;
import dev.isxander.controlify.controller.Controller;
@FunctionalInterface
public interface BindingSupplier {
ControllerBinding get(Controller controller);
}

View File

@ -8,54 +8,56 @@ import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
public class ControllerBindings { public class ControllerBindings {
public final ControllerBinding JUMP, SNEAK, ATTACK, USE, SPRINT, NEXT_SLOT, PREV_SLOT, PAUSE, INVENTORY, CHANGE_PERSPECTIVE, OPEN_CHAT; public final ControllerBinding JUMP, SNEAK, ATTACK, USE, SPRINT, NEXT_SLOT, PREV_SLOT, PAUSE, INVENTORY, CHANGE_PERSPECTIVE, OPEN_CHAT;
private final List<ControllerBinding> registry = new ArrayList<>(); private final Map<ResourceLocation, ControllerBinding> registry = new HashMap<>();
public ControllerBindings(Controller controller) { public ControllerBindings(Controller controller) {
var options = Minecraft.getInstance().options; var options = Minecraft.getInstance().options;
JUMP = register(new ControllerBinding(controller, Bind.A_BUTTON, new ResourceLocation("controlify", "jump"), options.keyJump)); register(JUMP = 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)); register(SNEAK = 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)); register(ATTACK = 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)); register(USE = 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)); register(SPRINT = 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)); register(NEXT_SLOT = 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)); register(PREV_SLOT = new ControllerBinding(controller, Bind.LEFT_BUMPER, new ResourceLocation("controlify", "prev_slot"), null));
PAUSE = register(new ControllerBinding(controller, Bind.START, new ResourceLocation("controlify", "pause"), null)); register(PAUSE = new ControllerBinding(controller, Bind.START, new ResourceLocation("controlify", "pause"), null));
INVENTORY = register(new ControllerBinding(controller, Bind.Y_BUTTON, new ResourceLocation("controlify", "inventory"), options.keyInventory)); register(INVENTORY = 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)); register(CHANGE_PERSPECTIVE = 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(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); ControlifyEvents.CONTROLLER_STATE_UPDATED.register(this::imitateVanillaClick);
} }
public ControllerBinding register(ControllerBinding binding) { public BindingSupplier register(ControllerBinding binding) {
registry.add(binding); registry.put(binding.id(), binding);
return binding; return controller -> controller.bindings().get(binding.id());
} }
public List<ControllerBinding> registry() { public ControllerBinding get(ResourceLocation id) {
return Collections.unmodifiableList(registry); return registry.get(id);
}
public Map<ResourceLocation, ControllerBinding> registry() {
return Collections.unmodifiableMap(registry);
} }
public JsonObject toJson() { public JsonObject toJson() {
JsonObject json = new JsonObject(); JsonObject json = new JsonObject();
for (var binding : registry()) { for (var binding : registry().values()) {
json.addProperty(binding.id().toString(), binding.currentBind().identifier()); json.addProperty(binding.id().toString(), binding.currentBind().identifier());
} }
return json; return json;
} }
public void fromJson(JsonObject json) { public void fromJson(JsonObject json) {
for (var binding : registry()) { for (var binding : registry().values()) {
var bind = json.get(binding.id().toString()); var bind = json.get(binding.id().toString());
if (bind == null) continue; if (bind == null) continue;
binding.setCurrentBind(Bind.fromIdentifier(bind.getAsString())); binding.setCurrentBind(Bind.fromIdentifier(bind.getAsString()));
@ -63,7 +65,7 @@ public class ControllerBindings {
} }
private void imitateVanillaClick(Controller controller) { private void imitateVanillaClick(Controller controller) {
for (var binding : registry()) { for (var binding : registry().values()) {
KeyMapping vanillaKey = binding.override(); KeyMapping vanillaKey = binding.override();
if (vanillaKey == null) continue; if (vanillaKey == null) continue;

View File

@ -4,7 +4,6 @@ import dev.isxander.controlify.Controlify;
import dev.isxander.controlify.InputMode; import dev.isxander.controlify.InputMode;
import dev.isxander.controlify.compatibility.screen.component.ComponentProcessorProvider; import dev.isxander.controlify.compatibility.screen.component.ComponentProcessorProvider;
import dev.isxander.controlify.controller.Controller; import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.controller.ControllerState;
import dev.isxander.controlify.mixins.ScreenAccessor; import dev.isxander.controlify.mixins.ScreenAccessor;
import net.minecraft.client.gui.ComponentPath; import net.minecraft.client.gui.ComponentPath;
import net.minecraft.client.gui.navigation.FocusNavigationEvent; import net.minecraft.client.gui.navigation.FocusNavigationEvent;
@ -28,7 +27,7 @@ public class ScreenProcessor {
handleButtons(controller); handleButtons(controller);
} }
private void handleComponentNavigation(Controller controller) { protected void handleComponentNavigation(Controller controller) {
if (screen.getFocused() != null) { if (screen.getFocused() != null) {
var focused = screen.getFocused(); var focused = screen.getFocused();
var processor = ComponentProcessorProvider.provide(focused); var processor = ComponentProcessorProvider.provide(focused);
@ -67,12 +66,13 @@ public class ScreenProcessor {
ComponentPath path = screen.nextFocusPath(event); ComponentPath path = screen.nextFocusPath(event);
if (path != null) { if (path != null) {
accessor.invokeChangeFocus(path); accessor.invokeChangeFocus(path);
ComponentProcessorProvider.provide(path.component()).onNavigateTo(this, controller);
lastMoved = repeatEventAvailable ? INITIAL_REPEAT_DELAY - REPEAT_DELAY : 0; lastMoved = repeatEventAvailable ? INITIAL_REPEAT_DELAY - REPEAT_DELAY : 0;
} }
} }
} }
private void handleButtons(Controller controller) { protected void handleButtons(Controller controller) {
if (screen.getFocused() != null) { if (screen.getFocused() != null) {
var focused = screen.getFocused(); var focused = screen.getFocused();
var processor = ComponentProcessorProvider.provide(focused); var processor = ComponentProcessorProvider.provide(focused);

View File

@ -23,4 +23,7 @@ public class ComponentProcessor<T extends GuiEventListener> {
public boolean overrideControllerButtons(ScreenProcessor screen, Controller controller) { public boolean overrideControllerButtons(ScreenProcessor screen, Controller controller) {
return false; return false;
} }
public void onNavigateTo(ScreenProcessor screen, Controller controller) {
}
} }

View File

@ -62,4 +62,9 @@ public class SliderComponentProcessor extends ComponentProcessor<AbstractSliderB
return false; return false;
} }
@Override
public void onNavigateTo(ScreenProcessor screen, Controller controller) {
this.canChangeValueSetter.accept(false);
}
} }

View File

@ -29,6 +29,12 @@ public class YACLHelper {
var configGroup = OptionGroup.createBuilder() var configGroup = OptionGroup.createBuilder()
.name(Component.translatable("controlify.gui.group.config")) .name(Component.translatable("controlify.gui.group.config"))
.tooltip(Component.translatable("controlify.gui.group.config.tooltip")) .tooltip(Component.translatable("controlify.gui.group.config.tooltip"))
.option(Option.createBuilder(float.class)
.name(Component.translatable("controlify.gui.look_sensitivity"))
.tooltip(Component.translatable("controlify.gui.look_sensitivity.tooltip"))
.binding(def.lookSensitivity, () -> 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) .option(Option.createBuilder(float.class)
.name(Component.translatable("controlify.gui.left_stick_deadzone")) .name(Component.translatable("controlify.gui.left_stick_deadzone"))
.tooltip(Component.translatable("controlify.gui.left_stick_deadzone.tooltip")) .tooltip(Component.translatable("controlify.gui.left_stick_deadzone.tooltip"))

View File

@ -5,6 +5,8 @@ import dev.isxander.controlify.config.ControlifyConfig;
public class ControllerConfig { public class ControllerConfig {
public static final ControllerConfig DEFAULT = new ControllerConfig(); public static final ControllerConfig DEFAULT = new ControllerConfig();
public float lookSensitivity = 1f;
public float leftStickDeadzone = 0.2f; public float leftStickDeadzone = 0.2f;
public float rightStickDeadzone = 0.2f; public float rightStickDeadzone = 0.2f;

View File

@ -19,9 +19,9 @@ public class ControlifyEvents {
} }
}); });
public static final Event<ControllerBindRegistry> CONTROLLER_BIND_REGISTRY = EventFactory.createArrayBacked(ControllerBindRegistry.class, callbacks -> bindings -> { public static final Event<ControllerBindRegistry> CONTROLLER_BIND_REGISTRY = EventFactory.createArrayBacked(ControllerBindRegistry.class, callbacks -> (bindings, controller) -> {
for (ControllerBindRegistry callback : callbacks) { for (ControllerBindRegistry callback : callbacks) {
callback.onRegisterControllerBinds(bindings); callback.onRegisterControllerBinds(bindings, controller);
} }
}); });
@ -37,6 +37,6 @@ public class ControlifyEvents {
@FunctionalInterface @FunctionalInterface
public interface ControllerBindRegistry { public interface ControllerBindRegistry {
void onRegisterControllerBinds(ControllerBindings bindings); void onRegisterControllerBinds(ControllerBindings bindings, Controller controller);
} }
} }

View File

@ -55,7 +55,7 @@ public class InGameInputHandler {
var delta = time - deltaTime; var delta = time - deltaTime;
deltaTime = time; deltaTime = time;
var sensitivity = 1f * 8f + 2f; var sensitivity = controller.config().lookSensitivity * 8f + 2f;
var sensCubed = sensitivity * sensitivity * sensitivity; var sensCubed = sensitivity * sensitivity * sensitivity;
var dx = accumulatedDX * delta; var dx = accumulatedDX * delta;