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:
@@ -23,6 +23,7 @@ import eu.midnightdust.midnightcontrols.client.gui.widget.ControllerControlsWidg
|
||||
import eu.midnightdust.midnightcontrols.client.mixin.*;
|
||||
import eu.midnightdust.midnightcontrols.client.ring.RingPage;
|
||||
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
|
||||
import eu.midnightdust.midnightcontrols.client.util.MathUtil;
|
||||
import eu.midnightdust.midnightcontrols.client.util.MouseAccessor;
|
||||
import dev.lambdaurora.spruceui.navigation.NavigationDirection;
|
||||
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.ParentElement;
|
||||
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.AdvancementsScreen;
|
||||
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.world.WorldListWidget;
|
||||
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.text.TranslatableTextContent;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
@@ -256,12 +254,33 @@ public class MidnightInput {
|
||||
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) {
|
||||
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++) {
|
||||
int axis = leftJoycon ? ButtonBinding.controller2Button(i) : i;
|
||||
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);
|
||||
|
||||
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))) {
|
||||
float x = Math.abs(buffer.get(GLFW_GAMEPAD_AXIS_LEFT_X)) > MidnightControlsConfig.leftDeadZone ? buffer.get(GLFW_GAMEPAD_AXIS_LEFT_X) : 0;
|
||||
float y = Math.abs(buffer.get(GLFW_GAMEPAD_AXIS_LEFT_Y)) > MidnightControlsConfig.leftDeadZone ? buffer.get(GLFW_GAMEPAD_AXIS_LEFT_Y) : 0;
|
||||
float x = leftX;
|
||||
float y = leftY;
|
||||
|
||||
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;
|
||||
y = Math.abs(buffer.get(GLFW_GAMEPAD_AXIS_RIGHT_Y)) > MidnightControlsConfig.rightDeadZone ? buffer.get(GLFW_GAMEPAD_AXIS_RIGHT_Y) : 0;
|
||||
x = rightX;
|
||||
y = rightY;
|
||||
}
|
||||
int index = -1;
|
||||
if (x < 0) {
|
||||
if (y < 0) index = 0;
|
||||
if (y == 0) index = 3;
|
||||
if (y > 0) index = 5;
|
||||
} else if (x == 0) {
|
||||
if (y < 0) index = 1;
|
||||
if (y > 0) index = 6;
|
||||
} else if (x > 0) {
|
||||
if (y < 0) index = 2;
|
||||
if (y == 0) index = 4;
|
||||
if (y > 0) index = 7;
|
||||
float border = 0.3f;
|
||||
if (x < -border) {
|
||||
index = 3;
|
||||
if (y < -border) index = 0;
|
||||
else if (y > border) index = 5;
|
||||
} else if (x > border) {
|
||||
index = 4;
|
||||
if (y < -border) index = 2;
|
||||
else if (y > border) index = 7;
|
||||
} else {
|
||||
if (y < -border) index = 1;
|
||||
else if (y > border) index = 6;
|
||||
}
|
||||
if (client.currentScreen instanceof RingScreen && index > -1) RingPage.selected = 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) {
|
||||
int asButtonState = value > .5f ? 1 : (value < -.5f ? 2 : 0);
|
||||
|
||||
|
||||
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_RIGHT_TRIGGER)) {
|
||||
@@ -468,8 +488,12 @@ public class MidnightInput {
|
||||
}
|
||||
|
||||
{
|
||||
boolean currentPlusState = asButtonState == 1;
|
||||
boolean currentMinusState = asButtonState == 2;
|
||||
boolean currentPlusState = value > getDeadZoneValue(axis);
|
||||
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 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 < deadZone ? 0.f : (float) (absValue - deadZone);
|
||||
axisValue /= (1.0 - deadZone);
|
||||
float axisValue = absValue;
|
||||
if (!MidnightControlsConfig.analogMovement) {
|
||||
double deadZone = this.getDeadZoneValue(axis);
|
||||
axisValue = (float) (absValue - deadZone);
|
||||
axisValue /= (1.0 - deadZone);
|
||||
axisValue *= deadZone;
|
||||
}
|
||||
|
||||
axisValue = (float) Math.min(axisValue / MidnightControlsConfig.getAxisMaxValue(axis), 1);
|
||||
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);
|
||||
if (client.currentScreen == null) {
|
||||
// Handles the look direction.
|
||||
@@ -746,6 +772,10 @@ public class MidnightInput {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private double prevX = 0;
|
||||
private double prevY = 0;
|
||||
private double xValue;
|
||||
private int xState;
|
||||
|
||||
/**
|
||||
* Handles the look direction input.
|
||||
@@ -757,22 +787,38 @@ public class MidnightInput {
|
||||
*/
|
||||
public void handleLook(@NotNull MinecraftClient client, int axis, float value, int state) {
|
||||
// Handles the look direction.
|
||||
if (client.player != null) {
|
||||
double powValue = Math.pow(value, 2.0);
|
||||
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
|
||||
if (state == 2) {
|
||||
this.targetPitch = -MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.yAxisRotationSpeed * powValue) * 0.11D;
|
||||
} else if (state == 1) {
|
||||
this.targetPitch = MidnightControlsConfig.getRightYAxisSign() * (MidnightControlsConfig.yAxisRotationSpeed * powValue) * 0.11D;
|
||||
}
|
||||
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X) {
|
||||
xValue = value;
|
||||
xState = state;
|
||||
return;
|
||||
}
|
||||
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y && client.player != null) {
|
||||
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) {
|
||||
this.targetYaw = -MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D;
|
||||
} else if (state == 1) {
|
||||
this.targetYaw = MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powValue) * 0.11D;
|
||||
}
|
||||
|
||||
if (xState == 2) {
|
||||
this.targetYaw = -MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powXValue) * 0.11D;
|
||||
} else if (xState == 1) {
|
||||
this.targetYaw = MidnightControlsConfig.getRightXAxisSign() * (MidnightControlsConfig.rotationSpeed * powXValue) * 0.11D;
|
||||
}
|
||||
|
||||
this.prevY = value;
|
||||
this.prevX = xValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user