Android: Basic game controller input forwarding

This commit is contained in:
Connor McLaughlin 2019-12-09 22:18:18 +10:00
parent 35bbde6d71
commit 9321fcb627
3 changed files with 97 additions and 2 deletions

View file

@ -50,7 +50,7 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
*/ */
private static final int UI_ANIMATION_DELAY = 300; private static final int UI_ANIMATION_DELAY = 300;
private final Handler mHideHandler = new Handler(); private final Handler mHideHandler = new Handler();
private SurfaceView mContentView; private EmulationSurfaceView mContentView;
private final Runnable mHidePart2Runnable = new Runnable() { private final Runnable mHidePart2Runnable = new Runnable() {
@SuppressLint("InlinedApi") @SuppressLint("InlinedApi")
@Override @Override
@ -148,6 +148,9 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
mTouchscreenController = new TouchscreenControllerView(this); mTouchscreenController = new TouchscreenControllerView(this);
activityLayout.addView(mTouchscreenController); activityLayout.addView(mTouchscreenController);
mTouchscreenController.init(0, "DigitalController", mHostInterface); mTouchscreenController.init(0, "DigitalController", mHostInterface);
// Hook up controller input.
mContentView.initControllerKeyMapping(mHostInterface, "DigitalController");
} }
@Override @Override

View file

@ -0,0 +1,92 @@
package com.github.stenzek.duckstation;
import android.content.Context;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Log;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.SurfaceView;
public class EmulationSurfaceView extends SurfaceView {
public EmulationSurfaceView(Context context) {
super(context);
}
public EmulationSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EmulationSurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
private boolean isDPadOrButtonEvent(KeyEvent event) {
final int source = event.getSource();
return (source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD ||
(source & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD ||
(source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (isDPadOrButtonEvent(event) && event.getRepeatCount() == 0 &&
handleControllerKey(keyCode, true)) {
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (isDPadOrButtonEvent(event) && event.getRepeatCount() == 0 &&
handleControllerKey(keyCode, false)) {
return true;
}
return super.onKeyDown(keyCode, event);
}
private AndroidHostInterface mHostInterface;
private ArrayMap<Integer, Integer> mControllerKeyMapping;
private void addControllerKeyMapping(int keyCode, String controllerType, String buttonName) {
int mapping = AndroidHostInterface.getControllerButtonCode(controllerType, buttonName);
Log.i("EmulationSurfaceView", String.format("Map %d to %d (%s)", keyCode, mapping,
buttonName));
if (mapping >= 0)
mControllerKeyMapping.put(keyCode, mapping);
}
public void initControllerKeyMapping(AndroidHostInterface hostInterface,
String controllerType) {
mHostInterface = hostInterface;
mControllerKeyMapping = new ArrayMap<>();
// TODO: Don't hardcode...
addControllerKeyMapping(KeyEvent.KEYCODE_DPAD_UP, controllerType, "Up");
addControllerKeyMapping(KeyEvent.KEYCODE_DPAD_RIGHT, controllerType, "Right");
addControllerKeyMapping(KeyEvent.KEYCODE_DPAD_DOWN, controllerType, "Down");
addControllerKeyMapping(KeyEvent.KEYCODE_DPAD_LEFT, controllerType, "Left");
addControllerKeyMapping(KeyEvent.KEYCODE_BUTTON_L1, controllerType, "L1");
addControllerKeyMapping(KeyEvent.KEYCODE_BUTTON_L2, controllerType, "L2");
addControllerKeyMapping(KeyEvent.KEYCODE_BUTTON_SELECT, controllerType, "Select");
addControllerKeyMapping(KeyEvent.KEYCODE_BUTTON_START, controllerType, "Start");
addControllerKeyMapping(KeyEvent.KEYCODE_BUTTON_Y, controllerType, "Triangle");
addControllerKeyMapping(KeyEvent.KEYCODE_BUTTON_B, controllerType, "Circle");
addControllerKeyMapping(KeyEvent.KEYCODE_BUTTON_A, controllerType, "Cross");
addControllerKeyMapping(KeyEvent.KEYCODE_BUTTON_X, controllerType, "Square");
addControllerKeyMapping(KeyEvent.KEYCODE_BUTTON_R1, controllerType, "R1");
addControllerKeyMapping(KeyEvent.KEYCODE_BUTTON_R2, controllerType, "R2");
}
private boolean handleControllerKey(int keyCode, boolean pressed) {
if (!mControllerKeyMapping.containsKey(keyCode))
return false;
final int mapping = mControllerKeyMapping.get(keyCode);
mHostInterface.setControllerButtonState(0, mapping, pressed);
return true;
}
}

View file

@ -10,7 +10,7 @@
<!-- The primary full-screen view. This can be replaced with whatever view <!-- The primary full-screen view. This can be replaced with whatever view
is needed to present your content, e.g. VideoView, SurfaceView, is needed to present your content, e.g. VideoView, SurfaceView,
TextureView, etc. --> TextureView, etc. -->
<SurfaceView <com.github.stenzek.duckstation.EmulationSurfaceView
android:id="@+id/fullscreen_content" android:id="@+id/fullscreen_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"