summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNarr the Reg <juangerman-13@hotmail.com>2023-02-13 21:08:06 +0100
committerbunnei <bunneidev@gmail.com>2023-06-03 09:05:30 +0200
commitf1bb2f3685a73c68765ada5298bfdc91fdb75e37 (patch)
treef85eee36f69b1467c15304cb08d05a6708148e53
parentandroid: Hook jni input properly (diff)
downloadyuzu-f1bb2f3685a73c68765ada5298bfdc91fdb75e37.tar
yuzu-f1bb2f3685a73c68765ada5298bfdc91fdb75e37.tar.gz
yuzu-f1bb2f3685a73c68765ada5298bfdc91fdb75e37.tar.bz2
yuzu-f1bb2f3685a73c68765ada5298bfdc91fdb75e37.tar.lz
yuzu-f1bb2f3685a73c68765ada5298bfdc91fdb75e37.tar.xz
yuzu-f1bb2f3685a73c68765ada5298bfdc91fdb75e37.tar.zst
yuzu-f1bb2f3685a73c68765ada5298bfdc91fdb75e37.zip
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java65
-rw-r--r--src/android/app/src/main/jni/emu_window/emu_window.cpp20
-rw-r--r--src/input_common/drivers/virtual_gamepad.cpp16
-rw-r--r--src/input_common/drivers/virtual_gamepad.h12
4 files changed, 92 insertions, 21 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java
index e6e91aea1..881c6de91 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.java
@@ -16,6 +16,10 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -38,20 +42,19 @@ import java.util.Set;
* Draws the interactive input overlay on top of the
* {@link SurfaceView} that is rendering emulation.
*/
-public final class InputOverlay extends SurfaceView implements OnTouchListener {
+public final class InputOverlay extends SurfaceView implements OnTouchListener, SensorEventListener {
private final Set<InputOverlayDrawableButton> overlayButtons = new HashSet<>();
private final Set<InputOverlayDrawableDpad> overlayDpads = new HashSet<>();
private final Set<InputOverlayDrawableJoystick> overlayJoysticks = new HashSet<>();
private boolean mIsInEditMode = false;
- private InputOverlayDrawableButton mButtonBeingConfigured;
- private InputOverlayDrawableDpad mDpadBeingConfigured;
- private InputOverlayDrawableJoystick mJoystickBeingConfigured;
private SharedPreferences mPreferences;
- // Stores the ID of the pointer that interacted with the 3DS touchscreen.
- private int mTouchscreenPointerId = -1;
+ private float[] gyro = new float[3];
+ private float[] accel = new float[3];
+
+ private long motionTimestamp;
/**
* Constructor
@@ -67,12 +70,12 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener {
defaultOverlay();
}
- // Reset 3ds touchscreen pointer ID
- mTouchscreenPointerId = -1;
-
// Load the controls.
refreshControls();
+ // Set the on motion sensor listener.
+ setMotionSensorListener(context);
+
// Set the on touch listener.
setOnTouchListener(this);
@@ -83,6 +86,20 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener {
requestFocus();
}
+ private void setMotionSensorListener(Context context) {
+ SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+ Sensor gyro_sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
+ Sensor accel_sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+
+ if (gyro_sensor != null) {
+ sensorManager.registerListener(this, gyro_sensor, SensorManager.SENSOR_DELAY_GAME);
+ }
+ if (accel_sensor != null) {
+ sensorManager.registerListener(this, accel_sensor, SensorManager.SENSOR_DELAY_GAME);
+ }
+ }
+
+
/**
* Resizes a {@link Bitmap} by a given scale factor
*
@@ -427,6 +444,36 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener {
return true;
}
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
+ accel[0] = -event.values[1] / SensorManager.GRAVITY_EARTH;
+ accel[1] = event.values[0] / SensorManager.GRAVITY_EARTH;
+ accel[2] = -event.values[2] / SensorManager.GRAVITY_EARTH;
+ }
+
+ if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
+ // Investigate why sensor value is off by 12x
+ gyro[0] = event.values[1] / 12.0f;
+ gyro[1] = -event.values[0] / 12.0f;
+ gyro[2] = event.values[2] / 12.0f;
+ }
+
+ // Only update state on accelerometer data
+ if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) {
+ return;
+ }
+
+ long delta_timestamp = (event.timestamp - motionTimestamp) / 1000;
+ motionTimestamp = event.timestamp;
+ NativeLibrary.onGamePadMotionEvent(NativeLibrary.Player1Device, delta_timestamp, gyro[0], gyro[1], gyro[2], accel[0], accel[1], accel[2]);
+ NativeLibrary.onGamePadMotionEvent(NativeLibrary.ConsoleDevice, delta_timestamp, gyro[0], gyro[1], gyro[2], accel[0], accel[1], accel[2]);
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int i) {
+ }
+
private void addOverlayControls(String orientation) {
if (mPreferences.getBoolean("buttonToggle0", true)) {
overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.button_a,
diff --git a/src/android/app/src/main/jni/emu_window/emu_window.cpp b/src/android/app/src/main/jni/emu_window/emu_window.cpp
index 0f6514a61..2beba6804 100644
--- a/src/android/app/src/main/jni/emu_window/emu_window.cpp
+++ b/src/android/app/src/main/jni/emu_window/emu_window.cpp
@@ -11,12 +11,12 @@ void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) {
}
void EmuWindow_Android::OnTouchPressed(int id, float x, float y) {
- const auto [touch_x,touch_y]=MapToTouchScreen(x,y);
+ const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, id);
}
void EmuWindow_Android::OnTouchMoved(int id, float x, float y) {
- const auto [touch_x,touch_y]=MapToTouchScreen(x,y);
+ const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, id);
}
@@ -29,21 +29,19 @@ void EmuWindow_Android::OnGamepadButtonEvent(int player_index, int button_id, bo
}
void EmuWindow_Android::OnGamepadJoystickEvent(int player_index, int stick_id, float x, float y) {
- input_subsystem->GetVirtualGamepad()->SetStickPosition(
- player_index, stick_id, x, y);
+ input_subsystem->GetVirtualGamepad()->SetStickPosition(player_index, stick_id, x, y);
}
-void EmuWindow_Android::OnGamepadMotionEvent(int player_index, u64 delta_timestamp, float gyro_x, float gyro_y,
- float gyro_z, float accel_x, float accel_y,
- float accel_z) {
- // TODO:
- // input_subsystem->GetVirtualGamepad()->SetMotionState(player_index, delta_timestamp, gyro_x, gyro_y,
- // gyro_z, accel_x, accel_y, accel_z);
+void EmuWindow_Android::OnGamepadMotionEvent(int player_index, u64 delta_timestamp, float gyro_x,
+ float gyro_y, float gyro_z, float accel_x,
+ float accel_y, float accel_z) {
+ input_subsystem->GetVirtualGamepad()->SetMotionState(player_index, delta_timestamp, gyro_x,
+ gyro_y, gyro_z, accel_x, accel_y, accel_z);
}
EmuWindow_Android::EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem_,
ANativeWindow* surface_)
- : input_subsystem{input_subsystem_} {
+ : input_subsystem{input_subsystem_} {
LOG_INFO(Frontend, "initializing");
if (!surface_) {
diff --git a/src/input_common/drivers/virtual_gamepad.cpp b/src/input_common/drivers/virtual_gamepad.cpp
index 7db945aa6..c15cbbe58 100644
--- a/src/input_common/drivers/virtual_gamepad.cpp
+++ b/src/input_common/drivers/virtual_gamepad.cpp
@@ -39,6 +39,22 @@ void VirtualGamepad::SetStickPosition(std::size_t player_index, VirtualStick axi
SetStickPosition(player_index, static_cast<int>(axis_id), x_value, y_value);
}
+void VirtualGamepad::SetMotionState(std::size_t player_index, u64 delta_timestamp, float gyro_x,
+ float gyro_y, float gyro_z, float accel_x, float accel_y,
+ float accel_z) {
+ const auto identifier = GetIdentifier(player_index);
+ const BasicMotion motion_data{
+ .gyro_x = gyro_x,
+ .gyro_y = gyro_y,
+ .gyro_z = gyro_z,
+ .accel_x = accel_x,
+ .accel_y = accel_y,
+ .accel_z = accel_z,
+ .delta_timestamp = delta_timestamp,
+ };
+ SetMotion(identifier, 0, motion_data);
+}
+
void VirtualGamepad::ResetControllers() {
for (std::size_t i = 0; i < PlayerIndexCount; i++) {
SetStickPosition(i, VirtualStick::Left, 0.0f, 0.0f);
diff --git a/src/input_common/drivers/virtual_gamepad.h b/src/input_common/drivers/virtual_gamepad.h
index 3df91cc6f..dfbc45a28 100644
--- a/src/input_common/drivers/virtual_gamepad.h
+++ b/src/input_common/drivers/virtual_gamepad.h
@@ -52,7 +52,7 @@ public:
void SetButtonState(std::size_t player_index, VirtualButton button_id, bool value);
/**
- * Sets the status of all buttons bound with the key to released
+ * Sets the status of a stick to a specific player index
* @param player_index the player number that will take this action
* @param axis_id the id of the axis to move
* @param x_value the position of the stick in the x axis
@@ -62,6 +62,16 @@ public:
void SetStickPosition(std::size_t player_index, VirtualStick axis_id, float x_value,
float y_value);
+ /**
+ * Sets the status of the motion sensor to a specific player index
+ * @param player_index the player number that will take this action
+ * @param delta_timestamp time passed since last reading
+ * @param gyro_x,gyro_y,gyro_z the gyro sensor readings
+ * @param accel_x,accel_y,accel_z the acelerometer reading
+ */
+ void SetMotionState(std::size_t player_index, u64 delta_timestamp, float gyro_x, float gyro_y,
+ float gyro_z, float accel_x, float accel_y, float accel_z);
+
/// Restores all inputs into the neutral position
void ResetControllers();