diff options
Diffstat (limited to 'src')
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; | |||
| 16 | import android.graphics.Canvas; | 16 | import android.graphics.Canvas; |
| 17 | import android.graphics.Rect; | 17 | import android.graphics.Rect; |
| 18 | import android.graphics.drawable.Drawable; | 18 | import android.graphics.drawable.Drawable; |
| 19 | import android.hardware.Sensor; | ||
| 20 | import android.hardware.SensorEvent; | ||
| 21 | import android.hardware.SensorEventListener; | ||
| 22 | import android.hardware.SensorManager; | ||
| 19 | import android.preference.PreferenceManager; | 23 | import android.preference.PreferenceManager; |
| 20 | import android.util.AttributeSet; | 24 | import android.util.AttributeSet; |
| 21 | import android.util.DisplayMetrics; | 25 | import android.util.DisplayMetrics; |
| @@ -38,20 +42,19 @@ import java.util.Set; | |||
| 38 | * Draws the interactive input overlay on top of the | 42 | * Draws the interactive input overlay on top of the |
| 39 | * {@link SurfaceView} that is rendering emulation. | 43 | * {@link SurfaceView} that is rendering emulation. |
| 40 | */ | 44 | */ |
| 41 | public final class InputOverlay extends SurfaceView implements OnTouchListener { | 45 | public final class InputOverlay extends SurfaceView implements OnTouchListener, SensorEventListener { |
| 42 | private final Set<InputOverlayDrawableButton> overlayButtons = new HashSet<>(); | 46 | private final Set<InputOverlayDrawableButton> overlayButtons = new HashSet<>(); |
| 43 | private final Set<InputOverlayDrawableDpad> overlayDpads = new HashSet<>(); | 47 | private final Set<InputOverlayDrawableDpad> overlayDpads = new HashSet<>(); |
| 44 | private final Set<InputOverlayDrawableJoystick> overlayJoysticks = new HashSet<>(); | 48 | private final Set<InputOverlayDrawableJoystick> overlayJoysticks = new HashSet<>(); |
| 45 | 49 | ||
| 46 | private boolean mIsInEditMode = false; | 50 | private boolean mIsInEditMode = false; |
| 47 | private InputOverlayDrawableButton mButtonBeingConfigured; | ||
| 48 | private InputOverlayDrawableDpad mDpadBeingConfigured; | ||
| 49 | private InputOverlayDrawableJoystick mJoystickBeingConfigured; | ||
| 50 | 51 | ||
| 51 | private SharedPreferences mPreferences; | 52 | private SharedPreferences mPreferences; |
| 52 | 53 | ||
| 53 | // Stores the ID of the pointer that interacted with the 3DS touchscreen. | 54 | private float[] gyro = new float[3]; |
| 54 | private int mTouchscreenPointerId = -1; | 55 | private float[] accel = new float[3]; |
| 56 | |||
| 57 | private long motionTimestamp; | ||
| 55 | 58 | ||
| 56 | /** | 59 | /** |
| 57 | * Constructor | 60 | * Constructor |
| @@ -67,12 +70,12 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener { | |||
| 67 | defaultOverlay(); | 70 | defaultOverlay(); |
| 68 | } | 71 | } |
| 69 | 72 | ||
| 70 | // Reset 3ds touchscreen pointer ID | ||
| 71 | mTouchscreenPointerId = -1; | ||
| 72 | |||
| 73 | // Load the controls. | 73 | // Load the controls. |
| 74 | refreshControls(); | 74 | refreshControls(); |
| 75 | 75 | ||
| 76 | // Set the on motion sensor listener. | ||
| 77 | setMotionSensorListener(context); | ||
| 78 | |||
| 76 | // Set the on touch listener. | 79 | // Set the on touch listener. |
| 77 | setOnTouchListener(this); | 80 | setOnTouchListener(this); |
| 78 | 81 | ||
| @@ -83,6 +86,20 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener { | |||
| 83 | requestFocus(); | 86 | requestFocus(); |
| 84 | } | 87 | } |
| 85 | 88 | ||
| 89 | private void setMotionSensorListener(Context context) { | ||
| 90 | SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); | ||
| 91 | Sensor gyro_sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); | ||
| 92 | Sensor accel_sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); | ||
| 93 | |||
| 94 | if (gyro_sensor != null) { | ||
| 95 | sensorManager.registerListener(this, gyro_sensor, SensorManager.SENSOR_DELAY_GAME); | ||
| 96 | } | ||
| 97 | if (accel_sensor != null) { | ||
| 98 | sensorManager.registerListener(this, accel_sensor, SensorManager.SENSOR_DELAY_GAME); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | |||
| 86 | /** | 103 | /** |
| 87 | * Resizes a {@link Bitmap} by a given scale factor | 104 | * Resizes a {@link Bitmap} by a given scale factor |
| 88 | * | 105 | * |
| @@ -427,6 +444,36 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener { | |||
| 427 | return true; | 444 | return true; |
| 428 | } | 445 | } |
| 429 | 446 | ||
| 447 | @Override | ||
| 448 | public void onSensorChanged(SensorEvent event) { | ||
| 449 | if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { | ||
| 450 | accel[0] = -event.values[1] / SensorManager.GRAVITY_EARTH; | ||
| 451 | accel[1] = event.values[0] / SensorManager.GRAVITY_EARTH; | ||
| 452 | accel[2] = -event.values[2] / SensorManager.GRAVITY_EARTH; | ||
| 453 | } | ||
| 454 | |||
| 455 | if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) { | ||
| 456 | // Investigate why sensor value is off by 12x | ||
| 457 | gyro[0] = event.values[1] / 12.0f; | ||
| 458 | gyro[1] = -event.values[0] / 12.0f; | ||
| 459 | gyro[2] = event.values[2] / 12.0f; | ||
| 460 | } | ||
| 461 | |||
| 462 | // Only update state on accelerometer data | ||
| 463 | if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) { | ||
| 464 | return; | ||
| 465 | } | ||
| 466 | |||
| 467 | long delta_timestamp = (event.timestamp - motionTimestamp) / 1000; | ||
| 468 | motionTimestamp = event.timestamp; | ||
| 469 | NativeLibrary.onGamePadMotionEvent(NativeLibrary.Player1Device, delta_timestamp, gyro[0], gyro[1], gyro[2], accel[0], accel[1], accel[2]); | ||
| 470 | NativeLibrary.onGamePadMotionEvent(NativeLibrary.ConsoleDevice, delta_timestamp, gyro[0], gyro[1], gyro[2], accel[0], accel[1], accel[2]); | ||
| 471 | } | ||
| 472 | |||
| 473 | @Override | ||
| 474 | public void onAccuracyChanged(Sensor sensor, int i) { | ||
| 475 | } | ||
| 476 | |||
| 430 | private void addOverlayControls(String orientation) { | 477 | private void addOverlayControls(String orientation) { |
| 431 | if (mPreferences.getBoolean("buttonToggle0", true)) { | 478 | if (mPreferences.getBoolean("buttonToggle0", true)) { |
| 432 | overlayButtons.add(initializeOverlayButton(getContext(), R.drawable.button_a, | 479 | 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) { | |||
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | void EmuWindow_Android::OnTouchPressed(int id, float x, float y) { | 13 | void EmuWindow_Android::OnTouchPressed(int id, float x, float y) { |
| 14 | const auto [touch_x,touch_y]=MapToTouchScreen(x,y); | 14 | const auto [touch_x, touch_y] = MapToTouchScreen(x, y); |
| 15 | input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, id); | 15 | input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, id); |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | void EmuWindow_Android::OnTouchMoved(int id, float x, float y) { | 18 | void EmuWindow_Android::OnTouchMoved(int id, float x, float y) { |
| 19 | const auto [touch_x,touch_y]=MapToTouchScreen(x,y); | 19 | const auto [touch_x, touch_y] = MapToTouchScreen(x, y); |
| 20 | input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, id); | 20 | input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, id); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| @@ -29,21 +29,19 @@ void EmuWindow_Android::OnGamepadButtonEvent(int player_index, int button_id, bo | |||
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | void EmuWindow_Android::OnGamepadJoystickEvent(int player_index, int stick_id, float x, float y) { | 31 | void EmuWindow_Android::OnGamepadJoystickEvent(int player_index, int stick_id, float x, float y) { |
| 32 | input_subsystem->GetVirtualGamepad()->SetStickPosition( | 32 | input_subsystem->GetVirtualGamepad()->SetStickPosition(player_index, stick_id, x, y); |
| 33 | player_index, stick_id, x, y); | ||
| 34 | } | 33 | } |
| 35 | 34 | ||
| 36 | void EmuWindow_Android::OnGamepadMotionEvent(int player_index, u64 delta_timestamp, float gyro_x, float gyro_y, | 35 | void EmuWindow_Android::OnGamepadMotionEvent(int player_index, u64 delta_timestamp, float gyro_x, |
| 37 | float gyro_z, float accel_x, float accel_y, | 36 | float gyro_y, float gyro_z, float accel_x, |
| 38 | float accel_z) { | 37 | float accel_y, float accel_z) { |
| 39 | // TODO: | 38 | input_subsystem->GetVirtualGamepad()->SetMotionState(player_index, delta_timestamp, gyro_x, |
| 40 | // input_subsystem->GetVirtualGamepad()->SetMotionState(player_index, delta_timestamp, gyro_x, gyro_y, | 39 | gyro_y, gyro_z, accel_x, accel_y, accel_z); |
| 41 | // gyro_z, accel_x, accel_y, accel_z); | ||
| 42 | } | 40 | } |
| 43 | 41 | ||
| 44 | EmuWindow_Android::EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem_, | 42 | EmuWindow_Android::EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem_, |
| 45 | ANativeWindow* surface_) | 43 | ANativeWindow* surface_) |
| 46 | : input_subsystem{input_subsystem_} { | 44 | : input_subsystem{input_subsystem_} { |
| 47 | LOG_INFO(Frontend, "initializing"); | 45 | LOG_INFO(Frontend, "initializing"); |
| 48 | 46 | ||
| 49 | if (!surface_) { | 47 | 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 | |||
| 39 | SetStickPosition(player_index, static_cast<int>(axis_id), x_value, y_value); | 39 | SetStickPosition(player_index, static_cast<int>(axis_id), x_value, y_value); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | void VirtualGamepad::SetMotionState(std::size_t player_index, u64 delta_timestamp, float gyro_x, | ||
| 43 | float gyro_y, float gyro_z, float accel_x, float accel_y, | ||
| 44 | float accel_z) { | ||
| 45 | const auto identifier = GetIdentifier(player_index); | ||
| 46 | const BasicMotion motion_data{ | ||
| 47 | .gyro_x = gyro_x, | ||
| 48 | .gyro_y = gyro_y, | ||
| 49 | .gyro_z = gyro_z, | ||
| 50 | .accel_x = accel_x, | ||
| 51 | .accel_y = accel_y, | ||
| 52 | .accel_z = accel_z, | ||
| 53 | .delta_timestamp = delta_timestamp, | ||
| 54 | }; | ||
| 55 | SetMotion(identifier, 0, motion_data); | ||
| 56 | } | ||
| 57 | |||
| 42 | void VirtualGamepad::ResetControllers() { | 58 | void VirtualGamepad::ResetControllers() { |
| 43 | for (std::size_t i = 0; i < PlayerIndexCount; i++) { | 59 | for (std::size_t i = 0; i < PlayerIndexCount; i++) { |
| 44 | SetStickPosition(i, VirtualStick::Left, 0.0f, 0.0f); | 60 | 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: | |||
| 52 | void SetButtonState(std::size_t player_index, VirtualButton button_id, bool value); | 52 | void SetButtonState(std::size_t player_index, VirtualButton button_id, bool value); |
| 53 | 53 | ||
| 54 | /** | 54 | /** |
| 55 | * Sets the status of all buttons bound with the key to released | 55 | * Sets the status of a stick to a specific player index |
| 56 | * @param player_index the player number that will take this action | 56 | * @param player_index the player number that will take this action |
| 57 | * @param axis_id the id of the axis to move | 57 | * @param axis_id the id of the axis to move |
| 58 | * @param x_value the position of the stick in the x axis | 58 | * @param x_value the position of the stick in the x axis |
| @@ -62,6 +62,16 @@ public: | |||
| 62 | void SetStickPosition(std::size_t player_index, VirtualStick axis_id, float x_value, | 62 | void SetStickPosition(std::size_t player_index, VirtualStick axis_id, float x_value, |
| 63 | float y_value); | 63 | float y_value); |
| 64 | 64 | ||
| 65 | /** | ||
| 66 | * Sets the status of the motion sensor to a specific player index | ||
| 67 | * @param player_index the player number that will take this action | ||
| 68 | * @param delta_timestamp time passed since last reading | ||
| 69 | * @param gyro_x,gyro_y,gyro_z the gyro sensor readings | ||
| 70 | * @param accel_x,accel_y,accel_z the acelerometer reading | ||
| 71 | */ | ||
| 72 | void SetMotionState(std::size_t player_index, u64 delta_timestamp, float gyro_x, float gyro_y, | ||
| 73 | float gyro_z, float accel_x, float accel_y, float accel_z); | ||
| 74 | |||
| 65 | /// Restores all inputs into the neutral position | 75 | /// Restores all inputs into the neutral position |
| 66 | void ResetControllers(); | 76 | void ResetControllers(); |
| 67 | 77 | ||