diff options
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(); | 
