forked from Clones/Controlify
small bits
This commit is contained in:
@ -49,7 +49,7 @@ public class YACLHelper {
|
|||||||
.name(Component.translatable("controlify.gui.current_controller"))
|
.name(Component.translatable("controlify.gui.current_controller"))
|
||||||
.tooltip(Component.translatable("controlify.gui.current_controller.tooltip"))
|
.tooltip(Component.translatable("controlify.gui.current_controller.tooltip"))
|
||||||
.binding(Controlify.instance().currentController(), () -> Controlify.instance().currentController(), v -> Controlify.instance().setCurrentController(v))
|
.binding(Controlify.instance().currentController(), () -> Controlify.instance().currentController(), v -> Controlify.instance().setCurrentController(v))
|
||||||
.controller(opt -> new CyclingListController<>(opt, Iterables.concat(List.of(Controller.DUMMY), Controller.CONTROLLERS.values()), c -> Component.literal(c == Controller.DUMMY ? "Disabled" : c.name())))
|
.controller(opt -> new CyclingListController<>(opt, Iterables.concat(List.of(Controller.DUMMY), Controller.CONTROLLERS.values().stream().filter(Controller::canBeUsed).toList()), c -> Component.literal(c == Controller.DUMMY ? "Disabled" : c.name())))
|
||||||
.instant(true)
|
.instant(true)
|
||||||
.build())
|
.build())
|
||||||
.option(Option.createBuilder(boolean.class)
|
.option(Option.createBuilder(boolean.class)
|
||||||
@ -67,189 +67,193 @@ public class YACLHelper {
|
|||||||
yacl.category(globalCategory.build());
|
yacl.category(globalCategory.build());
|
||||||
|
|
||||||
for (var controller : Controller.CONTROLLERS.values()) {
|
for (var controller : Controller.CONTROLLERS.values()) {
|
||||||
// if (controller instanceof JoystickController joystick && joystick.mapping() instanceof UnmappedJoystickMapping) {
|
yacl.category(createControllerCategory(controller));
|
||||||
// // PlaceholderCategory for onboarding
|
|
||||||
// }
|
|
||||||
|
|
||||||
var category = ConfigCategory.createBuilder();
|
|
||||||
|
|
||||||
category.name(Component.literal(controller.name()));
|
|
||||||
|
|
||||||
var config = controller.config();
|
|
||||||
var def = controller.defaultConfig();
|
|
||||||
|
|
||||||
var basicGroup = OptionGroup.createBuilder()
|
|
||||||
.name(Component.translatable("controlify.gui.group.basic"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.group.basic.tooltip"))
|
|
||||||
.option(Option.createBuilder(float.class)
|
|
||||||
.name(Component.translatable("controlify.gui.horizontal_look_sensitivity"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.horizontal_look_sensitivity.tooltip"))
|
|
||||||
.binding(def.horizontalLookSensitivity, () -> config.horizontalLookSensitivity, v -> config.horizontalLookSensitivity = 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)
|
|
||||||
.name(Component.translatable("controlify.gui.vertical_look_sensitivity"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.vertical_look_sensitivity.tooltip"))
|
|
||||||
.binding(def.verticalLookSensitivity, () -> config.verticalLookSensitivity, v -> config.verticalLookSensitivity = v)
|
|
||||||
.controller(opt -> new FloatSliderController(opt, 0.1f, 2f, 0.05f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
|
||||||
.build())
|
|
||||||
.option(Option.createBuilder(boolean.class)
|
|
||||||
.name(Component.translatable("controlify.gui.toggle_sprint"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.toggle_sprint.tooltip"))
|
|
||||||
.binding(def.toggleSprint, () -> config.toggleSprint, v -> config.toggleSprint = v)
|
|
||||||
.controller(opt -> new BooleanController(opt, v -> Component.translatable("controlify.gui.format.hold_toggle." + (v ? "toggle" : "hold")), false))
|
|
||||||
.build())
|
|
||||||
.option(Option.createBuilder(boolean.class)
|
|
||||||
.name(Component.translatable("controlify.gui.toggle_sneak"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.toggle_sneak.tooltip"))
|
|
||||||
.binding(def.toggleSneak, () -> config.toggleSneak, v -> config.toggleSneak = v)
|
|
||||||
.controller(opt -> new BooleanController(opt, v -> Component.translatable("controlify.gui.format.hold_toggle." + (v ? "toggle" : "hold")), false))
|
|
||||||
.build())
|
|
||||||
.option(Option.createBuilder(boolean.class)
|
|
||||||
.name(Component.translatable("controlify.gui.auto_jump"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.auto_jump.tooltip"))
|
|
||||||
.binding(def.autoJump, () -> config.autoJump, v -> config.autoJump = v)
|
|
||||||
.controller(BooleanController::new)
|
|
||||||
.build())
|
|
||||||
.option(Option.createBuilder(boolean.class)
|
|
||||||
.name(Component.translatable("controlify.gui.show_guide"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.show_guide.tooltip"))
|
|
||||||
.binding(def.showGuide, () -> config.showGuide, v -> config.showGuide = v)
|
|
||||||
.controller(TickBoxController::new)
|
|
||||||
.build())
|
|
||||||
.option(Option.createBuilder(float.class)
|
|
||||||
.name(Component.translatable("controlify.gui.vmouse_sensitivity"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.vmouse_sensitivity.tooltip"))
|
|
||||||
.binding(def.virtualMouseSensitivity, () -> config.virtualMouseSensitivity, v -> config.virtualMouseSensitivity = v)
|
|
||||||
.controller(opt -> new FloatSliderController(opt, 0.1f, 2f, 0.05f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
|
||||||
.build());
|
|
||||||
|
|
||||||
if (controller instanceof GamepadController gamepad) {
|
|
||||||
var gamepadConfig = gamepad.config();
|
|
||||||
var defaultGamepadConfig = gamepad.defaultConfig();
|
|
||||||
|
|
||||||
basicGroup.option(Option.createBuilder(BuiltinGamepadTheme.class)
|
|
||||||
.name(Component.translatable("controlify.gui.controller_theme"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.controller_theme.tooltip"))
|
|
||||||
.binding(defaultGamepadConfig.theme, () -> gamepadConfig.theme, v -> gamepadConfig.theme = v)
|
|
||||||
.controller(EnumController::new)
|
|
||||||
.instant(true)
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
basicGroup
|
|
||||||
.option(Option.createBuilder(String.class)
|
|
||||||
.name(Component.translatable("controlify.gui.custom_name"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.custom_name.tooltip"))
|
|
||||||
.binding(def.customName == null ? "" : def.customName, () -> config.customName == null ? "" : config.customName, v -> config.customName = (v.equals("") ? null : v))
|
|
||||||
.controller(StringController::new)
|
|
||||||
.build());
|
|
||||||
category.group(basicGroup.build());
|
|
||||||
|
|
||||||
var advancedGroup = OptionGroup.createBuilder()
|
|
||||||
.name(Component.translatable("controlify.gui.group.advanced"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.group.advanced.tooltip"))
|
|
||||||
.collapsed(true)
|
|
||||||
.option(Option.createBuilder(int.class)
|
|
||||||
.name(Component.translatable("controlify.gui.screen_repeat_navi_delay"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.screen_repeat_navi_delay.tooltip"))
|
|
||||||
.binding(def.screenRepeatNavigationDelay, () -> config.screenRepeatNavigationDelay, v -> config.screenRepeatNavigationDelay = v)
|
|
||||||
.controller(opt -> new IntegerSliderController(opt, 1, 20, 1, v -> Component.translatable("controlify.gui.format.ticks", v)))
|
|
||||||
.build());
|
|
||||||
|
|
||||||
if (controller instanceof GamepadController gamepad) {
|
|
||||||
var gpCfg = gamepad.config();
|
|
||||||
var gpCfgDef = gamepad.defaultConfig();
|
|
||||||
advancedGroup
|
|
||||||
.option(Option.createBuilder(float.class)
|
|
||||||
.name(Component.translatable("controlify.gui.left_stick_deadzone"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.left_stick_deadzone.tooltip"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.stickdrift_warning").withStyle(ChatFormatting.RED))
|
|
||||||
.binding(
|
|
||||||
Math.max(gpCfgDef.leftStickDeadzoneX, gpCfgDef.leftStickDeadzoneY),
|
|
||||||
() -> Math.max(gpCfg.leftStickDeadzoneX, gpCfgDef.leftStickDeadzoneY),
|
|
||||||
v -> gpCfg.leftStickDeadzoneX = gpCfg.leftStickDeadzoneY = v
|
|
||||||
)
|
|
||||||
.controller(opt -> new FloatSliderController(opt, 0, 1, 0.01f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
|
||||||
.build())
|
|
||||||
.option(Option.createBuilder(float.class)
|
|
||||||
.name(Component.translatable("controlify.gui.right_stick_deadzone"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.right_stick_deadzone.tooltip"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.stickdrift_warning").withStyle(ChatFormatting.RED))
|
|
||||||
.binding(
|
|
||||||
Math.max(gpCfgDef.rightStickDeadzoneX, gpCfgDef.rightStickDeadzoneY),
|
|
||||||
() -> Math.max(gpCfg.rightStickDeadzoneX, gpCfgDef.rightStickDeadzoneY),
|
|
||||||
v -> gpCfg.rightStickDeadzoneX = gpCfg.rightStickDeadzoneY = v
|
|
||||||
)
|
|
||||||
.controller(opt -> new FloatSliderController(opt, 0, 1, 0.01f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
|
||||||
.build());
|
|
||||||
} else if (controller instanceof JoystickController joystick) {
|
|
||||||
Collection<Integer> deadzoneAxes = IntStream.range(0, joystick.axisCount())
|
|
||||||
.filter(i -> joystick.mapping().axis(i).requiresDeadzone())
|
|
||||||
.boxed()
|
|
||||||
.collect(Collectors.toMap(
|
|
||||||
i -> joystick.mapping().axis(i).identifier(),
|
|
||||||
i -> i,
|
|
||||||
(x, y) -> x,
|
|
||||||
LinkedHashMap::new
|
|
||||||
))
|
|
||||||
.values();
|
|
||||||
var jsCfg = joystick.config();
|
|
||||||
var jsCfgDef = joystick.defaultConfig();
|
|
||||||
|
|
||||||
for (int i : deadzoneAxes) {
|
|
||||||
advancedGroup.option(Option.createBuilder(float.class)
|
|
||||||
.name(Component.translatable("controlify.gui.joystick_axis_deadzone", joystick.mapping().axis(i).name()))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.joystick_axis_deadzone.tooltip", joystick.mapping().axis(i).name()))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.stickdrift_warning").withStyle(ChatFormatting.RED))
|
|
||||||
.binding(jsCfgDef.getDeadzone(i), () -> jsCfg.getDeadzone(i), v -> jsCfg.setDeadzone(i, v))
|
|
||||||
.controller(opt -> new FloatSliderController(opt, 0, 1, 0.01f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
advancedGroup
|
|
||||||
.option(ButtonOption.createBuilder()
|
|
||||||
.name(Component.translatable("controlify.gui.auto_calibration"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.auto_calibration.tooltip"))
|
|
||||||
.action((screen, button) -> Minecraft.getInstance().setScreen(new ControllerDeadzoneCalibrationScreen(controller, screen)))
|
|
||||||
.controller(ActionController::new)
|
|
||||||
.build())
|
|
||||||
.option(Option.createBuilder(float.class)
|
|
||||||
.name(Component.translatable("controlify.gui.button_activation_threshold"))
|
|
||||||
.tooltip(Component.translatable("controlify.gui.button_activation_threshold.tooltip"))
|
|
||||||
.binding(def.buttonActivationThreshold, () -> config.buttonActivationThreshold, v -> config.buttonActivationThreshold = v)
|
|
||||||
.controller(opt -> new FloatSliderController(opt, 0, 1, 0.05f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
|
||||||
.build());
|
|
||||||
category.group(advancedGroup.build());
|
|
||||||
|
|
||||||
var controlsGroup = OptionGroup.createBuilder()
|
|
||||||
.name(Component.translatable("controlify.gui.group.controls"));
|
|
||||||
if (controller instanceof GamepadController gamepad) {
|
|
||||||
for (var binding : gamepad.bindings().registry().values()) {
|
|
||||||
controlsGroup.option(Option.createBuilder((Class<IBind<GamepadState>>) (Class<?>) IBind.class)
|
|
||||||
.name(binding.name())
|
|
||||||
.binding(binding.defaultBind(), binding::currentBind, binding::setCurrentBind)
|
|
||||||
.controller(opt -> new GamepadBindController(opt, gamepad))
|
|
||||||
.tooltip(binding.description())
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
} else if (controller instanceof JoystickController joystick) {
|
|
||||||
for (var binding : joystick.bindings().registry().values()) {
|
|
||||||
controlsGroup.option(Option.createBuilder((Class<IBind<JoystickState>>) (Class<?>) IBind.class)
|
|
||||||
.name(binding.name())
|
|
||||||
.binding(binding.defaultBind(), binding::currentBind, binding::setCurrentBind)
|
|
||||||
.controller(opt -> new JoystickBindController(opt, joystick))
|
|
||||||
.tooltip(binding.description())
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
category.group(controlsGroup.build());
|
|
||||||
|
|
||||||
yacl.category(category.build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return yacl.build().generateScreen(parent);
|
return yacl.build().generateScreen(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ConfigCategory createControllerCategory(Controller<?, ?> controller) {
|
||||||
|
var category = ConfigCategory.createBuilder();
|
||||||
|
|
||||||
|
category.name(Component.literal(controller.name()));
|
||||||
|
|
||||||
|
if (!controller.canBeUsed()) {
|
||||||
|
category.tooltip(Component.translatable("controlify.gui.controller_unavailable"));
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = controller.config();
|
||||||
|
var def = controller.defaultConfig();
|
||||||
|
|
||||||
|
var basicGroup = OptionGroup.createBuilder()
|
||||||
|
.name(Component.translatable("controlify.gui.group.basic"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.group.basic.tooltip"))
|
||||||
|
.option(Option.createBuilder(float.class)
|
||||||
|
.name(Component.translatable("controlify.gui.horizontal_look_sensitivity"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.horizontal_look_sensitivity.tooltip"))
|
||||||
|
.binding(def.horizontalLookSensitivity, () -> config.horizontalLookSensitivity, v -> config.horizontalLookSensitivity = 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)
|
||||||
|
.name(Component.translatable("controlify.gui.vertical_look_sensitivity"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.vertical_look_sensitivity.tooltip"))
|
||||||
|
.binding(def.verticalLookSensitivity, () -> config.verticalLookSensitivity, v -> config.verticalLookSensitivity = v)
|
||||||
|
.controller(opt -> new FloatSliderController(opt, 0.1f, 2f, 0.05f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
||||||
|
.build())
|
||||||
|
.option(Option.createBuilder(boolean.class)
|
||||||
|
.name(Component.translatable("controlify.gui.toggle_sprint"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.toggle_sprint.tooltip"))
|
||||||
|
.binding(def.toggleSprint, () -> config.toggleSprint, v -> config.toggleSprint = v)
|
||||||
|
.controller(opt -> new BooleanController(opt, v -> Component.translatable("controlify.gui.format.hold_toggle." + (v ? "toggle" : "hold")), false))
|
||||||
|
.build())
|
||||||
|
.option(Option.createBuilder(boolean.class)
|
||||||
|
.name(Component.translatable("controlify.gui.toggle_sneak"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.toggle_sneak.tooltip"))
|
||||||
|
.binding(def.toggleSneak, () -> config.toggleSneak, v -> config.toggleSneak = v)
|
||||||
|
.controller(opt -> new BooleanController(opt, v -> Component.translatable("controlify.gui.format.hold_toggle." + (v ? "toggle" : "hold")), false))
|
||||||
|
.build())
|
||||||
|
.option(Option.createBuilder(boolean.class)
|
||||||
|
.name(Component.translatable("controlify.gui.auto_jump"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.auto_jump.tooltip"))
|
||||||
|
.binding(def.autoJump, () -> config.autoJump, v -> config.autoJump = v)
|
||||||
|
.controller(BooleanController::new)
|
||||||
|
.build())
|
||||||
|
.option(Option.createBuilder(boolean.class)
|
||||||
|
.name(Component.translatable("controlify.gui.show_guide"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.show_guide.tooltip"))
|
||||||
|
.binding(def.showGuide, () -> config.showGuide, v -> config.showGuide = v)
|
||||||
|
.controller(TickBoxController::new)
|
||||||
|
.build())
|
||||||
|
.option(Option.createBuilder(float.class)
|
||||||
|
.name(Component.translatable("controlify.gui.vmouse_sensitivity"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.vmouse_sensitivity.tooltip"))
|
||||||
|
.binding(def.virtualMouseSensitivity, () -> config.virtualMouseSensitivity, v -> config.virtualMouseSensitivity = v)
|
||||||
|
.controller(opt -> new FloatSliderController(opt, 0.1f, 2f, 0.05f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
if (controller instanceof GamepadController gamepad) {
|
||||||
|
var gamepadConfig = gamepad.config();
|
||||||
|
var defaultGamepadConfig = gamepad.defaultConfig();
|
||||||
|
|
||||||
|
basicGroup.option(Option.createBuilder(BuiltinGamepadTheme.class)
|
||||||
|
.name(Component.translatable("controlify.gui.controller_theme"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.controller_theme.tooltip"))
|
||||||
|
.binding(defaultGamepadConfig.theme, () -> gamepadConfig.theme, v -> gamepadConfig.theme = v)
|
||||||
|
.controller(EnumController::new)
|
||||||
|
.instant(true)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
basicGroup
|
||||||
|
.option(Option.createBuilder(String.class)
|
||||||
|
.name(Component.translatable("controlify.gui.custom_name"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.custom_name.tooltip"))
|
||||||
|
.binding(def.customName == null ? "" : def.customName, () -> config.customName == null ? "" : config.customName, v -> config.customName = (v.equals("") ? null : v))
|
||||||
|
.controller(StringController::new)
|
||||||
|
.build());
|
||||||
|
category.group(basicGroup.build());
|
||||||
|
|
||||||
|
var advancedGroup = OptionGroup.createBuilder()
|
||||||
|
.name(Component.translatable("controlify.gui.group.advanced"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.group.advanced.tooltip"))
|
||||||
|
.collapsed(true)
|
||||||
|
.option(Option.createBuilder(int.class)
|
||||||
|
.name(Component.translatable("controlify.gui.screen_repeat_navi_delay"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.screen_repeat_navi_delay.tooltip"))
|
||||||
|
.binding(def.screenRepeatNavigationDelay, () -> config.screenRepeatNavigationDelay, v -> config.screenRepeatNavigationDelay = v)
|
||||||
|
.controller(opt -> new IntegerSliderController(opt, 1, 20, 1, v -> Component.translatable("controlify.gui.format.ticks", v)))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
if (controller instanceof GamepadController gamepad) {
|
||||||
|
var gpCfg = gamepad.config();
|
||||||
|
var gpCfgDef = gamepad.defaultConfig();
|
||||||
|
advancedGroup
|
||||||
|
.option(Option.createBuilder(float.class)
|
||||||
|
.name(Component.translatable("controlify.gui.left_stick_deadzone"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.left_stick_deadzone.tooltip"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.stickdrift_warning").withStyle(ChatFormatting.RED))
|
||||||
|
.binding(
|
||||||
|
Math.max(gpCfgDef.leftStickDeadzoneX, gpCfgDef.leftStickDeadzoneY),
|
||||||
|
() -> Math.max(gpCfg.leftStickDeadzoneX, gpCfgDef.leftStickDeadzoneY),
|
||||||
|
v -> gpCfg.leftStickDeadzoneX = gpCfg.leftStickDeadzoneY = v
|
||||||
|
)
|
||||||
|
.controller(opt -> new FloatSliderController(opt, 0, 1, 0.01f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
||||||
|
.build())
|
||||||
|
.option(Option.createBuilder(float.class)
|
||||||
|
.name(Component.translatable("controlify.gui.right_stick_deadzone"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.right_stick_deadzone.tooltip"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.stickdrift_warning").withStyle(ChatFormatting.RED))
|
||||||
|
.binding(
|
||||||
|
Math.max(gpCfgDef.rightStickDeadzoneX, gpCfgDef.rightStickDeadzoneY),
|
||||||
|
() -> Math.max(gpCfg.rightStickDeadzoneX, gpCfgDef.rightStickDeadzoneY),
|
||||||
|
v -> gpCfg.rightStickDeadzoneX = gpCfg.rightStickDeadzoneY = v
|
||||||
|
)
|
||||||
|
.controller(opt -> new FloatSliderController(opt, 0, 1, 0.01f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
||||||
|
.build());
|
||||||
|
} else if (controller instanceof JoystickController joystick) {
|
||||||
|
Collection<Integer> deadzoneAxes = IntStream.range(0, joystick.axisCount())
|
||||||
|
.filter(i -> joystick.mapping().axis(i).requiresDeadzone())
|
||||||
|
.boxed()
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
i -> joystick.mapping().axis(i).identifier(),
|
||||||
|
i -> i,
|
||||||
|
(x, y) -> x,
|
||||||
|
LinkedHashMap::new
|
||||||
|
))
|
||||||
|
.values();
|
||||||
|
var jsCfg = joystick.config();
|
||||||
|
var jsCfgDef = joystick.defaultConfig();
|
||||||
|
|
||||||
|
for (int i : deadzoneAxes) {
|
||||||
|
advancedGroup.option(Option.createBuilder(float.class)
|
||||||
|
.name(Component.translatable("controlify.gui.joystick_axis_deadzone", joystick.mapping().axis(i).name()))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.joystick_axis_deadzone.tooltip", joystick.mapping().axis(i).name()))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.stickdrift_warning").withStyle(ChatFormatting.RED))
|
||||||
|
.binding(jsCfgDef.getDeadzone(i), () -> jsCfg.getDeadzone(i), v -> jsCfg.setDeadzone(i, v))
|
||||||
|
.controller(opt -> new FloatSliderController(opt, 0, 1, 0.01f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
advancedGroup
|
||||||
|
.option(ButtonOption.createBuilder()
|
||||||
|
.name(Component.translatable("controlify.gui.auto_calibration"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.auto_calibration.tooltip"))
|
||||||
|
.action((screen, button) -> Minecraft.getInstance().setScreen(new ControllerDeadzoneCalibrationScreen(controller, screen)))
|
||||||
|
.controller(ActionController::new)
|
||||||
|
.build())
|
||||||
|
.option(Option.createBuilder(float.class)
|
||||||
|
.name(Component.translatable("controlify.gui.button_activation_threshold"))
|
||||||
|
.tooltip(Component.translatable("controlify.gui.button_activation_threshold.tooltip"))
|
||||||
|
.binding(def.buttonActivationThreshold, () -> config.buttonActivationThreshold, v -> config.buttonActivationThreshold = v)
|
||||||
|
.controller(opt -> new FloatSliderController(opt, 0, 1, 0.05f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
||||||
|
.build());
|
||||||
|
category.group(advancedGroup.build());
|
||||||
|
|
||||||
|
var controlsGroup = OptionGroup.createBuilder()
|
||||||
|
.name(Component.translatable("controlify.gui.group.controls"));
|
||||||
|
if (controller instanceof GamepadController gamepad) {
|
||||||
|
for (var binding : gamepad.bindings().registry().values()) {
|
||||||
|
controlsGroup.option(Option.createBuilder((Class<IBind<GamepadState>>) (Class<?>) IBind.class)
|
||||||
|
.name(binding.name())
|
||||||
|
.binding(binding.defaultBind(), binding::currentBind, binding::setCurrentBind)
|
||||||
|
.controller(opt -> new GamepadBindController(opt, gamepad))
|
||||||
|
.tooltip(binding.description())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
} else if (controller instanceof JoystickController joystick) {
|
||||||
|
for (var binding : joystick.bindings().registry().values()) {
|
||||||
|
controlsGroup.option(Option.createBuilder((Class<IBind<JoystickState>>) (Class<?>) IBind.class)
|
||||||
|
.name(binding.name())
|
||||||
|
.binding(binding.defaultBind(), binding::currentBind, binding::setCurrentBind)
|
||||||
|
.controller(opt -> new JoystickBindController(opt, joystick))
|
||||||
|
.tooltip(binding.description())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
category.group(controlsGroup.build());
|
||||||
|
|
||||||
|
return category.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,10 @@ public interface Controller<S extends ControllerState, C extends ControllerConfi
|
|||||||
|
|
||||||
void updateState();
|
void updateState();
|
||||||
|
|
||||||
|
default boolean canBeUsed() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Map<Integer, Controller<?, ?>> CONTROLLERS = new HashMap<>();
|
Map<Integer, Controller<?, ?>> CONTROLLERS = new HashMap<>();
|
||||||
|
|
||||||
static Controller<?, ?> createOrGet(int joystickId, @Nullable HidDevice device) {
|
static Controller<?, ?> createOrGet(int joystickId, @Nullable HidDevice device) {
|
||||||
|
@ -56,7 +56,11 @@ public class ControllerType {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
return typeMap.getOrDefault(hid, UNKNOWN);
|
var type = typeMap.getOrDefault(hid, UNKNOWN);
|
||||||
|
if (type == UNKNOWN) {
|
||||||
|
Controlify.LOGGER.warn("Controller type unknown! Please report the make and model of your controller and give the following details: " + hid);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void readControllerIdFiles(JsonReader reader) throws IOException {
|
private static void readControllerIdFiles(JsonReader reader) throws IOException {
|
||||||
|
@ -3,8 +3,9 @@ package dev.isxander.controlify.controller.joystick;
|
|||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import dev.isxander.controlify.controller.AbstractController;
|
import dev.isxander.controlify.controller.AbstractController;
|
||||||
import dev.isxander.controlify.controller.joystick.mapping.DataJoystickMapping;
|
import dev.isxander.controlify.controller.joystick.mapping.RPJoystickMapping;
|
||||||
import dev.isxander.controlify.controller.joystick.mapping.JoystickMapping;
|
import dev.isxander.controlify.controller.joystick.mapping.JoystickMapping;
|
||||||
|
import dev.isxander.controlify.controller.joystick.mapping.UnmappedJoystickMapping;
|
||||||
import org.hid4java.HidDevice;
|
import org.hid4java.HidDevice;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
@ -23,7 +24,7 @@ public class JoystickController extends AbstractController<JoystickState, Joysti
|
|||||||
this.buttonCount = GLFW.glfwGetJoystickButtons(joystickId).capacity();
|
this.buttonCount = GLFW.glfwGetJoystickButtons(joystickId).capacity();
|
||||||
this.hatCount = GLFW.glfwGetJoystickHats(joystickId).capacity();
|
this.hatCount = GLFW.glfwGetJoystickHats(joystickId).capacity();
|
||||||
|
|
||||||
this.mapping = Objects.requireNonNull(DataJoystickMapping.fromType(type()));
|
this.mapping = Objects.requireNonNull(RPJoystickMapping.fromType(type()));
|
||||||
|
|
||||||
this.config = new JoystickConfig(this);
|
this.config = new JoystickConfig(this);
|
||||||
this.defaultConfig = new JoystickConfig(this);
|
this.defaultConfig = new JoystickConfig(this);
|
||||||
@ -49,6 +50,11 @@ public class JoystickController extends AbstractController<JoystickState, Joysti
|
|||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBeUsed() {
|
||||||
|
return !(mapping() instanceof UnmappedJoystickMapping);
|
||||||
|
}
|
||||||
|
|
||||||
public int axisCount() {
|
public int axisCount() {
|
||||||
return axisCount;
|
return axisCount;
|
||||||
}
|
}
|
||||||
|
@ -15,17 +15,15 @@ import net.minecraft.world.phys.Vec2;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class DataJoystickMapping implements JoystickMapping {
|
public class RPJoystickMapping implements JoystickMapping {
|
||||||
private static final Gson gson = new Gson();
|
private static final Gson gson = new Gson();
|
||||||
|
|
||||||
private final Map<Integer, AxisMapping> axisMappings;
|
private final Map<Integer, AxisMapping> axisMappings;
|
||||||
private final Map<Integer, ButtonMapping> buttonMappings;
|
private final Map<Integer, ButtonMapping> buttonMappings;
|
||||||
private final Map<Integer, HatMapping> hatMappings;
|
private final Map<Integer, HatMapping> hatMappings;
|
||||||
|
|
||||||
public DataJoystickMapping(JsonObject object, ControllerType type) {
|
public RPJoystickMapping(JsonObject object, ControllerType type) {
|
||||||
axisMappings = new HashMap<>();
|
axisMappings = new HashMap<>();
|
||||||
object.getAsJsonArray("axes").forEach(element -> {
|
object.getAsJsonArray("axes").forEach(element -> {
|
||||||
var axis = element.getAsJsonObject();
|
var axis = element.getAsJsonObject();
|
||||||
@ -106,7 +104,7 @@ public class DataJoystickMapping implements JoystickMapping {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try (var reader = resource.get().openAsReader()) {
|
try (var reader = resource.get().openAsReader()) {
|
||||||
return new DataJoystickMapping(gson.fromJson(reader, JsonObject.class), type);
|
return new RPJoystickMapping(gson.fromJson(reader, JsonObject.class), type);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Controlify.LOGGER.error("Failed to load joystick mapping for controller: '" + type.identifier() + "'", e);
|
Controlify.LOGGER.error("Failed to load joystick mapping for controller: '" + type.identifier() + "'", e);
|
||||||
return UnmappedJoystickMapping.INSTANCE;
|
return UnmappedJoystickMapping.INSTANCE;
|
Reference in New Issue
Block a user