1
0
forked from Clones/Controlify

virtual mouse + singleplayer screen compat + 22w05a

This commit is contained in:
isXander
2023-02-02 21:36:44 +00:00
parent 57fcd0c0dc
commit 09628defc4
34 changed files with 697 additions and 111 deletions

View File

@ -7,8 +7,12 @@ import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.controller.ControllerState;
import dev.isxander.controlify.event.ControlifyEvents;
import dev.isxander.controlify.ingame.InGameInputHandler;
import dev.isxander.controlify.mixins.feature.virtualmouse.MouseHandlerAccessor;
import dev.isxander.controlify.virtualmouse.VirtualMouseHandler;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.toasts.SystemToast;
import net.minecraft.network.chat.Component;
import org.lwjgl.glfw.GLFW;
import org.slf4j.Logger;
@ -18,20 +22,24 @@ public class Controlify {
private Controller currentController;
private InGameInputHandler inGameInputHandler;
private VirtualMouseHandler virtualMouseHandler;
private InputMode currentInputMode;
private final ControlifyConfig config = new ControlifyConfig();
public void onInitializeInput() {
Minecraft minecraft = Minecraft.getInstance();
// find already connected controllers
for (int i = 0; i < GLFW.GLFW_JOYSTICK_LAST; i++) {
if (GLFW.glfwJoystickPresent(i)) {
setCurrentController(Controller.byId(i));
LOGGER.info("Controller found: " + currentController.name());
this.setCurrentInputMode(InputMode.CONTROLLER);
}
}
// load after initial controller discovery
ControlifyConfig.load();
config().load();
// listen for new controllers
GLFW.glfwSetJoystickCallback((jid, event) -> {
@ -40,16 +48,32 @@ public class Controlify {
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
config().load(); // load config again if a configuration already exists for this controller
config().save(); // save config if it doesn't exist
minecraft.getToasts().addToast(SystemToast.multiline(
minecraft,
SystemToast.SystemToastIds.PERIODIC_NOTIFICATION,
Component.translatable("controlify.toast.controller_connected.title"),
Component.translatable("controlify.toast.controller_connected.description")
));
} else if (event == GLFW.GLFW_DISCONNECTED) {
var controller = Controller.CONTROLLERS.remove(jid);
setCurrentController(Controller.CONTROLLERS.values().stream().filter(Controller::connected).findFirst().orElse(null));
LOGGER.info("Controller disconnected: " + controller.name());
this.setCurrentInputMode(currentController == null ? InputMode.KEYBOARD_MOUSE : InputMode.CONTROLLER);
minecraft.getToasts().addToast(SystemToast.multiline(
minecraft,
SystemToast.SystemToastIds.PERIODIC_NOTIFICATION,
Component.translatable("controlify.toast.controller_disconnected.title"),
Component.translatable("controlify.toast.controller_disconnected.description", controller.name())
));
}
});
this.virtualMouseHandler = new VirtualMouseHandler();
ClientTickEvents.START_CLIENT_TICK.register(this::tick);
}
@ -69,39 +93,74 @@ public class Controlify {
}
if (client.screen != null) {
ScreenProcessorProvider.provide(client.screen).onControllerUpdate(currentController);
if (!this.virtualMouseHandler().isVirtualMouseEnabled())
ScreenProcessorProvider.provide(client.screen).onControllerUpdate(currentController);
} else {
this.getInGameInputHandler().inputTick();
this.inGameInputHandler().inputTick();
}
this.virtualMouseHandler().handleControllerInput(currentController);
}
public Controller getCurrentController() {
public ControlifyConfig config() {
return config;
}
public Controller currentController() {
return currentController;
}
public void setCurrentController(Controller controller) {
if (this.currentController == controller) return;
this.currentController = controller;
this.inGameInputHandler = new InGameInputHandler(controller);
this.inGameInputHandler = new InGameInputHandler(this.currentController != null ? controller : Controller.DUMMY);
}
public InGameInputHandler getInGameInputHandler() {
public InGameInputHandler inGameInputHandler() {
return inGameInputHandler;
}
public InputMode getCurrentInputMode() {
public VirtualMouseHandler virtualMouseHandler() {
return virtualMouseHandler;
}
public InputMode currentInputMode() {
return currentInputMode;
}
public void setCurrentInputMode(InputMode currentInputMode) {
if (this.currentInputMode == currentInputMode) return;
this.currentInputMode = currentInputMode;
var minecraft = Minecraft.getInstance();
hideMouse(currentInputMode == InputMode.CONTROLLER);
if (minecraft.screen != null) {
ScreenProcessorProvider.provide(minecraft.screen).onInputModeChanged(currentInputMode);
}
ControlifyEvents.INPUT_MODE_CHANGED.invoker().onInputModeChanged(currentInputMode);
}
public static Controlify getInstance() {
public void hideMouse(boolean hide) {
var minecraft = Minecraft.getInstance();
GLFW.glfwSetInputMode(
minecraft.getWindow().getWindow(),
GLFW.GLFW_CURSOR,
hide
? GLFW.GLFW_CURSOR_HIDDEN
: GLFW.GLFW_CURSOR_NORMAL
);
if (minecraft.screen != null) {
var mouseHandlerAccessor = (MouseHandlerAccessor) minecraft.mouseHandler;
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);
}
}
}
public static Controlify instance() {
if (instance == null) instance = new Controlify();
return instance;
}