diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a0d94d0..377c7e9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,10 +11,10 @@ blossom = "1.3.+" minecraft = "1.19.4" quilt_mappings = "10" fabric_loader = "0.14.17" -fabric_api = "0.76.0+1.19.4" -mixin_extras = "0.2.0-beta.1" +fabric_api = "0.78.0+1.19.4" +mixin_extras = "0.2.0-beta.6" yet_another_config_lib = "2.4.0" -mod_menu = "6.1.0-rc.1" +mod_menu = "6.1.0-rc.4" hid4java = "0.7.0" quilt_json5 = "1.0.3" sodium = "mc1.19.4-0.4.10" @@ -27,7 +27,7 @@ minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" } fabric_loader = { module = "net.fabricmc:fabric-loader", version.ref = "fabric_loader" } fabric_api = { module = "net.fabricmc.fabric-api:fabric-api", version.ref = "fabric_api" } -mixin_extras = { module = "com.github.llamalad7:mixinextras", version.ref = "mixin_extras" } +mixin_extras = { module = "com.github.llamalad7.mixinextras:mixinextras-fabric", version.ref = "mixin_extras" } yet_another_config_lib = { module = "dev.isxander:yet-another-config-lib", version.ref = "yet_another_config_lib" } mod_menu = { module = "com.terraformersmc:modmenu", version.ref = "mod_menu" } hid4java = { module = "org.hid4java:hid4java", version.ref = "hid4java" } diff --git a/src/main/java/dev/isxander/controlify/Controlify.java b/src/main/java/dev/isxander/controlify/Controlify.java index 838696f..f6a22db 100644 --- a/src/main/java/dev/isxander/controlify/Controlify.java +++ b/src/main/java/dev/isxander/controlify/Controlify.java @@ -8,6 +8,7 @@ import dev.isxander.controlify.controller.Controller; import dev.isxander.controlify.controller.ControllerState; import dev.isxander.controlify.controller.joystick.CompoundJoystickController; import dev.isxander.controlify.controller.sdl2.SDL2NativesManager; +import dev.isxander.controlify.debug.DebugProperties; import dev.isxander.controlify.gui.screen.ControllerDeadzoneCalibrationScreen; import dev.isxander.controlify.gui.screen.VibrationOnboardingScreen; import dev.isxander.controlify.screenop.ScreenProcessorProvider; @@ -17,6 +18,7 @@ import dev.isxander.controlify.api.event.ControlifyEvents; import dev.isxander.controlify.ingame.guide.InGameButtonGuide; import dev.isxander.controlify.ingame.InGameInputHandler; import dev.isxander.controlify.mixins.feature.virtualmouse.MouseHandlerAccessor; +import dev.isxander.controlify.utils.DebugLog; import dev.isxander.controlify.utils.ToastUtils; import dev.isxander.controlify.virtualmouse.VirtualMouseHandler; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; @@ -74,9 +76,7 @@ public class Controlify implements ControlifyApi { } private void initializeControllers() { - LOGGER.info("Discovering and initializing controllers..."); - - config().load(); + DebugLog.log("Discovering and initializing controllers..."); if (config().globalSettings().loadVibrationNatives) SDL2NativesManager.initialise(); @@ -140,6 +140,8 @@ public class Controlify implements ControlifyApi { } public void preInitialiseControlify() { + DebugProperties.printProperties(); + LOGGER.info("Pre-initializing Controlify..."); this.inGameInputHandler = new InGameInputHandler(Controller.DUMMY); // initialize with dummy controller before connection in case of no controller @@ -205,7 +207,7 @@ public class Controlify implements ControlifyApi { if (state.hasAnyInput()) this.setInputMode(InputMode.CONTROLLER); - if (consecutiveInputSwitches > 500) { + if (consecutiveInputSwitches > 100) { LOGGER.warn("Controlify detected current controller to be constantly giving input and has been disabled."); ToastUtils.sendToast( Component.translatable("controlify.toast.faulty_input.title"), @@ -289,13 +291,13 @@ public class Controlify implements ControlifyApi { try { if (info.isLoaded() && !info.canBeUsed()) { LOGGER.warn("Unloading compound joystick " + info.friendlyName() + " due to missing controllers."); - Controller.CONTROLLERS.remove(info.type().identifier()); + Controller.CONTROLLERS.remove(info.type().mappingId()); } if (!info.isLoaded() && info.canBeUsed()) { - LOGGER.info("Loading compound joystick " + info.type().identifier() + "."); + LOGGER.info("Loading compound joystick " + info.type().mappingId() + "."); CompoundJoystickController controller = info.attemptCreate().orElseThrow(); - Controller.CONTROLLERS.put(info.type().identifier(), controller); + Controller.CONTROLLERS.put(info.type().mappingId(), controller); config().loadOrCreateControllerData(controller); } } catch (Exception e) { @@ -339,14 +341,14 @@ public class Controlify implements ControlifyApi { switchableController = null; } - LOGGER.info("Updated current controller to " + controller.name() + "(" + controller.uid() + ")"); + DebugLog.log("Updated current controller to {}({})", controller.name(), controller.uid()); if (!config().currentControllerUid().equals(controller.uid())) { config().save(); } this.inGameInputHandler = new InGameInputHandler(controller); - if (Minecraft.getInstance().player != null) { + if (minecraft.player != null) { this.inGameButtonGuide = new InGameButtonGuide(controller, Minecraft.getInstance().player); } diff --git a/src/main/java/dev/isxander/controlify/bindings/GamepadBind.java b/src/main/java/dev/isxander/controlify/bindings/GamepadBind.java index b6d38a4..78f6bae 100644 --- a/src/main/java/dev/isxander/controlify/bindings/GamepadBind.java +++ b/src/main/java/dev/isxander/controlify/bindings/GamepadBind.java @@ -65,7 +65,7 @@ public class GamepadBind implements IBind { private ResourceLocation getTexture(BuiltinGamepadTheme theme) { String themeId = theme.id(); if (theme == BuiltinGamepadTheme.DEFAULT) - themeId = gamepad.type().identifier(); + themeId = gamepad.type().themeId(); return new ResourceLocation("controlify", "textures/gui/gamepad/" + themeId + "/" + identifier + ".png"); } diff --git a/src/main/java/dev/isxander/controlify/bindings/JoystickAxisBind.java b/src/main/java/dev/isxander/controlify/bindings/JoystickAxisBind.java index 1fa638e..5e032b1 100644 --- a/src/main/java/dev/isxander/controlify/bindings/JoystickAxisBind.java +++ b/src/main/java/dev/isxander/controlify/bindings/JoystickAxisBind.java @@ -41,7 +41,7 @@ public class JoystickAxisBind implements IBind { public void draw(PoseStack matrices, int x, int centerY) { JoystickMapping mapping = joystick.mapping(); - String type = joystick.type().identifier(); + String type = joystick.type().themeId(); String axis = mapping.axes()[axisIndex].identifier(); String direction = mapping.axes()[axisIndex].getDirectionIdentifier(axisIndex, this.direction); var texture = new ResourceLocation("controlify", "textures/gui/joystick/" + type + "/axis_" + axis + "_" + direction + ".png"); diff --git a/src/main/java/dev/isxander/controlify/bindings/JoystickButtonBind.java b/src/main/java/dev/isxander/controlify/bindings/JoystickButtonBind.java index 8f9def8..2c7d082 100644 --- a/src/main/java/dev/isxander/controlify/bindings/JoystickButtonBind.java +++ b/src/main/java/dev/isxander/controlify/bindings/JoystickButtonBind.java @@ -30,7 +30,7 @@ public class JoystickButtonBind implements IBind { @Override public void draw(PoseStack matrices, int x, int centerY) { - String type = joystick.type().identifier(); + String type = joystick.type().themeId(); String button = joystick.mapping().buttons()[buttonIndex].identifier(); var texture = new ResourceLocation("controlify", "textures/gui/joystick/" + type + "/button_" + button + ".png"); diff --git a/src/main/java/dev/isxander/controlify/bindings/JoystickHatBind.java b/src/main/java/dev/isxander/controlify/bindings/JoystickHatBind.java index 254d0aa..a3d3338 100644 --- a/src/main/java/dev/isxander/controlify/bindings/JoystickHatBind.java +++ b/src/main/java/dev/isxander/controlify/bindings/JoystickHatBind.java @@ -32,7 +32,7 @@ public class JoystickHatBind implements IBind { @Override public void draw(PoseStack matrices, int x, int centerY) { - String type = joystick.type().identifier(); + String type = joystick.type().themeId(); String hat = joystick.mapping().hats()[hatIndex].identifier(); String direction = "centered"; if (hatState.isUp()) diff --git a/src/main/java/dev/isxander/controlify/config/ControlifyConfig.java b/src/main/java/dev/isxander/controlify/config/ControlifyConfig.java index 4d7e881..c18d61a 100644 --- a/src/main/java/dev/isxander/controlify/config/ControlifyConfig.java +++ b/src/main/java/dev/isxander/controlify/config/ControlifyConfig.java @@ -4,6 +4,7 @@ import com.google.gson.*; import dev.isxander.controlify.Controlify; import dev.isxander.controlify.controller.Controller; import dev.isxander.controlify.controller.joystick.CompoundJoystickInfo; +import dev.isxander.controlify.utils.DebugLog; import net.fabricmc.loader.api.FabricLoader; import java.io.IOException; @@ -66,7 +67,7 @@ public class ControlifyConfig { } if (dirty) { - Controlify.LOGGER.info("Config was dirty after load, saving..."); + DebugLog.log("Config was dirty after load, saving..."); save(); } } @@ -121,7 +122,7 @@ public class ControlifyConfig { .asList() .stream() .map(element -> GSON.fromJson(element, CompoundJoystickInfo.class)) - .collect(Collectors.toMap(info -> info.type().identifier(), Function.identity())); + .collect(Collectors.toMap(info -> info.type().mappingId(), Function.identity())); if (object.has("current_controller")) { currentControllerUid = object.get("current_controller").getAsString(); @@ -134,10 +135,10 @@ public class ControlifyConfig { public void loadOrCreateControllerData(Controller controller) { var uid = controller.uid(); if (controllerData.has(uid)) { - Controlify.LOGGER.info("Loading controller data for " + uid); + DebugLog.log("Loading controller data for " + uid); applyControllerConfig(controller, controllerData.getAsJsonObject(uid)); } else { - Controlify.LOGGER.info("New controller found, creating controller data for " + uid); + DebugLog.log("New controller found, setting config dirty ({})", uid); setDirty(); } } @@ -159,7 +160,7 @@ public class ControlifyConfig { public void saveIfDirty() { if (dirty) { - Controlify.LOGGER.info("Config is dirty. Saving..."); + DebugLog.log("Config is dirty. Saving..."); save(); } } diff --git a/src/main/java/dev/isxander/controlify/config/gui/YACLHelper.java b/src/main/java/dev/isxander/controlify/config/gui/YACLHelper.java index c4f1d76..a41642e 100644 --- a/src/main/java/dev/isxander/controlify/config/gui/YACLHelper.java +++ b/src/main/java/dev/isxander/controlify/config/gui/YACLHelper.java @@ -237,7 +237,7 @@ public class YACLHelper { } category.group(vibrationGroup.build()); - if (controller instanceof GamepadController gamepad && (gamepad.hasGyro() || true)) { + if (controller instanceof GamepadController gamepad && gamepad.hasGyro()) { var gpCfg = gamepad.config(); var gpCfgDef = gamepad.defaultConfig(); diff --git a/src/main/java/dev/isxander/controlify/controller/Controller.java b/src/main/java/dev/isxander/controlify/controller/Controller.java index ffffdf9..c979548 100644 --- a/src/main/java/dev/isxander/controlify/controller/Controller.java +++ b/src/main/java/dev/isxander/controlify/controller/Controller.java @@ -11,6 +11,7 @@ import dev.isxander.controlify.debug.DebugProperties; import dev.isxander.controlify.rumble.RumbleCapable; import dev.isxander.controlify.rumble.RumbleManager; import dev.isxander.controlify.rumble.RumbleSource; +import dev.isxander.controlify.utils.DebugLog; import net.minecraft.CrashReport; import net.minecraft.CrashReportCategory; import net.minecraft.ReportedException; @@ -59,7 +60,7 @@ public interface Controller typeMap = null; private static final ResourceLocation hidDbLocation = new ResourceLocation("controlify", "controllers/controller_identification.json5"); @@ -46,7 +46,9 @@ public record ControllerType(String friendlyName, String identifier, boolean for reader.beginArray(); while (reader.hasNext()) { String friendlyName = null; - String identifier = null; + String legacyIdentifier = null; + String themeId = null; + String mappingId = null; boolean forceJoystick = false; boolean dontLoad = false; Set hids = new HashSet<>(); @@ -57,7 +59,9 @@ public record ControllerType(String friendlyName, String identifier, boolean for switch (name) { case "name" -> friendlyName = reader.nextString(); - case "identifier" -> identifier = reader.nextString(); + case "identifier" -> legacyIdentifier = reader.nextString(); + case "theme" -> themeId = reader.nextString(); + case "mapping" -> mappingId = reader.nextString(); case "hids" -> { reader.beginArray(); while (reader.hasNext()) { @@ -89,12 +93,18 @@ public record ControllerType(String friendlyName, String identifier, boolean for } reader.endObject(); - if (friendlyName == null || identifier == null || hids.isEmpty()) { + if (legacyIdentifier != null) { + Controlify.LOGGER.warn("Legacy identifier found in HID DB. Please replace with `theme` and `mapping` (if needed)."); + themeId = legacyIdentifier; + mappingId = legacyIdentifier; + } + + if (friendlyName == null || themeId == null || hids.isEmpty()) { Controlify.LOGGER.warn("Invalid entry in HID DB. Skipping..."); continue; } - var type = new ControllerType(friendlyName, identifier, forceJoystick, dontLoad); + var type = new ControllerType(friendlyName, mappingId, themeId, forceJoystick, dontLoad); for (var hid : hids) { typeMap.put(hid, type); } diff --git a/src/main/java/dev/isxander/controlify/controller/gamepad/GamepadController.java b/src/main/java/dev/isxander/controlify/controller/gamepad/GamepadController.java index d3cbe70..138a98e 100644 --- a/src/main/java/dev/isxander/controlify/controller/gamepad/GamepadController.java +++ b/src/main/java/dev/isxander/controlify/controller/gamepad/GamepadController.java @@ -129,7 +129,6 @@ public class GamepadController extends AbstractController joystickUids, String friendlyName) { public ControllerType type() { - return new ControllerType(friendlyName, createUID(joystickUids), true, false); + return new ControllerType(friendlyName, createUID(joystickUids), "generic", true, false); } public boolean canBeUsed() { @@ -37,7 +37,7 @@ public record CompoundJoystickInfo(Collection joystickUids, String frien .toList(); ControllerType type = type(); - return Optional.of(new CompoundJoystickController(joystickIDs, type.identifier(), type)); + return Optional.of(new CompoundJoystickController(joystickIDs, type.mappingId(), type)); } public static String createUID(Collection joystickUIDs) { diff --git a/src/main/java/dev/isxander/controlify/controller/joystick/mapping/JoystickMapping.java b/src/main/java/dev/isxander/controlify/controller/joystick/mapping/JoystickMapping.java index c0e499c..6950233 100644 --- a/src/main/java/dev/isxander/controlify/controller/joystick/mapping/JoystickMapping.java +++ b/src/main/java/dev/isxander/controlify/controller/joystick/mapping/JoystickMapping.java @@ -2,6 +2,7 @@ package dev.isxander.controlify.controller.joystick.mapping; import dev.isxander.controlify.bindings.JoystickAxisBind; import dev.isxander.controlify.controller.joystick.JoystickState; +import dev.isxander.controlify.controller.joystick.render.JoystickRenderer; import net.minecraft.network.chat.Component; public interface JoystickMapping { @@ -23,6 +24,8 @@ public interface JoystickMapping { float restingValue(); String getDirectionIdentifier(int axis, JoystickAxisBind.AxisDirection direction); + + JoystickRenderer renderer(); } interface Button { @@ -31,6 +34,8 @@ public interface JoystickMapping { Component name(); boolean isPressed(JoystickData data); + + JoystickRenderer renderer(); } interface Hat { @@ -39,6 +44,8 @@ public interface JoystickMapping { String identifier(); Component name(); + + JoystickRenderer renderer(JoystickState.HatState state); } record JoystickData(float[] axes, boolean[] buttons, JoystickState.HatState[] hats) { diff --git a/src/main/java/dev/isxander/controlify/controller/joystick/mapping/RPJoystickMapping.java b/src/main/java/dev/isxander/controlify/controller/joystick/mapping/RPJoystickMapping.java index d0d351e..6ba10f6 100644 --- a/src/main/java/dev/isxander/controlify/controller/joystick/mapping/RPJoystickMapping.java +++ b/src/main/java/dev/isxander/controlify/controller/joystick/mapping/RPJoystickMapping.java @@ -5,6 +5,7 @@ import dev.isxander.controlify.bindings.JoystickAxisBind; import dev.isxander.controlify.controller.ControllerType; import dev.isxander.controlify.controller.joystick.JoystickController; import dev.isxander.controlify.controller.joystick.JoystickState; +import dev.isxander.controlify.controller.joystick.render.JoystickRenderer; import net.minecraft.client.Minecraft; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -141,7 +142,7 @@ public class RPJoystickMapping implements JoystickMapping { reader.endObject(); for (var id : ids) { - axes.add(new AxisMapping(id, identifier, inpRange, outRange, restState, deadzone, type.identifier(), axisNames.get(ids.indexOf(id)))); + axes.add(new AxisMapping(id, identifier, inpRange, outRange, restState, deadzone, type.mappingId(), axisNames.get(ids.indexOf(id)))); } } reader.endArray(); @@ -171,7 +172,7 @@ public class RPJoystickMapping implements JoystickMapping { } reader.endObject(); - buttons.add(new ButtonMapping(id, btnName, type.identifier())); + buttons.add(new ButtonMapping(id, btnName, type.mappingId())); } reader.endArray(); @@ -231,7 +232,7 @@ public class RPJoystickMapping implements JoystickMapping { } reader.endObject(); - hats.add(new HatMapping(id, hatName, type.identifier(), axis)); + hats.add(new HatMapping(id, hatName, type.mappingId(), axis)); } reader.endArray(); @@ -254,21 +255,21 @@ public class RPJoystickMapping implements JoystickMapping { } public static JoystickMapping fromType(JoystickController joystick) { - var resource = Minecraft.getInstance().getResourceManager().getResource(new ResourceLocation("controlify", "mappings/" + joystick.type().identifier() + ".json")); + var resource = Minecraft.getInstance().getResourceManager().getResource(new ResourceLocation("controlify", "mappings/" + joystick.type().mappingId() + ".json")); if (resource.isEmpty()) { - Controlify.LOGGER.warn("No joystick mapping found for controller: '" + joystick.type().identifier() + "'"); + Controlify.LOGGER.warn("No joystick mapping found for controller: '" + joystick.type().mappingId() + "'"); return new UnmappedJoystickMapping(joystick.joystickId()); } try (var reader = JsonReader.json5(resource.get().openAsReader())) { return new RPJoystickMapping(reader, joystick.type()); } catch (Exception e) { - Controlify.LOGGER.error("Failed to load joystick mapping for controller: '" + joystick.type().identifier() + "'", e); + Controlify.LOGGER.error("Failed to load joystick mapping for controller: '" + joystick.type().mappingId() + "'", e); return new UnmappedJoystickMapping(joystick.joystickId()); } } - private record AxisMapping(int id, String identifier, Vec2 inpRange, Vec2 outRange, float restingValue, boolean requiresDeadzone, String typeId, String[] axisNames) implements Axis { + private record AxisMapping(int id, String identifier, Vec2 inpRange, Vec2 outRange, float restingValue, boolean requiresDeadzone, String theme, String[] axisNames) implements Axis { @Override public float getAxis(JoystickData data) { float rawAxis = data.axes()[id]; @@ -286,13 +287,18 @@ public class RPJoystickMapping implements JoystickMapping { @Override public Component name() { - return Component.translatable("controlify.joystick_mapping." + typeId() + ".axis." + identifier()); + return Component.translatable("controlify.joystick_mapping." + theme() + ".axis." + identifier()); } @Override public String getDirectionIdentifier(int axis, JoystickAxisBind.AxisDirection direction) { return this.axisNames()[direction.ordinal()]; } + + @Override + public JoystickRenderer renderer() { + return null; + } } private record ButtonMapping(int id, String identifier, String typeId) implements Button { @@ -305,6 +311,11 @@ public class RPJoystickMapping implements JoystickMapping { public Component name() { return Component.translatable("controlify.joystick_mapping." + typeId() + ".button." + identifier()); } + + @Override + public JoystickRenderer renderer() { + return null; + } } private record HatMapping(int hatId, String identifier, String typeId, @Nullable EmulatedAxis emulatedAxis) implements Hat { @@ -324,6 +335,11 @@ public class RPJoystickMapping implements JoystickMapping { return Component.translatable("controlify.joystick_mapping." + typeId() + ".hat." + identifier()); } + @Override + public JoystickRenderer renderer(JoystickState.HatState state) { + return null; + } + private record EmulatedAxis(int axisId, Map states) { } } diff --git a/src/main/java/dev/isxander/controlify/controller/joystick/mapping/UnmappedJoystickMapping.java b/src/main/java/dev/isxander/controlify/controller/joystick/mapping/UnmappedJoystickMapping.java index 5ae8c53..b49e03f 100644 --- a/src/main/java/dev/isxander/controlify/controller/joystick/mapping/UnmappedJoystickMapping.java +++ b/src/main/java/dev/isxander/controlify/controller/joystick/mapping/UnmappedJoystickMapping.java @@ -1,13 +1,12 @@ package dev.isxander.controlify.controller.joystick.mapping; import dev.isxander.controlify.bindings.JoystickAxisBind; -import dev.isxander.controlify.controller.joystick.JoystickController; import dev.isxander.controlify.controller.joystick.JoystickState; +import dev.isxander.controlify.controller.joystick.render.GenericRenderer; +import dev.isxander.controlify.controller.joystick.render.JoystickRenderer; import net.minecraft.network.chat.Component; import org.lwjgl.glfw.GLFW; -import java.util.Arrays; - public class UnmappedJoystickMapping implements JoystickMapping { public static final UnmappedJoystickMapping EMPTY = new UnmappedJoystickMapping(0, 0, 0); @@ -18,12 +17,12 @@ public class UnmappedJoystickMapping implements JoystickMapping { private UnmappedJoystickMapping(int axisCount, int buttonCount, int hatCount) { this.axes = new UnmappedAxis[axisCount]; for (int i = 0; i < axisCount; i++) { - this.axes[i] = new UnmappedAxis(i); + this.axes[i] = new UnmappedAxis(i, new GenericRenderer.Axis(Integer.toString(i + 1))); } this.buttons = new UnmappedButton[axisCount]; for (int i = 0; i < buttonCount; i++) { - this.buttons[i] = new UnmappedButton(i); + this.buttons[i] = new UnmappedButton(i, new GenericRenderer.Button(Integer.toString(i + 1))); } this.hats = new UnmappedHat[hatCount]; @@ -55,7 +54,7 @@ public class UnmappedJoystickMapping implements JoystickMapping { return hats; } - private record UnmappedAxis(int axis) implements Axis { + private record UnmappedAxis(int axis, GenericRenderer.Axis renderer) implements Axis { @Override public float getAxis(JoystickData data) { return data.axes()[axis]; @@ -92,7 +91,7 @@ public class UnmappedJoystickMapping implements JoystickMapping { } } - private record UnmappedButton(int button) implements Button { + private record UnmappedButton(int button, GenericRenderer.Button renderer) implements Button { @Override public boolean isPressed(JoystickData data) { return data.buttons()[button]; @@ -124,5 +123,10 @@ public class UnmappedJoystickMapping implements JoystickMapping { public Component name() { return Component.translatable("controlify.joystick_mapping.unmapped.hat", hat + 1); } + + @Override + public JoystickRenderer renderer(JoystickState.HatState state) { + return new GenericRenderer.Hat(Integer.toString(hat + 1)); + } } } diff --git a/src/main/java/dev/isxander/controlify/controller/joystick/render/GenericRenderer.java b/src/main/java/dev/isxander/controlify/controller/joystick/render/GenericRenderer.java new file mode 100644 index 0000000..cebbb3c --- /dev/null +++ b/src/main/java/dev/isxander/controlify/controller/joystick/render/GenericRenderer.java @@ -0,0 +1,144 @@ +package dev.isxander.controlify.controller.joystick.render; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import dev.isxander.controlify.bindings.JoystickAxisBind; +import dev.isxander.controlify.controller.joystick.JoystickState; +import dev.isxander.controlify.gui.DrawSize; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiComponent; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.Nullable; + +public abstract class GenericRenderer implements JoystickRenderer { + protected final @Nullable String annotation; + protected final Minecraft minecraft = Minecraft.getInstance(); + + public GenericRenderer(@Nullable String annotation) { + this.annotation = annotation; + } + + @Override + public DrawSize render(PoseStack poseStack, int x, int centerY, int size) { + if (annotation != null) { + minecraft.font.draw( + poseStack, + annotation, + x + size + 2 - minecraft.font.width(annotation), + centerY + size/2f - minecraft.font.lineHeight * 0.75f, + -1 + ); + } + + return null; + } + + public static class Button extends GenericRenderer implements JoystickRenderer.Button { + private static final ResourceLocation BUTTON_TEXTURE = new ResourceLocation("controlify", "textures/gui/joystick/generic/button.png"); + + public Button(@Nullable String annotation) { + super(annotation); + } + + @Override + public DrawSize render(PoseStack poseStack, int x, int centerY, int size) { + RenderSystem.setShaderTexture(0, BUTTON_TEXTURE); + RenderSystem.setShaderColor(1, 1, 1, 1); + + poseStack.pushPose(); + poseStack.translate(x, centerY, 0); + + float scale = (float) size / 22f; + poseStack.scale(scale, scale, 1); + poseStack.translate(0f, -DEFAULT_SIZE / scale / 2f, 0); + + GuiComponent.blit(poseStack, 0, 0, 0, 0, DEFAULT_SIZE, DEFAULT_SIZE, DEFAULT_SIZE, DEFAULT_SIZE); + + poseStack.popPose(); + + super.render(poseStack, x, centerY, size); + + return new DrawSize(size, size); + } + + @Override + public DrawSize render(PoseStack poseStack, int x, int centerY, int size, boolean down) { + return this.render(poseStack, x, centerY, size); + } + + @Override + public DrawSize render(PoseStack poseStack, int x, int centerY, boolean down) { + return this.render(poseStack, x, centerY, DEFAULT_SIZE); + } + } + + public static class Axis extends GenericRenderer implements JoystickRenderer.Axis { + private static final ResourceLocation AXIS_TEXTURE = new ResourceLocation("controlify", "textures/gui/joystick/generic/axis.png"); + + public Axis(@Nullable String annotation) { + super(annotation); + } + + @Override + public DrawSize render(PoseStack poseStack, int x, int centerY, int size, JoystickAxisBind.AxisDirection direction) { + RenderSystem.setShaderTexture(0, AXIS_TEXTURE); + RenderSystem.setShaderColor(1, 1, 1, 1); + + poseStack.pushPose(); + poseStack.translate(x, centerY, 0); + + float scale = (float) size / 22f; + poseStack.scale(scale, scale, 1); + poseStack.translate(0f, -DEFAULT_SIZE / scale / 2f, 0); + + GuiComponent.blit( + poseStack, + 0, 0, + direction.ordinal() * DEFAULT_SIZE, 0, + DEFAULT_SIZE, DEFAULT_SIZE, + DEFAULT_SIZE * JoystickAxisBind.AxisDirection.values().length, DEFAULT_SIZE + ); + + poseStack.popPose(); + + super.render(poseStack, x, centerY, size); + + return new DrawSize(size, size); + } + } + + public static class Hat extends GenericRenderer implements JoystickRenderer.Hat { + private static final ResourceLocation HAT_TEXTURE = new ResourceLocation("controlify", "textures/gui/joystick/generic/hat.png"); + + public Hat(@Nullable String annotation) { + super(annotation); + } + + @Override + public DrawSize render(PoseStack poseStack, int x, int centerY, int size, JoystickState.HatState hatState) { + RenderSystem.setShaderTexture(0, HAT_TEXTURE); + RenderSystem.setShaderColor(1, 1, 1, 1); + + poseStack.pushPose(); + poseStack.translate(x, centerY, 0); + + float scale = (float) size / 22f; + poseStack.scale(scale, scale, 1); + poseStack.translate(0f, -DEFAULT_SIZE / scale / 2f, 0); + + GuiComponent.blit( + poseStack, + 0, 0, + hatState.ordinal() * DEFAULT_SIZE, 0, + DEFAULT_SIZE, DEFAULT_SIZE, + DEFAULT_SIZE * JoystickState.HatState.values().length, DEFAULT_SIZE + ); + + poseStack.popPose(); + + super.render(poseStack, x, centerY, size); + + return new DrawSize(size, size); + } + } +} diff --git a/src/main/java/dev/isxander/controlify/controller/joystick/render/JoystickRenderer.java b/src/main/java/dev/isxander/controlify/controller/joystick/render/JoystickRenderer.java new file mode 100644 index 0000000..c389af8 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/controller/joystick/render/JoystickRenderer.java @@ -0,0 +1,48 @@ +package dev.isxander.controlify.controller.joystick.render; + +import com.mojang.blaze3d.vertex.PoseStack; +import dev.isxander.controlify.bindings.JoystickAxisBind; +import dev.isxander.controlify.controller.joystick.JoystickState; +import dev.isxander.controlify.gui.DrawSize; + +public interface JoystickRenderer { + int DEFAULT_SIZE = 22; + + DrawSize render(PoseStack poseStack, int x, int centerY, int size); + + interface Button extends JoystickRenderer { + DrawSize render(PoseStack poseStack, int x, int centerY, int size, boolean down); + + default DrawSize render(PoseStack poseStack, int x, int centerY, boolean down) { + return render(poseStack, x, centerY, DEFAULT_SIZE, down); + } + + default DrawSize render(PoseStack poseStack, int x, int centerY, int size) { + return render(poseStack, x, centerY, size, false); + } + } + + interface Axis extends JoystickRenderer { + DrawSize render(PoseStack poseStack, int x, int centerY, int size, JoystickAxisBind.AxisDirection direction); + + default DrawSize render(PoseStack poseStack, int x, int centerY, JoystickAxisBind.AxisDirection direction) { + return render(poseStack, x, centerY, DEFAULT_SIZE, direction); + } + + default DrawSize render(PoseStack poseStack, int x, int centerY, int size) { + return render(poseStack, x, centerY, size, JoystickAxisBind.AxisDirection.POSITIVE); + } + } + + interface Hat extends JoystickRenderer { + DrawSize render(PoseStack poseStack, int x, int centerY, int size, JoystickState.HatState state); + + default DrawSize render(PoseStack poseStack, int x, int centerY, JoystickState.HatState state) { + return render(poseStack, x, centerY, DEFAULT_SIZE, state); + } + + default DrawSize render(PoseStack poseStack, int x, int centerY, int size) { + return render(poseStack, x, centerY, size, JoystickState.HatState.CENTERED); + } + } +} diff --git a/src/main/java/dev/isxander/controlify/controller/joystick/render/ThemedRenderer.java b/src/main/java/dev/isxander/controlify/controller/joystick/render/ThemedRenderer.java new file mode 100644 index 0000000..50853dd --- /dev/null +++ b/src/main/java/dev/isxander/controlify/controller/joystick/render/ThemedRenderer.java @@ -0,0 +1,116 @@ +package dev.isxander.controlify.controller.joystick.render; + + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import dev.isxander.controlify.bindings.JoystickAxisBind; +import dev.isxander.controlify.controller.joystick.JoystickState; +import dev.isxander.controlify.gui.DrawSize; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiComponent; +import net.minecraft.resources.ResourceLocation; + +public abstract class ThemedRenderer { + protected final Minecraft minecraft = Minecraft.getInstance(); + protected final String themeId; + + public ThemedRenderer(String themeId) { + this.themeId = themeId; + } + + public static class Button extends ThemedRenderer implements JoystickRenderer.Button { + private final ResourceLocation texture; + + public Button(String themeId, String identifier) { + super(themeId); + this.texture = new ResourceLocation("controlify", "textures/gui/joystick/" + themeId + "/" + identifier + ".png"); + } + + @Override + public DrawSize render(PoseStack poseStack, int x, int centerY, int size, boolean down) { + RenderSystem.setShaderTexture(0, texture); + RenderSystem.setShaderColor(1, 1, 1, 1); + + poseStack.pushPose(); + poseStack.translate(x, centerY, 0); + + float scale = (float) size / 22f; + poseStack.scale(scale, scale, 1); + poseStack.translate(0f, -DEFAULT_SIZE / scale / 2f, 0); + + GuiComponent.blit(poseStack, 0, 0, 0, 0, DEFAULT_SIZE, DEFAULT_SIZE, DEFAULT_SIZE, DEFAULT_SIZE); + + poseStack.popPose(); + + return new DrawSize(size, size); + } + } + + public static class Axis extends ThemedRenderer implements JoystickRenderer.Axis { + private final ResourceLocation texture; + + public Axis(String themeId, String identifier) { + super(themeId); + this.texture = new ResourceLocation("controlify", "textures/gui/joystick/" + themeId + "/" + identifier + ".png"); + } + + @Override + public DrawSize render(PoseStack poseStack, int x, int centerY, int size, JoystickAxisBind.AxisDirection direction) { + RenderSystem.setShaderTexture(0, texture); + RenderSystem.setShaderColor(1, 1, 1, 1); + + poseStack.pushPose(); + poseStack.translate(x, centerY, 0); + + float scale = (float) size / 22f; + poseStack.scale(scale, scale, 1); + poseStack.translate(0f, -DEFAULT_SIZE / scale / 2f, 0); + + GuiComponent.blit( + poseStack, + 0, 0, + direction.ordinal() * DEFAULT_SIZE, 0, + DEFAULT_SIZE, DEFAULT_SIZE, + DEFAULT_SIZE * JoystickAxisBind.AxisDirection.values().length, DEFAULT_SIZE + ); + + poseStack.popPose(); + + return new DrawSize(size, size); + } + } + + public static class Hat extends ThemedRenderer implements JoystickRenderer.Hat { + private final ResourceLocation texture; + + public Hat(String themeId, String identifier) { + super(themeId); + this.texture = new ResourceLocation("controlify", "textures/gui/joystick/" + themeId + "/" + identifier + ".png"); + } + + @Override + public DrawSize render(PoseStack poseStack, int x, int centerY, int size, JoystickState.HatState hatState) { + RenderSystem.setShaderTexture(0, texture); + RenderSystem.setShaderColor(1, 1, 1, 1); + + poseStack.pushPose(); + poseStack.translate(x, centerY, 0); + + float scale = (float) size / 22f; + poseStack.scale(scale, scale, 1); + poseStack.translate(0f, -DEFAULT_SIZE / scale / 2f, 0); + + GuiComponent.blit( + poseStack, + 0, 0, + hatState.ordinal() * DEFAULT_SIZE, 0, + DEFAULT_SIZE, DEFAULT_SIZE, + DEFAULT_SIZE * JoystickState.HatState.values().length, DEFAULT_SIZE + ); + + poseStack.popPose(); + + return new DrawSize(size, size); + } + } +} diff --git a/src/main/java/dev/isxander/controlify/controller/sdl2/SDL2NativesManager.java b/src/main/java/dev/isxander/controlify/controller/sdl2/SDL2NativesManager.java index 0bc4b4b..2c78b91 100644 --- a/src/main/java/dev/isxander/controlify/controller/sdl2/SDL2NativesManager.java +++ b/src/main/java/dev/isxander/controlify/controller/sdl2/SDL2NativesManager.java @@ -1,6 +1,7 @@ package dev.isxander.controlify.controller.sdl2; import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.utils.DebugLog; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.Util; import org.libsdl.SDL; @@ -31,7 +32,7 @@ public class SDL2NativesManager { public static void initialise() { if (loaded) return; - Controlify.LOGGER.info("Initialising SDL2 native library"); + DebugLog.log("Initialising SDL2 native library"); if (!Target.CURRENT.hasNativeLibrary()) { Controlify.LOGGER.warn("SDL2 native library not available for OS: " + Target.CURRENT); @@ -77,7 +78,7 @@ public class SDL2NativesManager { throw new RuntimeException("Failed to initialise SDL2: " + SDL.SDL_GetError()); } - Controlify.LOGGER.info("Initialised SDL2"); + DebugLog.log("Initialised SDL2"); } private static boolean downloadLibrary(Path path) { diff --git a/src/main/java/dev/isxander/controlify/debug/DebugProperties.java b/src/main/java/dev/isxander/controlify/debug/DebugProperties.java index dd60d9e..6e50f34 100644 --- a/src/main/java/dev/isxander/controlify/debug/DebugProperties.java +++ b/src/main/java/dev/isxander/controlify/debug/DebugProperties.java @@ -1,19 +1,49 @@ package dev.isxander.controlify.debug; +import dev.isxander.controlify.Controlify; import net.fabricmc.loader.api.FabricLoader; +import java.util.ArrayList; +import java.util.List; + public class DebugProperties { + private static final List properties = new ArrayList<>(); + + public static final boolean DEBUG_LOGGING = boolProp("controlify.debug.logging", false, true); /* Renders debug overlay for vmouse snapping */ public static final boolean DEBUG_SNAPPING = boolProp("controlify.debug.snapping", false, false); /* Forces all gamepads to be treated as a regular joystick */ public static final boolean FORCE_JOYSTICK = boolProp("controlify.debug.force_joystick", false, false); /* Prints joystick input counts for making joystick mappings */ - public static final boolean PRINT_JOY_INPUT_COUNT = boolProp("controlify.debug.print_joy_input_count", false, true); + public static final boolean PRINT_JOY_INPUT_COUNT = boolProp("controlify.debug.print_joy_input_count", false, false); /* Print gyro data if supported */ public static final boolean PRINT_GYRO = boolProp("controlify.debug.print_gyro", false, false); + public static void printProperties() { + if (properties.stream().noneMatch(DebugProperty::enabled)) + return; + + String header = "*----------------- Controlify Debug Properties -----------------*"; + Controlify.LOGGER.error(header); + + int maxWidth = properties.stream().mapToInt(prop -> prop.name().length()).max().orElse(0); + for (var prop : properties) { + String line = "| %s%s = %s".formatted(prop.name(), " ".repeat(maxWidth - prop.name().length()), prop.enabled()); + line += " ".repeat(header.length() - line.length() - 1) + "|"; + + Controlify.LOGGER.error(line); + } + + Controlify.LOGGER.error("*---------------------------------------------------------------*"); + } + private static boolean boolProp(String name, boolean defProd, boolean defDev) { boolean def = FabricLoader.getInstance().isDevelopmentEnvironment() ? defDev : defProd; - return Boolean.parseBoolean(System.getProperty(name, Boolean.toString(def))); + boolean enabled = Boolean.parseBoolean(System.getProperty(name, Boolean.toString(def))); + properties.add(new DebugProperty(name, enabled)); + return enabled; + } + + private record DebugProperty(String name, boolean enabled) { } } diff --git a/src/main/java/dev/isxander/controlify/utils/DebugLog.java b/src/main/java/dev/isxander/controlify/utils/DebugLog.java new file mode 100644 index 0000000..74d03e0 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/utils/DebugLog.java @@ -0,0 +1,12 @@ +package dev.isxander.controlify.utils; + +import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.debug.DebugProperties; + +public class DebugLog { + public static void log(String message, Object... args) { + if (DebugProperties.DEBUG_LOGGING) { + Controlify.LOGGER.info(message, args); + } + } +} diff --git a/src/main/resources/assets/controlify/controllers/controller_identification.json5 b/src/main/resources/assets/controlify/controllers/controller_identification.json5 index 058148b..dd9c23f 100644 --- a/src/main/resources/assets/controlify/controllers/controller_identification.json5 +++ b/src/main/resources/assets/controlify/controllers/controller_identification.json5 @@ -1,7 +1,7 @@ [ { "name": "Xbox One Controller", - "identifier": "xbox_one", + "theme": "xbox_one", "hids": [ [0x45e, 0x2ff], @@ -21,7 +21,7 @@ }, { "name": "Dualshock 4 Controller", - "identifier": "dualshock4", + "theme": "dualshock4", "hids": [ [0x54c, 0x5c4], @@ -31,7 +31,7 @@ }, { "name": "Steam Deck", - "identifier": "steam_deck", + "theme": "xbox_one", "hids": [ [0x28de, 0x1205], @@ -39,10 +39,19 @@ }, { "name": "Stadia Controller", - "identifier": "stadia", + "theme": "stadia", "hids": [ [0x18d1, 0x9400], ] + }, + { + "name": "Thrustmaster T16000M", + "theme": "thrustmaster", + "mapping": "tm_t16000m", + + "hids": [ + [0x044f, 0xb10a] + ] } ] diff --git a/src/main/resources/assets/controlify/lang/en_us.json b/src/main/resources/assets/controlify/lang/en_us.json index ab9b588..7226b83 100644 --- a/src/main/resources/assets/controlify/lang/en_us.json +++ b/src/main/resources/assets/controlify/lang/en_us.json @@ -202,40 +202,6 @@ "controlify.guide.interact": "Interact", "controlify.guide.pick_block": "Pick Block", - "controlify.joystick_mapping.unmapped.axis": "Axis #%s", - "controlify.joystick_mapping.unmapped.button": "Button #%s", - "controlify.joystick_mapping.unmapped.hat": "Hat #%s", - "controlify.joystick_mapping.unmapped.axis_direction.negative": "(Negative)", - "controlify.joystick_mapping.unmapped.axis_direction.positive": "(Positive)", - "controlify.joystick_mapping.xbox_one.axis.left_stick": "Left Stick", - "controlify.joystick_mapping.xbox_one.axis.left_stick.left": "Left", - "controlify.joystick_mapping.xbox_one.axis.left_stick.right": "Right", - "controlify.joystick_mapping.xbox_one.axis.left_stick.up": "Up", - "controlify.joystick_mapping.xbox_one.axis.left_stick.down": "Down", - "controlify.joystick_mapping.xbox_one.axis.right_stick": "Right Stick", - "controlify.joystick_mapping.xbox_one.axis.right_stick.left": "Left", - "controlify.joystick_mapping.xbox_one.axis.right_stick.right": "Right", - "controlify.joystick_mapping.xbox_one.axis.right_stick.up": "Up", - "controlify.joystick_mapping.xbox_one.axis.right_stick.down": "Down", - "controlify.joystick_mapping.xbox_one.axis.left_trigger": "Left Trigger", - "controlify.joystick_mapping.xbox_one.axis.left_trigger.up": "Up", - "controlify.joystick_mapping.xbox_one.axis.left_trigger.down": "Down", - "controlify.joystick_mapping.xbox_one.axis.right_trigger": "Right Trigger", - "controlify.joystick_mapping.xbox_one.axis.right_trigger.up": "Up", - "controlify.joystick_mapping.xbox_one.axis.right_trigger.down": "Down", - "controlify.joystick_mapping.xbox_one.button.a": "A", - "controlify.joystick_mapping.xbox_one.button.b": "B", - "controlify.joystick_mapping.xbox_one.button.x": "X", - "controlify.joystick_mapping.xbox_one.button.y": "Y", - "controlify.joystick_mapping.xbox_one.button.left_bumper": "Left Bumper", - "controlify.joystick_mapping.xbox_one.button.right_bumper": "Right Bumper", - "controlify.joystick_mapping.xbox_one.button.left_stick": "Left Stick Press", - "controlify.joystick_mapping.xbox_one.button.right_stick": "Right Stick Press", - "controlify.joystick_mapping.xbox_one.button.back": "Back", - "controlify.joystick_mapping.xbox_one.button.start": "Start", - "controlify.joystick_mapping.xbox_one.button.guide": "Guide", - "controlify.joystick_mapping.xbox_one.hat.dpad": "D-Pad", - "controlify.calibration.title": "Controller Calibration for '%s'", "controlify.calibration.info": "This process will optimize settings for your controller to prevent stick drift. Stick drift happens in your controller thumbsticks and outputs slightly wrong values when you aren't touching them at all. Deadzones are used to prevent this.\n\nThis will only take a few seconds.", "controlify.calibration.wait": "Please do not touch your controller thumbsticks until the progress bar is complete. This process will only take a few seconds.", @@ -255,5 +221,33 @@ "controlify.hat_state.up": "Up", "controlify.hat_state.down": "Down", "controlify.hat_state.left": "Left", - "controlify.hat_state.right": "Right" + "controlify.hat_state.right": "Right", + + "controlify.joystick_mapping.unmapped.axis": "Axis #%s", + "controlify.joystick_mapping.unmapped.button": "Button #%s", + "controlify.joystick_mapping.unmapped.hat": "Hat #%s", + "controlify.joystick_mapping.unmapped.axis_direction.negative": "(Negative)", + "controlify.joystick_mapping.unmapped.axis_direction.positive": "(Positive)", + + "controlify.joystick_mapping.tm_t16000.axis.roll": "Roll", + "controlify.joystick_mapping.tm_t16000.axis.pitch": "Pitch", + "controlify.joystick_mapping.tm_t16000.axis.yaw": "Yaw", + "controlify.joystick_mapping.tm_t16000.axis.throttle": "Throttle", + "controlify.joystick_mapping.tm_t16000.button.trigger": "Trigger", + "controlify.joystick_mapping.tm_t16000.button.a": "A", + "controlify.joystick_mapping.tm_t16000.button.x": "X", + "controlify.joystick_mapping.tm_t16000.button.b": "B", + "controlify.joystick_mapping.tm_t16000.left_1": "Left 1", + "controlify.joystick_mapping.tm_t16000.left_2": "Left 2", + "controlify.joystick_mapping.tm_t16000.left_3": "Left 3", + "controlify.joystick_mapping.tm_t16000.left_4": "Left 4", + "controlify.joystick_mapping.tm_t16000.left_5": "Left 5", + "controlify.joystick_mapping.tm_t16000.left_6": "Left 6", + "controlify.joystick_mapping.tm_t16000.right_1": "Right 1", + "controlify.joystick_mapping.tm_t16000.right_2": "Right 2", + "controlify.joystick_mapping.tm_t16000.right_3": "Right 3", + "controlify.joystick_mapping.tm_t16000.right_4": "Right 4", + "controlify.joystick_mapping.tm_t16000.right_5": "Right 5", + "controlify.joystick_mapping.tm_t16000.right_6": "Right 6", + "controlify.joystick_mapping.tm_t16000.hat": "Hat" } diff --git a/src/main/resources/assets/controlify/mappings/compound-5be9f119-838b-3afd-92b3-e1069f897a51_a9dbf1cb-246b-3c70-91c9-40dcf2a13889.json b/src/main/resources/assets/controlify/mappings/compound-5be9f119-838b-3afd-92b3-e1069f897a51_a9dbf1cb-246b-3c70-91c9-40dcf2a13889.json deleted file mode 100644 index d32ef68..0000000 --- a/src/main/resources/assets/controlify/mappings/compound-5be9f119-838b-3afd-92b3-e1069f897a51_a9dbf1cb-246b-3c70-91c9-40dcf2a13889.json +++ /dev/null @@ -1,176 +0,0 @@ -{ - "axes": [ - { - "ids": [0, 1], - "identifier": "ps4_left_stick", - "deadzone": true, - "rest": 0.0, - "axis_names": [ - ["right", "left"], - ["down", "up"] - ] - }, - { - "ids": [2, 5], - "identifier": "ps4_right_stick", - "deadzone": true, - "axis_names": [ - ["right", "left"], - ["down", "up"] - ], - "rest": 0.0 - }, - { - "ids": [3], - "identifier": "ps4_left_trigger", - "rest": 0.0, - "deadzone": false, - "range": [0.0, 1.0], - "axis_names": [ - ["down", "up"] - ] - }, - { - "ids": [4], - "identifier": "ps4_right_trigger", - "rest": 0.0, - "deadzone": false, - "range": [0.0, 1.0], - "axis_names": [ - ["down", "up"] - ] - }, - { - "ids": [6, 7], - "identifier": "xbox_left_stick", - "deadzone": true, - "rest": 0.0, - "axis_names": [ - ["right", "left"], - ["down", "up"] - ] - }, - { - "ids": [8, 9], - "identifier": "xbox_right_stick", - "deadzone": true, - "axis_names": [ - ["right", "left"], - ["down", "up"] - ], - "rest": 0.0 - }, - { - "ids": [10], - "identifier": "xbox_left_trigger", - "deadzone": false, - "rest": 0.0, - "range": [0.0, 1.0], - "axis_names": [ - ["down", "up"] - ] - }, - { - "ids": [11], - "identifier": "xbox_right_trigger", - "deadzone": false, - "rest": 0.0, - "range": [0.0, 1.0], - "axis_names": [ - ["down", "up"] - ] - } - ], - "buttons": [ - { - "button": 0, - "name": "a" - }, - { - "button": 1, - "name": "b" - }, - { - "button": 2, - "name": "x" - }, - { - "button": 3, - "name": "y" - }, - { - "button": 4, - "name": "left_bumper" - }, - { - "button": 5, - "name": "right_bumper" - }, - { - "button": 6, - "name": "back" - }, - { - "button": 7, - "name": "start" - }, - { - "button": 8, - "name": "left_stick" - }, - { - "button": 9, - "name": "right_stick" - }, - { - "button": 10, - "name": "a1" - }, - { - "button": 11, - "name": "b1" - }, - { - "button": 12, - "name": "x1" - }, - { - "button": 13, - "name": "y1" - }, - { - "button": 14, - "name": "left_bumper1" - }, - { - "button": 15, - "name": "right_bumper1" - }, - { - "button": 16, - "name": "back1" - }, - { - "button": 17, - "name": "start1" - }, - { - "button": 18, - "name": "left_stick1" - }, - { - "button": 19, - "name": "right_stick1" - } - ], - "hats": [ - { - "hat": 0, - "name": "dpad_xbox" - }, - { - "hat": 1, - "name": "dpad_ps4" - } - ] -} diff --git a/src/main/resources/assets/controlify/mappings/tm_t16000.json b/src/main/resources/assets/controlify/mappings/tm_t16000.json new file mode 100644 index 0000000..786be43 --- /dev/null +++ b/src/main/resources/assets/controlify/mappings/tm_t16000.json @@ -0,0 +1,113 @@ +{ + "axes": [ + { + "ids": [0], + "identifier": "roll", + "deadzone": true, + "rest": 0.0, + "axis_names": [ + ["right", "left"] + ] + }, + { + "ids": [1], + "identifier": "pitch", + "deadzone": true, + "rest": 0.0, + "axis_names": [ + ["down", "up"] + ] + }, + { + "ids": [2], + "identifier": "yaw", + "deadzone": true, + "rest": 0.0, + "axis_names": [ + ["right", "left"] + ] + }, + { + "ids": [3], + "identifier": "throttle", + "rest": 0.0, + "deadzone": false, + "range": [0.0, 1.0], + "axis_names": [ + ["down", "up"] + ] + } + ], + "buttons": [ + { + "button": 0, + "name": "trigger" + }, + { + "button": 1, + "name": "a" + }, + { + "button": 2, + "name": "x" + }, + { + "button": 3, + "name": "b" + }, + { + "button": 4, + "name": "left_1" + }, + { + "button": 5, + "name": "left_2" + }, + { + "button": 6, + "name": "left_3" + }, + { + "button": 7, + "name": "left_4" + }, + { + "button": 8, + "name": "left_5" + }, + { + "button": 9, + "name": "left_6" + }, + { + "button": 10, + "name": "right_1" + }, + { + "button": 11, + "name": "right_2" + }, + { + "button": 12, + "name": "right_3" + }, + { + "button": 13, + "name": "right_4" + }, + { + "button": 14, + "name": "right_5" + }, + { + "button": 15, + "name": "right_6" + } + ], + "hats": [ + { + "name": "hat", + "hat": 0 + } + ] +}