- Gamepad optimisations (now works on 1.13+)

This commit is contained in:
SerpentSpirale 2021-07-19 16:03:12 +02:00
parent 5855b1ef93
commit c2e851fc8f
2 changed files with 126 additions and 99 deletions

View File

@ -31,10 +31,10 @@ import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.isJoyst
public class Gamepad {
private BaseMainActivity gameActivity;
private ImageView pointerView;
private final BaseMainActivity gameActivity;
private final ImageView pointerView;
private GamepadDpad gamepadDpad = new GamepadDpad(this);
private final GamepadDpad gamepadDpad = new GamepadDpad(this);
private final GamepadJoystick leftJoystick;
private int currentJoystickDirection = DIRECTION_NONE;
@ -50,17 +50,17 @@ public class Gamepad {
private double mouseAngle;
private double mouseSensitivity = 19;
private final GamepadMap gameMap = new GamepadMap();
private final GamepadMap menuMap = new GamepadMap();
private final GamepadMap gameMap = GamepadMap.getDefaultGameMap();
private final GamepadMap menuMap = GamepadMap.getDefaultMenuMap();
private GamepadMap currentMap = gameMap;
private boolean lastGrabbingState = true;
private MotionEvent lastMotionEvent = null;
private final Thread mouseThread;
private final Runnable mouseRunnable;
private final Runnable switchStateRunnable;
private final Runnable motionEventRunnable;
public Gamepad(BaseMainActivity gameActivity, InputDevice inputDevice){
Toast.makeText(gameActivity.getApplicationContext(),"GAMEPAD CREATED", Toast.LENGTH_LONG).show();
@ -68,10 +68,8 @@ public class Gamepad {
leftJoystick = new GamepadJoystick(MotionEvent.AXIS_X, MotionEvent.AXIS_Y, inputDevice);
rightJoystick = new GamepadJoystick(MotionEvent.AXIS_Z, MotionEvent.AXIS_RZ, inputDevice);
this.gameActivity = gameActivity;
pointerView = this.gameActivity.findViewById(R.id.console_pointer);
createMapping();
mouseThread = new Thread("Gamepad Thread"){
long lastTime = System.nanoTime();
@ -89,32 +87,21 @@ public class Gamepad {
if(delta >= 1) {
updateGrabbingState();
tick();
delta--;
try {
sleep(Math.max((long) ( (1 - delta) * (1000/ticks) ), 0));
} catch (InterruptedException e) {
e.printStackTrace();
}
try{ sleep(Math.max((long) ( (1 - delta) * (1000/ticks) ), 0)); } catch (InterruptedException e) {e.printStackTrace();}
}
}
}
private void tick(){
if(lastMotionEvent != null){
updateDirectionalJoystick(lastMotionEvent);
updateMouseJoystick(lastMotionEvent);
updateAnalogTriggers(lastMotionEvent);
}
//Update motion events, and the mouse position
if(lastMotionEvent != null)gameActivity.runOnUiThread(motionEventRunnable);
if(lastHorizontalValue != 0 || lastVerticalValue != 0){
GamepadJoystick currentJoystick = CallbackBridge.isGrabbing() ? leftJoystick : rightJoystick;
GamepadJoystick currentJoystick = lastGrabbingState ? leftJoystick : rightJoystick;
acceleration = (mouseMagnitude - currentJoystick.getDeadzone())/(1 - currentJoystick.getDeadzone());
acceleration = Math.pow(acceleration, mouseMaxAcceleration);
@ -127,7 +114,7 @@ public class Gamepad {
gameActivity.runOnUiThread(mouseRunnable);
if(!CallbackBridge.isGrabbing()){
if(!lastGrabbingState){
CallbackBridge.mouseX = MathUtils.clamp(CallbackBridge.mouseX, 0, CallbackBridge.windowWidth);
CallbackBridge.mouseY = MathUtils.clamp(CallbackBridge.mouseY, 0, CallbackBridge.windowHeight);
placePointerView((int) (CallbackBridge.mouseX /gameActivity.scaleFactor), (int) (CallbackBridge.mouseY/gameActivity.scaleFactor));
@ -164,6 +151,14 @@ public class Gamepad {
pointerView.setVisibility(View.VISIBLE);
mouseSensitivity = 15; //sensitivity in game doesn't need to be resolution dependent
};
motionEventRunnable = () -> {
updateDirectionalJoystick(lastMotionEvent);
updateMouseJoystick(lastMotionEvent);
updateAnalogTriggers(lastMotionEvent);
gamepadDpad.update(lastMotionEvent);
};
}
private void updateGrabbingState() {
@ -174,83 +169,18 @@ public class Gamepad {
}
}
private void createMapping(){
//create mappings to fit our needs
//GAMEMAP
gameMap.BUTTON_A.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_SPACE};
gameMap.BUTTON_B.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_Q};
gameMap.BUTTON_X.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_F};
gameMap.BUTTON_Y.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_E};
gameMap.DIRECTION_FORWARD = new int[]{LWJGLGLFWKeycode.GLFW_KEY_W};
gameMap.DIRECTION_BACKWARD = new int[]{LWJGLGLFWKeycode.GLFW_KEY_S};
gameMap.DIRECTION_RIGHT = new int[]{LWJGLGLFWKeycode.GLFW_KEY_D};
gameMap.DIRECTION_LEFT = new int[]{LWJGLGLFWKeycode.GLFW_KEY_A};
gameMap.DPAD_UP.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_W};
gameMap.DPAD_DOWN.keycodes = new int[]{};
gameMap.DPAD_RIGHT.keycodes = new int[]{};
gameMap.DPAD_LEFT.keycodes = new int[]{};
gameMap.SHOULDER_LEFT.keycodes = new int[]{GamepadMap.MOUSE_SCROLL_UP};
gameMap.SHOULDER_RIGHT.keycodes = new int[]{GamepadMap.MOUSE_SCROLL_DOWN};
gameMap.TRIGGER_LEFT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT};
gameMap.TRIGGER_RIGHT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT};
gameMap.THUMBSTICK_LEFT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT};
gameMap.THUMBSTICK_LEFT.isToggleable = true;
gameMap.THUMBSTICK_RIGHT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_F5};
gameMap.BUTTON_START.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_ESCAPE};
gameMap.BUTTON_SELECT.keycodes = new int[]{};
//MENU MAP
menuMap.BUTTON_A.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT};
menuMap.BUTTON_B.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_ESCAPE};
menuMap.BUTTON_X.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT};
menuMap.BUTTON_Y.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT, LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT}; //Oops, doesn't work since left shift isn't properly applied.
menuMap.DIRECTION_FORWARD = new int[]{GamepadMap.MOUSE_SCROLL_UP, GamepadMap.MOUSE_SCROLL_UP, GamepadMap.MOUSE_SCROLL_UP, GamepadMap.MOUSE_SCROLL_UP, GamepadMap.MOUSE_SCROLL_UP};
menuMap.DIRECTION_BACKWARD = new int[]{GamepadMap.MOUSE_SCROLL_DOWN, GamepadMap.MOUSE_SCROLL_DOWN, GamepadMap.MOUSE_SCROLL_DOWN, GamepadMap.MOUSE_SCROLL_DOWN, GamepadMap.MOUSE_SCROLL_DOWN};
menuMap.DIRECTION_RIGHT = new int[]{};
menuMap.DIRECTION_LEFT = new int[]{};
menuMap.DPAD_UP.keycodes = new int[]{};
menuMap.DPAD_DOWN.keycodes = new int[]{};
menuMap.DPAD_RIGHT.keycodes = new int[]{};
menuMap.DPAD_LEFT.keycodes = new int[]{};
menuMap.SHOULDER_LEFT.keycodes = new int[]{GamepadMap.MOUSE_SCROLL_UP};
menuMap.SHOULDER_RIGHT.keycodes = new int[]{GamepadMap.MOUSE_SCROLL_DOWN};
menuMap.TRIGGER_LEFT.keycodes = new int[]{};
menuMap.TRIGGER_RIGHT.keycodes = new int[]{};
menuMap.THUMBSTICK_LEFT.keycodes = new int[]{};
menuMap.THUMBSTICK_RIGHT.keycodes = new int[]{};
menuMap.BUTTON_START.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_ESCAPE};
menuMap.BUTTON_SELECT.keycodes = new int[]{};
}
public void update(KeyEvent event){
gamepadDpad.update(event);
sendButton(event);
}
public void update(MotionEvent event){
//Motion events are taken into account every 1/60th second
lastMotionEvent = event;
if(gamepadDpad.update(event) != -1) return;
//The rest of events are now sent each 1/60 second.
}
private void updateMouseJoystick(MotionEvent event){
GamepadJoystick currentJoystick = CallbackBridge.isGrabbing() ? rightJoystick : leftJoystick;
GamepadJoystick currentJoystick = lastGrabbingState ? rightJoystick : leftJoystick;
lastHorizontalValue = currentJoystick.getHorizontalAxis(event);
lastVerticalValue = currentJoystick.getVerticalAxis(event);
@ -259,7 +189,7 @@ public class Gamepad {
}
private void updateDirectionalJoystick(MotionEvent event){
GamepadJoystick currentJoystick = CallbackBridge.isGrabbing() ? leftJoystick : rightJoystick;
GamepadJoystick currentJoystick = lastGrabbingState ? leftJoystick : rightJoystick;
int lastJoystickDirection = currentJoystickDirection;
currentJoystickDirection = currentJoystick.getHeightDirection(event);

View File

@ -2,22 +2,16 @@ package net.kdt.pojavlaunch.customcontrols.gamepad;
import net.kdt.pojavlaunch.LWJGLGLFWKeycode;
import java.security.PublicKey;
import java.util.HashMap;
public class GamepadMap {
public static final int MOUSE_SCROLL_DOWN = -1;
public static final int MOUSE_SCROLL_UP = -2;
/*
This class is just here to store the mapping
can be modified to create re-mappable controls I guess
Be warned, you should define ALL keys if you want to avoid a non defined exception
*/
public GamepadButton BUTTON_A = new GamepadButton();
@ -48,6 +42,9 @@ public class GamepadMap {
public GamepadButton DPAD_LEFT = new GamepadButton();
/*
* Sets all buttons to a not pressed state, sending an input if needed
*/
public void resetPressedState(){
BUTTON_A.resetButtonState();
BUTTON_B.resetButtonState();
@ -73,5 +70,105 @@ public class GamepadMap {
}
/*
* Returns a pre-done mapping used when the mouse is grabbed by the game.
*/
public static GamepadMap getDefaultGameMap(){
GamepadMap gameMap = new GamepadMap();
gameMap.BUTTON_A.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_SPACE};
gameMap.BUTTON_B.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_Q};
gameMap.BUTTON_X.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_F};
gameMap.BUTTON_Y.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_E};
gameMap.DIRECTION_FORWARD = new int[]{LWJGLGLFWKeycode.GLFW_KEY_W};
gameMap.DIRECTION_BACKWARD = new int[]{LWJGLGLFWKeycode.GLFW_KEY_S};
gameMap.DIRECTION_RIGHT = new int[]{LWJGLGLFWKeycode.GLFW_KEY_D};
gameMap.DIRECTION_LEFT = new int[]{LWJGLGLFWKeycode.GLFW_KEY_A};
gameMap.DPAD_UP.keycodes = new int[]{};
gameMap.DPAD_DOWN.keycodes = new int[]{};
gameMap.DPAD_RIGHT.keycodes = new int[]{};
gameMap.DPAD_LEFT.keycodes = new int[]{};
gameMap.SHOULDER_LEFT.keycodes = new int[]{GamepadMap.MOUSE_SCROLL_UP};
gameMap.SHOULDER_RIGHT.keycodes = new int[]{GamepadMap.MOUSE_SCROLL_DOWN};
gameMap.TRIGGER_LEFT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT};
gameMap.TRIGGER_RIGHT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT};
gameMap.THUMBSTICK_LEFT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT};
gameMap.THUMBSTICK_LEFT.isToggleable = true;
gameMap.THUMBSTICK_RIGHT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_F5};
gameMap.BUTTON_START.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_ESCAPE};
gameMap.BUTTON_SELECT.keycodes = new int[]{};
return gameMap;
}
/*
* Returns a pre-done mapping used when the mouse is NOT grabbed by the game.
*/
public static GamepadMap getDefaultMenuMap(){
GamepadMap menuMap = new GamepadMap();
menuMap.BUTTON_A.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT};
menuMap.BUTTON_B.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_ESCAPE};
menuMap.BUTTON_X.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT};
menuMap.BUTTON_Y.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT, LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT}; //Oops, doesn't work since left shift isn't properly applied.
menuMap.DIRECTION_FORWARD = new int[]{GamepadMap.MOUSE_SCROLL_UP, GamepadMap.MOUSE_SCROLL_UP, GamepadMap.MOUSE_SCROLL_UP, GamepadMap.MOUSE_SCROLL_UP, GamepadMap.MOUSE_SCROLL_UP};
menuMap.DIRECTION_BACKWARD = new int[]{GamepadMap.MOUSE_SCROLL_DOWN, GamepadMap.MOUSE_SCROLL_DOWN, GamepadMap.MOUSE_SCROLL_DOWN, GamepadMap.MOUSE_SCROLL_DOWN, GamepadMap.MOUSE_SCROLL_DOWN};
menuMap.DIRECTION_RIGHT = new int[]{};
menuMap.DIRECTION_LEFT = new int[]{};
menuMap.DPAD_UP.keycodes = new int[]{};
menuMap.DPAD_DOWN.keycodes = new int[]{};
menuMap.DPAD_RIGHT.keycodes = new int[]{};
menuMap.DPAD_LEFT.keycodes = new int[]{};
menuMap.SHOULDER_LEFT.keycodes = new int[]{GamepadMap.MOUSE_SCROLL_UP};
menuMap.SHOULDER_RIGHT.keycodes = new int[]{GamepadMap.MOUSE_SCROLL_DOWN};
menuMap.TRIGGER_LEFT.keycodes = new int[]{};
menuMap.TRIGGER_RIGHT.keycodes = new int[]{};
menuMap.THUMBSTICK_LEFT.keycodes = new int[]{};
menuMap.THUMBSTICK_RIGHT.keycodes = new int[]{};
menuMap.BUTTON_START.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_ESCAPE};
menuMap.BUTTON_SELECT.keycodes = new int[]{};
return menuMap;
}
/*
* Returns all GamepadButtons, does not include directional keys
*/
public GamepadButton[] getButtons(){
return new GamepadButton[]{ BUTTON_A, BUTTON_B, BUTTON_X, BUTTON_Y,
BUTTON_SELECT, BUTTON_START,
TRIGGER_LEFT, TRIGGER_RIGHT,
SHOULDER_LEFT, SHOULDER_RIGHT,
THUMBSTICK_LEFT, THUMBSTICK_RIGHT,
DPAD_UP, DPAD_RIGHT, DPAD_DOWN, DPAD_LEFT};
}
/*
* Returns an pre-initialized GamepadMap with only empty keycodes
*/
public static GamepadMap getEmptyMap(){
GamepadMap emptyMap = new GamepadMap();
for(GamepadButton button : emptyMap.getButtons())
button.keycodes = new int[]{};
emptyMap.DIRECTION_LEFT = new int[]{};
emptyMap.DIRECTION_FORWARD = new int[]{};
emptyMap.DIRECTION_RIGHT = new int[]{};
emptyMap.DIRECTION_BACKWARD = new int[]{};
return emptyMap;
}
}