mirror of
https://github.com/TeamMidnightDust/MidnightControls.git
synced 2025-12-14 07:35:10 +01:00
Completely rewritten joystick input
- Joystick input is now processed using polar coordinates, resulting in better accuracy and fixing tons of issues (Fixes #135, #138, #186 & #180) - Camera movement is now way smoother by including the previous stick values in the calculation (Fixes #217 & #167) - updateMappings() is now called asyncronously (Closes #219)
This commit is contained in:
@@ -63,7 +63,7 @@ public class MidnightControlsConfig extends MidnightConfig {
|
|||||||
@Entry(category = "controller", name = "midnightcontrols.menu.left_dead_zone", isSlider = true, min = 0.05, max = 1) public static double leftDeadZone = 0.25;
|
@Entry(category = "controller", name = "midnightcontrols.menu.left_dead_zone", isSlider = true, min = 0.05, max = 1) public static double leftDeadZone = 0.25;
|
||||||
@Entry(category = "controller", name = "midnightcontrols.menu.invert_right_y_axis") public static boolean invertRightYAxis = false;
|
@Entry(category = "controller", name = "midnightcontrols.menu.invert_right_y_axis") public static boolean invertRightYAxis = false;
|
||||||
@Entry(category = "controller", name = "midnightcontrols.menu.invert_right_x_axis") public static boolean invertRightXAxis = false;
|
@Entry(category = "controller", name = "midnightcontrols.menu.invert_right_x_axis") public static boolean invertRightXAxis = false;
|
||||||
@Entry(category = "controller", name = "midnightcontrols.menu.rotation_speed", isSlider = true, min = 0, max = 100, precision = 10) public static double rotationSpeed = 40.0; //used for x-axis, name kept for compatibility
|
@Entry(category = "controller", name = "midnightcontrols.menu.rotation_speed", isSlider = true, min = 0, max = 100, precision = 10) public static double rotationSpeed = 35.0; //used for x-axis, name kept for compatibility
|
||||||
@Entry(category = "controller", name = "midnightcontrols.menu.y_axis_rotation_speed", isSlider = true, min = 0, max = 100, precision = 10) public static double yAxisRotationSpeed = rotationSpeed;
|
@Entry(category = "controller", name = "midnightcontrols.menu.y_axis_rotation_speed", isSlider = true, min = 0, max = 100, precision = 10) public static double yAxisRotationSpeed = rotationSpeed;
|
||||||
@Entry(category = "screens", name = "midnightcontrols.menu.mouse_speed", isSlider = true, min = 0, max = 150, precision = 10) public static double mouseSpeed = 25.0;
|
@Entry(category = "screens", name = "midnightcontrols.menu.mouse_speed", isSlider = true, min = 0, max = 150, precision = 10) public static double mouseSpeed = 25.0;
|
||||||
@Entry(category = "screens", name = "midnightcontrols.menu.joystick_as_mouse") public static boolean joystickAsMouse = false;
|
@Entry(category = "screens", name = "midnightcontrols.menu.joystick_as_mouse") public static boolean joystickAsMouse = false;
|
||||||
@@ -101,7 +101,7 @@ public class MidnightControlsConfig extends MidnightConfig {
|
|||||||
@Entry(category = "controller", name = "Max analog value: Left Y", isSlider = true, min = .25f, max = 1.f) public static double maxAnalogValueLeftY = maxAnalogValues[1];
|
@Entry(category = "controller", name = "Max analog value: Left Y", isSlider = true, min = .25f, max = 1.f) public static double maxAnalogValueLeftY = maxAnalogValues[1];
|
||||||
@Entry(category = "controller", name = "Max analog value: Right X", isSlider = true, min = .25f, max = 1.f) public static double maxAnalogValueRightX = maxAnalogValues[2];
|
@Entry(category = "controller", name = "Max analog value: Right X", isSlider = true, min = .25f, max = 1.f) public static double maxAnalogValueRightX = maxAnalogValues[2];
|
||||||
@Entry(category = "controller", name = "Max analog value: Right Y", isSlider = true, min = .25f, max = 1.f) public static double maxAnalogValueRightY = maxAnalogValues[3];
|
@Entry(category = "controller", name = "Max analog value: Right Y", isSlider = true, min = .25f, max = 1.f) public static double maxAnalogValueRightY = maxAnalogValues[3];
|
||||||
@Entry(category = "controller", name = "Trigger button fix") public static boolean triggerFix = true;
|
@Entry(category = "controller", name = "Trigger button fix") public static boolean triggerFix = false;
|
||||||
@Entry(category = "gameplay", name = "Enable Hints") public static boolean enableHints = true;
|
@Entry(category = "gameplay", name = "Enable Hints") public static boolean enableHints = true;
|
||||||
@Entry(category = "screens", name = "Enable Shortcut in Controls Options") public static boolean shortcutInControls = true;
|
@Entry(category = "screens", name = "Enable Shortcut in Controls Options") public static boolean shortcutInControls = true;
|
||||||
@Entry(category = "misc", name = "Ring Bindings (WIP)") public static List<String> ringBindings = new ArrayList<>();
|
@Entry(category = "misc", name = "Ring Bindings (WIP)") public static List<String> ringBindings = new ArrayList<>();
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import eu.midnightdust.midnightcontrols.client.gui.widget.ControllerControlsWidg
|
|||||||
import eu.midnightdust.midnightcontrols.client.mixin.*;
|
import eu.midnightdust.midnightcontrols.client.mixin.*;
|
||||||
import eu.midnightdust.midnightcontrols.client.ring.RingPage;
|
import eu.midnightdust.midnightcontrols.client.ring.RingPage;
|
||||||
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
|
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
|
||||||
|
import eu.midnightdust.midnightcontrols.client.util.MathUtil;
|
||||||
import eu.midnightdust.midnightcontrols.client.util.MouseAccessor;
|
import eu.midnightdust.midnightcontrols.client.util.MouseAccessor;
|
||||||
import dev.lambdaurora.spruceui.navigation.NavigationDirection;
|
import dev.lambdaurora.spruceui.navigation.NavigationDirection;
|
||||||
import dev.lambdaurora.spruceui.screen.SpruceScreen;
|
import dev.lambdaurora.spruceui.screen.SpruceScreen;
|
||||||
@@ -35,7 +36,6 @@ import net.minecraft.client.MinecraftClient;
|
|||||||
import net.minecraft.client.gui.Element;
|
import net.minecraft.client.gui.Element;
|
||||||
import net.minecraft.client.gui.ParentElement;
|
import net.minecraft.client.gui.ParentElement;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
import net.minecraft.client.gui.screen.TitleScreen;
|
|
||||||
import net.minecraft.client.gui.screen.advancement.AdvancementTab;
|
import net.minecraft.client.gui.screen.advancement.AdvancementTab;
|
||||||
import net.minecraft.client.gui.screen.advancement.AdvancementsScreen;
|
import net.minecraft.client.gui.screen.advancement.AdvancementsScreen;
|
||||||
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
|
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
|
||||||
@@ -46,8 +46,6 @@ import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
|
|||||||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
|
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
|
||||||
import net.minecraft.client.gui.screen.world.WorldListWidget;
|
import net.minecraft.client.gui.screen.world.WorldListWidget;
|
||||||
import net.minecraft.client.gui.widget.*;
|
import net.minecraft.client.gui.widget.*;
|
||||||
import net.minecraft.client.input.Input;
|
|
||||||
import net.minecraft.client.util.InputUtil;
|
|
||||||
import net.minecraft.screen.slot.Slot;
|
import net.minecraft.screen.slot.Slot;
|
||||||
import net.minecraft.text.TranslatableTextContent;
|
import net.minecraft.text.TranslatableTextContent;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
@@ -256,12 +254,33 @@ public class MidnightInput {
|
|||||||
InputManager.STATES.put(btn, state);
|
InputManager.STATES.put(btn, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MathUtil.PolarUtil polarLeft = new MathUtil.PolarUtil();
|
||||||
|
MathUtil.PolarUtil polarRight = new MathUtil.PolarUtil();
|
||||||
|
|
||||||
private void fetchAxeInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) {
|
private void fetchAxeInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) {
|
||||||
var buffer = gamepadState.axes();
|
var buffer = gamepadState.axes();
|
||||||
|
|
||||||
|
polarLeft.calculate(buffer.get(GLFW_GAMEPAD_AXIS_LEFT_X), buffer.get(GLFW_GAMEPAD_AXIS_LEFT_Y), 1, MidnightControlsConfig.leftDeadZone);
|
||||||
|
float leftX = polarLeft.polarX;
|
||||||
|
float leftY = polarLeft.polarY;
|
||||||
|
polarRight.calculate(buffer.get(GLFW_GAMEPAD_AXIS_RIGHT_X), buffer.get(GLFW_GAMEPAD_AXIS_RIGHT_Y), 1, MidnightControlsConfig.rightDeadZone);
|
||||||
|
float rightX = polarRight.polarX;
|
||||||
|
float rightY = polarRight.polarY;
|
||||||
|
|
||||||
for (int i = 0; i < buffer.limit(); i++) {
|
for (int i = 0; i < buffer.limit(); i++) {
|
||||||
int axis = leftJoycon ? ButtonBinding.controller2Button(i) : i;
|
int axis = leftJoycon ? ButtonBinding.controller2Button(i) : i;
|
||||||
float value = buffer.get();
|
float value = buffer.get();
|
||||||
|
|
||||||
|
if (MidnightControlsConfig.analogMovement) {
|
||||||
|
switch (i) {
|
||||||
|
case GLFW_GAMEPAD_AXIS_LEFT_X -> value = leftX;
|
||||||
|
case GLFW_GAMEPAD_AXIS_LEFT_Y -> value = leftY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (i) {
|
||||||
|
case GLFW_GAMEPAD_AXIS_RIGHT_X -> value = rightX;
|
||||||
|
case GLFW_GAMEPAD_AXIS_RIGHT_Y -> value = rightY;
|
||||||
|
}
|
||||||
float absValue = Math.abs(value);
|
float absValue = Math.abs(value);
|
||||||
|
|
||||||
if (i == GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y)
|
if (i == GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y)
|
||||||
@@ -271,24 +290,26 @@ public class MidnightInput {
|
|||||||
if (!(client.currentScreen instanceof RingScreen || (MidnightControlsCompat.isEmotecraftPresent() && EmotecraftCompat.isEmotecraftScreen(client.currentScreen)))) this.handleAxe(client, axis, value, absValue, state);
|
if (!(client.currentScreen instanceof RingScreen || (MidnightControlsCompat.isEmotecraftPresent() && EmotecraftCompat.isEmotecraftScreen(client.currentScreen)))) this.handleAxe(client, axis, value, absValue, state);
|
||||||
}
|
}
|
||||||
if (client.currentScreen instanceof RingScreen || (MidnightControlsCompat.isEmotecraftPresent() && EmotecraftCompat.isEmotecraftScreen(client.currentScreen))) {
|
if (client.currentScreen instanceof RingScreen || (MidnightControlsCompat.isEmotecraftPresent() && EmotecraftCompat.isEmotecraftScreen(client.currentScreen))) {
|
||||||
float x = Math.abs(buffer.get(GLFW_GAMEPAD_AXIS_LEFT_X)) > MidnightControlsConfig.leftDeadZone ? buffer.get(GLFW_GAMEPAD_AXIS_LEFT_X) : 0;
|
float x = leftX;
|
||||||
float y = Math.abs(buffer.get(GLFW_GAMEPAD_AXIS_LEFT_Y)) > MidnightControlsConfig.leftDeadZone ? buffer.get(GLFW_GAMEPAD_AXIS_LEFT_Y) : 0;
|
float y = leftY;
|
||||||
|
|
||||||
if (x == 0 && y == 0) {
|
if (x == 0 && y == 0) {
|
||||||
x = Math.abs(buffer.get(GLFW_GAMEPAD_AXIS_RIGHT_X)) > MidnightControlsConfig.rightDeadZone ? buffer.get(GLFW_GAMEPAD_AXIS_RIGHT_X) : 0;
|
x = rightX;
|
||||||
y = Math.abs(buffer.get(GLFW_GAMEPAD_AXIS_RIGHT_Y)) > MidnightControlsConfig.rightDeadZone ? buffer.get(GLFW_GAMEPAD_AXIS_RIGHT_Y) : 0;
|
y = rightY;
|
||||||
}
|
}
|
||||||
int index = -1;
|
int index = -1;
|
||||||
if (x < 0) {
|
float border = 0.3f;
|
||||||
if (y < 0) index = 0;
|
if (x < -border) {
|
||||||
if (y == 0) index = 3;
|
index = 3;
|
||||||
if (y > 0) index = 5;
|
if (y < -border) index = 0;
|
||||||
} else if (x == 0) {
|
else if (y > border) index = 5;
|
||||||
if (y < 0) index = 1;
|
} else if (x > border) {
|
||||||
if (y > 0) index = 6;
|
index = 4;
|
||||||
} else if (x > 0) {
|
if (y < -border) index = 2;
|
||||||
if (y < 0) index = 2;
|
else if (y > border) index = 7;
|
||||||
if (y == 0) index = 4;
|
} else {
|
||||||
if (y > 0) index = 7;
|
if (y < -border) index = 1;
|
||||||
|
else if (y > border) index = 6;
|
||||||
}
|
}
|
||||||
if (client.currentScreen instanceof RingScreen && index > -1) RingPage.selected = index;
|
if (client.currentScreen instanceof RingScreen && index > -1) RingPage.selected = index;
|
||||||
if (MidnightControlsCompat.isEmotecraftPresent() && EmotecraftCompat.isEmotecraftScreen(client.currentScreen)) EmotecraftCompat.handleEmoteSelector(index);
|
if (MidnightControlsCompat.isEmotecraftPresent() && EmotecraftCompat.isEmotecraftScreen(client.currentScreen)) EmotecraftCompat.handleEmoteSelector(index);
|
||||||
@@ -448,7 +469,6 @@ public class MidnightInput {
|
|||||||
private void handleAxe(@NotNull MinecraftClient client, int axis, float value, float absValue, int state) {
|
private void handleAxe(@NotNull MinecraftClient client, int axis, float value, float absValue, int state) {
|
||||||
int asButtonState = value > .5f ? 1 : (value < -.5f ? 2 : 0);
|
int asButtonState = value > .5f ? 1 : (value < -.5f ? 2 : 0);
|
||||||
|
|
||||||
|
|
||||||
if (axis == GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || axis == GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
|
if (axis == GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || axis == GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
|
||||||
|| axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER)
|
|| axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER)
|
||||||
|| axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER)) {
|
|| axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER)) {
|
||||||
@@ -468,8 +488,12 @@ public class MidnightInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
boolean currentPlusState = asButtonState == 1;
|
boolean currentPlusState = value > getDeadZoneValue(axis);
|
||||||
boolean currentMinusState = asButtonState == 2;
|
boolean currentMinusState = value < -getDeadZoneValue(axis);
|
||||||
|
if (!MidnightControlsConfig.analogMovement && (axis == GLFW_GAMEPAD_AXIS_LEFT_X || axis == GLFW_GAMEPAD_AXIS_LEFT_Y)) {
|
||||||
|
currentPlusState = asButtonState == 1;
|
||||||
|
currentMinusState = asButtonState == 2;
|
||||||
|
}
|
||||||
var previousPlusState = InputManager.STATES.getOrDefault(ButtonBinding.axisAsButton(axis, true), ButtonState.NONE);
|
var previousPlusState = InputManager.STATES.getOrDefault(ButtonBinding.axisAsButton(axis, true), ButtonState.NONE);
|
||||||
var previousMinusState = InputManager.STATES.getOrDefault(ButtonBinding.axisAsButton(axis, false), ButtonState.NONE);
|
var previousMinusState = InputManager.STATES.getOrDefault(ButtonBinding.axisAsButton(axis, false), ButtonState.NONE);
|
||||||
|
|
||||||
@@ -495,9 +519,13 @@ public class MidnightInput {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double deadZone = this.getDeadZoneValue(axis);
|
float axisValue = absValue;
|
||||||
float axisValue = absValue < deadZone ? 0.f : (float) (absValue - deadZone);
|
if (!MidnightControlsConfig.analogMovement) {
|
||||||
axisValue /= (1.0 - deadZone);
|
double deadZone = this.getDeadZoneValue(axis);
|
||||||
|
axisValue = (float) (absValue - deadZone);
|
||||||
|
axisValue /= (1.0 - deadZone);
|
||||||
|
axisValue *= deadZone;
|
||||||
|
}
|
||||||
|
|
||||||
axisValue = (float) Math.min(axisValue / MidnightControlsConfig.getAxisMaxValue(axis), 1);
|
axisValue = (float) Math.min(axisValue / MidnightControlsConfig.getAxisMaxValue(axis), 1);
|
||||||
if (currentPlusState)
|
if (currentPlusState)
|
||||||
@@ -597,8 +625,6 @@ public class MidnightInput {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
absValue -= deadZone;
|
|
||||||
absValue /= (1.0 - deadZone);
|
|
||||||
absValue = (float) MathHelper.clamp(absValue / MidnightControlsConfig.getAxisMaxValue(axis), 0.f, 1.f);
|
absValue = (float) MathHelper.clamp(absValue / MidnightControlsConfig.getAxisMaxValue(axis), 0.f, 1.f);
|
||||||
if (client.currentScreen == null) {
|
if (client.currentScreen == null) {
|
||||||
// Handles the look direction.
|
// Handles the look direction.
|
||||||
@@ -746,6 +772,10 @@ public class MidnightInput {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
private double prevX = 0;
|
||||||
|
private double prevY = 0;
|
||||||
|
private double xValue;
|
||||||
|
private int xState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the look direction input.
|
* Handles the look direction input.
|
||||||
@@ -757,22 +787,38 @@ public class MidnightInput {
|
|||||||
*/
|
*/
|
||||||
public void handleLook(@NotNull MinecraftClient client, int axis, float value, int state) {
|
public void handleLook(@NotNull MinecraftClient client, int axis, float value, int state) {
|
||||||
// Handles the look direction.
|
// Handles the look direction.
|
||||||
if (client.player != null) {
|
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X) {
|
||||||
double powValue = Math.pow(value, 2.0);
|
xValue = value;
|
||||||
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
|
xState = state;
|
||||||
if (state == 2) {
|
return;
|
||||||
this.targetPitch = -MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.yAxisRotationSpeed * powValue) * 0.11D;
|
}
|
||||||
} else if (state == 1) {
|
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y && client.player != null) {
|
||||||
this.targetPitch = MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.yAxisRotationSpeed * powValue) * 0.11D;
|
double yStep = (MidnightControlsConfig.yAxisRotationSpeed / 100) * 0.6000000238418579 + 0.20000000298023224;
|
||||||
}
|
double xStep = (MidnightControlsConfig.rotationSpeed / 100) * 0.6000000238418579 + 0.20000000298023224;
|
||||||
|
|
||||||
|
double cursorDeltaX = 2 * xValue - this.prevX;
|
||||||
|
double cursorDeltaY = 2 * value - this.prevY;
|
||||||
|
boolean slowdown = client.options.getPerspective().isFirstPerson() && client.player.isUsingSpyglass();
|
||||||
|
double x = cursorDeltaX * xStep * (slowdown ? xStep : 1);
|
||||||
|
double y = cursorDeltaY * yStep * (slowdown ? yStep : 1);
|
||||||
|
|
||||||
|
double powXValue = Math.pow(x, 2.0);
|
||||||
|
double powYValue = Math.pow(y, 2.0);
|
||||||
|
|
||||||
|
if (state == 2) {
|
||||||
|
this.targetPitch = -MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.yAxisRotationSpeed * powYValue) * 0.11D;
|
||||||
|
} else if (state == 1) {
|
||||||
|
this.targetPitch = MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.yAxisRotationSpeed * powYValue) * 0.11D;
|
||||||
}
|
}
|
||||||
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X) {
|
|
||||||
if (state == 2) {
|
if (xState == 2) {
|
||||||
this.targetYaw = -MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D;
|
this.targetYaw = -MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powXValue) * 0.11D;
|
||||||
} else if (state == 1) {
|
} else if (xState == 1) {
|
||||||
this.targetYaw = MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D;
|
this.targetYaw = MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powXValue) * 0.11D;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.prevY = value;
|
||||||
|
this.prevX = xValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import java.util.Comparator;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import static org.lwjgl.BufferUtils.createByteBuffer;
|
import static org.lwjgl.BufferUtils.createByteBuffer;
|
||||||
|
|
||||||
@@ -79,7 +80,7 @@ public record Controller(int id) implements Nameable {
|
|||||||
* @return the controller's name
|
* @return the controller's name
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public @NotNull String getName() {
|
||||||
var name = this.isGamepad() ? GLFW.glfwGetGamepadName(this.id) : GLFW.glfwGetJoystickName(this.id);
|
var name = this.isGamepad() ? GLFW.glfwGetGamepadName(this.id) : GLFW.glfwGetJoystickName(this.id);
|
||||||
return name == null ? String.valueOf(this.id()) : name;
|
return name == null ? String.valueOf(this.id()) : name;
|
||||||
}
|
}
|
||||||
@@ -145,6 +146,9 @@ public record Controller(int id) implements Nameable {
|
|||||||
* Updates the controller mappings.
|
* Updates the controller mappings.
|
||||||
*/
|
*/
|
||||||
public static void updateMappings() {
|
public static void updateMappings() {
|
||||||
|
CompletableFuture.supplyAsync(Controller::updateMappingsSync);
|
||||||
|
}
|
||||||
|
private static boolean updateMappingsSync() {
|
||||||
try {
|
try {
|
||||||
MidnightControlsClient.get().log("Updating controller mappings...");
|
MidnightControlsClient.get().log("Updating controller mappings...");
|
||||||
File databaseFile = new File("config/gamecontrollerdatabase.txt");
|
File databaseFile = new File("config/gamecontrollerdatabase.txt");
|
||||||
@@ -161,7 +165,7 @@ public record Controller(int id) implements Nameable {
|
|||||||
var database = ioResourceToBuffer(databaseFile.getPath(), 1024);
|
var database = ioResourceToBuffer(databaseFile.getPath(), 1024);
|
||||||
if (database != null) GLFW.glfwUpdateGamepadMappings(database);
|
if (database != null) GLFW.glfwUpdateGamepadMappings(database);
|
||||||
if (!MidnightControlsClient.MAPPINGS_FILE.exists())
|
if (!MidnightControlsClient.MAPPINGS_FILE.exists())
|
||||||
return;
|
return false;
|
||||||
var buffer = ioResourceToBuffer(MidnightControlsClient.MAPPINGS_FILE.getPath(), 1024);
|
var buffer = ioResourceToBuffer(MidnightControlsClient.MAPPINGS_FILE.getPath(), 1024);
|
||||||
if (buffer != null) GLFW.glfwUpdateGamepadMappings(buffer);
|
if (buffer != null) GLFW.glfwUpdateGamepadMappings(buffer);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -199,5 +203,6 @@ public record Controller(int id) implements Nameable {
|
|||||||
controller.isGamepad()));
|
controller.isGamepad()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ package eu.midnightdust.midnightcontrols.client.controller;
|
|||||||
import eu.midnightdust.midnightcontrols.client.ButtonState;
|
import eu.midnightdust.midnightcontrols.client.ButtonState;
|
||||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||||
|
import eu.midnightdust.midnightcontrols.client.util.MathUtil;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.input.Input;
|
import net.minecraft.client.input.Input;
|
||||||
import net.minecraft.client.network.ClientPlayerEntity;
|
import net.minecraft.client.network.ClientPlayerEntity;
|
||||||
@@ -43,6 +44,7 @@ public final class MovementHandler implements PressAction {
|
|||||||
private float slowdownFactor = 1.f;
|
private float slowdownFactor = 1.f;
|
||||||
private float movementForward = 0.f;
|
private float movementForward = 0.f;
|
||||||
private float movementSideways = 0.f;
|
private float movementSideways = 0.f;
|
||||||
|
private MathUtil.PolarUtil polarUtil = new MathUtil.PolarUtil();
|
||||||
|
|
||||||
private MovementHandler() {
|
private MovementHandler() {
|
||||||
}
|
}
|
||||||
@@ -53,8 +55,6 @@ public final class MovementHandler implements PressAction {
|
|||||||
* @param player The client player.
|
* @param player The client player.
|
||||||
*/
|
*/
|
||||||
public void applyMovement(@NotNull ClientPlayerEntity player) {
|
public void applyMovement(@NotNull ClientPlayerEntity player) {
|
||||||
double movementR, movementTheta;
|
|
||||||
|
|
||||||
if (!this.shouldOverrideMovement)
|
if (!this.shouldOverrideMovement)
|
||||||
return;
|
return;
|
||||||
player.input.pressingForward = this.pressingForward;
|
player.input.pressingForward = this.pressingForward;
|
||||||
@@ -62,12 +62,9 @@ public final class MovementHandler implements PressAction {
|
|||||||
player.input.pressingLeft = this.pressingLeft;
|
player.input.pressingLeft = this.pressingLeft;
|
||||||
player.input.pressingRight = this.pressingRight;
|
player.input.pressingRight = this.pressingRight;
|
||||||
|
|
||||||
// Do an implicit square here
|
polarUtil.calculate(this.movementSideways, this.movementForward, this.slowdownFactor);
|
||||||
movementR = this.slowdownFactor * (Math.pow(this.movementSideways, 2) + Math.pow(this.movementForward, 2));
|
player.input.movementForward = polarUtil.polarY;
|
||||||
movementR = MathHelper.clamp(movementR, 0.f, 1.f);
|
player.input.movementSideways = polarUtil.polarX;
|
||||||
movementTheta = Math.atan2(this.movementForward, this.movementSideways);
|
|
||||||
player.input.movementForward = (float) (movementR * Math.sin(movementTheta));
|
|
||||||
player.input.movementSideways = (float) (movementR * Math.cos(movementTheta));
|
|
||||||
|
|
||||||
this.shouldOverrideMovement = false;
|
this.shouldOverrideMovement = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -432,6 +432,7 @@ public class TouchscreenOverlay extends Screen {
|
|||||||
if (result instanceof BlockHitResult blockHit && firstHitResult instanceof BlockHitResult firstBlock && blockHit.getBlockPos().equals(firstBlock.getBlockPos())) {
|
if (result instanceof BlockHitResult blockHit && firstHitResult instanceof BlockHitResult firstBlock && blockHit.getBlockPos().equals(firstBlock.getBlockPos())) {
|
||||||
if (MidnightControlsConfig.debug) System.out.println(blockHit.getBlockPos().toString());
|
if (MidnightControlsConfig.debug) System.out.println(blockHit.getBlockPos().toString());
|
||||||
if (client.interactionManager.updateBlockBreakingProgress(blockHit.getBlockPos(), blockHit.getSide())) {
|
if (client.interactionManager.updateBlockBreakingProgress(blockHit.getBlockPos(), blockHit.getSide())) {
|
||||||
|
client.particleManager.addBlockBreakingParticles(blockHit.getBlockPos(), blockHit.getSide());
|
||||||
client.player.swingHand(Hand.MAIN_HAND);
|
client.player.swingHand(Hand.MAIN_HAND);
|
||||||
} else client.interactionManager.cancelBlockBreaking();
|
} else client.interactionManager.cancelBlockBreaking();
|
||||||
firstHitResult = TouchUtils.getTargettedObject(mouseX, mouseY);
|
firstHitResult = TouchUtils.getTargettedObject(mouseX, mouseY);
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package eu.midnightdust.midnightcontrols.client.util;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
|
public class MathUtil {
|
||||||
|
public static class PolarUtil {
|
||||||
|
public float polarX;
|
||||||
|
public float polarY;
|
||||||
|
public PolarUtil() {}
|
||||||
|
|
||||||
|
public void calculate(float x, float y, float speedFactor) {
|
||||||
|
calculate(x, y, speedFactor, 0);
|
||||||
|
}
|
||||||
|
public void calculate(float x, float y, float speedFactor, double deadZone) {
|
||||||
|
double inputR = Math.pow(x, 2) + Math.pow(y, 2);
|
||||||
|
inputR = (Math.abs(speedFactor * MathHelper.clamp(inputR,0.f,1.f)));
|
||||||
|
inputR = inputR < deadZone ? 0f : (inputR-deadZone) / (1f-deadZone);
|
||||||
|
double inputTheta = Math.atan2(y, x);
|
||||||
|
polarX = (float) (inputR *Math.cos(inputTheta));
|
||||||
|
polarY = (float) (inputR *Math.sin(inputTheta));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user