diff --git a/src/main/java/dev/isxander/controlify/Controlify.java b/src/main/java/dev/isxander/controlify/Controlify.java index fcb4552..73ee122 100644 --- a/src/main/java/dev/isxander/controlify/Controlify.java +++ b/src/main/java/dev/isxander/controlify/Controlify.java @@ -13,7 +13,6 @@ import dev.isxander.controlify.ingame.guide.InGameButtonGuide; import dev.isxander.controlify.ingame.InGameInputHandler; import dev.isxander.controlify.mixins.feature.virtualmouse.MouseHandlerAccessor; import dev.isxander.controlify.virtualmouse.VirtualMouseHandler; -import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.toasts.SystemToast; @@ -29,14 +28,14 @@ public class Controlify { public static final Logger LOGGER = LogUtils.getLogger(); private static Controlify instance = null; - private Controller currentController; + private Controller currentController = Controller.DUMMY; private InGameInputHandler inGameInputHandler; public InGameButtonGuide inGameButtonGuide; private VirtualMouseHandler virtualMouseHandler; private InputMode currentInputMode; private ControllerHIDService controllerHIDService; - private final ControlifyConfig config = new ControlifyConfig(); + private final ControlifyConfig config = new ControlifyConfig(this); private final Queue> calibrationQueue = new ArrayDeque<>(); @@ -57,25 +56,39 @@ public class Controlify { if (GLFW.glfwJoystickPresent(i)) { int jid = i; controllerHIDService.awaitNextController(device -> { - setCurrentController(Controller.createOrGet(jid, device)); - LOGGER.info("Controller found: " + currentController.name()); + var controller = Controller.createOrGet(jid, device); + LOGGER.info("Controller found: " + controller.name()); - if (!config().loadOrCreateControllerData(currentController)) { - calibrationQueue.add(currentController); + if (config().currentControllerUid().equals(controller.uid())) + setCurrentController(controller); + + if (!config().loadOrCreateControllerData(controller)) { + calibrationQueue.add(controller); } }); } } + controllerHIDService.setOnQueueEmptyEvent(() -> { + if (currentController() == Controller.DUMMY && config().isFirstLaunch()) { + this.setCurrentController(Controller.CONTROLLERS.values().stream().findFirst().orElse(null)); + } + }); + controllerHIDService.start(); // listen for new controllers GLFW.glfwSetJoystickCallback((jid, event) -> { if (event == GLFW.GLFW_CONNECTED) { controllerHIDService.awaitNextController(device -> { - setCurrentController(Controller.createOrGet(jid, device)); - LOGGER.info("Controller connected: " + currentController.name()); - this.setCurrentInputMode(InputMode.CONTROLLER); + var firstController = Controller.CONTROLLERS.values().isEmpty(); + var controller = Controller.createOrGet(jid, device); + LOGGER.info("Controller connected: " + controller.name()); + + if (firstController) { + this.setCurrentController(controller); + this.setCurrentInputMode(InputMode.CONTROLLER); + } if (!config().loadOrCreateControllerData(currentController)) { calibrationQueue.add(currentController); @@ -188,6 +201,12 @@ public class Controlify { if (this.currentController == controller) return; this.currentController = controller; + LOGGER.info("Updated current controller to " + controller.name() + "(" + controller.uid() + ")"); + + if (!config().currentControllerUid().equals(controller.uid())) { + config().save(); + } + this.inGameInputHandler = new InGameInputHandler(controller); if (Minecraft.getInstance().player != null) { this.inGameButtonGuide = new InGameButtonGuide(controller, Minecraft.getInstance().player); diff --git a/src/main/java/dev/isxander/controlify/config/ControlifyConfig.java b/src/main/java/dev/isxander/controlify/config/ControlifyConfig.java index 42298ef..e0a232b 100644 --- a/src/main/java/dev/isxander/controlify/config/ControlifyConfig.java +++ b/src/main/java/dev/isxander/controlify/config/ControlifyConfig.java @@ -20,10 +20,17 @@ public class ControlifyConfig { .registerTypeHierarchyAdapter(Class.class, new ClassTypeAdapter()) .create(); + private final Controlify controlify; + + private String currentControllerUid; private JsonObject controllerData = new JsonObject(); private GlobalSettings globalSettings = new GlobalSettings(); private boolean firstLaunch; + public ControlifyConfig(Controlify controlify) { + this.controlify = controlify; + } + public void save() { Controlify.LOGGER.info("Saving Controlify config..."); @@ -46,8 +53,8 @@ public class ControlifyConfig { try { applyConfig(GSON.fromJson(Files.readString(CONFIG_PATH), JsonObject.class)); - } catch (IOException e) { - throw new IllegalStateException("Failed to load config!", e); + } catch (Exception e) { + Controlify.LOGGER.error("Failed to load Controlify config!", e); } } @@ -63,8 +70,8 @@ public class ControlifyConfig { controllerData = newControllerData; config.add("controllers", controllerData); - config.add("global", GSON.toJsonTree(globalSettings)); + config.addProperty("current_controller", currentControllerUid = controlify.currentController().uid()); return config; } @@ -89,6 +96,12 @@ public class ControlifyConfig { loadOrCreateControllerData(controller); } } + + if (object.has("current_controller")) { + currentControllerUid = object.get("current_controller").getAsString(); + } else { + currentControllerUid = controlify.currentController().uid(); + } } public boolean loadOrCreateControllerData(Controller controller) { @@ -122,4 +135,8 @@ public class ControlifyConfig { public boolean isFirstLaunch() { return firstLaunch; } + + public String currentControllerUid() { + return currentControllerUid; + } } diff --git a/src/main/java/dev/isxander/controlify/config/GlobalSettings.java b/src/main/java/dev/isxander/controlify/config/GlobalSettings.java index 693fbfd..4622dde 100644 --- a/src/main/java/dev/isxander/controlify/config/GlobalSettings.java +++ b/src/main/java/dev/isxander/controlify/config/GlobalSettings.java @@ -1,6 +1,7 @@ package dev.isxander.controlify.config; import com.google.common.collect.Lists; +import dev.isxander.controlify.Controlify; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import java.util.List; diff --git a/src/main/java/dev/isxander/controlify/controller/Controller.java b/src/main/java/dev/isxander/controlify/controller/Controller.java index 2fef521..3d80e78 100644 --- a/src/main/java/dev/isxander/controlify/controller/Controller.java +++ b/src/main/java/dev/isxander/controlify/controller/Controller.java @@ -68,7 +68,7 @@ public interface Controller> deviceQueue; + private Runnable onQueueEmpty = () -> {}; private boolean disabled = false; @@ -59,6 +60,10 @@ public class ControllerHIDService implements HidServicesListener { if (deviceQueue.peek() != null) { try { deviceQueue.poll().accept(device); + + if (deviceQueue.isEmpty()) { + onQueueEmpty.run(); + } } catch (Throwable e) { Controlify.LOGGER.error("Failed to handle controller device attach event.", e); } @@ -75,6 +80,10 @@ public class ControllerHIDService implements HidServicesListener { return isGenericDesktopControlOrGameControl && isController; } + public void setOnQueueEmptyEvent(Runnable runnable) { + this.onQueueEmpty = runnable; + } + public boolean isDisabled() { return disabled; }