Refactor gamepad related files

This commit is contained in:
SerpentSpirale 2022-02-26 18:06:40 +01:00 committed by ArtDev
parent 8c62cef47b
commit 8f0e1ab361
4 changed files with 259 additions and 262 deletions

View File

@ -40,60 +40,60 @@ import static org.lwjgl.glfw.CallbackBridge.sendMouseButton;
public class Gamepad { public class Gamepad {
/* Resolution scaler option, allow downsizing a window */ /* Resolution scaler option, allow downsizing a window */
private final float scaleFactor = LauncherPreferences.DEFAULT_PREF.getInt("resolutionRatio",100)/100f; private final float mScaleFactor = LauncherPreferences.DEFAULT_PREF.getInt("resolutionRatio",100)/100f;
/* Mouse positions, scaled by the scaleFactor */ /* Mouse positions, scaled by the scaleFactor */
private float mouse_x, mouse_y; private float mMouse_x, mMouse_y;
/* Sensitivity, adjusted according to screen size */ /* Sensitivity, adjusted according to screen size */
private final double sensitivityFactor = (1.4 * (1080f/ currentDisplayMetrics.heightPixels)); private final double mSensitivityFactor = (1.4 * (1080f/ currentDisplayMetrics.heightPixels));
private final ImageView pointerView; private final ImageView mPointerImageView;
private final GamepadDpad gamepadDpad = new GamepadDpad(); private final GamepadDpad mGamepadDpad = new GamepadDpad();
private final GamepadJoystick leftJoystick; private final GamepadJoystick mLeftJoystick;
private int currentJoystickDirection = DIRECTION_NONE; private int mCurrentJoystickDirection = DIRECTION_NONE;
private final GamepadJoystick rightJoystick; private final GamepadJoystick mRightJoystick;
private float lastHorizontalValue = 0.0f; private float mLastHorizontalValue = 0.0f;
private float lastVerticalValue = 0.0f; private float mLastVerticalValue = 0.0f;
private final double mouseMaxAcceleration = 2f; private final double MOUSE_MAX_ACCELERATION = 2f;
private double mouseMagnitude; private double mMouseMagnitude;
private double mouseAngle; private double mMouseAngle;
private double mouseSensitivity = 19; private double mMouseSensitivity = 19;
private final GamepadMap gameMap = GamepadMap.getDefaultGameMap(); private final GamepadMap mGameMap = GamepadMap.getDefaultGameMap();
private final GamepadMap menuMap = GamepadMap.getDefaultMenuMap(); private final GamepadMap mMenuMap = GamepadMap.getDefaultMenuMap();
private GamepadMap currentMap = gameMap; private GamepadMap mCurrentMap = mGameMap;
private boolean lastGrabbingState = true; private boolean mLastGrabbingState = true;
//private final boolean mModifierDigitalTriggers; //private final boolean mModifierDigitalTriggers;
private final boolean mModifierAnalogTriggers; private final boolean mModifierAnalogTriggers;
private boolean mModifierSwappedAxis = true; //Triggers and right stick axis are swapped. private boolean mModifierSwappedAxis = true; //Triggers and right stick axis are swapped.
/* Choreographer with time to compute delta on ticking */ /* Choreographer with time to compute delta on ticking */
private final Choreographer screenChoreographer; private final Choreographer mScreenChoreographer;
private long lastFrameTime; private long mLastFrameTime;
/* Listen for change in gui scale */ /* Listen for change in gui scale */
private MCOptionUtils.MCOptionListener GUIScaleListener = () -> notifyGUISizeChange(getMcScale()); private MCOptionUtils.MCOptionListener mGuiScaleListener = () -> notifyGUISizeChange(getMcScale());
public Gamepad(View contextView, InputDevice inputDevice){ public Gamepad(View contextView, InputDevice inputDevice){
screenChoreographer = Choreographer.getInstance(); mScreenChoreographer = Choreographer.getInstance();
Choreographer.FrameCallback frameCallback = new Choreographer.FrameCallback() { Choreographer.FrameCallback frameCallback = new Choreographer.FrameCallback() {
@Override @Override
public void doFrame(long frameTimeNanos) { public void doFrame(long frameTimeNanos) {
updateGrabbingState(); updateGrabbingState();
tick(frameTimeNanos); tick(frameTimeNanos);
screenChoreographer.postFrameCallback(this); mScreenChoreographer.postFrameCallback(this);
} }
}; };
screenChoreographer.postFrameCallback(frameCallback); mScreenChoreographer.postFrameCallback(frameCallback);
lastFrameTime = System.nanoTime(); mLastFrameTime = System.nanoTime();
/* Add the listener for the cross hair */ /* Add the listener for the cross hair */
MCOptionUtils.addMCOptionListener(GUIScaleListener); MCOptionUtils.addMCOptionListener(mGuiScaleListener);
Toast.makeText(contextView.getContext(),"GAMEPAD CREATED", Toast.LENGTH_LONG).show(); Toast.makeText(contextView.getContext(),"GAMEPAD CREATED", Toast.LENGTH_LONG).show();
for(InputDevice.MotionRange range : inputDevice.getMotionRanges()){ for(InputDevice.MotionRange range : inputDevice.getMotionRanges()){
@ -106,98 +106,31 @@ public class Gamepad {
} }
} }
leftJoystick = new GamepadJoystick(MotionEvent.AXIS_X, MotionEvent.AXIS_Y, inputDevice); mLeftJoystick = new GamepadJoystick(MotionEvent.AXIS_X, MotionEvent.AXIS_Y, inputDevice);
if(!mModifierSwappedAxis) if(!mModifierSwappedAxis)
rightJoystick = new GamepadJoystick(MotionEvent.AXIS_Z, MotionEvent.AXIS_RZ, inputDevice); mRightJoystick = new GamepadJoystick(MotionEvent.AXIS_Z, MotionEvent.AXIS_RZ, inputDevice);
else else
rightJoystick = new GamepadJoystick(MotionEvent.AXIS_RX, MotionEvent.AXIS_RY, inputDevice); mRightJoystick = new GamepadJoystick(MotionEvent.AXIS_RX, MotionEvent.AXIS_RY, inputDevice);
//mModifierDigitalTriggers = inputDevice.hasKeys(KeyEvent.KEYCODE_BUTTON_R2)[0]; //mModifierDigitalTriggers = inputDevice.hasKeys(KeyEvent.KEYCODE_BUTTON_R2)[0];
mModifierAnalogTriggers = supportAnalogTriggers(inputDevice); mModifierAnalogTriggers = supportAnalogTriggers(inputDevice);
Context ctx = contextView.getContext(); Context ctx = contextView.getContext();
pointerView = new ImageView(contextView.getContext()); mPointerImageView = new ImageView(contextView.getContext());
pointerView.setImageDrawable(ResourcesCompat.getDrawable(ctx.getResources(), R.drawable.pointer, ctx.getTheme())); mPointerImageView.setImageDrawable(ResourcesCompat.getDrawable(ctx.getResources(), R.drawable.pointer, ctx.getTheme()));
pointerView.getDrawable().setFilterBitmap(false); mPointerImageView.getDrawable().setFilterBitmap(false);
int size = (int) ((22 * getMcScale()) / scaleFactor); int size = (int) ((22 * getMcScale()) / mScaleFactor);
pointerView.setLayoutParams(new FrameLayout.LayoutParams(size, size)); mPointerImageView.setLayoutParams(new FrameLayout.LayoutParams(size, size));
mouse_x = CallbackBridge.windowWidth/2; mMouse_x = CallbackBridge.windowWidth/2;
mouse_y = CallbackBridge.windowHeight/2; mMouse_y = CallbackBridge.windowHeight/2;
CallbackBridge.sendCursorPos(mouse_x, mouse_y); CallbackBridge.sendCursorPos(mMouse_x, mMouse_y);
placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2); placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2);
((ViewGroup)contextView.getParent()).addView(pointerView); ((ViewGroup)contextView.getParent()).addView(mPointerImageView);
} }
/**
* Send the new mouse position, computing the delta
* @param frameTimeNanos The time to render the frame, used to compute mouse delta
*/
public void tick(long frameTimeNanos){
//update mouse position
if(lastHorizontalValue != 0 || lastVerticalValue != 0){
GamepadJoystick currentJoystick = lastGrabbingState ? leftJoystick : rightJoystick;
double acceleration = (mouseMagnitude - currentJoystick.getDeadzone()) / (1 - currentJoystick.getDeadzone());
acceleration = Math.pow(acceleration, mouseMaxAcceleration);
if(acceleration > 1) acceleration = 1;
// Compute delta since last tick time
float deltaX = (float) (Math.cos(mouseAngle) * acceleration * mouseSensitivity);
float deltaY = (float) (Math.sin(mouseAngle) * acceleration * mouseSensitivity);
float deltaTimeScale = ((frameTimeNanos - lastFrameTime) / 16666666f); // Scale of 1 = 60Hz
deltaX *= deltaTimeScale;
deltaY *= deltaTimeScale;
CallbackBridge.mouseX += deltaX;
CallbackBridge.mouseY -= deltaY;
if(!lastGrabbingState){
CallbackBridge.mouseX = MathUtils.clamp(CallbackBridge.mouseX, 0, CallbackBridge.windowWidth);
CallbackBridge.mouseY = MathUtils.clamp(CallbackBridge.mouseY, 0, CallbackBridge.windowHeight);
placePointerView((int) (CallbackBridge.mouseX / scaleFactor), (int) (CallbackBridge.mouseY/ scaleFactor));
}
mouse_x = CallbackBridge.mouseX;
mouse_y = CallbackBridge.mouseY;
//Send the mouse to the game
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
}
// Update last nano time
lastFrameTime = frameTimeNanos;
}
/** Update the grabbing state, and change the currentMap, mouse position and sensibility */
private void updateGrabbingState() {
boolean lastGrabbingValue = lastGrabbingState;
lastGrabbingState = CallbackBridge.isGrabbing();
if(lastGrabbingValue == lastGrabbingState) return;
// Switch grabbing state then
currentMap.resetPressedState();
if(lastGrabbingState){
currentMap = gameMap;
pointerView.setVisibility(View.INVISIBLE);
mouseSensitivity = 18;
return;
}
currentMap = menuMap;
sendDirectionalKeycode(currentJoystickDirection, false, gameMap); // removing what we were doing
mouse_x = CallbackBridge.windowWidth/2;
mouse_y = CallbackBridge.windowHeight/2;
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2);
pointerView.setVisibility(View.VISIBLE);
// Sensitivity in menu is MC and HARDWARE resolution dependent
mouseSensitivity = 19 * scaleFactor / sensitivityFactor;
}
public void update(KeyEvent event){ public void update(KeyEvent event){
sendButton(event); sendButton(event);
@ -208,125 +141,17 @@ public class Gamepad {
updateMouseJoystick(event); updateMouseJoystick(event);
updateAnalogTriggers(event); updateAnalogTriggers(event);
int[] dpadEvent = gamepadDpad.convertEvent(event); int[] dpadEvent = mGamepadDpad.convertEvent(event);
sendButton(dpadEvent[0], dpadEvent[1]); sendButton(dpadEvent[0], dpadEvent[1]);
} }
private void updateMouseJoystick(MotionEvent event){
GamepadJoystick currentJoystick = lastGrabbingState ? rightJoystick : leftJoystick;
float horizontalValue = currentJoystick.getHorizontalAxis(event);
float verticalValue = currentJoystick.getVerticalAxis(event);
if(horizontalValue != lastHorizontalValue || verticalValue != lastVerticalValue){
lastHorizontalValue = horizontalValue;
lastVerticalValue = verticalValue;
mouseMagnitude = currentJoystick.getMagnitude(event);
mouseAngle = currentJoystick.getAngleRadian(event);
tick(System.nanoTime());
return;
}
lastHorizontalValue = horizontalValue;
lastVerticalValue = verticalValue;
mouseMagnitude = currentJoystick.getMagnitude(event);
mouseAngle = currentJoystick.getAngleRadian(event);
}
private void updateDirectionalJoystick(MotionEvent event){
GamepadJoystick currentJoystick = lastGrabbingState ? leftJoystick : rightJoystick;
int lastJoystickDirection = currentJoystickDirection;
currentJoystickDirection = currentJoystick.getHeightDirection(event);
if(currentJoystickDirection == lastJoystickDirection) return;
sendDirectionalKeycode(lastJoystickDirection, false, getCurrentMap());
sendDirectionalKeycode(currentJoystickDirection, 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) );
}
}
public void notifyGUISizeChange(int newSize){ public void notifyGUISizeChange(int newSize){
//Change the pointer size to match UI //Change the pointer size to match UI
int size = (int) ((22 * newSize) / scaleFactor); int size = (int) ((22 * newSize) / mScaleFactor);
pointerView.post(() -> pointerView.setLayoutParams(new FrameLayout.LayoutParams(size, size))); mPointerImageView.post(() -> mPointerImageView.setLayoutParams(new FrameLayout.LayoutParams(size, size)));
} }
/**
* 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 currentMap;
}
private static void sendDirectionalKeycode(int direction, boolean isDown, GamepadMap map){
switch (direction){
case DIRECTION_NORTH:
sendInput(map.DIRECTION_FORWARD, isDown);
break;
case DIRECTION_NORTH_EAST:
sendInput(map.DIRECTION_FORWARD, isDown);
sendInput(map.DIRECTION_RIGHT, isDown);
break;
case DIRECTION_EAST:
sendInput(map.DIRECTION_RIGHT, isDown);
break;
case DIRECTION_SOUTH_EAST:
sendInput(map.DIRECTION_RIGHT, isDown);
sendInput(map.DIRECTION_BACKWARD, isDown);
break;
case DIRECTION_SOUTH:
sendInput(map.DIRECTION_BACKWARD, isDown);
break;
case DIRECTION_SOUTH_WEST:
sendInput(map.DIRECTION_BACKWARD, isDown);
sendInput(map.DIRECTION_LEFT, isDown);
break;
case DIRECTION_WEST:
sendInput(map.DIRECTION_LEFT, isDown);
break;
case DIRECTION_NORTH_WEST:
sendInput(map.DIRECTION_FORWARD, isDown);
sendInput(map.DIRECTION_LEFT, isDown);
break;
}
}
private void placePointerView(int x, int y){
pointerView.setX(x - pointerView.getWidth()/2);
pointerView.setY(y - pointerView.getHeight()/2);
}
public void sendButton(KeyEvent event){ public void sendButton(KeyEvent event){
sendButton(event.getKeyCode(), event.getAction()); sendButton(event.getKeyCode(), event.getAction());
} }
@ -443,4 +268,180 @@ public class Gamepad {
return ((event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD return ((event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD
|| GamepadDpad.isDpadEvent(event) ); || GamepadDpad.isDpadEvent(event) );
} }
/**
* Send the new mouse position, computing the delta
* @param frameTimeNanos The time to render the frame, used to compute mouse delta
*/
private void tick(long frameTimeNanos){
//update mouse position
if(mLastHorizontalValue != 0 || mLastVerticalValue != 0){
GamepadJoystick currentJoystick = mLastGrabbingState ? mLeftJoystick : mRightJoystick;
double acceleration = (mMouseMagnitude - currentJoystick.getDeadzone()) / (1 - currentJoystick.getDeadzone());
acceleration = Math.pow(acceleration, MOUSE_MAX_ACCELERATION);
if(acceleration > 1) acceleration = 1;
// 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
deltaX *= deltaTimeScale;
deltaY *= deltaTimeScale;
CallbackBridge.mouseX += deltaX;
CallbackBridge.mouseY -= deltaY;
if(!mLastGrabbingState){
CallbackBridge.mouseX = MathUtils.clamp(CallbackBridge.mouseX, 0, CallbackBridge.windowWidth);
CallbackBridge.mouseY = MathUtils.clamp(CallbackBridge.mouseY, 0, CallbackBridge.windowHeight);
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;
}
/** Update the grabbing state, and change the currentMap, mouse position and sensibility */
private void updateGrabbingState() {
boolean lastGrabbingValue = mLastGrabbingState;
mLastGrabbingState = CallbackBridge.isGrabbing();
if(lastGrabbingValue == mLastGrabbingState) return;
// Switch grabbing state then
mCurrentMap.resetPressedState();
if(mLastGrabbingState){
mCurrentMap = mGameMap;
mPointerImageView.setVisibility(View.INVISIBLE);
mMouseSensitivity = 18;
return;
}
mCurrentMap = mMenuMap;
sendDirectionalKeycode(mCurrentJoystickDirection, false, mGameMap); // removing what we were doing
mMouse_x = CallbackBridge.windowWidth/2;
mMouse_y = CallbackBridge.windowHeight/2;
CallbackBridge.sendCursorPos(mMouse_x, mMouse_y);
placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2);
mPointerImageView.setVisibility(View.VISIBLE);
// Sensitivity in menu is MC and HARDWARE resolution dependent
mMouseSensitivity = 19 * mScaleFactor / mSensitivityFactor;
}
private void updateMouseJoystick(MotionEvent event){
GamepadJoystick currentJoystick = mLastGrabbingState ? mRightJoystick : mLeftJoystick;
float horizontalValue = currentJoystick.getHorizontalAxis(event);
float verticalValue = currentJoystick.getVerticalAxis(event);
if(horizontalValue != mLastHorizontalValue || verticalValue != mLastVerticalValue){
mLastHorizontalValue = horizontalValue;
mLastVerticalValue = verticalValue;
mMouseMagnitude = currentJoystick.getMagnitude(event);
mMouseAngle = currentJoystick.getAngleRadian(event);
tick(System.nanoTime());
return;
}
mLastHorizontalValue = horizontalValue;
mLastVerticalValue = verticalValue;
mMouseMagnitude = currentJoystick.getMagnitude(event);
mMouseAngle = currentJoystick.getAngleRadian(event);
}
private void updateDirectionalJoystick(MotionEvent event){
GamepadJoystick currentJoystick = mLastGrabbingState ? mLeftJoystick : mRightJoystick;
int lastJoystickDirection = mCurrentJoystickDirection;
mCurrentJoystickDirection = currentJoystick.getHeightDirection(event);
if(mCurrentJoystickDirection == lastJoystickDirection) return;
sendDirectionalKeycode(lastJoystickDirection, false, getCurrentMap());
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;
}
private static void sendDirectionalKeycode(int direction, boolean isDown, GamepadMap map){
switch (direction){
case DIRECTION_NORTH:
sendInput(map.DIRECTION_FORWARD, isDown);
break;
case DIRECTION_NORTH_EAST:
sendInput(map.DIRECTION_FORWARD, isDown);
sendInput(map.DIRECTION_RIGHT, isDown);
break;
case DIRECTION_EAST:
sendInput(map.DIRECTION_RIGHT, isDown);
break;
case DIRECTION_SOUTH_EAST:
sendInput(map.DIRECTION_RIGHT, isDown);
sendInput(map.DIRECTION_BACKWARD, isDown);
break;
case DIRECTION_SOUTH:
sendInput(map.DIRECTION_BACKWARD, isDown);
break;
case DIRECTION_SOUTH_WEST:
sendInput(map.DIRECTION_BACKWARD, isDown);
sendInput(map.DIRECTION_LEFT, isDown);
break;
case DIRECTION_WEST:
sendInput(map.DIRECTION_LEFT, isDown);
break;
case DIRECTION_NORTH_WEST:
sendInput(map.DIRECTION_FORWARD, isDown);
sendInput(map.DIRECTION_LEFT, isDown);
break;
}
}
private void placePointerView(int x, int y){
mPointerImageView.setX(x - mPointerImageView.getWidth()/2);
mPointerImageView.setY(y - mPointerImageView.getHeight()/2);
}
} }

View File

@ -2,15 +2,15 @@ package net.kdt.pojavlaunch.customcontrols.gamepad;
import android.view.KeyEvent; import android.view.KeyEvent;
/**
* Simple button able to store its state and some properties
*/
public class GamepadButton { public class GamepadButton {
/*
Just a simple button, that auto deal with the great habit from android to just SPAAAMS input events
*/
public int[] keycodes; public int[] keycodes;
public boolean isToggleable = false; public boolean isToggleable = false;
private boolean isDown = false; private boolean mIsDown = false;
private boolean isToggled = false; private boolean mIsToggled = false;
public void update(KeyEvent event){ public void update(KeyEvent event){
boolean isKeyDown = (event.getAction() == KeyEvent.ACTION_DOWN); boolean isKeyDown = (event.getAction() == KeyEvent.ACTION_DOWN);
@ -18,29 +18,29 @@ public class GamepadButton {
} }
public void update(boolean isKeyDown){ public void update(boolean isKeyDown){
if(isKeyDown != isDown){ if(isKeyDown != mIsDown){
isDown = isKeyDown; mIsDown = isKeyDown;
if(isToggleable){ if(isToggleable){
if(isKeyDown){ if(isKeyDown){
isToggled = !isToggled; mIsToggled = !mIsToggled;
Gamepad.sendInput(keycodes, isToggled); Gamepad.sendInput(keycodes, mIsToggled);
} }
return; return;
} }
Gamepad.sendInput(keycodes, isDown); Gamepad.sendInput(keycodes, mIsDown);
} }
} }
public void resetButtonState(){ public void resetButtonState(){
if(isDown || isToggled){ if(mIsDown || mIsToggled){
Gamepad.sendInput(keycodes, false); Gamepad.sendInput(keycodes, false);
} }
isDown = false; mIsDown = false;
isToggled = false; mIsToggled = false;
} }
public boolean isDown(){ public boolean isDown(){
return isToggleable ? isToggled : isDown; return isToggleable ? mIsToggled : mIsDown;
} }
} }

View File

@ -5,7 +5,6 @@ import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import static android.view.InputDevice.KEYBOARD_TYPE_NON_ALPHABETIC; import static android.view.InputDevice.KEYBOARD_TYPE_NON_ALPHABETIC;
import static android.view.InputDevice.SOURCE_DPAD;
import static android.view.KeyEvent.KEYCODE_DPAD_CENTER; import static android.view.KeyEvent.KEYCODE_DPAD_CENTER;
import static android.view.KeyEvent.KEYCODE_DPAD_DOWN; import static android.view.KeyEvent.KEYCODE_DPAD_DOWN;
import static android.view.KeyEvent.KEYCODE_DPAD_LEFT; import static android.view.KeyEvent.KEYCODE_DPAD_LEFT;
@ -14,7 +13,7 @@ import static android.view.KeyEvent.KEYCODE_DPAD_UP;
public class GamepadDpad { public class GamepadDpad {
private int lastKeycode = KEYCODE_DPAD_CENTER; private int mLastKeycode = KEYCODE_DPAD_CENTER;
/** /**
* Convert the event to a 2 int array: keycode and keyAction, similar to a keyEvent * Convert the event to a 2 int array: keycode and keyAction, similar to a keyEvent
@ -30,22 +29,22 @@ public class GamepadDpad {
// Check if the AXIS_HAT_X value is -1 or 1, and set the D-pad // Check if the AXIS_HAT_X value is -1 or 1, and set the D-pad
// LEFT and RIGHT direction accordingly. // LEFT and RIGHT direction accordingly.
if (Float.compare(xaxis, -1.0f) == 0) { if (Float.compare(xaxis, -1.0f) == 0) {
lastKeycode = KEYCODE_DPAD_LEFT; mLastKeycode = KEYCODE_DPAD_LEFT;
} else if (Float.compare(xaxis, 1.0f) == 0) { } else if (Float.compare(xaxis, 1.0f) == 0) {
lastKeycode = KEYCODE_DPAD_RIGHT; mLastKeycode = KEYCODE_DPAD_RIGHT;
} }
// Check if the AXIS_HAT_Y value is -1 or 1, and set the D-pad // Check if the AXIS_HAT_Y value is -1 or 1, and set the D-pad
// UP and DOWN direction accordingly. // UP and DOWN direction accordingly.
else if (Float.compare(yaxis, -1.0f) == 0) { else if (Float.compare(yaxis, -1.0f) == 0) {
lastKeycode = KEYCODE_DPAD_UP; mLastKeycode = KEYCODE_DPAD_UP;
} else if (Float.compare(yaxis, 1.0f) == 0) { } else if (Float.compare(yaxis, 1.0f) == 0) {
lastKeycode = KEYCODE_DPAD_DOWN; mLastKeycode = KEYCODE_DPAD_DOWN;
}else { }else {
//No keycode change //No keycode change
action = KeyEvent.ACTION_UP; action = KeyEvent.ACTION_UP;
} }
return new int[]{lastKeycode, action}; return new int[]{mLastKeycode, action};
} }

View File

@ -20,17 +20,14 @@ public class GamepadJoystick {
public static final int DIRECTION_SOUTH = 6; public static final int DIRECTION_SOUTH = 6;
public static final int DIRECTION_SOUTH_EAST = 7; public static final int DIRECTION_SOUTH_EAST = 7;
private final InputDevice device; private final InputDevice mInputDevice;
private final int mVerticalAxis;
private final int verticalAxis; private final int mHorizontalAxis;
private final int horizontalAxis;
public GamepadJoystick(int horizontalAxis, int verticalAxis, InputDevice device){ public GamepadJoystick(int horizontalAxis, int verticalAxis, InputDevice device){
this.verticalAxis = verticalAxis; this.mVerticalAxis = verticalAxis;
this.horizontalAxis = horizontalAxis; this.mHorizontalAxis = horizontalAxis;
this.device = device; this.mInputDevice = device;
} }
public double getAngleRadian(MotionEvent event){ public double getAngleRadian(MotionEvent event){
@ -48,29 +45,18 @@ public class GamepadJoystick {
} }
public double getMagnitude(MotionEvent event){ public double getMagnitude(MotionEvent event){
float x = Math.abs(event.getAxisValue(horizontalAxis)); float x = Math.abs(event.getAxisValue(mHorizontalAxis));
float y = Math.abs(event.getAxisValue(verticalAxis)); float y = Math.abs(event.getAxisValue(mVerticalAxis));
return MathUtils.dist(0,0, x, y); return MathUtils.dist(0,0, x, y);
} }
public float getVerticalAxis(MotionEvent event){ public float getVerticalAxis(MotionEvent event){
return applyDeadzone(event, verticalAxis); return applyDeadzone(event, mVerticalAxis);
} }
public float getHorizontalAxis(MotionEvent event){ public float getHorizontalAxis(MotionEvent event){
return applyDeadzone(event, horizontalAxis); return applyDeadzone(event, mHorizontalAxis);
}
private float applyDeadzone(MotionEvent event, int axis){
//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);
float deadzone = getDeadzone();
if (magnitude < deadzone) return 0;
return (float) ( (event.getAxisValue(axis) / magnitude) * ((magnitude - deadzone) / (1 - deadzone)) );
} }
public static boolean isJoystickEvent(MotionEvent event){ public static boolean isJoystickEvent(MotionEvent event){
@ -91,9 +77,20 @@ public class GamepadJoystick {
*/ */
public float getDeadzone() { public float getDeadzone() {
try{ try{
return Math.max(device.getMotionRange(horizontalAxis).getFlat() * 1.9f, 0.2f); return Math.max(mInputDevice.getMotionRange(mHorizontalAxis).getFlat() * 1.9f, 0.2f);
}catch (Exception e){ }catch (Exception e){
return 0.2f; return 0.2f;
} }
} }
private float applyDeadzone(MotionEvent event, int axis){
//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);
float deadzone = getDeadzone();
if (magnitude < deadzone) return 0;
return (float) ( (event.getAxisValue(axis) / magnitude) * ((magnitude - deadzone) / (1 - deadzone)) );
}
} }