More work on joystick support

This commit is contained in:
Speiger 2024-05-17 15:58:35 +02:00
parent 0caf508535
commit 618ccc1cc2
5 changed files with 101 additions and 21 deletions

View File

@ -1,20 +1,31 @@
package speiger.src.coreengine; package speiger.src.coreengine;
import speiger.src.coreengine.rendering.input.window.Window; import org.lwjgl.glfw.GLFW;
import speiger.src.coreengine.rendering.input.window.WindowManager;
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 { public class NewInputTest {
WindowManager manager = new WindowManager(); EventBus bus = new EventBus();
public static void main(String[] args) { public static void main(String[] args) {
new NewInputTest(); new NewInputTest().run();
} }
public void run() { public void run() {
Window window = manager.builder().title("Testing").build(); GLFW.glfwInit();
Joystick.INSTANCE.init(bus);
ButtonData data = new ButtonData();
while(true) { while(true) {
Joystick.INSTANCE.handleJoystick(GLFW.GLFW_JOYSTICK_1, data);
try {
Thread.sleep(100);
}
catch(InterruptedException e) {
e.printStackTrace();
}
} }
} }
} }

View File

@ -1,37 +1,98 @@
package speiger.src.coreengine.rendering.input.devices; package speiger.src.coreengine.rendering.input.devices;
import org.lwjgl.glfw.GLFW; import java.nio.ByteBuffer;
import org.lwjgl.glfw.GLFWGamepadState; 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.JoyStickData;
import speiger.src.coreengine.rendering.input.devices.Joystick.JoyStickTask; 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<JoyStickData, JoyStickTask> { public class Joystick extends AbstractDevice<JoyStickData, JoyStickTask> {
public static final Joystick INSTANCE = new Joystick();
IntSet presentJoysticks = new IntLinkedOpenHashSet();
Callback callback;
@Override @Override
protected void registerCallbacks(Window window) { public void init(EventBus bus) {
super.registerCallbacks(window); 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 @Override
public void reset(long windowId) { public void reset(long windowId) {}
}
@Override @Override
protected JoyStickData createData(long windowId) { protected JoyStickData createData(long windowId) { return new JoyStickData(); }
return new JoyStickData();
}
@Override @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 JoyStickData {
} }
public static interface JoyStickTask { 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) {
}
} }
} }

View File

@ -12,7 +12,7 @@ import speiger.src.coreengine.rendering.input.window.Window;
public class Keyboard extends AbstractDevice<KeyData, KeyTask> { public class Keyboard extends AbstractDevice<KeyData, KeyTask> {
@Override @Override
public void reset(long windowId) { get(windowId).reset(); } public void reset(long windowId) {}
@Override @Override
protected KeyData createData(long windowId) { return new KeyData(); } protected KeyData createData(long windowId) { return new KeyData(); }
@Override @Override

View File

@ -11,6 +11,7 @@ import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.math.vector.ints.Vec4i; import speiger.src.coreengine.math.vector.ints.Vec4i;
import speiger.src.coreengine.rendering.input.window.IWindowListener.Reason; 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.ReloadFunction;
import speiger.src.coreengine.rendering.input.window.WindowCallback.SimpleReloadFunction;
import speiger.src.coreengine.rendering.input.window.WindowManager.WindowBuilder; import speiger.src.coreengine.rendering.input.window.WindowManager.WindowBuilder;
import speiger.src.coreengine.rendering.utils.GLStateTracker; import speiger.src.coreengine.rendering.utils.GLStateTracker;
import speiger.src.coreengine.utils.collections.FlagHolder; import speiger.src.coreengine.utils.collections.FlagHolder;
@ -155,6 +156,7 @@ public class Window {
callbacks.clear(); callbacks.clear();
} }
public <T extends CallbackI> WindowCallback addSimpleCallback(T listener, SimpleReloadFunction<T> function) { return addCallback(listener, function); }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends CallbackI> WindowCallback addCallback(T listener, ReloadFunction<T> function) { public <T extends CallbackI> WindowCallback addCallback(T listener, ReloadFunction<T> function) {
WindowCallback callback = new WindowCallback(listener, (ReloadFunction<CallbackI>)function); WindowCallback callback = new WindowCallback(listener, (ReloadFunction<CallbackI>)function);

View File

@ -30,5 +30,11 @@ public class WindowCallback {
public static interface ReloadFunction<T extends CallbackI> { public static interface ReloadFunction<T extends CallbackI> {
Callback applyListener(long window, T listener); Callback applyListener(long window, T listener);
}
public static interface SimpleReloadFunction<T extends CallbackI> extends ReloadFunction<T> {
Callback applyListener(T listener);
@Override
default Callback applyListener(long window, T listener) { return applyListener(listener); }
} }
} }