forked from Clones/Controlify
controllers!
This commit is contained in:
@ -0,0 +1,61 @@
|
||||
package dev.isxander.controlify.controller;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
public record AxesState(
|
||||
float leftStickX, float leftStickY,
|
||||
float rightStickX, float rightStickY,
|
||||
float leftTrigger, float rightTrigger
|
||||
) {
|
||||
public static AxesState EMPTY = new AxesState(0, 0, 0, 0, 0, 0);
|
||||
|
||||
public AxesState leftJoystickDeadZone(float deadZoneX, float deadZoneY) {
|
||||
return new AxesState(
|
||||
Math.abs(leftStickX) < deadZoneX ? 0 : leftStickX,
|
||||
Math.abs(leftStickY) < deadZoneY ? 0 : leftStickY,
|
||||
rightStickX, rightStickY, leftTrigger, rightTrigger
|
||||
);
|
||||
}
|
||||
|
||||
public AxesState rightJoystickDeadZone(float deadZoneX, float deadZoneY) {
|
||||
return new AxesState(
|
||||
leftStickX, leftStickY,
|
||||
Math.abs(rightStickX) < deadZoneX ? 0 : rightStickX,
|
||||
Math.abs(rightStickY) < deadZoneY ? 0 : rightStickY,
|
||||
leftTrigger, rightTrigger
|
||||
);
|
||||
}
|
||||
|
||||
public AxesState leftTriggerDeadZone(float deadZone) {
|
||||
return new AxesState(
|
||||
leftStickX, leftStickY, rightStickX, rightStickY,
|
||||
Math.abs(leftTrigger) < deadZone ? 0 : leftTrigger,
|
||||
rightTrigger
|
||||
);
|
||||
}
|
||||
|
||||
public AxesState rightTriggerDeadZone(float deadZone) {
|
||||
return new AxesState(
|
||||
leftStickX, leftStickY, rightStickX, rightStickY,
|
||||
leftTrigger,
|
||||
Math.abs(rightTrigger) < deadZone ? 0 : rightTrigger
|
||||
);
|
||||
}
|
||||
|
||||
public static AxesState fromController(Controller controller) {
|
||||
if (controller == null || !controller.connected())
|
||||
return EMPTY;
|
||||
|
||||
var state = controller.getGamepadState();
|
||||
var axes = state.axes();
|
||||
|
||||
float leftX = axes.get(GLFW.GLFW_GAMEPAD_AXIS_LEFT_X);
|
||||
float leftY = axes.get(GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y);
|
||||
float rightX = axes.get(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X);
|
||||
float rightY = axes.get(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y);
|
||||
float leftTrigger = (axes.get(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER) + 1f) / 2f;
|
||||
float rightTrigger = (axes.get(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER) + 1f) / 2f;
|
||||
|
||||
return new AxesState(leftX, leftY, rightX, rightY, leftTrigger, rightTrigger);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package dev.isxander.controlify.controller;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
public record ButtonState(
|
||||
boolean a, boolean b, boolean x, boolean y,
|
||||
boolean leftBumper, boolean rightBumper,
|
||||
boolean back, boolean start,
|
||||
boolean dpadUp, boolean dpadDown, boolean dpadLeft, boolean dpadRight,
|
||||
boolean leftStick, boolean rightStick
|
||||
) {
|
||||
public static ButtonState EMPTY = new ButtonState(
|
||||
false, false, false, false,
|
||||
false, false,
|
||||
false, false,
|
||||
false, false, false, false,
|
||||
false, false
|
||||
);
|
||||
|
||||
public static ButtonState fromController(Controller controller) {
|
||||
if (controller == null || !controller.connected())
|
||||
return EMPTY;
|
||||
|
||||
var state = controller.getGamepadState();
|
||||
var buttons = state.buttons();
|
||||
|
||||
boolean a = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_A) == GLFW.GLFW_PRESS;
|
||||
boolean b = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_B) == GLFW.GLFW_PRESS;
|
||||
boolean x = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_X) == GLFW.GLFW_PRESS;
|
||||
boolean y = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_Y) == GLFW.GLFW_PRESS;
|
||||
boolean leftBumper = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER) == GLFW.GLFW_PRESS;
|
||||
boolean rightBumper = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER) == GLFW.GLFW_PRESS;
|
||||
boolean back = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_BACK) == GLFW.GLFW_PRESS;
|
||||
boolean start = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_START) == GLFW.GLFW_PRESS;
|
||||
boolean dpadUp = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP) == GLFW.GLFW_PRESS;
|
||||
boolean dpadDown = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN) == GLFW.GLFW_PRESS;
|
||||
boolean dpadLeft = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT) == GLFW.GLFW_PRESS;
|
||||
boolean dpadRight = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT) == GLFW.GLFW_PRESS;
|
||||
boolean leftStick = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB) == GLFW.GLFW_PRESS;
|
||||
boolean rightStick = buttons.get(GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB) == GLFW.GLFW_PRESS;
|
||||
|
||||
return new ButtonState(a, b, x, y, leftBumper, rightBumper, back, start, dpadUp, dpadDown, dpadLeft, dpadRight, leftStick, rightStick);
|
||||
}
|
||||
}
|
119
src/main/java/dev/isxander/controlify/controller/Controller.java
Normal file
119
src/main/java/dev/isxander/controlify/controller/Controller.java
Normal file
@ -0,0 +1,119 @@
|
||||
package dev.isxander.controlify.controller;
|
||||
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWGamepadState;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class Controller {
|
||||
public static final Map<Integer, Controller> CONTROLLERS = new HashMap<>();
|
||||
private final int id;
|
||||
private final String guid;
|
||||
private final String name;
|
||||
private final boolean gamepad;
|
||||
private ControllerState state = ControllerState.EMPTY;
|
||||
private ControllerState prevState = ControllerState.EMPTY;
|
||||
|
||||
public Controller(int id, String guid, String name, boolean gamepad) {
|
||||
this.id = id;
|
||||
this.guid = guid;
|
||||
this.name = name;
|
||||
this.gamepad = gamepad;
|
||||
}
|
||||
|
||||
public ControllerState state() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public ControllerState prevState() {
|
||||
return prevState;
|
||||
}
|
||||
|
||||
public void updateState() {
|
||||
if (!connected()) {
|
||||
state = prevState = ControllerState.EMPTY;
|
||||
return;
|
||||
}
|
||||
|
||||
prevState = state;
|
||||
|
||||
AxesState axesState = AxesState.fromController(this)
|
||||
.leftJoystickDeadZone(0.2f, 0.2f)
|
||||
.rightJoystickDeadZone(0.2f, 0.2f)
|
||||
.leftTriggerDeadZone(0.1f)
|
||||
.rightTriggerDeadZone(0.1f);
|
||||
ButtonState buttonState = ButtonState.fromController(this);
|
||||
state = new ControllerState(axesState, buttonState);
|
||||
}
|
||||
|
||||
public boolean connected() {
|
||||
return GLFW.glfwJoystickPresent(id);
|
||||
}
|
||||
|
||||
GLFWGamepadState getGamepadState() {
|
||||
GLFWGamepadState state = GLFWGamepadState.create();
|
||||
if (gamepad)
|
||||
GLFW.glfwGetGamepadState(id, state);
|
||||
return state;
|
||||
}
|
||||
|
||||
public int id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String guid() {
|
||||
return guid;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean gamepad() {
|
||||
return gamepad;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) return true;
|
||||
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||
var that = (Controller) obj;
|
||||
return this.id == that.id &&
|
||||
Objects.equals(this.guid, that.guid) &&
|
||||
Objects.equals(this.name, that.name) &&
|
||||
this.gamepad == that.gamepad;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Controller[" +
|
||||
"id=" + id + ", " +
|
||||
"name=" + name + ']';
|
||||
}
|
||||
|
||||
public static Controller byId(int id) {
|
||||
if (id > GLFW.GLFW_JOYSTICK_LAST)
|
||||
throw new IllegalArgumentException("Invalid joystick id: " + id);
|
||||
if (CONTROLLERS.containsKey(id))
|
||||
return CONTROLLERS.get(id);
|
||||
|
||||
String guid = GLFW.glfwGetJoystickGUID(id);
|
||||
boolean gamepad = GLFW.glfwJoystickIsGamepad(id);
|
||||
String name = gamepad ? GLFW.glfwGetGamepadName(id) : GLFW.glfwGetJoystickName(id);
|
||||
if (name == null) name = Integer.toString(id);
|
||||
|
||||
Controller controller = new Controller(id, guid, name, gamepad);
|
||||
CONTROLLERS.put(id, controller);
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package dev.isxander.controlify.controller;
|
||||
|
||||
public record ControllerState(AxesState axes, ButtonState buttons) {
|
||||
public static final ControllerState EMPTY = new ControllerState(AxesState.EMPTY, ButtonState.EMPTY);
|
||||
|
||||
public boolean hasAnyInput() {
|
||||
return !this.equals(EMPTY);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user