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:
Motschen
2023-10-03 17:36:30 +02:00
parent 233ae36343
commit e1d53ee463
6 changed files with 124 additions and 52 deletions

View File

@@ -32,6 +32,7 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import static org.lwjgl.BufferUtils.createByteBuffer;
@@ -79,7 +80,7 @@ public record Controller(int id) implements Nameable {
* @return the controller's name
*/
@Override
public String getName() {
public @NotNull String getName() {
var name = this.isGamepad() ? GLFW.glfwGetGamepadName(this.id) : GLFW.glfwGetJoystickName(this.id);
return name == null ? String.valueOf(this.id()) : name;
}
@@ -145,6 +146,9 @@ public record Controller(int id) implements Nameable {
* Updates the controller mappings.
*/
public static void updateMappings() {
CompletableFuture.supplyAsync(Controller::updateMappingsSync);
}
private static boolean updateMappingsSync() {
try {
MidnightControlsClient.get().log("Updating controller mappings...");
File databaseFile = new File("config/gamecontrollerdatabase.txt");
@@ -161,7 +165,7 @@ public record Controller(int id) implements Nameable {
var database = ioResourceToBuffer(databaseFile.getPath(), 1024);
if (database != null) GLFW.glfwUpdateGamepadMappings(database);
if (!MidnightControlsClient.MAPPINGS_FILE.exists())
return;
return false;
var buffer = ioResourceToBuffer(MidnightControlsClient.MAPPINGS_FILE.getPath(), 1024);
if (buffer != null) GLFW.glfwUpdateGamepadMappings(buffer);
} catch (IOException e) {
@@ -199,5 +203,6 @@ public record Controller(int id) implements Nameable {
controller.isGamepad()));
}
}
return true;
}
}

View File

@@ -12,6 +12,7 @@ package eu.midnightdust.midnightcontrols.client.controller;
import eu.midnightdust.midnightcontrols.client.ButtonState;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.util.MathUtil;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.input.Input;
import net.minecraft.client.network.ClientPlayerEntity;
@@ -43,6 +44,7 @@ public final class MovementHandler implements PressAction {
private float slowdownFactor = 1.f;
private float movementForward = 0.f;
private float movementSideways = 0.f;
private MathUtil.PolarUtil polarUtil = new MathUtil.PolarUtil();
private MovementHandler() {
}
@@ -53,8 +55,6 @@ public final class MovementHandler implements PressAction {
* @param player The client player.
*/
public void applyMovement(@NotNull ClientPlayerEntity player) {
double movementR, movementTheta;
if (!this.shouldOverrideMovement)
return;
player.input.pressingForward = this.pressingForward;
@@ -62,12 +62,9 @@ public final class MovementHandler implements PressAction {
player.input.pressingLeft = this.pressingLeft;
player.input.pressingRight = this.pressingRight;
// Do an implicit square here
movementR = this.slowdownFactor * (Math.pow(this.movementSideways, 2) + Math.pow(this.movementForward, 2));
movementR = MathHelper.clamp(movementR, 0.f, 1.f);
movementTheta = Math.atan2(this.movementForward, this.movementSideways);
player.input.movementForward = (float) (movementR * Math.sin(movementTheta));
player.input.movementSideways = (float) (movementR * Math.cos(movementTheta));
polarUtil.calculate(this.movementSideways, this.movementForward, this.slowdownFactor);
player.input.movementForward = polarUtil.polarY;
player.input.movementSideways = polarUtil.polarX;
this.shouldOverrideMovement = false;
}