From 618ccc1cc258c5f0b67aa462dda601b637685dcc Mon Sep 17 00:00:00 2001 From: Speiger Date: Fri, 17 May 2024 15:58:35 +0200 Subject: [PATCH] More work on joystick support --- .../speiger/src/coreengine/NewInputTest.java | 23 +++-- .../rendering/input/devices/Joystick.java | 89 ++++++++++++++++--- .../rendering/input/devices/Keyboard.java | 2 +- .../rendering/input/window/Window.java | 2 + .../input/window/WindowCallback.java | 6 ++ 5 files changed, 101 insertions(+), 21 deletions(-) diff --git a/src/main/java/speiger/src/coreengine/NewInputTest.java b/src/main/java/speiger/src/coreengine/NewInputTest.java index 9dc5343..da7dc79 100644 --- a/src/main/java/speiger/src/coreengine/NewInputTest.java +++ b/src/main/java/speiger/src/coreengine/NewInputTest.java @@ -1,20 +1,31 @@ package speiger.src.coreengine; -import speiger.src.coreengine.rendering.input.window.Window; -import speiger.src.coreengine.rendering.input.window.WindowManager; +import org.lwjgl.glfw.GLFW; + +import speiger.src.coreengine.rendering.input.devices.Joystick; +import speiger.src.coreengine.rendering.input.devices.Joystick.ButtonData; +import speiger.src.coreengine.utils.eventbus.EventBus; public class NewInputTest { - WindowManager manager = new WindowManager(); + EventBus bus = new EventBus(); public static void main(String[] args) { - new NewInputTest(); + new NewInputTest().run(); } public void run() { - Window window = manager.builder().title("Testing").build(); + GLFW.glfwInit(); + Joystick.INSTANCE.init(bus); + ButtonData data = new ButtonData(); while(true) { - + Joystick.INSTANCE.handleJoystick(GLFW.GLFW_JOYSTICK_1, data); + try { + Thread.sleep(100); + } + catch(InterruptedException e) { + e.printStackTrace(); + } } } } diff --git a/src/main/java/speiger/src/coreengine/rendering/input/devices/Joystick.java b/src/main/java/speiger/src/coreengine/rendering/input/devices/Joystick.java index 1891abf..bb7fed0 100644 --- a/src/main/java/speiger/src/coreengine/rendering/input/devices/Joystick.java +++ b/src/main/java/speiger/src/coreengine/rendering/input/devices/Joystick.java @@ -1,37 +1,98 @@ package speiger.src.coreengine.rendering.input.devices; -import org.lwjgl.glfw.GLFW; -import org.lwjgl.glfw.GLFWGamepadState; +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.util.BitSet; +import org.lwjgl.glfw.GLFW; +import org.lwjgl.system.Callback; + +import speiger.src.collections.floats.lists.FloatArrayList; +import speiger.src.collections.floats.lists.FloatList; +import speiger.src.collections.ints.sets.IntLinkedOpenHashSet; +import speiger.src.collections.ints.sets.IntSet; +import speiger.src.collections.longs.collections.LongIterator; import speiger.src.coreengine.rendering.input.devices.Joystick.JoyStickData; import speiger.src.coreengine.rendering.input.devices.Joystick.JoyStickTask; -import speiger.src.coreengine.rendering.input.window.Window; +import speiger.src.coreengine.utils.eventbus.EventBus; public class Joystick extends AbstractDevice { + public static final Joystick INSTANCE = new Joystick(); + IntSet presentJoysticks = new IntLinkedOpenHashSet(); + Callback callback; @Override - protected void registerCallbacks(Window window) { - super.registerCallbacks(window); + public void init(EventBus bus) { + super.init(bus); + callback = GLFW.glfwSetJoystickCallback(this::plugin); + for(int i = 0,m=GLFW.GLFW_JOYSTICK_LAST;i<=m;i++) { + if(GLFW.glfwJoystickPresent(i)) { + presentJoysticks.add(i); + } + } + } + + public void destroy() { + callback.free(); + } + + private void plugin(int jid, int event) { + if(event == GLFW.GLFW_CONNECTED) presentJoysticks.add(jid); + else presentJoysticks.remove(jid); + for(LongIterator iter = knownWindows().iterator();iter.hasNext();) { + long window = iter.nextLong(); + push(window, new Plugin(window, jid, event)); + } } @Override - public void reset(long windowId) { - - } + public void reset(long windowId) {} @Override - protected JoyStickData createData(long windowId) { - return new JoyStickData(); - } + protected JoyStickData createData(long windowId) { return new JoyStickData(); } @Override - protected void process(JoyStickTask task) { - + protected void process(JoyStickTask task) { task.process(this); } + + @Override + public void processInput(long windowId) { + super.processInput(windowId); + } + + public void handleJoystick(int jid, ButtonData data) { + ByteBuffer buttons = GLFW.glfwGetJoystickButtons(jid); + for(int i = 0;buttons.hasRemaining();i++) { + data.buttons.set(i, buttons.get() == GLFW.GLFW_PRESS); + } + FloatBuffer axis = GLFW.glfwGetJoystickAxes(jid); + for(int i = 0;axis.hasRemaining();i++) { + float state = axis.get(); + if(i >= data.axis.size()) data.axis.add(state); + else data.axis.set(i, state); + boolean max = state < -0.95F || state > 0.95F; + boolean min = state < -0.5F || state > 0.5F; + data.axisState.set(i*3, state < 0); + data.axisState.set(i*3+1, max); + data.axisState.set(i*3+2, !max && min); + } } public static class JoyStickData { } + public static class ButtonData { + BitSet buttons = new BitSet(); + FloatList axis = new FloatArrayList(); + BitSet axisState = new BitSet(); + } + public static interface JoyStickTask { - + public void process(Joystick stick); + } + + public record Plugin(long window, int jid, int event) implements JoyStickTask { + @Override + public void process(Joystick stick) { + + } } } diff --git a/src/main/java/speiger/src/coreengine/rendering/input/devices/Keyboard.java b/src/main/java/speiger/src/coreengine/rendering/input/devices/Keyboard.java index c885a3d..52b3c95 100644 --- a/src/main/java/speiger/src/coreengine/rendering/input/devices/Keyboard.java +++ b/src/main/java/speiger/src/coreengine/rendering/input/devices/Keyboard.java @@ -12,7 +12,7 @@ import speiger.src.coreengine.rendering.input.window.Window; public class Keyboard extends AbstractDevice { @Override - public void reset(long windowId) { get(windowId).reset(); } + public void reset(long windowId) {} @Override protected KeyData createData(long windowId) { return new KeyData(); } @Override diff --git a/src/main/java/speiger/src/coreengine/rendering/input/window/Window.java b/src/main/java/speiger/src/coreengine/rendering/input/window/Window.java index 0bf5a1a..2845c43 100644 --- a/src/main/java/speiger/src/coreengine/rendering/input/window/Window.java +++ b/src/main/java/speiger/src/coreengine/rendering/input/window/Window.java @@ -11,6 +11,7 @@ import speiger.src.collections.objects.lists.ObjectArrayList; import speiger.src.coreengine.math.vector.ints.Vec4i; import speiger.src.coreengine.rendering.input.window.IWindowListener.Reason; import speiger.src.coreengine.rendering.input.window.WindowCallback.ReloadFunction; +import speiger.src.coreengine.rendering.input.window.WindowCallback.SimpleReloadFunction; import speiger.src.coreengine.rendering.input.window.WindowManager.WindowBuilder; import speiger.src.coreengine.rendering.utils.GLStateTracker; import speiger.src.coreengine.utils.collections.FlagHolder; @@ -155,6 +156,7 @@ public class Window { callbacks.clear(); } + public WindowCallback addSimpleCallback(T listener, SimpleReloadFunction function) { return addCallback(listener, function); } @SuppressWarnings("unchecked") public WindowCallback addCallback(T listener, ReloadFunction function) { WindowCallback callback = new WindowCallback(listener, (ReloadFunction)function); diff --git a/src/main/java/speiger/src/coreengine/rendering/input/window/WindowCallback.java b/src/main/java/speiger/src/coreengine/rendering/input/window/WindowCallback.java index a0a6aba..6ace78e 100644 --- a/src/main/java/speiger/src/coreengine/rendering/input/window/WindowCallback.java +++ b/src/main/java/speiger/src/coreengine/rendering/input/window/WindowCallback.java @@ -30,5 +30,11 @@ public class WindowCallback { public static interface ReloadFunction { Callback applyListener(long window, T listener); + + } + public static interface SimpleReloadFunction extends ReloadFunction { + Callback applyListener(T listener); + @Override + default Callback applyListener(long window, T listener) { return applyListener(listener); } } }