1
0
forked from Clones/Controlify

fix binding api not working with generics and iris compat

This commit is contained in:
isXander
2023-02-25 23:27:23 +00:00
parent 05be05bab5
commit 05f863a0d7
36 changed files with 180 additions and 109 deletions

View File

@ -69,6 +69,10 @@ dependencies {
// sodium compat // sodium compat
modImplementation(libs.sodium) modImplementation(libs.sodium)
// iris compat
modImplementation(files("libs/iris-5d0efad3.jar"))
modRuntimeOnly("org.anarres:jcpp:1.4.14")
modRuntimeOnly("io.github.douira:glsl-transformer:2.0.0-pre9")
} }
tasks { tasks {

View File

@ -9,7 +9,7 @@ grgit = "5.0.+"
minecraft = "1.19.4-pre1" minecraft = "1.19.4-pre1"
quilt_mappings = "1" quilt_mappings = "1"
fabric_loader = "0.14.15" fabric_loader = "0.14.16"
fabric_api = "0.74.1+1.19.4" fabric_api = "0.74.1+1.19.4"
mixin_extras = "0.2.0-beta.1" mixin_extras = "0.2.0-beta.1"
yet_another_config_lib = "2.3.0+beta.2+update.1.19.4-SNAPSHOT" yet_another_config_lib = "2.3.0+beta.2+update.1.19.4-SNAPSHOT"
@ -30,6 +30,8 @@ hid4java = { module = "org.hid4java:hid4java", version.ref = "hid4java" }
quilt_json5 = { module = "org.quiltmc:quilt-json5", version.ref = "quilt_json5" } quilt_json5 = { module = "org.quiltmc:quilt-json5", version.ref = "quilt_json5" }
sodium = { module = "me.jellysquid.mods:sodium-fabric", version.ref = "sodium" } sodium = { module = "me.jellysquid.mods:sodium-fabric", version.ref = "sodium" }
test_fabric_loader = { module = "net.fabricmc:fabric-loader-junit", version.ref = "fabric_loader" }
[plugins] [plugins]
loom = { id = "fabric-loom", version.ref = "loom" } loom = { id = "fabric-loom", version.ref = "loom" }
loom_quiltflower = { id = "io.github.juuxel.loom-quiltflower", version.ref = "loom_quiltflower" } loom_quiltflower = { id = "io.github.juuxel.loom-quiltflower", version.ref = "loom_quiltflower" }

Binary file not shown.

View File

@ -1,5 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-all.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

18
gradlew vendored
View File

@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@ -80,10 +80,10 @@ do
esac esac
done done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # This is normally unused
# shellcheck disable=SC2034
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
@ -143,12 +143,16 @@ fi
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
case $MAX_FD in #( case $MAX_FD in #(
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -205,6 +209,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \ org.gradle.wrapper.GradleWrapperMain \
"$@" "$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args. # Use "xargs" to parse quoted args.
# #
# With -n1 it outputs one arg per line, with the quotes and backslashes removed. # With -n1 it outputs one arg per line, with the quotes and backslashes removed.

15
gradlew.bat vendored
View File

@ -14,7 +14,7 @@
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem Gradle startup script for Windows
@ -25,7 +25,8 @@
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd if %ERRORLEVEL% equ 0 goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 set EXIT_CODE=%ERRORLEVEL%
exit /b 1 if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal

BIN
libs/iris-5d0efad3.jar Normal file

Binary file not shown.

View File

@ -8,7 +8,7 @@ import dev.isxander.controlify.gui.screen.ControllerDeadzoneCalibrationScreen;
import dev.isxander.controlify.screenop.ScreenProcessorProvider; import dev.isxander.controlify.screenop.ScreenProcessorProvider;
import dev.isxander.controlify.config.ControlifyConfig; import dev.isxander.controlify.config.ControlifyConfig;
import dev.isxander.controlify.controller.hid.ControllerHIDService; import dev.isxander.controlify.controller.hid.ControllerHIDService;
import dev.isxander.controlify.event.ControlifyEvents; import dev.isxander.controlify.event.ControlifyClientEvents;
import dev.isxander.controlify.ingame.guide.InGameButtonGuide; import dev.isxander.controlify.ingame.guide.InGameButtonGuide;
import dev.isxander.controlify.ingame.InGameInputHandler; import dev.isxander.controlify.ingame.InGameInputHandler;
import dev.isxander.controlify.mixins.feature.virtualmouse.MouseHandlerAccessor; import dev.isxander.controlify.mixins.feature.virtualmouse.MouseHandlerAccessor;
@ -175,12 +175,13 @@ public class Controlify {
if (client.screen != null) { if (client.screen != null) {
ScreenProcessorProvider.provide(client.screen).onControllerUpdate(currentController); ScreenProcessorProvider.provide(client.screen).onControllerUpdate(currentController);
} else { }
if (client.level != null) {
this.inGameInputHandler().inputTick(); this.inGameInputHandler().inputTick();
} }
this.virtualMouseHandler().handleControllerInput(currentController); this.virtualMouseHandler().handleControllerInput(currentController);
ControlifyEvents.CONTROLLER_STATE_UPDATED.invoker().onControllerStateUpdate(currentController); ControlifyClientEvents.CONTROLLER_STATE_UPDATED.invoker().onControllerStateUpdate(currentController);
} }
public ControlifyConfig config() { public ControlifyConfig config() {
@ -257,7 +258,7 @@ public class Controlify {
} }
lastInputSwitchTime = Blaze3D.getTime(); lastInputSwitchTime = Blaze3D.getTime();
ControlifyEvents.INPUT_MODE_CHANGED.invoker().onInputModeChanged(currentInputMode); ControlifyClientEvents.INPUT_MODE_CHANGED.invoker().onInputModeChanged(currentInputMode);
} }
public void hideMouse(boolean hide, boolean moveMouse) { public void hideMouse(boolean hide, boolean moveMouse) {

View File

@ -1,9 +1,8 @@
package dev.isxander.controlify.bindings; package dev.isxander.controlify.bindings;
import dev.isxander.controlify.controller.Controller; import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.controller.ControllerState;
@FunctionalInterface @FunctionalInterface
public interface BindingSupplier<T extends ControllerState> { public interface BindingSupplier {
ControllerBinding<T> get(Controller<T, ?> controller); ControllerBinding<?> get(Controller<?, ?> controller);
} }

View File

@ -5,15 +5,19 @@ import dev.isxander.controlify.Controlify;
import dev.isxander.controlify.InputMode; import dev.isxander.controlify.InputMode;
import dev.isxander.controlify.controller.Controller; import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.controller.ControllerState; import dev.isxander.controlify.controller.ControllerState;
import dev.isxander.controlify.event.ControlifyEvents; import dev.isxander.controlify.event.ControlifyClientEvents;
import dev.isxander.controlify.mixins.feature.bind.KeyMappingAccessor; import dev.isxander.controlify.mixins.feature.bind.KeyMappingAccessor;
import net.minecraft.client.KeyMapping; 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.*; import java.util.*;
import java.util.function.BooleanSupplier;
import java.util.function.Function;
public class ControllerBindings<T extends ControllerState> { public class ControllerBindings<T extends ControllerState> {
private static final Map<ResourceLocation, Function<ControllerBindings<?>, ControllerBinding<?>>> CUSTOM_BINDS = new LinkedHashMap<>();
public final ControllerBinding<T> public final ControllerBinding<T>
WALK_FORWARD, WALK_BACKWARD, WALK_LEFT, WALK_RIGHT, WALK_FORWARD, WALK_BACKWARD, WALK_LEFT, WALK_RIGHT,
LOOK_UP, LOOK_DOWN, LOOK_LEFT, LOOK_RIGHT, LOOK_UP, LOOK_DOWN, LOOK_LEFT, LOOK_RIGHT,
@ -41,7 +45,6 @@ public class ControllerBindings<T extends ControllerState> {
CYCLE_OPT_FORWARD, CYCLE_OPT_BACKWARD; CYCLE_OPT_FORWARD, CYCLE_OPT_BACKWARD;
private final Map<ResourceLocation, ControllerBinding<T>> registry = new LinkedHashMap<>(); private final Map<ResourceLocation, ControllerBinding<T>> registry = new LinkedHashMap<>();
private final Controller<T, ?> controller; private final Controller<T, ?> controller;
public ControllerBindings(Controller<T, ?> controller) { public ControllerBindings(Controller<T, ?> controller) {
@ -95,15 +98,25 @@ public class ControllerBindings<T extends ControllerState> {
register(CYCLE_OPT_FORWARD = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_RIGHT, new ResourceLocation("controlify", "cycle_opt_forward"))); register(CYCLE_OPT_FORWARD = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_RIGHT, new ResourceLocation("controlify", "cycle_opt_forward")));
register(CYCLE_OPT_BACKWARD = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_LEFT, new ResourceLocation("controlify", "cycle_opt_backward"))); register(CYCLE_OPT_BACKWARD = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_LEFT, new ResourceLocation("controlify", "cycle_opt_backward")));
ControlifyEvents.CONTROLLER_BIND_REGISTRY.invoker().onRegisterControllerBinds(this, controller); for (var constructor : CUSTOM_BINDS.values()) {
register((ControllerBinding<T>) constructor.apply(this));
}
ControlifyEvents.CONTROLLER_STATE_UPDATED.register(this::onControllerUpdate); ControlifyClientEvents.CONTROLLER_STATE_UPDATED.register(this::onControllerUpdate);
ControlifyEvents.INPUT_MODE_CHANGED.register(mode -> KeyMapping.releaseAll()); ControlifyClientEvents.INPUT_MODE_CHANGED.register(mode -> KeyMapping.releaseAll());
} }
public BindingSupplier<T> register(ControllerBinding<T> binding) { public ControllerBinding<T> register(ControllerBinding<T> binding) {
registry.put(binding.id(), binding); registry.put(binding.id(), binding);
return controller -> controller.bindings().get(binding.id()); return binding;
}
private ControllerBinding<?> create(GamepadBinds bind, ResourceLocation id) {
return new ControllerBinding<>(controller, bind, id);
}
private ControllerBinding<?> create(GamepadBinds bind, ResourceLocation id, KeyMapping override, BooleanSupplier toggleOverride) {
return new ControllerBinding<>(controller, bind, id, override, toggleOverride);
} }
public ControllerBinding<T> get(ResourceLocation id) { public ControllerBinding<T> get(ResourceLocation id) {
@ -165,4 +178,14 @@ public class ControllerBindings<T extends ControllerState> {
if (binding.justPressed()) KeyMapping.click(vanillaKeyCode); if (binding.justPressed()) KeyMapping.click(vanillaKeyCode);
} }
} }
public static BindingSupplier registerBind(GamepadBinds bind, ResourceLocation id) {
CUSTOM_BINDS.put(id, bindings -> bindings.create(bind, id));
return controller -> controller.bindings().get(id);
}
public static BindingSupplier registerBind(GamepadBinds bind, ResourceLocation id, KeyMapping override, BooleanSupplier toggleOverride) {
CUSTOM_BINDS.put(id, bindings -> bindings.create(bind, id, override, toggleOverride));
return controller -> controller.bindings().get(id);
}
} }

View File

@ -5,7 +5,6 @@ import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import dev.isxander.controlify.controller.Controller; import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.controller.gamepad.BuiltinGamepadTheme; import dev.isxander.controlify.controller.gamepad.BuiltinGamepadTheme;
import dev.isxander.controlify.controller.gamepad.GamepadConfig;
import dev.isxander.controlify.controller.gamepad.GamepadController; import dev.isxander.controlify.controller.gamepad.GamepadController;
import dev.isxander.controlify.controller.gamepad.GamepadState; import dev.isxander.controlify.controller.gamepad.GamepadState;
import dev.isxander.controlify.gui.DrawSize; import dev.isxander.controlify.gui.DrawSize;

View File

@ -2,7 +2,6 @@ package dev.isxander.controlify.bindings;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import dev.isxander.controlify.Controlify;
import dev.isxander.controlify.controller.*; import dev.isxander.controlify.controller.*;
import dev.isxander.controlify.controller.gamepad.GamepadController; import dev.isxander.controlify.controller.gamepad.GamepadController;
import dev.isxander.controlify.controller.joystick.JoystickController; import dev.isxander.controlify.controller.joystick.JoystickController;

View File

@ -11,7 +11,6 @@ import dev.isxander.controlify.controller.joystick.mapping.UnmappedJoystickMappi
import dev.isxander.controlify.gui.DrawSize; import dev.isxander.controlify.gui.DrawSize;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiComponent; import net.minecraft.client.gui.GuiComponent;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import java.util.Objects; import java.util.Objects;

View File

@ -9,7 +9,6 @@ import dev.isxander.controlify.controller.joystick.JoystickState;
import dev.isxander.controlify.gui.DrawSize; import dev.isxander.controlify.gui.DrawSize;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiComponent; import net.minecraft.client.gui.GuiComponent;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import java.util.Objects; import java.util.Objects;

View File

@ -9,7 +9,6 @@ import dev.isxander.controlify.controller.joystick.JoystickState;
import dev.isxander.controlify.gui.DrawSize; import dev.isxander.controlify.gui.DrawSize;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiComponent; import net.minecraft.client.gui.GuiComponent;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import java.util.Objects; import java.util.Objects;

View File

@ -0,0 +1,18 @@
package dev.isxander.controlify.compatibility.iris;
import dev.isxander.controlify.screenop.compat.AbstractSliderComponentProcessor;
import java.util.function.Consumer;
public class BaseOptionElementComponentProcessor extends AbstractSliderComponentProcessor {
private final Consumer<Boolean> cycleMethod;
public BaseOptionElementComponentProcessor(Consumer<Boolean> cycleMethod) {
this.cycleMethod = cycleMethod;
}
@Override
protected void incrementSlider(boolean reverse) {
this.cycleMethod.accept(reverse);
}
}

View File

@ -1,40 +1,18 @@
package dev.isxander.controlify.compatibility.sodium; package dev.isxander.controlify.compatibility.sodium;
import dev.isxander.controlify.controller.Controller; import dev.isxander.controlify.screenop.compat.AbstractSliderComponentProcessor;
import dev.isxander.controlify.screenop.ComponentProcessor;
import dev.isxander.controlify.screenop.ScreenProcessor;
import java.util.function.Consumer; import java.util.function.Consumer;
public class SliderControlProcessor implements ComponentProcessor { public class SliderControlProcessor extends AbstractSliderComponentProcessor {
private final Consumer<Boolean> cycleMethod; private final Consumer<Boolean> cycleMethod;
private int ticksSinceIncrement = 0;
private boolean prevLeft, prevRight;
public SliderControlProcessor(Consumer<Boolean> cycleMethod) { public SliderControlProcessor(Consumer<Boolean> cycleMethod) {
this.cycleMethod = cycleMethod; this.cycleMethod = cycleMethod;
} }
@Override @Override
public boolean overrideControllerButtons(ScreenProcessor<?> screen, Controller<?, ?> controller) { protected void incrementSlider(boolean reverse) {
ticksSinceIncrement++; cycleMethod.accept(reverse);
var left = controller.bindings().CYCLE_OPT_BACKWARD.held();
var right = controller.bindings().CYCLE_OPT_FORWARD.held();
if (left || right) {
if (ticksSinceIncrement > controller.config().screenRepeatNavigationDelay || left != prevLeft || right != prevRight) {
cycleMethod.accept(left);
ticksSinceIncrement = 0;
prevLeft = left;
prevRight = right;
return true;
}
} else {
this.prevLeft = false;
this.prevRight = false;
}
return false;
} }
} }

View File

@ -1,7 +1,6 @@
package dev.isxander.controlify.config; package dev.isxander.controlify.config;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import dev.isxander.controlify.Controlify;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import java.util.List; import java.util.List;

View File

@ -8,7 +8,6 @@ import dev.isxander.controlify.controller.gamepad.GamepadController;
import dev.isxander.controlify.controller.gamepad.GamepadState; import dev.isxander.controlify.controller.gamepad.GamepadState;
import dev.isxander.controlify.screenop.ScreenProcessor; import dev.isxander.controlify.screenop.ScreenProcessor;
import dev.isxander.controlify.screenop.ComponentProcessor; import dev.isxander.controlify.screenop.ComponentProcessor;
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
import dev.isxander.yacl.api.Controller; import dev.isxander.yacl.api.Controller;
import dev.isxander.yacl.api.Option; import dev.isxander.yacl.api.Option;
import dev.isxander.yacl.api.utils.Dimension; import dev.isxander.yacl.api.utils.Dimension;
@ -43,7 +42,7 @@ public class GamepadBindController implements Controller<IBind<GamepadState>> {
return new BindButtonWidget(this, yaclScreen, dimension); return new BindButtonWidget(this, yaclScreen, dimension);
} }
public static class BindButtonWidget extends ControllerWidget<GamepadBindController> implements ComponentProcessorProvider, ComponentProcessor { public static class BindButtonWidget extends ControllerWidget<GamepadBindController> implements ComponentProcessor {
private boolean awaitingControllerInput = false; private boolean awaitingControllerInput = false;
private final Component awaitingText = Component.translatable("controlify.gui.bind_input_awaiting").withStyle(ChatFormatting.ITALIC); private final Component awaitingText = Component.translatable("controlify.gui.bind_input_awaiting").withStyle(ChatFormatting.ITALIC);
@ -81,11 +80,6 @@ public class GamepadBindController implements Controller<IBind<GamepadState>> {
return false; return false;
} }
@Override
public ComponentProcessor componentProcessor() {
return this;
}
@Override @Override
public boolean overrideControllerButtons(ScreenProcessor<?> screen, dev.isxander.controlify.controller.Controller<?, ?> controller) { public boolean overrideControllerButtons(ScreenProcessor<?> screen, dev.isxander.controlify.controller.Controller<?, ?> controller) {
if (controller != control.controller) return true; if (controller != control.controller) return true;

View File

@ -2,12 +2,9 @@ package dev.isxander.controlify.config.gui;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import dev.isxander.controlify.bindings.*; import dev.isxander.controlify.bindings.*;
import dev.isxander.controlify.controller.gamepad.GamepadController;
import dev.isxander.controlify.controller.gamepad.GamepadState;
import dev.isxander.controlify.controller.joystick.JoystickController; import dev.isxander.controlify.controller.joystick.JoystickController;
import dev.isxander.controlify.controller.joystick.JoystickState; import dev.isxander.controlify.controller.joystick.JoystickState;
import dev.isxander.controlify.screenop.ComponentProcessor; import dev.isxander.controlify.screenop.ComponentProcessor;
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
import dev.isxander.controlify.screenop.ScreenProcessor; import dev.isxander.controlify.screenop.ScreenProcessor;
import dev.isxander.yacl.api.Controller; import dev.isxander.yacl.api.Controller;
import dev.isxander.yacl.api.Option; import dev.isxander.yacl.api.Option;
@ -19,8 +16,6 @@ import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.util.ArrayList;
public class JoystickBindController implements Controller<IBind<JoystickState>> { public class JoystickBindController implements Controller<IBind<JoystickState>> {
private final Option<IBind<JoystickState>> option; private final Option<IBind<JoystickState>> option;
private final JoystickController controller; private final JoystickController controller;
@ -45,7 +40,7 @@ public class JoystickBindController implements Controller<IBind<JoystickState>>
return new BindButtonWidget(this, yaclScreen, dimension); return new BindButtonWidget(this, yaclScreen, dimension);
} }
public static class BindButtonWidget extends ControllerWidget<JoystickBindController> implements ComponentProcessorProvider, ComponentProcessor { public static class BindButtonWidget extends ControllerWidget<JoystickBindController> implements ComponentProcessor {
private boolean awaitingControllerInput = false; private boolean awaitingControllerInput = false;
private final Component awaitingText = Component.translatable("controlify.gui.bind_input_awaiting").withStyle(ChatFormatting.ITALIC); private final Component awaitingText = Component.translatable("controlify.gui.bind_input_awaiting").withStyle(ChatFormatting.ITALIC);
@ -83,11 +78,6 @@ public class JoystickBindController implements Controller<IBind<JoystickState>>
return false; return false;
} }
@Override
public ComponentProcessor componentProcessor() {
return this;
}
@Override @Override
public boolean overrideControllerButtons(ScreenProcessor<?> screen, dev.isxander.controlify.controller.Controller<?, ?> controller) { public boolean overrideControllerButtons(ScreenProcessor<?> screen, dev.isxander.controlify.controller.Controller<?, ?> controller) {
if (controller != control.controller) return true; if (controller != control.controller) return true;

View File

@ -10,7 +10,6 @@ import dev.isxander.controlify.controller.gamepad.GamepadState;
import dev.isxander.controlify.controller.gamepad.BuiltinGamepadTheme; import dev.isxander.controlify.controller.gamepad.BuiltinGamepadTheme;
import dev.isxander.controlify.controller.joystick.JoystickController; import dev.isxander.controlify.controller.joystick.JoystickController;
import dev.isxander.controlify.controller.joystick.JoystickState; import dev.isxander.controlify.controller.joystick.JoystickState;
import dev.isxander.controlify.controller.joystick.mapping.UnmappedJoystickMapping;
import dev.isxander.controlify.gui.screen.ControllerDeadzoneCalibrationScreen; import dev.isxander.controlify.gui.screen.ControllerDeadzoneCalibrationScreen;
import dev.isxander.yacl.api.*; import dev.isxander.yacl.api.*;
import dev.isxander.yacl.gui.controllers.ActionController; import dev.isxander.yacl.gui.controllers.ActionController;
@ -24,7 +23,6 @@ import dev.isxander.yacl.gui.controllers.string.StringController;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.Util; import net.minecraft.Util;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.AlertScreen;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;

View File

@ -56,7 +56,7 @@ public abstract class AbstractController<S extends ControllerState, C extends Co
protected void setName(String name) { protected void setName(String name) {
String uniqueName = name; String uniqueName = name;
int i = 0; int i = 0;
while (Controller.CONTROLLERS.values().stream().map(Controller::name).anyMatch(name::equalsIgnoreCase)) { while (CONTROLLERS.values().stream().map(Controller::name).anyMatch(name::equalsIgnoreCase)) {
uniqueName = name + " (" + i++ + ")"; uniqueName = name + " (" + i++ + ")";
} }
this.name = uniqueName; this.name = uniqueName;

View File

@ -1,7 +1,6 @@
package dev.isxander.controlify.controller; package dev.isxander.controlify.controller;
import java.util.List; import java.util.List;
import java.util.Set;
public interface ControllerState { public interface ControllerState {
List<Float> axes(); List<Float> axes();

View File

@ -6,7 +6,6 @@ import org.lwjgl.glfw.GLFW;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
public final class GamepadState implements ControllerState { public final class GamepadState implements ControllerState {
public static final GamepadState EMPTY = new GamepadState(AxesState.EMPTY, AxesState.EMPTY, ButtonState.EMPTY); public static final GamepadState EMPTY = new GamepadState(AxesState.EMPTY, AxesState.EMPTY, ButtonState.EMPTY);

View File

@ -7,7 +7,7 @@ import dev.isxander.controlify.ingame.guide.ButtonGuideRegistry;
import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory; import net.fabricmc.fabric.api.event.EventFactory;
public class ControlifyEvents { public class ControlifyClientEvents {
public static final Event<InputModeChanged> INPUT_MODE_CHANGED = EventFactory.createArrayBacked(InputModeChanged.class, callbacks -> mode -> { public static final Event<InputModeChanged> INPUT_MODE_CHANGED = EventFactory.createArrayBacked(InputModeChanged.class, callbacks -> mode -> {
for (InputModeChanged callback : callbacks) { for (InputModeChanged callback : callbacks) {
callback.onInputModeChanged(mode); callback.onInputModeChanged(mode);
@ -20,12 +20,6 @@ public class ControlifyEvents {
} }
}); });
public static final Event<ControllerBindRegistry> CONTROLLER_BIND_REGISTRY = EventFactory.createArrayBacked(ControllerBindRegistry.class, callbacks -> (bindings, controller) -> {
for (ControllerBindRegistry callback : callbacks) {
callback.onRegisterControllerBinds(bindings, controller);
}
});
public static final Event<ButtonGuideRegistryEvent> BUTTON_GUIDE_REGISTRY = EventFactory.createArrayBacked(ButtonGuideRegistryEvent.class, callbacks -> (bindings, registry) -> { public static final Event<ButtonGuideRegistryEvent> BUTTON_GUIDE_REGISTRY = EventFactory.createArrayBacked(ButtonGuideRegistryEvent.class, callbacks -> (bindings, registry) -> {
for (ButtonGuideRegistryEvent callback : callbacks) { for (ButtonGuideRegistryEvent callback : callbacks) {
callback.onRegisterButtonGuide(bindings, registry); callback.onRegisterButtonGuide(bindings, registry);
@ -48,11 +42,6 @@ public class ControlifyEvents {
void onControllerStateUpdate(Controller<?, ?> controller); void onControllerStateUpdate(Controller<?, ?> controller);
} }
@FunctionalInterface
public interface ControllerBindRegistry {
void onRegisterControllerBinds(ControllerBindings<?> bindings, Controller<?, ?> controller);
}
@FunctionalInterface @FunctionalInterface
public interface ButtonGuideRegistryEvent { public interface ButtonGuideRegistryEvent {
void onRegisterButtonGuide(ControllerBindings<?> bindings, ButtonGuideRegistry registry); void onRegisterButtonGuide(ControllerBindings<?> bindings, ButtonGuideRegistry registry);

View File

@ -10,7 +10,6 @@ import net.minecraft.client.gui.layouts.FrameLayout;
import net.minecraft.client.gui.layouts.GridLayout; import net.minecraft.client.gui.layouts.GridLayout;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.TitleScreen; import net.minecraft.client.gui.screens.TitleScreen;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;

View File

@ -2,7 +2,7 @@ package dev.isxander.controlify.ingame;
import dev.isxander.controlify.InputMode; import dev.isxander.controlify.InputMode;
import dev.isxander.controlify.controller.Controller; import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.event.ControlifyEvents; import dev.isxander.controlify.event.ControlifyClientEvents;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.player.KeyboardInput; import net.minecraft.client.player.KeyboardInput;
@ -16,7 +16,7 @@ public class InGameInputHandler {
this.controller = controller; this.controller = controller;
this.minecraft = Minecraft.getInstance(); this.minecraft = Minecraft.getInstance();
ControlifyEvents.INPUT_MODE_CHANGED.register(mode -> { ControlifyClientEvents.INPUT_MODE_CHANGED.register(mode -> {
if (minecraft.player != null) { if (minecraft.player != null) {
minecraft.player.input = mode == InputMode.CONTROLLER minecraft.player.input = mode == InputMode.CONTROLLER
? new ControllerPlayerMovement(controller, minecraft.player) ? new ControllerPlayerMovement(controller, minecraft.player)

View File

@ -3,7 +3,7 @@ package dev.isxander.controlify.ingame.guide;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import dev.isxander.controlify.bindings.ControllerBinding; import dev.isxander.controlify.bindings.ControllerBinding;
import dev.isxander.controlify.controller.Controller; import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.event.ControlifyEvents; import dev.isxander.controlify.event.ControlifyClientEvents;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiComponent; import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
@ -33,7 +33,7 @@ public class InGameButtonGuide implements ButtonGuideRegistry {
this.player = localPlayer; this.player = localPlayer;
registerDefaultActions(); registerDefaultActions();
ControlifyEvents.BUTTON_GUIDE_REGISTRY.invoker().onRegisterButtonGuide(controller.bindings(), this); ControlifyClientEvents.BUTTON_GUIDE_REGISTRY.invoker().onRegisterButtonGuide(controller.bindings(), this);
} }
public void renderHud(PoseStack poseStack, float tickDelta, int width, int height) { public void renderHud(PoseStack poseStack, float tickDelta, int width, int height) {

View File

@ -0,0 +1,32 @@
package dev.isxander.controlify.mixins.compat.iris;
import dev.isxander.controlify.compatibility.iris.BaseOptionElementComponentProcessor;
import dev.isxander.controlify.screenop.ComponentProcessor;
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
import net.coderbot.iris.gui.NavigationController;
import net.coderbot.iris.gui.element.widget.BaseOptionElementWidget;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@Mixin(BaseOptionElementWidget.class)
public abstract class BaseOptionElementWidgetMixin implements ComponentProcessorProvider {
@Shadow public abstract boolean applyPreviousValue();
@Shadow public abstract boolean applyNextValue();
@Shadow protected NavigationController navigation;
@Unique private final BaseOptionElementComponentProcessor processor
= new BaseOptionElementComponentProcessor(this::cycle);
@Override
public ComponentProcessor componentProcessor() {
return processor;
}
private void cycle(boolean reverse) {
boolean needsUpdate = reverse ? applyPreviousValue() : applyNextValue();
if (needsUpdate) {
navigation.refresh();
}
}
}

View File

@ -1,6 +1,5 @@
package dev.isxander.controlify.mixins.compat.sodium; package dev.isxander.controlify.mixins.compat.sodium;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import dev.isxander.controlify.compatibility.sodium.SliderControlProcessor; import dev.isxander.controlify.compatibility.sodium.SliderControlProcessor;
import dev.isxander.controlify.screenop.ComponentProcessor; import dev.isxander.controlify.screenop.ComponentProcessor;
import dev.isxander.controlify.screenop.ComponentProcessorProvider; import dev.isxander.controlify.screenop.ComponentProcessorProvider;
@ -8,9 +7,7 @@ import me.jellysquid.mods.sodium.client.gui.options.Option;
import me.jellysquid.mods.sodium.client.gui.options.control.ControlElement; import me.jellysquid.mods.sodium.client.gui.options.control.ControlElement;
import me.jellysquid.mods.sodium.client.util.Dim2i; import me.jellysquid.mods.sodium.client.util.Dim2i;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
@Pseudo @Pseudo
@Mixin(targets = "me.jellysquid.mods.sodium.client.gui.options.control.SliderControl$Button", remap = false) @Mixin(targets = "me.jellysquid.mods.sodium.client.gui.options.control.SliderControl$Button", remap = false)

View File

@ -13,6 +13,7 @@ import java.util.function.LongSupplier;
public class GLXMixin { public class GLXMixin {
@Inject(method = "_initGlfw", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwInit()Z", shift = At.Shift.BEFORE)) @Inject(method = "_initGlfw", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwInit()Z", shift = At.Shift.BEFORE))
private static void addInitHints(CallbackInfoReturnable<LongSupplier> cir) { private static void addInitHints(CallbackInfoReturnable<LongSupplier> cir) {
// stops GLFW adding hats to button list (backward compat)
GLFW.glfwInitHint(GLFW.GLFW_JOYSTICK_HAT_BUTTONS, GLFW.GLFW_FALSE); GLFW.glfwInitHint(GLFW.GLFW_JOYSTICK_HAT_BUTTONS, GLFW.GLFW_FALSE);
} }
} }

View File

@ -2,7 +2,7 @@ package dev.isxander.controlify.screenop;
import dev.isxander.controlify.controller.Controller; import dev.isxander.controlify.controller.Controller;
public interface ComponentProcessor { public interface ComponentProcessor extends ComponentProcessorProvider {
ComponentProcessor EMPTY = new ComponentProcessor(){}; ComponentProcessor EMPTY = new ComponentProcessor(){};
default boolean overrideControllerNavigation(ScreenProcessor<?> screen, Controller<?, ?> controller) { default boolean overrideControllerNavigation(ScreenProcessor<?> screen, Controller<?, ?> controller) {
@ -15,4 +15,9 @@ public interface ComponentProcessor {
default void onFocusGained(ScreenProcessor<?> screen, Controller<?, ?> controller) { default void onFocusGained(ScreenProcessor<?> screen, Controller<?, ?> controller) {
} }
@Override
default ComponentProcessor componentProcessor() {
return this;
}
} }

View File

@ -3,7 +3,7 @@ package dev.isxander.controlify.screenop;
import dev.isxander.controlify.Controlify; import dev.isxander.controlify.Controlify;
import dev.isxander.controlify.InputMode; import dev.isxander.controlify.InputMode;
import dev.isxander.controlify.controller.Controller; import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.event.ControlifyEvents; import dev.isxander.controlify.event.ControlifyClientEvents;
import dev.isxander.controlify.mixins.feature.screenop.vanilla.ScreenAccessor; import dev.isxander.controlify.mixins.feature.screenop.vanilla.ScreenAccessor;
import net.minecraft.client.gui.ComponentPath; import net.minecraft.client.gui.ComponentPath;
import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.components.events.GuiEventListener;
@ -20,7 +20,7 @@ public class ScreenProcessor<T extends Screen> {
public ScreenProcessor(T screen) { public ScreenProcessor(T screen) {
this.screen = screen; this.screen = screen;
ControlifyEvents.VIRTUAL_MOUSE_TOGGLED.register(this::onVirtualMouseToggled); ControlifyClientEvents.VIRTUAL_MOUSE_TOGGLED.register(this::onVirtualMouseToggled);
} }
public void onControllerUpdate(Controller<?, ?> controller) { public void onControllerUpdate(Controller<?, ?> controller) {

View File

@ -0,0 +1,35 @@
package dev.isxander.controlify.screenop.compat;
import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.screenop.ComponentProcessor;
import dev.isxander.controlify.screenop.ScreenProcessor;
public abstract class AbstractSliderComponentProcessor implements ComponentProcessor {
private int ticksSinceIncrement = 0;
private boolean prevLeft, prevRight;
@Override
public boolean overrideControllerNavigation(ScreenProcessor<?> screen, Controller<?, ?> controller) {
ticksSinceIncrement++;
var left = controller.bindings().CYCLE_OPT_BACKWARD.held();
var right = controller.bindings().CYCLE_OPT_FORWARD.held();
if (left || right) {
if (ticksSinceIncrement > controller.config().screenRepeatNavigationDelay || left != prevLeft || right != prevRight) {
incrementSlider(left);
ticksSinceIncrement = 0;
prevLeft = left;
prevRight = right;
return true;
}
} else {
this.prevLeft = false;
this.prevRight = false;
}
return false;
}
protected abstract void incrementSlider(boolean reverse);
}

View File

@ -8,10 +8,9 @@ import dev.isxander.controlify.InputMode;
import dev.isxander.controlify.controller.Controller; import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.debug.DebugProperties; import dev.isxander.controlify.debug.DebugProperties;
import dev.isxander.controlify.screenop.ScreenProcessorProvider; import dev.isxander.controlify.screenop.ScreenProcessorProvider;
import dev.isxander.controlify.event.ControlifyEvents; import dev.isxander.controlify.event.ControlifyClientEvents;
import dev.isxander.controlify.mixins.feature.virtualmouse.KeyboardHandlerAccessor; import dev.isxander.controlify.mixins.feature.virtualmouse.KeyboardHandlerAccessor;
import dev.isxander.controlify.mixins.feature.virtualmouse.MouseHandlerAccessor; import dev.isxander.controlify.mixins.feature.virtualmouse.MouseHandlerAccessor;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiComponent; import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.gui.components.toasts.SystemToast; import net.minecraft.client.gui.components.toasts.SystemToast;
@ -49,7 +48,7 @@ public class VirtualMouseHandler {
else else
snapPoints = Set.of(); snapPoints = Set.of();
ControlifyEvents.INPUT_MODE_CHANGED.register(this::onInputModeChanged); ControlifyClientEvents.INPUT_MODE_CHANGED.register(this::onInputModeChanged);
} }
public void handleControllerInput(Controller<?, ?> controller) { public void handleControllerInput(Controller<?, ?> controller) {
@ -241,7 +240,7 @@ public class VirtualMouseHandler {
} }
setMousePosition(); setMousePosition();
ControlifyEvents.VIRTUAL_MOUSE_TOGGLED.invoker().onVirtualMouseToggled(true); ControlifyClientEvents.VIRTUAL_MOUSE_TOGGLED.invoker().onVirtualMouseToggled(true);
} }
public void disableVirtualMouse() { public void disableVirtualMouse() {
@ -257,7 +256,7 @@ public class VirtualMouseHandler {
targetX = currentX = minecraft.mouseHandler.xpos(); targetX = currentX = minecraft.mouseHandler.xpos();
targetY = currentY = minecraft.mouseHandler.ypos(); targetY = currentY = minecraft.mouseHandler.ypos();
ControlifyEvents.VIRTUAL_MOUSE_TOGGLED.invoker().onVirtualMouseToggled(false); ControlifyClientEvents.VIRTUAL_MOUSE_TOGGLED.invoker().onVirtualMouseToggled(false);
} }
private void setMousePosition() { private void setMousePosition() {

View File

@ -4,6 +4,7 @@
"minVersion": "0.8", "minVersion": "0.8",
"compatibilityLevel": "JAVA_17", "compatibilityLevel": "JAVA_17",
"mixins": [ "mixins": [
"compat.iris.BaseOptionElementWidgetMixin",
"compat.sodium.CycleControlElementMixin", "compat.sodium.CycleControlElementMixin",
"compat.sodium.SliderControlElementMixin", "compat.sodium.SliderControlElementMixin",
"compat.sodium.TickBoxControlElementMixin", "compat.sodium.TickBoxControlElementMixin",