forked from Clones/Controlify
127 lines
3.8 KiB
Java
127 lines
3.8 KiB
Java
package dev.isxander.controlify.controller.joystick;
|
|
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.JsonElement;
|
|
import dev.isxander.controlify.bindings.ControllerBindings;
|
|
import dev.isxander.controlify.controller.AbstractController;
|
|
import dev.isxander.controlify.hid.ControllerHIDService;
|
|
import dev.isxander.controlify.controller.joystick.mapping.RPJoystickMapping;
|
|
import dev.isxander.controlify.controller.joystick.mapping.JoystickMapping;
|
|
import dev.isxander.controlify.controller.sdl2.SDL2NativesManager;
|
|
import dev.isxander.controlify.rumble.RumbleManager;
|
|
import dev.isxander.controlify.rumble.RumbleSource;
|
|
import dev.isxander.controlify.utils.Log;
|
|
import org.libsdl.SDL;
|
|
|
|
import java.util.Objects;
|
|
|
|
public class SingleJoystickController extends AbstractController<JoystickState, JoystickConfig> implements JoystickController<JoystickConfig> {
|
|
private JoystickState state = JoystickState.EMPTY, prevState = JoystickState.EMPTY;
|
|
private final JoystickMapping mapping;
|
|
|
|
private final long ptrJoystick;
|
|
private RumbleManager rumbleManager;
|
|
private boolean rumbleSupported;
|
|
|
|
public SingleJoystickController(int joystickId, ControllerHIDService.ControllerHIDInfo hidInfo) {
|
|
super(joystickId, hidInfo);
|
|
|
|
this.mapping = Objects.requireNonNull(RPJoystickMapping.fromType(this));
|
|
|
|
this.config = new JoystickConfig(this);
|
|
this.defaultConfig = new JoystickConfig(this);
|
|
|
|
this.ptrJoystick = SDL2NativesManager.isLoaded() ? SDL.SDL_JoystickOpen(joystickId) : 0;
|
|
this.rumbleSupported = SDL2NativesManager.isLoaded() && SDL.SDL_JoystickHasRumble(this.ptrJoystick);
|
|
this.rumbleManager = new RumbleManager(this);
|
|
|
|
this.bindings = new ControllerBindings<>(this);
|
|
|
|
this.config.validateRadialActions(bindings);
|
|
this.defaultConfig.validateRadialActions(bindings);
|
|
}
|
|
|
|
@Override
|
|
public JoystickState state() {
|
|
return state;
|
|
}
|
|
|
|
@Override
|
|
public JoystickState prevState() {
|
|
return prevState;
|
|
}
|
|
|
|
@Override
|
|
public void updateState() {
|
|
prevState = state;
|
|
state = JoystickState.fromJoystick(this, joystickId);
|
|
}
|
|
|
|
@Override
|
|
public void clearState() {
|
|
this.state = JoystickState.empty(this);
|
|
}
|
|
|
|
@Override
|
|
public JoystickMapping mapping() {
|
|
return mapping;
|
|
}
|
|
|
|
@Override
|
|
public int axisCount() {
|
|
return mapping().axes().length;
|
|
}
|
|
|
|
@Override
|
|
public int buttonCount() {
|
|
return mapping.buttons().length;
|
|
}
|
|
|
|
@Override
|
|
public int hatCount() {
|
|
return mapping.hats().length;
|
|
}
|
|
|
|
@Override
|
|
public int joystickId() {
|
|
return joystickId;
|
|
}
|
|
|
|
@Override
|
|
public void setConfig(Gson gson, JsonElement json) {
|
|
super.setConfig(gson, json);
|
|
this.config.setup(this);
|
|
}
|
|
|
|
@Override
|
|
public boolean setRumble(float strongMagnitude, float weakMagnitude) {
|
|
if (!supportsRumble()) return false;
|
|
|
|
// the duration doesn't matter because we are not updating the joystick state,
|
|
// so there is never any SDL check to stop the rumble after the desired time.
|
|
if (!SDL.SDL_JoystickRumbleTriggers(ptrJoystick, (int)(strongMagnitude * 65535.0F), (int)(weakMagnitude * 65535.0F), 1)) {
|
|
Log.LOGGER.error("Could not rumble controller " + name() + ": " + SDL.SDL_GetError());
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean supportsRumble() {
|
|
return rumbleSupported;
|
|
}
|
|
|
|
@Override
|
|
public RumbleManager rumbleManager() {
|
|
return this.rumbleManager;
|
|
}
|
|
|
|
@Override
|
|
public void close() {
|
|
if (ptrJoystick != 0)
|
|
SDL.SDL_JoystickClose(ptrJoystick);
|
|
this.rumbleSupported = false;
|
|
this.rumbleManager = null;
|
|
}
|
|
}
|