mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-12 06:05:10 -04:00
Feat[V 2.Gamepad]: Merge #4179
* Feat: gamepad remapping, with custom deazone * Fix[gamepad]: wrong starting pointer offset * cleanup[gamepad]: Remove useless variables * Fix[gamepad]: Reduce jitter Turns out the argument was a bit off when there are cpu constraints * Chore: bump up remapper library version * Build: bump up library version
This commit is contained in:
parent
7916166795
commit
809f5cd6e5
@ -157,6 +157,7 @@ dependencies {
|
||||
implementation 'com.github.PojavLauncherTeam:portrait-sdp:ed33e89cbc'
|
||||
implementation 'com.github.PojavLauncherTeam:portrait-ssp:6c02fd739b'
|
||||
implementation 'com.github.Mathias-Boulay:ExtendedView:1.0.0'
|
||||
implementation 'com.github.Mathias-Boulay:android_gamepad_remapper:71397676b5'
|
||||
|
||||
|
||||
// implementation 'com.intuit.sdp:sdp-android:1.0.5'
|
||||
|
@ -39,12 +39,32 @@ import net.kdt.pojavlaunch.utils.MathUtils;
|
||||
|
||||
import org.lwjgl.glfw.CallbackBridge;
|
||||
|
||||
import fr.spse.gamepad_remapper.RemapperManager;
|
||||
import fr.spse.gamepad_remapper.RemapperView;
|
||||
|
||||
/**
|
||||
* Class dealing with showing minecraft surface and taking inputs to dispatch them to minecraft
|
||||
*/
|
||||
public class MinecraftGLSurface extends View implements GrabListener{
|
||||
public class MinecraftGLSurface extends View implements GrabListener {
|
||||
/* Gamepad object for gamepad inputs, instantiated on need */
|
||||
private Gamepad mGamepad = null;
|
||||
/* The RemapperView.Builder object allows you to set which buttons to remap */
|
||||
private final RemapperManager mInputManager = new RemapperManager(getContext(), new RemapperView.Builder(null)
|
||||
.remapA(true)
|
||||
.remapB(true)
|
||||
.remapX(true)
|
||||
.remapY(true)
|
||||
|
||||
.remapDpad(true)
|
||||
.remapLeftJoystick(true)
|
||||
.remapRightJoystick(true)
|
||||
.remapStart(true)
|
||||
.remapSelect(true)
|
||||
.remapLeftShoulder(true)
|
||||
.remapRightShoulder(true)
|
||||
.remapLeftTrigger(true)
|
||||
.remapRightTrigger(true));
|
||||
|
||||
/* Resolution scaler option, allow downsizing a window */
|
||||
private final float mScaleFactor = LauncherPreferences.PREF_SCALE_FACTOR/100f;
|
||||
/* Sensitivity, adjusted according to screen size */
|
||||
@ -385,7 +405,7 @@ public class MinecraftGLSurface extends View implements GrabListener{
|
||||
mGamepad = new Gamepad(this, event.getDevice());
|
||||
}
|
||||
|
||||
mGamepad.update(event);
|
||||
mInputManager.handleMotionEventInput(getContext(), event, mGamepad);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -479,7 +499,7 @@ public class MinecraftGLSurface extends View implements GrabListener{
|
||||
mGamepad = new Gamepad(this, event.getDevice());
|
||||
}
|
||||
|
||||
mGamepad.update(event);
|
||||
mInputManager.handleKeyEventInput(getContext(), event, mGamepad);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,15 @@
|
||||
package net.kdt.pojavlaunch.customcontrols.gamepad;
|
||||
|
||||
|
||||
import static android.view.MotionEvent.AXIS_HAT_X;
|
||||
import static android.view.MotionEvent.AXIS_HAT_Y;
|
||||
import static android.view.MotionEvent.AXIS_LTRIGGER;
|
||||
import static android.view.MotionEvent.AXIS_RTRIGGER;
|
||||
import static android.view.MotionEvent.AXIS_RZ;
|
||||
import static android.view.MotionEvent.AXIS_X;
|
||||
import static android.view.MotionEvent.AXIS_Y;
|
||||
import static android.view.MotionEvent.AXIS_Z;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.Choreographer;
|
||||
import android.view.InputDevice;
|
||||
@ -38,19 +47,18 @@ import static net.kdt.pojavlaunch.utils.MCOptionUtils.getMcScale;
|
||||
import static org.lwjgl.glfw.CallbackBridge.sendKeyPress;
|
||||
import static org.lwjgl.glfw.CallbackBridge.sendMouseButton;
|
||||
|
||||
public class Gamepad implements GrabListener {
|
||||
import fr.spse.gamepad_remapper.GamepadHandler;
|
||||
|
||||
public class Gamepad implements GrabListener, GamepadHandler {
|
||||
|
||||
/* Resolution scaler option, allow downsizing a window */
|
||||
private final float mScaleFactor = LauncherPreferences.DEFAULT_PREF.getInt("resolutionRatio",100)/100f;
|
||||
/* Mouse positions, scaled by the scaleFactor */
|
||||
private float mMouse_x, mMouse_y;
|
||||
|
||||
/* Sensitivity, adjusted according to screen size */
|
||||
private final double mSensitivityFactor = (1.4 * (1080f/ currentDisplayMetrics.heightPixels));
|
||||
|
||||
private final ImageView mPointerImageView;
|
||||
|
||||
private final GamepadDpad mGamepadDpad = new GamepadDpad();
|
||||
|
||||
private final GamepadJoystick mLeftJoystick;
|
||||
private int mCurrentJoystickDirection = DIRECTION_NONE;
|
||||
|
||||
@ -70,9 +78,7 @@ public class Gamepad implements GrabListener {
|
||||
|
||||
// The negation is to force trigger the onGrabState
|
||||
private boolean isGrabbing = !CallbackBridge.isGrabbing();
|
||||
//private final boolean mModifierDigitalTriggers;
|
||||
private final boolean mModifierAnalogTriggers;
|
||||
private boolean mModifierSwappedAxis = true; //Triggers and right stick axis are swapped.
|
||||
|
||||
|
||||
/* Choreographer with time to compute delta on ticking */
|
||||
private final Choreographer mScreenChoreographer;
|
||||
@ -97,25 +103,9 @@ public class Gamepad implements GrabListener {
|
||||
/* Add the listener for the cross hair */
|
||||
MCOptionUtils.addMCOptionListener(mGuiScaleListener);
|
||||
|
||||
Toast.makeText(contextView.getContext(),"GAMEPAD CREATED", Toast.LENGTH_LONG).show();
|
||||
for(InputDevice.MotionRange range : inputDevice.getMotionRanges()){
|
||||
if(range.getAxis() == MotionEvent.AXIS_RTRIGGER
|
||||
|| range.getAxis() == MotionEvent.AXIS_LTRIGGER
|
||||
|| range.getAxis() == MotionEvent.AXIS_GAS
|
||||
|| range.getAxis() == MotionEvent.AXIS_BRAKE){
|
||||
mModifierSwappedAxis = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mLeftJoystick = new GamepadJoystick(AXIS_X, AXIS_Y, inputDevice);
|
||||
mRightJoystick = new GamepadJoystick(AXIS_Z, AXIS_RZ, inputDevice);
|
||||
|
||||
mLeftJoystick = new GamepadJoystick(MotionEvent.AXIS_X, MotionEvent.AXIS_Y, inputDevice);
|
||||
if(!mModifierSwappedAxis)
|
||||
mRightJoystick = new GamepadJoystick(MotionEvent.AXIS_Z, MotionEvent.AXIS_RZ, inputDevice);
|
||||
else
|
||||
mRightJoystick = new GamepadJoystick(MotionEvent.AXIS_RX, MotionEvent.AXIS_RY, inputDevice);
|
||||
|
||||
//mModifierDigitalTriggers = inputDevice.hasKeys(KeyEvent.KEYCODE_BUTTON_R2)[0];
|
||||
mModifierAnalogTriggers = supportAnalogTriggers(inputDevice);
|
||||
|
||||
Context ctx = contextView.getContext();
|
||||
mPointerImageView = new ImageView(contextView.getContext());
|
||||
@ -125,28 +115,20 @@ public class Gamepad implements GrabListener {
|
||||
int size = (int) ((22 * getMcScale()) / mScaleFactor);
|
||||
mPointerImageView.setLayoutParams(new FrameLayout.LayoutParams(size, size));
|
||||
|
||||
mMouse_x = CallbackBridge.windowWidth/2f;
|
||||
mMouse_y = CallbackBridge.windowHeight/2f;
|
||||
CallbackBridge.sendCursorPos(mMouse_x, mMouse_y);
|
||||
placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2);
|
||||
|
||||
CallbackBridge.sendCursorPos(CallbackBridge.windowWidth/2f, CallbackBridge.windowHeight/2f);
|
||||
((ViewGroup)contextView.getParent()).addView(mPointerImageView);
|
||||
|
||||
placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2);
|
||||
|
||||
CallbackBridge.addGrabListener(this);
|
||||
}
|
||||
|
||||
|
||||
public void update(KeyEvent event){
|
||||
sendButton(event);
|
||||
}
|
||||
|
||||
public void update(MotionEvent event){
|
||||
updateDirectionalJoystick(event);
|
||||
updateMouseJoystick(event);
|
||||
updateAnalogTriggers(event);
|
||||
|
||||
int[] dpadEvent = mGamepadDpad.convertEvent(event);
|
||||
sendButton(dpadEvent[0], dpadEvent[1]);
|
||||
public void updateJoysticks(){
|
||||
updateDirectionalJoystick();
|
||||
updateMouseJoystick();
|
||||
}
|
||||
|
||||
public void notifyGUISizeChange(int newSize){
|
||||
@ -156,86 +138,6 @@ public class Gamepad implements GrabListener {
|
||||
|
||||
}
|
||||
|
||||
public void sendButton(KeyEvent event){
|
||||
sendButton(event.getKeyCode(), event.getAction());
|
||||
}
|
||||
|
||||
public void sendButton(int keycode, int action){
|
||||
boolean isDown = action == KeyEvent.ACTION_DOWN;
|
||||
switch (keycode){
|
||||
case KeyEvent.KEYCODE_BUTTON_A:
|
||||
getCurrentMap().BUTTON_A.update(isDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_B:
|
||||
getCurrentMap().BUTTON_B.update(isDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_X:
|
||||
getCurrentMap().BUTTON_X.update(isDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_Y:
|
||||
getCurrentMap().BUTTON_Y.update(isDown);
|
||||
break;
|
||||
|
||||
//Shoulders
|
||||
case KeyEvent.KEYCODE_BUTTON_L1:
|
||||
getCurrentMap().SHOULDER_LEFT.update(isDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_R1:
|
||||
getCurrentMap().SHOULDER_RIGHT.update(isDown);
|
||||
break;
|
||||
|
||||
//Triggers
|
||||
case KeyEvent.KEYCODE_BUTTON_L2:
|
||||
if(mModifierAnalogTriggers) break;
|
||||
getCurrentMap().TRIGGER_LEFT.update(isDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_R2:
|
||||
if(mModifierAnalogTriggers) break;
|
||||
getCurrentMap().TRIGGER_RIGHT.update(isDown);
|
||||
break;
|
||||
|
||||
//L3 || R3
|
||||
case KeyEvent.KEYCODE_BUTTON_THUMBL:
|
||||
getCurrentMap().THUMBSTICK_LEFT.update(isDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_THUMBR:
|
||||
getCurrentMap().THUMBSTICK_RIGHT.update(isDown);
|
||||
break;
|
||||
|
||||
//DPAD
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
getCurrentMap().DPAD_UP.update(isDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
getCurrentMap().DPAD_DOWN.update(isDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
getCurrentMap().DPAD_LEFT.update(isDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
getCurrentMap().DPAD_RIGHT.update(isDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||
getCurrentMap().DPAD_RIGHT.update(false);
|
||||
getCurrentMap().DPAD_LEFT.update(false);
|
||||
getCurrentMap().DPAD_UP.update(false);
|
||||
getCurrentMap().DPAD_DOWN.update(false);
|
||||
break;
|
||||
|
||||
//Start/select
|
||||
case KeyEvent.KEYCODE_BUTTON_START:
|
||||
getCurrentMap().BUTTON_START.update(isDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_SELECT:
|
||||
getCurrentMap().BUTTON_SELECT.update(isDown);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_SPACE, CallbackBridge.getCurrentMods(), isDown);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendInput(int[] keycodes, boolean isDown){
|
||||
for(int keycode : keycodes){
|
||||
@ -281,6 +183,7 @@ public class Gamepad implements GrabListener {
|
||||
*/
|
||||
private void tick(long frameTimeNanos){
|
||||
//update mouse position
|
||||
long newFrameTime = System.nanoTime();
|
||||
if(mLastHorizontalValue != 0 || mLastVerticalValue != 0){
|
||||
GamepadJoystick currentJoystick = isGrabbing ? mLeftJoystick : mRightJoystick;
|
||||
|
||||
@ -291,7 +194,8 @@ public class Gamepad implements GrabListener {
|
||||
// Compute delta since last tick time
|
||||
float deltaX = (float) (Math.cos(mMouseAngle) * acceleration * mMouseSensitivity);
|
||||
float deltaY = (float) (Math.sin(mMouseAngle) * acceleration * mMouseSensitivity);
|
||||
float deltaTimeScale = ((frameTimeNanos - mLastFrameTime) / 16666666f); // Scale of 1 = 60Hz
|
||||
newFrameTime = System.nanoTime(); // More accurate delta
|
||||
float deltaTimeScale = ((newFrameTime - mLastFrameTime) / 16666666f); // Scale of 1 = 60Hz
|
||||
deltaX *= deltaTimeScale;
|
||||
deltaY *= deltaTimeScale;
|
||||
|
||||
@ -304,27 +208,24 @@ public class Gamepad implements GrabListener {
|
||||
placePointerView((int) (CallbackBridge.mouseX / mScaleFactor), (int) (CallbackBridge.mouseY/ mScaleFactor));
|
||||
}
|
||||
|
||||
mMouse_x = CallbackBridge.mouseX;
|
||||
mMouse_y = CallbackBridge.mouseY;
|
||||
|
||||
//Send the mouse to the game
|
||||
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
|
||||
}
|
||||
|
||||
// Update last nano time
|
||||
mLastFrameTime = frameTimeNanos;
|
||||
mLastFrameTime = newFrameTime;
|
||||
}
|
||||
|
||||
private void updateMouseJoystick(MotionEvent event){
|
||||
private void updateMouseJoystick(){
|
||||
GamepadJoystick currentJoystick = isGrabbing ? mRightJoystick : mLeftJoystick;
|
||||
float horizontalValue = currentJoystick.getHorizontalAxis(event);
|
||||
float verticalValue = currentJoystick.getVerticalAxis(event);
|
||||
float horizontalValue = currentJoystick.getHorizontalAxis();
|
||||
float verticalValue = currentJoystick.getVerticalAxis();
|
||||
if(horizontalValue != mLastHorizontalValue || verticalValue != mLastVerticalValue){
|
||||
mLastHorizontalValue = horizontalValue;
|
||||
mLastVerticalValue = verticalValue;
|
||||
|
||||
mMouseMagnitude = currentJoystick.getMagnitude(event);
|
||||
mMouseAngle = currentJoystick.getAngleRadian(event);
|
||||
mMouseMagnitude = currentJoystick.getMagnitude();
|
||||
mMouseAngle = currentJoystick.getAngleRadian();
|
||||
|
||||
tick(System.nanoTime());
|
||||
return;
|
||||
@ -332,16 +233,16 @@ public class Gamepad implements GrabListener {
|
||||
mLastHorizontalValue = horizontalValue;
|
||||
mLastVerticalValue = verticalValue;
|
||||
|
||||
mMouseMagnitude = currentJoystick.getMagnitude(event);
|
||||
mMouseAngle = currentJoystick.getAngleRadian(event);
|
||||
mMouseMagnitude = currentJoystick.getMagnitude();
|
||||
mMouseAngle = currentJoystick.getAngleRadian();
|
||||
|
||||
}
|
||||
|
||||
private void updateDirectionalJoystick(MotionEvent event){
|
||||
private void updateDirectionalJoystick(){
|
||||
GamepadJoystick currentJoystick = isGrabbing ? mLeftJoystick : mRightJoystick;
|
||||
|
||||
int lastJoystickDirection = mCurrentJoystickDirection;
|
||||
mCurrentJoystickDirection = currentJoystick.getHeightDirection(event);
|
||||
mCurrentJoystickDirection = currentJoystick.getHeightDirection();
|
||||
|
||||
if(mCurrentJoystickDirection == lastJoystickDirection) return;
|
||||
|
||||
@ -349,37 +250,6 @@ public class Gamepad implements GrabListener {
|
||||
sendDirectionalKeycode(mCurrentJoystickDirection, true, getCurrentMap());
|
||||
}
|
||||
|
||||
private void updateAnalogTriggers(MotionEvent event){
|
||||
if(mModifierAnalogTriggers){
|
||||
getCurrentMap().TRIGGER_LEFT.update(
|
||||
(event.getAxisValue(MotionEvent.AXIS_LTRIGGER) > 0.5)
|
||||
|| (event.getAxisValue(MotionEvent.AXIS_BRAKE) > 0.5)
|
||||
|| (mModifierSwappedAxis &&(event.getAxisValue(MotionEvent.AXIS_Z) > 0.5)) );
|
||||
getCurrentMap().TRIGGER_RIGHT.update(
|
||||
(event.getAxisValue( MotionEvent.AXIS_RTRIGGER) > 0.5)
|
||||
|| (event.getAxisValue(MotionEvent.AXIS_GAS) > 0.5)
|
||||
|| (mModifierSwappedAxis && event.getAxisValue(MotionEvent.AXIS_RZ) > 0.5) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect if a gamepad supports analog triggers
|
||||
* @param inputDevice The input device with all the MotionRange
|
||||
* @return Whether the gamepad supports analog triggers
|
||||
*/
|
||||
private boolean supportAnalogTriggers(InputDevice inputDevice){
|
||||
for(InputDevice.MotionRange motionRange : inputDevice.getMotionRanges()){
|
||||
int axis = motionRange.getAxis();
|
||||
|
||||
if( axis == MotionEvent.AXIS_BRAKE || axis == MotionEvent.AXIS_GAS ||
|
||||
axis == MotionEvent.AXIS_LTRIGGER || axis == MotionEvent.AXIS_RTRIGGER ||
|
||||
(mModifierSwappedAxis && axis == MotionEvent.AXIS_Z) ||
|
||||
(mModifierSwappedAxis && axis == MotionEvent.AXIS_RZ)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private GamepadMap getCurrentMap(){
|
||||
return mCurrentMap;
|
||||
@ -418,6 +288,7 @@ public class Gamepad implements GrabListener {
|
||||
}
|
||||
}
|
||||
|
||||
/** Place the pointer on the screen, offsetting the image size */
|
||||
private void placePointerView(int x, int y){
|
||||
mPointerImageView.setX(x - mPointerImageView.getWidth()/2f);
|
||||
mPointerImageView.setY(y - mPointerImageView.getHeight()/2f);
|
||||
@ -442,12 +313,123 @@ public class Gamepad implements GrabListener {
|
||||
mCurrentMap = mMenuMap;
|
||||
sendDirectionalKeycode(mCurrentJoystickDirection, false, mGameMap); // removing what we were doing
|
||||
|
||||
mMouse_x = CallbackBridge.windowWidth/2f;
|
||||
mMouse_y = CallbackBridge.windowHeight/2f;
|
||||
CallbackBridge.sendCursorPos(mMouse_x, mMouse_y);
|
||||
CallbackBridge.sendCursorPos(CallbackBridge.windowWidth/2f, CallbackBridge.windowHeight/2f);
|
||||
placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2);
|
||||
mPointerImageView.setVisibility(View.VISIBLE);
|
||||
// Sensitivity in menu is MC and HARDWARE resolution dependent
|
||||
mMouseSensitivity = 19 * mScaleFactor / mSensitivityFactor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleGamepadInput(int keycode, float value) {
|
||||
boolean isKeyEventDown = value == 1f;
|
||||
switch (keycode){
|
||||
case KeyEvent.KEYCODE_BUTTON_A:
|
||||
getCurrentMap().BUTTON_A.update(isKeyEventDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_B:
|
||||
getCurrentMap().BUTTON_B.update(isKeyEventDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_X:
|
||||
getCurrentMap().BUTTON_X.update(isKeyEventDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_Y:
|
||||
getCurrentMap().BUTTON_Y.update(isKeyEventDown);
|
||||
break;
|
||||
|
||||
//Shoulders
|
||||
case KeyEvent.KEYCODE_BUTTON_L1:
|
||||
getCurrentMap().SHOULDER_LEFT.update(isKeyEventDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_R1:
|
||||
getCurrentMap().SHOULDER_RIGHT.update(isKeyEventDown);
|
||||
break;
|
||||
|
||||
//Triggers
|
||||
case KeyEvent.KEYCODE_BUTTON_L2:
|
||||
getCurrentMap().TRIGGER_LEFT.update(isKeyEventDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_R2:
|
||||
getCurrentMap().TRIGGER_RIGHT.update(isKeyEventDown);
|
||||
break;
|
||||
|
||||
//L3 || R3
|
||||
case KeyEvent.KEYCODE_BUTTON_THUMBL:
|
||||
getCurrentMap().THUMBSTICK_LEFT.update(isKeyEventDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_THUMBR:
|
||||
getCurrentMap().THUMBSTICK_RIGHT.update(isKeyEventDown);
|
||||
break;
|
||||
|
||||
//DPAD
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
getCurrentMap().DPAD_UP.update(isKeyEventDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
getCurrentMap().DPAD_DOWN.update(isKeyEventDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
getCurrentMap().DPAD_LEFT.update(isKeyEventDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
getCurrentMap().DPAD_RIGHT.update(isKeyEventDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||
getCurrentMap().DPAD_RIGHT.update(false);
|
||||
getCurrentMap().DPAD_LEFT.update(false);
|
||||
getCurrentMap().DPAD_UP.update(false);
|
||||
getCurrentMap().DPAD_DOWN.update(false);
|
||||
break;
|
||||
|
||||
//Start/select
|
||||
case KeyEvent.KEYCODE_BUTTON_START:
|
||||
getCurrentMap().BUTTON_START.update(isKeyEventDown);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_SELECT:
|
||||
getCurrentMap().BUTTON_SELECT.update(isKeyEventDown);
|
||||
break;
|
||||
|
||||
/* Now, it is time for motionEvents */
|
||||
case AXIS_HAT_X:
|
||||
getCurrentMap().DPAD_RIGHT.update(value > 0.85);
|
||||
getCurrentMap().DPAD_LEFT.update(value < -0.85);
|
||||
break;
|
||||
case AXIS_HAT_Y:
|
||||
getCurrentMap().DPAD_DOWN.update(value > 0.85);
|
||||
getCurrentMap().DPAD_UP.update(value < -0.85);
|
||||
break;
|
||||
|
||||
// Left joystick
|
||||
case AXIS_X:
|
||||
mLeftJoystick.setXAxisValue(value);
|
||||
updateJoysticks();
|
||||
break;
|
||||
case AXIS_Y:
|
||||
mLeftJoystick.setYAxisValue(value);
|
||||
updateJoysticks();
|
||||
break;
|
||||
|
||||
// Right joystick
|
||||
case AXIS_Z:
|
||||
mRightJoystick.setXAxisValue(value);
|
||||
updateJoysticks();
|
||||
break;
|
||||
case AXIS_RZ:
|
||||
mRightJoystick.setYAxisValue(value);
|
||||
updateJoysticks();
|
||||
break;
|
||||
|
||||
// Triggers
|
||||
case AXIS_RTRIGGER:
|
||||
getCurrentMap().TRIGGER_RIGHT.update(value > 0.5);
|
||||
break;
|
||||
case AXIS_LTRIGGER:
|
||||
getCurrentMap().TRIGGER_LEFT.update(value > 0.5);
|
||||
break;
|
||||
|
||||
default:
|
||||
sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_SPACE, CallbackBridge.getCurrentMods(), isKeyEventDown);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
package net.kdt.pojavlaunch.customcontrols.gamepad;
|
||||
|
||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_DEADZONE_SCALE;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
@ -21,42 +24,46 @@ public class GamepadJoystick {
|
||||
public static final int DIRECTION_SOUTH_EAST = 7;
|
||||
|
||||
private final InputDevice mInputDevice;
|
||||
private final int mVerticalAxis;
|
||||
|
||||
private final int mHorizontalAxis;
|
||||
private final int mVerticalAxis;
|
||||
private float mVerticalAxisValue = 0;
|
||||
private float mHorizontalAxisValue = 0;
|
||||
|
||||
public GamepadJoystick(int horizontalAxis, int verticalAxis, InputDevice device){
|
||||
this.mVerticalAxis = verticalAxis;
|
||||
this.mHorizontalAxis = horizontalAxis;
|
||||
mHorizontalAxis = horizontalAxis;
|
||||
mVerticalAxis = verticalAxis;
|
||||
this.mInputDevice = device;
|
||||
}
|
||||
|
||||
public double getAngleRadian(MotionEvent event){
|
||||
public double getAngleRadian(){
|
||||
//From -PI to PI
|
||||
return -Math.atan2(getVerticalAxis(event), getHorizontalAxis(event));
|
||||
// TODO misuse of the deadzone here !
|
||||
return -Math.atan2(getVerticalAxis(), getHorizontalAxis());
|
||||
}
|
||||
|
||||
|
||||
public double getAngleDegree(MotionEvent event){
|
||||
public double getAngleDegree(){
|
||||
//From 0 to 360 degrees
|
||||
double result = Math.toDegrees(getAngleRadian(event));
|
||||
double result = Math.toDegrees(getAngleRadian());
|
||||
if(result < 0) result += 360;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public double getMagnitude(MotionEvent event){
|
||||
float x = Math.abs(event.getAxisValue(mHorizontalAxis));
|
||||
float y = Math.abs(event.getAxisValue(mVerticalAxis));
|
||||
public double getMagnitude(){
|
||||
float x = Math.abs(mHorizontalAxisValue);
|
||||
float y = Math.abs(mVerticalAxisValue);
|
||||
|
||||
return MathUtils.dist(0,0, x, y);
|
||||
}
|
||||
|
||||
public float getVerticalAxis(MotionEvent event){
|
||||
return applyDeadzone(event, mVerticalAxis);
|
||||
public float getVerticalAxis(){
|
||||
return applyDeadzone(mVerticalAxisValue);
|
||||
}
|
||||
|
||||
public float getHorizontalAxis(MotionEvent event){
|
||||
return applyDeadzone(event, mHorizontalAxis);
|
||||
public float getHorizontalAxis(){
|
||||
return applyDeadzone(mHorizontalAxisValue);
|
||||
}
|
||||
|
||||
public static boolean isJoystickEvent(MotionEvent event){
|
||||
@ -65,9 +72,9 @@ public class GamepadJoystick {
|
||||
}
|
||||
|
||||
|
||||
public int getHeightDirection(MotionEvent event){
|
||||
if(getMagnitude(event) <= getDeadzone()) return DIRECTION_NONE;
|
||||
return ((int) ((getAngleDegree(event)+22.5)/45)) % 8;
|
||||
public int getHeightDirection(){
|
||||
if(getMagnitude() <= getDeadzone()) return DIRECTION_NONE;
|
||||
return ((int) ((getAngleDegree()+22.5)/45)) % 8;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,20 +84,31 @@ public class GamepadJoystick {
|
||||
*/
|
||||
public float getDeadzone() {
|
||||
try{
|
||||
return Math.max(mInputDevice.getMotionRange(mHorizontalAxis).getFlat() * 1.9f, 0.2f);
|
||||
return mInputDevice.getMotionRange(mHorizontalAxis).getFlat() * PREF_DEADZONE_SCALE;
|
||||
}catch (Exception e){
|
||||
Log.e(GamepadJoystick.class.toString(), "Dynamic Deadzone is not supported ");
|
||||
return 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
private float applyDeadzone(MotionEvent event, int axis){
|
||||
private float applyDeadzone(float value){
|
||||
//This piece of code also modifies the value
|
||||
//to make it seem like there was no deadzone in the first place
|
||||
|
||||
double magnitude = getMagnitude(event);
|
||||
double magnitude = getMagnitude();
|
||||
float deadzone = getDeadzone();
|
||||
if (magnitude < deadzone) return 0;
|
||||
|
||||
return (float) ( (event.getAxisValue(axis) / magnitude) * ((magnitude - deadzone) / (1 - deadzone)) );
|
||||
return (float) ( (value / magnitude) * ((magnitude - deadzone) / (1 - deadzone)) );
|
||||
}
|
||||
|
||||
|
||||
/* Setters */
|
||||
public void setXAxisValue(float value){
|
||||
this.mHorizontalAxisValue = value;
|
||||
}
|
||||
|
||||
public void setYAxisValue(float value){
|
||||
this.mVerticalAxisValue = value;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
package net.kdt.pojavlaunch.prefs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
|
||||
import fr.spse.gamepad_remapper.Remapper;
|
||||
|
||||
public class GamepadRemapPreference extends Preference {
|
||||
|
||||
public GamepadRemapPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public GamepadRemapPreference(@NonNull Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init(){
|
||||
setOnPreferenceClickListener(preference -> {
|
||||
Remapper.wipePreferences(getContext());
|
||||
Toast.makeText(getContext(), R.string.preference_controller_map_wiped, Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
@ -57,6 +57,7 @@ public class LauncherPreferences {
|
||||
|
||||
public static boolean PREF_BUTTON_ALL_CAPS = true;
|
||||
public static boolean PREF_DUMP_SHADERS = false;
|
||||
public static float PREF_DEADZONE_SCALE = 1f;
|
||||
|
||||
|
||||
public static void loadPreferences(Context ctx) {
|
||||
@ -96,6 +97,7 @@ public class LauncherPreferences {
|
||||
PREF_FORCE_VSYNC = DEFAULT_PREF.getBoolean("force_vsync", false);
|
||||
PREF_BUTTON_ALL_CAPS = DEFAULT_PREF.getBoolean("buttonAllCaps", true);
|
||||
PREF_DUMP_SHADERS = DEFAULT_PREF.getBoolean("dump_shaders", false);
|
||||
PREF_DEADZONE_SCALE = DEFAULT_PREF.getInt("gamepad_deadzone_scale", 100)/100f;
|
||||
|
||||
String argLwjglLibname = "-Dorg.lwjgl.opengl.libname=";
|
||||
for (String arg : JREUtils.parseJavaArguments(PREF_CUSTOM_JAVA_ARGS)) {
|
||||
|
@ -23,6 +23,7 @@ public class LauncherPreferenceControlFragment extends LauncherPreferenceFragmen
|
||||
int gyroSampleRate = LauncherPreferences.PREF_GYRO_SAMPLE_RATE;
|
||||
float mouseSpeed = LauncherPreferences.PREF_MOUSESPEED;
|
||||
float gyroSpeed = LauncherPreferences.PREF_GYRO_SENSITIVITY;
|
||||
float joystickDeadzone = LauncherPreferences.PREF_DEADZONE_SCALE;
|
||||
|
||||
//Triggers a write for some reason which resets the value
|
||||
addPreferencesFromResource(R.xml.pref_control);
|
||||
@ -47,6 +48,11 @@ public class LauncherPreferenceControlFragment extends LauncherPreferenceFragmen
|
||||
seek6.setValue((int)(mouseSpeed *100f));
|
||||
seek6.setSuffix(" %");
|
||||
|
||||
CustomSeekBarPreference deadzoneSeek = findPreference("gamepad_deadzone_scale");
|
||||
deadzoneSeek.setRange(50, 200);
|
||||
deadzoneSeek.setValue((int) joystickDeadzone * 100);
|
||||
deadzoneSeek.setSuffix(" %");
|
||||
|
||||
Context context = getContext();
|
||||
if(context != null) {
|
||||
mGyroAvailable = ((SensorManager)context.getSystemService(Context.SENSOR_SERVICE)).getDefaultSensor(Sensor.TYPE_GYROSCOPE) != null;
|
||||
|
@ -364,4 +364,10 @@
|
||||
<string name="global_save_and_exit">Save and exit</string>
|
||||
<string name="global_yes">Yes</string>
|
||||
<string name="global_no">No</string>
|
||||
<string name="preference_controller_map_wiped">The controller config has been wiped</string>
|
||||
<string name="preference_category_controller_settings">Controller settings</string>
|
||||
<string name="preference_wipe_controller_title">Reset controller mapping</string>
|
||||
<string name="preference_wipe_controller_description">Allow you to remap the controller buttons</string>
|
||||
<string name="preference_deadzone_scale_title">Joystick deadzone scale</string>
|
||||
<string name="preference_deadzone_scale_description">Increase it if the joystick drifts</string>
|
||||
</resources>
|
||||
|
@ -123,6 +123,22 @@
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/preference_category_controller_settings"
|
||||
>
|
||||
<net.kdt.pojavlaunch.prefs.GamepadRemapPreference
|
||||
android:title="@string/preference_wipe_controller_title"
|
||||
android:summary="@string/preference_wipe_controller_description"
|
||||
/>
|
||||
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
|
||||
android:key="gamepad_deadzone_scale"
|
||||
android:title="@string/preference_deadzone_scale_title"
|
||||
android:summary="@string/preference_deadzone_scale_description"
|
||||
app2:showSeekBarValue="true"
|
||||
app2:seekBarIncrement="5"
|
||||
/>
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user