forked from Clones/Controlify
✏️ Abstract GUID and controller name into drivers
This commit is contained in:
@ -32,13 +32,13 @@ public class GamepadController extends AbstractController<GamepadState, GamepadC
|
||||
if (!GLFW.glfwJoystickIsGamepad(joystickId))
|
||||
throw new IllegalArgumentException("Joystick " + joystickId + " is not a gamepad!");
|
||||
|
||||
if (!this.name.startsWith(type().friendlyName()))
|
||||
setName(GLFW.glfwGetGamepadName(joystickId));
|
||||
|
||||
this.drivers = GamepadDrivers.forController(joystickId, hidInfo.hidDevice());
|
||||
this.uniqueDrivers = drivers.getUniqueDrivers();
|
||||
this.drivers.printDrivers();
|
||||
|
||||
if (!this.name.startsWith(type().friendlyName()))
|
||||
setName(this.drivers.nameProviderDriver().getName());
|
||||
|
||||
this.rumbleManager = new RumbleManager(this);
|
||||
|
||||
this.defaultConfig = new GamepadConfig();
|
||||
|
@ -4,13 +4,15 @@ import dev.isxander.controlify.controller.gamepad.GamepadState;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWGamepadState;
|
||||
|
||||
public class GLFWGamepadDriver implements BasicGamepadInputDriver {
|
||||
public class GLFWGamepadDriver implements BasicGamepadInputDriver, NameProviderDriver, GUIDProvider {
|
||||
private final int jid;
|
||||
private final String guid;
|
||||
|
||||
private BasicGamepadState state = new BasicGamepadState(GamepadState.AxesState.EMPTY, GamepadState.ButtonState.EMPTY);
|
||||
|
||||
public GLFWGamepadDriver(int jid) {
|
||||
this.jid = jid;
|
||||
this.guid = GLFW.glfwGetJoystickGUID(jid);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -56,4 +58,24 @@ public class GLFWGamepadDriver implements BasicGamepadInputDriver {
|
||||
public String getBasicGamepadDetails() {
|
||||
return "GLFW Gamepad";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return GLFW.glfwGetGamepadName(jid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameProviderDetails() {
|
||||
return "GLFW Gamepad";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGUID() {
|
||||
return guid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGUIDProviderDetails() {
|
||||
return "GLFW Gamepad";
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package dev.isxander.controlify.driver;
|
||||
|
||||
public interface GUIDProvider extends Driver {
|
||||
String getGUID();
|
||||
|
||||
String getGUIDProviderDetails();
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package dev.isxander.controlify.driver;
|
||||
|
||||
import dev.isxander.controlify.Controlify;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class GameControllerDBDriver implements NameProviderDriver {
|
||||
private static final Map<String, String> GUID_TO_NAME = generateNameMap();
|
||||
|
||||
private final String name;
|
||||
|
||||
public GameControllerDBDriver(String guid) {
|
||||
this.name = GUID_TO_NAME.getOrDefault(guid, "Unknown Controller");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameProviderDetails() {
|
||||
return "gamecontrollerdb.txt";
|
||||
}
|
||||
|
||||
public static boolean isSupported(String guid) {
|
||||
return GUID_TO_NAME.containsKey(guid);
|
||||
}
|
||||
|
||||
private static Map<String, String> generateNameMap() {
|
||||
Resource resource = Minecraft.getInstance().getResourceManager()
|
||||
.getResource(Controlify.id("controllers/gamecontrollerdb.txt"))
|
||||
.orElseThrow();
|
||||
|
||||
try (BufferedReader reader = resource.openAsReader()) {
|
||||
return reader
|
||||
.lines()//.parallel() for some reason this causes deadlock https://stackoverflow.com/questions/34820066/why-does-parallel-stream-with-lambda-in-static-initializer-cause-a-deadlock
|
||||
.filter(line -> !line.startsWith("#") && !line.isBlank())
|
||||
.map(line -> line.split(","))
|
||||
.filter(entry -> entry.length >= 2)
|
||||
.collect(Collectors.toUnmodifiableMap(
|
||||
entry -> entry[0], // guid
|
||||
entry -> entry[1], // name,
|
||||
(a, b) -> a // if there are duplicates, just use the first one
|
||||
));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ import org.hid4java.HidDevice;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public record GamepadDrivers(BasicGamepadInputDriver basicGamepadInputDriver, GyroDriver gyroDriver, RumbleDriver rumbleDriver, BatteryDriver batteryDriver) {
|
||||
public record GamepadDrivers(BasicGamepadInputDriver basicGamepadInputDriver, GyroDriver gyroDriver, RumbleDriver rumbleDriver, BatteryDriver batteryDriver, GUIDProvider guidProviderDriver, NameProviderDriver nameProviderDriver) {
|
||||
public Set<Driver> getUniqueDrivers() {
|
||||
Set<Driver> drivers = Sets.newIdentityHashSet();
|
||||
drivers.addAll(List.of(basicGamepadInputDriver, gyroDriver, rumbleDriver, batteryDriver));
|
||||
@ -17,17 +17,24 @@ public record GamepadDrivers(BasicGamepadInputDriver basicGamepadInputDriver, Gy
|
||||
|
||||
public void printDrivers() {
|
||||
if (DebugProperties.PRINT_DRIVER) {
|
||||
Controlify.LOGGER.info("Drivers in use: Basic Input = '{}', Gyro = '{}', Rumble = '{}', Battery = '{}'",
|
||||
Controlify.LOGGER.info("Drivers in use: Basic Input = '{}', Gyro = '{}', Rumble = '{}', Battery = '{}', Name = '{}', GUID = '{}'",
|
||||
basicGamepadInputDriver.getBasicGamepadDetails(),
|
||||
gyroDriver.getGyroDetails(),
|
||||
rumbleDriver.getRumbleDetails(),
|
||||
batteryDriver.getBatteryDriverDetails()
|
||||
batteryDriver.getBatteryDriverDetails(),
|
||||
nameProviderDriver.getNameProviderDetails(),
|
||||
guidProviderDriver.getGUIDProviderDetails()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static GamepadDrivers forController(int jid, Optional<HidDevice> hid) {
|
||||
BasicGamepadInputDriver basicGamepadInputDriver = new GLFWGamepadDriver(jid);
|
||||
GLFWGamepadDriver glfwDriver = new GLFWGamepadDriver(jid);
|
||||
|
||||
BasicGamepadInputDriver basicGamepadInputDriver = glfwDriver;
|
||||
NameProviderDriver nameProviderDriver = glfwDriver;
|
||||
GUIDProvider guidProviderDriver = glfwDriver;
|
||||
|
||||
GyroDriver gyroDriver = GyroDriver.UNSUPPORTED;
|
||||
RumbleDriver rumbleDriver = RumbleDriver.UNSUPPORTED;
|
||||
BatteryDriver batteryDriver = BatteryDriver.UNSUPPORTED;
|
||||
@ -37,13 +44,20 @@ public record GamepadDrivers(BasicGamepadInputDriver basicGamepadInputDriver, Gy
|
||||
gyroDriver = sdl2Driver;
|
||||
rumbleDriver = sdl2Driver;
|
||||
batteryDriver = sdl2Driver;
|
||||
|
||||
// SDL2 bypasses XInput abstraction
|
||||
guidProviderDriver = sdl2Driver;
|
||||
}
|
||||
|
||||
// broken
|
||||
// TODO: Fix Steam Deck driver
|
||||
if (hid.isPresent() && SteamDeckDriver.isSteamDeck(hid.get()) && false) {
|
||||
gyroDriver = new SteamDeckDriver(hid.get());
|
||||
}
|
||||
|
||||
return new GamepadDrivers(basicGamepadInputDriver, gyroDriver, rumbleDriver, batteryDriver);
|
||||
if (GameControllerDBDriver.isSupported(guidProviderDriver.getGUID())) {
|
||||
nameProviderDriver = new GameControllerDBDriver(guidProviderDriver.getGUID());
|
||||
}
|
||||
|
||||
return new GamepadDrivers(basicGamepadInputDriver, gyroDriver, rumbleDriver, batteryDriver, guidProviderDriver, nameProviderDriver);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package dev.isxander.controlify.driver;
|
||||
|
||||
public interface NameProviderDriver extends Driver {
|
||||
String getName();
|
||||
|
||||
String getNameProviderDetails();
|
||||
}
|
@ -6,13 +6,15 @@ import dev.isxander.controlify.controller.gamepad.GamepadState;
|
||||
import dev.isxander.controlify.debug.DebugProperties;
|
||||
import org.libsdl.SDL;
|
||||
|
||||
public class SDL2GamepadDriver implements GyroDriver, RumbleDriver, BatteryDriver {
|
||||
public class SDL2GamepadDriver implements GyroDriver, RumbleDriver, BatteryDriver, GUIDProvider {
|
||||
private final long ptrGamepad;
|
||||
private GamepadState.GyroState gyroDelta;
|
||||
private GamepadState.GyroState gyroDelta = new GamepadState.GyroState(0, 0, 0);
|
||||
private final boolean isGyroSupported, isRumbleSupported;
|
||||
private final String guid;
|
||||
|
||||
public SDL2GamepadDriver(int jid) {
|
||||
this.ptrGamepad = SDL.SDL_GameControllerOpen(jid);
|
||||
this.guid = SDL.SDL_JoystickGUIDString(SDL.SDL_GameControllerGetJoystick(ptrGamepad));
|
||||
this.isGyroSupported = SDL.SDL_GameControllerHasSensor(ptrGamepad, SDL.SDL_SENSOR_GYRO);
|
||||
this.isRumbleSupported = SDL.SDL_GameControllerHasRumble(ptrGamepad);
|
||||
|
||||
@ -75,6 +77,11 @@ public class SDL2GamepadDriver implements GyroDriver, RumbleDriver, BatteryDrive
|
||||
return isRumbleSupported;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGUID() {
|
||||
return guid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
SDL.SDL_GameControllerClose(ptrGamepad);
|
||||
@ -94,4 +101,9 @@ public class SDL2GamepadDriver implements GyroDriver, RumbleDriver, BatteryDrive
|
||||
public String getBatteryDriverDetails() {
|
||||
return "SDL2gp";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGUIDProviderDetails() {
|
||||
return "SDL2gp";
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user