Android: Implement vibrate-on-press and dualshock vibration
This commit is contained in:
@ -15,6 +15,7 @@ public class AndroidHostInterface {
|
||||
private Context mContext;
|
||||
|
||||
static public native String getScmVersion();
|
||||
|
||||
static public native AndroidHostInterface create(Context context, String userDirectory);
|
||||
|
||||
public AndroidHostInterface(Context context) {
|
||||
@ -71,7 +72,9 @@ public class AndroidHostInterface {
|
||||
public native void setDisplayAlignment(int alignment);
|
||||
|
||||
public native PatchCode[] getPatchCodeList();
|
||||
|
||||
public native void setPatchCodeEnabled(int index, boolean enabled);
|
||||
|
||||
public native boolean importPatchCodesFromString(String str);
|
||||
|
||||
public native void addOSDMessage(String message, float duration);
|
||||
@ -81,10 +84,13 @@ public class AndroidHostInterface {
|
||||
public native String importBIOSImage(byte[] data);
|
||||
|
||||
public native boolean isFastForwardEnabled();
|
||||
|
||||
public native void setFastForwardEnabled(boolean enabled);
|
||||
|
||||
public native String[] getMediaPlaylistPaths();
|
||||
|
||||
public native int getMediaPlaylistIndex();
|
||||
|
||||
public native boolean setMediaPlaylistIndex(int index);
|
||||
|
||||
static {
|
||||
|
||||
@ -8,6 +8,7 @@ import android.content.res.Configuration;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Vibrator;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.View;
|
||||
@ -124,6 +125,7 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
|
||||
private void doApplySettings() {
|
||||
AndroidHostInterface.getInstance().applySettings();
|
||||
updateRequestedOrientation();
|
||||
updateControllers();
|
||||
}
|
||||
|
||||
private void applySettings() {
|
||||
@ -163,9 +165,6 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
|
||||
doApplySettings();
|
||||
}
|
||||
|
||||
if (AndroidHostInterface.getInstance().isEmulationThreadPaused())
|
||||
AndroidHostInterface.getInstance().pauseEmulationThread(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -323,8 +322,7 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
|
||||
|
||||
private void showMenu() {
|
||||
if (getBooleanSetting("Main/PauseOnMenu", false) &&
|
||||
!AndroidHostInterface.getInstance().isEmulationThreadPaused())
|
||||
{
|
||||
!AndroidHostInterface.getInstance().isEmulationThreadPaused()) {
|
||||
AndroidHostInterface.getInstance().pauseEmulationThread(true);
|
||||
}
|
||||
|
||||
@ -485,8 +483,7 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
|
||||
private void showDiscChangeMenu() {
|
||||
final String[] paths = AndroidHostInterface.getInstance().getMediaPlaylistPaths();
|
||||
final int currentPath = AndroidHostInterface.getInstance().getMediaPlaylistIndex();
|
||||
if (paths == null)
|
||||
{
|
||||
if (paths == null) {
|
||||
onMenuClosed();
|
||||
return;
|
||||
}
|
||||
@ -515,6 +512,8 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
|
||||
final String controllerType = getStringSetting("Controller1/Type", "DigitalController");
|
||||
final String viewType = getStringSetting("Controller1/TouchscreenControllerView", "digital");
|
||||
final boolean autoHideTouchscreenController = getBooleanSetting("Controller1/AutoHideTouchscreenController", false);
|
||||
final boolean hapticFeedback = getBooleanSetting("Controller1/HapticFeedback", false);
|
||||
final boolean vibration = getBooleanSetting("Controller1/Vibration", false);
|
||||
final FrameLayout activityLayout = findViewById(R.id.frameLayout);
|
||||
|
||||
Log.i("EmulationActivity", "Controller type: " + controllerType);
|
||||
@ -526,14 +525,18 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
|
||||
if (mTouchscreenController != null) {
|
||||
activityLayout.removeView(mTouchscreenController);
|
||||
mTouchscreenController = null;
|
||||
mVibratorService = null;
|
||||
}
|
||||
} else {
|
||||
if (mTouchscreenController == null) {
|
||||
mTouchscreenController = new TouchscreenControllerView(this);
|
||||
if (vibration)
|
||||
mVibratorService = (Vibrator) getSystemService(VIBRATOR_SERVICE);
|
||||
|
||||
activityLayout.addView(mTouchscreenController);
|
||||
}
|
||||
|
||||
mTouchscreenController.init(0, controllerType, viewType);
|
||||
mTouchscreenController.init(0, controllerType, viewType, hapticFeedback);
|
||||
}
|
||||
}
|
||||
|
||||
@ -578,4 +581,21 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
|
||||
|
||||
mInputDeviceListener = null;
|
||||
}
|
||||
|
||||
private Vibrator mVibratorService;
|
||||
|
||||
public void setVibration(boolean enabled) {
|
||||
if (mVibratorService == null)
|
||||
return;
|
||||
|
||||
runOnUiThread(() -> {
|
||||
if (mVibratorService == null)
|
||||
return;
|
||||
|
||||
if (enabled)
|
||||
mVibratorService.vibrate(1000);
|
||||
else
|
||||
mVibratorService.cancel();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,19 +9,14 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
@ -73,7 +73,9 @@ public class GameListEntry {
|
||||
return mTitle;
|
||||
}
|
||||
|
||||
public String getFileTitle() { return mFileTitle; }
|
||||
public String getFileTitle() {
|
||||
return mFileTitle;
|
||||
}
|
||||
|
||||
public String getModifiedTime() {
|
||||
return mModifiedTime;
|
||||
|
||||
@ -5,6 +5,7 @@ import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
@ -14,6 +15,7 @@ public class TouchscreenControllerButtonView extends View {
|
||||
private Drawable mUnpressedDrawable;
|
||||
private Drawable mPressedDrawable;
|
||||
private boolean mPressed = false;
|
||||
private boolean mHapticFeedback = false;
|
||||
private int mControllerIndex = -1;
|
||||
private int mButtonCode = -1;
|
||||
|
||||
@ -81,6 +83,10 @@ public class TouchscreenControllerButtonView extends View {
|
||||
mPressed = pressed;
|
||||
invalidate();
|
||||
updateControllerState();
|
||||
|
||||
if (mHapticFeedback) {
|
||||
performHapticFeedback(pressed ? HapticFeedbackConstants.VIRTUAL_KEY : HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setButtonCode(int controllerIndex, int code) {
|
||||
@ -88,6 +94,10 @@ public class TouchscreenControllerButtonView extends View {
|
||||
mButtonCode = code;
|
||||
}
|
||||
|
||||
public void setHapticFeedback(boolean enabled) {
|
||||
mHapticFeedback = enabled;
|
||||
}
|
||||
|
||||
private void updateControllerState() {
|
||||
if (mButtonCode >= 0)
|
||||
AndroidHostInterface.getInstance().setControllerButtonState(mControllerIndex, mButtonCode, mPressed);
|
||||
|
||||
@ -20,6 +20,7 @@ public class TouchscreenControllerView extends FrameLayout {
|
||||
private View mMainView;
|
||||
private ArrayList<TouchscreenControllerButtonView> mButtonViews = new ArrayList<>();
|
||||
private ArrayList<TouchscreenControllerAxisView> mAxisViews = new ArrayList<>();
|
||||
private boolean mHapticFeedback;
|
||||
|
||||
public TouchscreenControllerView(Context context) {
|
||||
super(context);
|
||||
@ -33,9 +34,10 @@ public class TouchscreenControllerView extends FrameLayout {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
public void init(int controllerIndex, String controllerType, String viewType) {
|
||||
public void init(int controllerIndex, String controllerType, String viewType, boolean hapticFeedback) {
|
||||
mControllerIndex = controllerIndex;
|
||||
mControllerType = controllerType;
|
||||
mHapticFeedback = hapticFeedback;
|
||||
|
||||
mButtonViews.clear();
|
||||
mAxisViews.clear();
|
||||
@ -99,6 +101,7 @@ public class TouchscreenControllerView extends FrameLayout {
|
||||
|
||||
if (code >= 0) {
|
||||
buttonView.setButtonCode(mControllerIndex, code);
|
||||
buttonView.setHapticFeedback(mHapticFeedback);
|
||||
mButtonViews.add(buttonView);
|
||||
} else {
|
||||
Log.e("TouchscreenController", String.format("Unknown button name '%s' " +
|
||||
|
||||
Reference in New Issue
Block a user