1
0
forked from Clones/Controlify

better theme handling and better mouse hide handling (still not perfect)

This commit is contained in:
isXander
2023-02-03 20:57:42 +00:00
parent c9b0870af3
commit ee774dcfee
14 changed files with 94 additions and 84 deletions

View File

@ -48,8 +48,8 @@ public class Controlify {
controllerHIDService.start();
// load after initial controller discovery
config().load();
config().load(); // load after initial controller discovery
config().save(); // save new controller configs if they don't exist
// listen for new controllers
GLFW.glfwSetJoystickCallback((jid, event) -> {
@ -148,7 +148,8 @@ public class Controlify {
this.currentInputMode = currentInputMode;
var minecraft = Minecraft.getInstance();
hideMouse(currentInputMode == InputMode.CONTROLLER);
if (!minecraft.mouseHandler.isMouseGrabbed())
hideMouse(currentInputMode == InputMode.CONTROLLER);
if (minecraft.screen != null) {
ScreenProcessorProvider.provide(minecraft.screen).onInputModeChanged(currentInputMode);
}
@ -170,7 +171,7 @@ public class Controlify {
if (hide && !virtualMouseHandler().isVirtualMouseEnabled()) {
// stop mouse hovering over last element before hiding cursor but don't actually move it
// so when the user switches back to mouse it will be in the same place
mouseHandlerAccessor.invokeOnMove(minecraft.getWindow().getWindow(), 0, 0);
mouseHandlerAccessor.invokeOnMove(minecraft.getWindow().getWindow(), -50, -50);
}
}
}

View File

@ -47,7 +47,7 @@ public enum Bind {
}
public ResourceLocation textureLocation(Controller controller) {
return new ResourceLocation("controlify", "textures/gui/buttons/" + controller.config().theme.id(controller) + "/" + identifier + ".png");
return new ResourceLocation("controlify", "textures/gui/buttons/" + controller.config().theme.id() + "/" + identifier + ".png");
}
public static Bind fromIdentifier(String identifier) {

View File

@ -1,28 +0,0 @@
package dev.isxander.controlify.bindings;
import dev.isxander.controlify.controller.Controller;
import dev.isxander.yacl.api.NameableEnum;
import net.minecraft.network.chat.Component;
import java.util.function.Function;
public enum ControllerTheme implements NameableEnum {
AUTO(c -> c.type().theme().id(c)),
XBOX_ONE(c -> "xbox"),
DUALSHOCK4(c -> "dualshock4");
private final Function<Controller, String> idGetter;
ControllerTheme(Function<Controller, String> idGetter) {
this.idGetter = idGetter;
}
public String id(Controller controller) {
return idGetter.apply(controller);
}
@Override
public Component getDisplayName() {
return Component.translatable("controlify.controller_theme." + name().toLowerCase());
}
}

View File

@ -3,7 +3,6 @@ package dev.isxander.controlify.config;
import com.google.gson.*;
import dev.isxander.controlify.Controlify;
import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.controller.ControllerConfig;
import net.fabricmc.loader.api.FabricLoader;
import java.io.IOException;
@ -93,7 +92,7 @@ public class ControlifyConfig {
}
private void applyControllerConfig(Controller controller, JsonObject object) {
controller.setConfig(GSON.fromJson(object.getAsJsonObject("config"), ControllerConfig.class));
controller.setConfig(GSON.fromJson(object.getAsJsonObject("config"), Controller.ControllerConfig.class));
controller.bindings().fromJson(object.getAsJsonObject("bindings"));
}

View File

@ -2,19 +2,17 @@ package dev.isxander.controlify.config.gui;
import dev.isxander.controlify.Controlify;
import dev.isxander.controlify.bindings.Bind;
import dev.isxander.controlify.bindings.ControllerTheme;
import dev.isxander.controlify.config.GlobalSettings;
import dev.isxander.controlify.controller.ControllerTheme;
import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.controller.ControllerConfig;
import dev.isxander.yacl.api.*;
import dev.isxander.yacl.gui.controllers.TickBoxController;
import dev.isxander.yacl.gui.controllers.cycling.CyclingListController;
import dev.isxander.yacl.gui.controllers.cycling.EnumController;
import dev.isxander.yacl.gui.controllers.slider.FloatSliderController;
import dev.isxander.yacl.gui.controllers.slider.IntegerSliderController;
import dev.isxander.yacl.gui.controllers.string.StringController;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.locale.Language;
import net.minecraft.network.chat.Component;
public class YACLHelper {
@ -33,13 +31,6 @@ public class YACLHelper {
.binding(Controlify.instance().currentController(), () -> Controlify.instance().currentController(), v -> Controlify.instance().setCurrentController(v))
.controller(opt -> new CyclingListController<>(opt, Controller.CONTROLLERS.values().stream().filter(Controller::connected).toList(), c -> Component.literal(c.name())))
.instant(true)
.build())
.option(ListOption.createBuilder(String.class)
.name(Component.translatable("controlify.gui.vmouse_screens"))
.tooltip(Component.translatable("controlify.gui.vmouse_screens.tooltip"))
.binding(GlobalSettings.DEFAULT.virtualMouseScreens, () -> controlify.config().globalSettings().virtualMouseScreens, v -> controlify.config().globalSettings().virtualMouseScreens = v)
.controller(StringController::new)
.initial(Language.getInstance().getOrDefault("controlify.gui.vmouse_screens.placeholder"))
.build());
yacl.category(globalCategory.build());
@ -51,7 +42,7 @@ public class YACLHelper {
category.name(Component.literal(customName == null ? controller.name() : customName));
var config = controller.config();
var def = ControllerConfig.DEFAULT;
var def = controller.defaultConfig();
var configGroup = OptionGroup.createBuilder()
.name(Component.translatable("controlify.gui.group.config"))
.tooltip(Component.translatable("controlify.gui.group.config.tooltip"))
@ -108,7 +99,7 @@ public class YACLHelper {
.option(Option.createBuilder(ControllerTheme.class)
.name(Component.translatable("controlify.gui.controller_theme"))
.tooltip(Component.translatable("controlify.gui.controller_theme.tooltip"))
.binding(def.theme, () -> config.theme, v -> config.theme = v)
.binding(controller.type().theme(), () -> config.theme, v -> config.theme = v)
.controller(EnumController::new)
.instant(true)
.build());

View File

@ -1,7 +1,6 @@
package dev.isxander.controlify.controller;
import dev.isxander.controlify.bindings.ControllerBindings;
import dev.isxander.controlify.bindings.ControllerTheme;
import dev.isxander.controlify.controller.hid.HIDIdentifier;
import dev.isxander.controlify.event.ControlifyEvents;
import org.hid4java.HidDevice;
@ -27,7 +26,7 @@ public final class Controller {
private ControllerState prevState = ControllerState.EMPTY;
private final ControllerBindings bindings = new ControllerBindings(this);
private ControllerConfig config = new ControllerConfig();
private ControllerConfig config, defaultConfig;
public Controller(int joystickId, String guid, String name, boolean gamepad, String uid, ControllerType type) {
this.joystickId = joystickId;
@ -36,6 +35,8 @@ public final class Controller {
this.gamepad = gamepad;
this.uid = uid;
this.type = type;
this.config = new ControllerConfig();
this.defaultConfig = new ControllerConfig();
}
public ControllerState state() {
@ -110,6 +111,10 @@ public final class Controller {
return config;
}
public ControllerConfig defaultConfig() {
return defaultConfig;
}
public void setConfig(ControllerConfig config) {
this.config = config;
}
@ -150,4 +155,26 @@ public final class Controller {
return controller;
}
public class ControllerConfig {
public float horizontalLookSensitivity = 1f;
public float verticalLookSensitivity = 0.9f;
public float leftStickDeadzone = 0.2f;
public float rightStickDeadzone = 0.2f;
// not sure if triggers need deadzones
public float leftTriggerDeadzone = 0.0f;
public float rightTriggerDeadzone = 0.0f;
public float leftTriggerActivationThreshold = 0.5f;
public float rightTriggerActivationThreshold = 0.5f;
public int screenRepeatNavigationDelay = 4;
public float virtualMouseSensitivity = 1f;
public ControllerTheme theme = type().theme();
public String customName = null;
}
}

View File

@ -1,28 +0,0 @@
package dev.isxander.controlify.controller;
import dev.isxander.controlify.bindings.ControllerTheme;
public class ControllerConfig {
public static final ControllerConfig DEFAULT = new ControllerConfig();
public float horizontalLookSensitivity = 1f;
public float verticalLookSensitivity = 0.9f;
public float leftStickDeadzone = 0.2f;
public float rightStickDeadzone = 0.2f;
// not sure if triggers need deadzones
public float leftTriggerDeadzone = 0.0f;
public float rightTriggerDeadzone = 0.0f;
public float leftTriggerActivationThreshold = 0.5f;
public float rightTriggerActivationThreshold = 0.5f;
public int screenRepeatNavigationDelay = 4;
public float virtualMouseSensitivity = 1f;
public ControllerTheme theme = ControllerTheme.AUTO;
public String customName = null;
}

View File

@ -0,0 +1,24 @@
package dev.isxander.controlify.controller;
import dev.isxander.yacl.api.NameableEnum;
import net.minecraft.network.chat.Component;
public enum ControllerTheme implements NameableEnum {
XBOX_ONE("xbox"),
DUALSHOCK4("dualshock4");
private final String id;
ControllerTheme(String id) {
this.id = id;
}
public String id() {
return id;
}
@Override
public Component getDisplayName() {
return Component.translatable("controlify.controller_theme." + name().toLowerCase());
}
}

View File

@ -3,7 +3,6 @@ package dev.isxander.controlify.controller;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import dev.isxander.controlify.bindings.ControllerTheme;
import dev.isxander.controlify.controller.hid.HIDIdentifier;
import java.io.InputStreamReader;

View File

@ -2,6 +2,7 @@ package dev.isxander.controlify.mixins.feature.virtualmouse;
import net.minecraft.client.MouseHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(MouseHandler.class)
@ -14,4 +15,7 @@ public interface MouseHandlerAccessor {
@Invoker
void invokeOnScroll(long window, double scrollDeltaX, double scrollDeltaY);
@Accessor
void setMouseGrabbed(boolean mouseGrabbed);
}

View File

@ -0,0 +1,17 @@
package dev.isxander.controlify.mixins.feature.virtualmouse;
import com.llamalad7.mixinextras.injector.WrapWithCondition;
import dev.isxander.controlify.Controlify;
import dev.isxander.controlify.InputMode;
import net.minecraft.client.MouseHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(MouseHandler.class)
public class MouseHandlerMixin {
@WrapWithCondition(method = "releaseMouse", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/InputConstants;grabOrReleaseMouse(JIDD)V"))
private boolean shouldReleaseMouse(long window, int newMouseState, double x, double y) {
// mouse cursor appears for a split second when going into guis on controller input
return Controlify.instance().currentInputMode() != InputMode.CONTROLLER;
}
}

View File

@ -102,7 +102,8 @@ public class VirtualMouseHandler {
GLFW.glfwSetInputMode(minecraft.getWindow().getWindow(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_HIDDEN);
} else if (virtualMouseEnabled) {
disableVirtualMouse();
minecraft.mouseHandler.grabMouse();
minecraft.mouseHandler.grabMouse(); // re-grab mouse after vmouse disable
}
}
@ -127,7 +128,7 @@ public class VirtualMouseHandler {
var scaledY = currentY * (double)this.minecraft.getWindow().getGuiScaledHeight() / (double)this.minecraft.getWindow().getScreenHeight();
matrices.pushPose();
matrices.translate(scaledX, scaledY, 0);
matrices.translate(scaledX, scaledY, 1000f);
matrices.scale(0.5f, 0.5f, 0.5f);
GuiComponent.blit(matrices, -16, -16, 0, 0, 32, 32, 32, 32);
@ -158,6 +159,9 @@ public class VirtualMouseHandler {
public void disableVirtualMouse() {
if (!virtualMouseEnabled) return;
// make sure minecraft doesn't think the mouse is grabbed when it isn't
((MouseHandlerAccessor) minecraft.mouseHandler).setMouseGrabbed(false);
GLFW.glfwSetInputMode(minecraft.getWindow().getWindow(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL);
setMousePosition();
virtualMouseEnabled = false;

View File

@ -41,11 +41,10 @@
"controlify.toast.vmouse_disabled.title": "Virtual Mouse Disabled",
"controlify.toast.vmouse_disabled.description": "Controlify virtual mouse is now disabled for this screen.",
"controlify.toast.controller_connected.title": "Controller Connected",
"controlify.toast.controller_connected.description": "A new controller has just been connected. You can switch to it in Controlify settings.",
"controlify.toast.controller_connected.description": "A new '%s' controller named has just been connected. You can switch to your other controller in Controlify settings.",
"controlify.toast.controller_disconnected.title": "Controller Disconnected",
"controlify.toast.controller_disconnected.description": "'%s' was disconnected.",
"controlify.controller_theme.auto": "Auto",
"controlify.controller_theme.xbox_one": "Xbox",
"controlify.controller_theme.dualshock4": "PS4",

View File

@ -24,6 +24,7 @@
"feature.virtualmouse.GameRendererMixin",
"feature.virtualmouse.KeyboardHandlerAccessor",
"feature.virtualmouse.MinecraftMixin",
"feature.virtualmouse.MouseHandlerAccessor"
"feature.virtualmouse.MouseHandlerAccessor",
"feature.virtualmouse.MouseHandlerMixin"
]
}