forked from Clones/Controlify
better binding api and look sensitivity
This commit is contained in:
@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package dev.isxander.controlify.bindings;
|
||||||
|
|
||||||
|
import dev.isxander.controlify.controller.Controller;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface BindingSupplier {
|
||||||
|
ControllerBinding get(Controller controller);
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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"))
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user