diff --git a/src/LibRyujinx/Android/JniExportedMethods.cs b/src/LibRyujinx/Android/JniExportedMethods.cs
index 615d6d561..6a110ba7c 100644
--- a/src/LibRyujinx/Android/JniExportedMethods.cs
+++ b/src/LibRyujinx/Android/JniExportedMethods.cs
@@ -553,6 +553,20 @@ namespace LibRyujinx
             SetButtonReleased((GamepadButtonInputId)(int)button, id);
         }
 
+        [UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputSetAccelerometerData")]
+        public static void JniSetAccelerometerData(JEnvRef jEnv, JObjectLocalRef jObj, JFloat x, JFloat y, JFloat z, JInt id)
+        {
+            var accel = new Vector3(x, y, z);
+            SetAccelerometerData(accel, id);
+        }
+
+        [UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputSetGyroData")]
+        public static void JniSetGyroData(JEnvRef jEnv, JObjectLocalRef jObj, JFloat x, JFloat y, JFloat z, JInt id)
+        {
+            var gryo = new Vector3(x, y, z);
+            SetGryoData(gryo, id);
+        }
+
         [UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputSetStickAxis")]
         public static void JniSetStickAxis(JEnvRef jEnv, JObjectLocalRef jObj, JInt stick, JFloat x, JFloat y, JInt id)
         {
diff --git a/src/LibRyujinx/LibRyujinx.Input.cs b/src/LibRyujinx/LibRyujinx.Input.cs
index dc1c1f6d2..89fb04a2d 100644
--- a/src/LibRyujinx/LibRyujinx.Input.cs
+++ b/src/LibRyujinx/LibRyujinx.Input.cs
@@ -1,4 +1,4 @@
-using DiscordRPC;
+using DiscordRPC;
 using Ryujinx.Common.Configuration;
 using Ryujinx.Common.Configuration.Hid;
 using Ryujinx.Common.Configuration.Hid.Controller;
@@ -83,6 +83,16 @@ namespace LibRyujinx
             _gamepadDriver?.SetButtonReleased(button, id);
         }
 
+        public static void SetAccelerometerData(Vector3 accel, int id)
+        {
+            _gamepadDriver?.SetAccelerometerData(accel, id);
+        }
+
+        public static void SetGryoData(Vector3 gyro, int id)
+        {
+            _gamepadDriver?.SetGryoData(gyro, id);
+        }
+
         public static void SetStickAxis(StickInputId stick, Vector2 axes, int deviceId)
         {
             _gamepadDriver?.SetStickAxis(stick, axes, deviceId);
@@ -460,6 +470,22 @@ namespace LibRyujinx
                 gamePad.ButtonInputs[(int)button] = false;
             }
         }
+
+        public void SetAccelerometerData(Vector3 accel, int deviceId)
+        {
+            if (_gamePads.TryGetValue(deviceId, out var gamePad))
+            {
+                gamePad.Accelerometer = accel;
+            }
+        }
+
+        public void SetGryoData(Vector3 gyro, int deviceId)
+        {
+            if (_gamePads.TryGetValue(deviceId, out var gamePad))
+            {
+                gamePad.Gyro = gyro;
+            }
+        }
     }
 
     public class VirtualGamepad : IGamepad
@@ -481,7 +507,7 @@ namespace LibRyujinx
 
         public void Dispose() { }
 
-        public GamepadFeaturesFlag Features { get; }
+        public GamepadFeaturesFlag Features { get; } = GamepadFeaturesFlag.Motion;
         public string Id { get; }
 
         internal readonly int IdInt;
@@ -490,6 +516,8 @@ namespace LibRyujinx
         public bool IsConnected { get; }
         public Vector2[] StickInputs { get => _stickInputs; set => _stickInputs = value; }
         public bool[] ButtonInputs { get => _buttonInputs; set => _buttonInputs = value; }
+        public Vector3 Accelerometer { get; internal set; }
+        public Vector3 Gyro { get; internal set; }
 
         public bool IsPressed(GamepadButtonInputId inputId)
         {
@@ -505,9 +533,18 @@ namespace LibRyujinx
 
         public Vector3 GetMotionData(MotionInputId inputId)
         {
+            if (inputId == MotionInputId.Accelerometer)
+                return Accelerometer;
+            else if (inputId == MotionInputId.Gyroscope)
+                return RadToDegree(Gyro);
             return new Vector3();
         }
 
+        private static Vector3 RadToDegree(Vector3 rad)
+        {
+            return rad * (180 / MathF.PI);
+        }
+
         public void SetTriggerThreshold(float triggerThreshold)
         {
             //throw new System.NotImplementedException();
diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/GameHost.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/GameHost.kt
index 48cfb4ff6..81fef9c7b 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/GameHost.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/GameHost.kt
@@ -96,7 +96,8 @@ class GameHost(context: Context?, private val mainViewModel: MainViewModel) : Su
             mainViewModel.controller?.connect()
         }
 
-        mainViewModel.physicalControllerManager?.connect()
+        val id = mainViewModel.physicalControllerManager?.connect()
+        mainViewModel.motionSensorManager?.setControllerId(id ?: -1)
 
         _nativeRyujinx.graphicsRendererSetSize(
             surfaceHolder.surfaceFrame.width(),
diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/MainActivity.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/MainActivity.kt
index f8e28f3e5..b00cf8ed1 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/MainActivity.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/MainActivity.kt
@@ -28,6 +28,7 @@ import kotlin.math.abs
 class MainActivity : BaseActivity() {
     private var physicalControllerManager: PhysicalControllerManager =
         PhysicalControllerManager(this)
+    private lateinit var motionSensorManager: MotionSensorManager
     private var _isInit: Boolean = false
     var isGameRunning = false
     var storageHelper: SimpleStorageHelper? = null
@@ -80,6 +81,8 @@ class MainActivity : BaseActivity() {
     }
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+
+        motionSensorManager = MotionSensorManager(this)
         Thread.setDefaultUncaughtExceptionHandler(crashHandler)
 
         if(
@@ -97,6 +100,7 @@ class MainActivity : BaseActivity() {
 
         mainViewModel = MainViewModel(this)
         mainViewModel!!.physicalControllerManager = physicalControllerManager
+        mainViewModel!!.motionSensorManager = motionSensorManager
 
         mainViewModel?.apply {
             setContent {
@@ -194,6 +198,7 @@ class MainActivity : BaseActivity() {
             setFullScreen(true)
             NativeHelpers.instance.setTurboMode(true)
             force60HzRefreshRate(true)
+            motionSensorManager.register()
         }
     }
 
@@ -204,5 +209,7 @@ class MainActivity : BaseActivity() {
             NativeHelpers.instance.setTurboMode(false)
             force60HzRefreshRate(false)
         }
+
+        motionSensorManager.unregister()
     }
 }
diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/MotionSensorManager.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/MotionSensorManager.kt
new file mode 100644
index 000000000..f8a4e8c92
--- /dev/null
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/MotionSensorManager.kt
@@ -0,0 +1,111 @@
+package org.ryujinx.android
+
+import android.app.Activity
+import android.hardware.Sensor
+import android.hardware.SensorEvent
+import android.hardware.SensorEventListener2
+import android.hardware.SensorManager
+import android.view.OrientationEventListener
+
+class MotionSensorManager(val activity: MainActivity) : SensorEventListener2 {
+    private var isRegistered: Boolean = false
+    private var gyro: Sensor?
+    private var accelerometer: Sensor?
+    private var sensorManager: SensorManager =
+        activity.getSystemService(Activity.SENSOR_SERVICE) as SensorManager
+    private var controllerId: Int = -1
+
+    private val motionGyroOrientation : FloatArray = FloatArray(3)
+    private val motionAcelOrientation : FloatArray = FloatArray(3)
+    init {
+        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
+        gyro = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
+        setOrientation90()
+        var orientationListener = object : OrientationEventListener(activity){
+            override fun onOrientationChanged(orientation: Int) {
+                when{
+                    isWithinOrientationRange(orientation, 270) -> {
+                        setOrientation270()
+                    }
+                    isWithinOrientationRange(orientation, 90) -> {
+                        setOrientation90()
+                    }
+                }
+            }
+
+            private fun isWithinOrientationRange(
+                currentOrientation : Int, targetOrientation : Int, epsilon : Int = 90
+            ) : Boolean {
+                return currentOrientation > targetOrientation - epsilon
+                    && currentOrientation < targetOrientation + epsilon
+            }
+        }
+    }
+
+    fun setOrientation270() {
+        motionGyroOrientation[0] = -1.0f
+        motionGyroOrientation[1] = 1.0f
+        motionGyroOrientation[2] = 1.0f
+        motionAcelOrientation[0] = 1.0f
+        motionAcelOrientation[1] = -1.0f
+        motionAcelOrientation[2] = -1.0f
+    }
+    fun setOrientation90() {
+        motionGyroOrientation[0] = 1.0f
+        motionGyroOrientation[1] = -1.0f
+        motionGyroOrientation[2] = 1.0f
+        motionAcelOrientation[0] = -1.0f
+        motionAcelOrientation[1] = 1.0f
+        motionAcelOrientation[2] = -1.0f
+    }
+
+    fun setControllerId(id: Int){
+        controllerId = id
+    }
+
+    fun register(){
+        if(isRegistered)
+            return
+        gyro?.apply {
+            sensorManager.registerListener(this@MotionSensorManager, gyro, SensorManager.SENSOR_DELAY_GAME)
+        }
+        accelerometer?.apply {
+            sensorManager.registerListener(this@MotionSensorManager, accelerometer, SensorManager.SENSOR_DELAY_GAME)
+        }
+
+        isRegistered = true;
+    }
+
+    fun unregister(){
+        sensorManager.unregisterListener(this)
+        isRegistered = false
+    }
+
+    override fun onSensorChanged(event: SensorEvent?) {
+        if (controllerId != -1)
+            event?.apply {
+                when (sensor.type) {
+                    Sensor.TYPE_ACCELEROMETER -> {
+                        val x = motionAcelOrientation[0] * event.values[1]
+                        val y = motionAcelOrientation[1] * event.values[0]
+                        val z = motionAcelOrientation[2] * event.values[2]
+
+                        RyujinxNative.instance.inputSetAccelerometerData(x, y, z, controllerId)
+                    }
+
+                    Sensor.TYPE_GYROSCOPE -> {
+                        val x = motionGyroOrientation[0] * event.values[1]
+                        val y = motionGyroOrientation[1] * event.values[0]
+                        val z = motionGyroOrientation[2] * event.values[2]
+                        RyujinxNative.instance.inputSetGyroData(x, y, z, controllerId)
+                    }
+                }
+            }
+    }
+
+    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
+    }
+
+    override fun onFlushCompleted(sensor: Sensor?) {
+    }
+}
diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/PhysicalControllerManager.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/PhysicalControllerManager.kt
index c61ac456e..df1a726dd 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/PhysicalControllerManager.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/PhysicalControllerManager.kt
@@ -41,8 +41,13 @@ class PhysicalControllerManager(val activity: MainActivity) {
         }
     }
 
-    fun connect(){
+    fun connect() : Int {
         controllerId = ryujinxNative.inputConnectGamepad(0)
+        return controllerId
+    }
+
+    fun disconnect(){
+        controllerId = -1
     }
 
     private fun getGamePadButtonInputId(keycode: Int): GamePadButtonInputId {
diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/RyujinxNative.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/RyujinxNative.kt
index 5836372f4..d09362e11 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/RyujinxNative.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/RyujinxNative.kt
@@ -49,6 +49,8 @@ class RyujinxNative {
     external fun inputSetButtonReleased(button: Int, id: Int)
     external fun inputConnectGamepad(index: Int): Int
     external fun inputSetStickAxis(stick: Int, x: Float, y: Float, id: Int)
+    external fun inputSetAccelerometerData(x: Float, y: Float, z: Float, id: Int)
+    external fun inputSetGyroData(x: Float, y: Float, z: Float, id: Int)
     external fun graphicsSetSurface(surface: Long, window: Long)
     external fun deviceCloseEmulation()
     external fun deviceSignalEmulationClose()
diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/MainViewModel.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/MainViewModel.kt
index 6bf1fca72..7daad2393 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/MainViewModel.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/MainViewModel.kt
@@ -14,6 +14,7 @@ import org.ryujinx.android.GameHost
 import org.ryujinx.android.GraphicsConfiguration
 import org.ryujinx.android.Logging
 import org.ryujinx.android.MainActivity
+import org.ryujinx.android.MotionSensorManager
 import org.ryujinx.android.NativeGraphicsInterop
 import org.ryujinx.android.NativeHelpers
 import org.ryujinx.android.PerformanceManager
@@ -26,6 +27,7 @@ import java.io.File
 @SuppressLint("WrongConstant")
 class MainViewModel(val activity: MainActivity) {
     var physicalControllerManager: PhysicalControllerManager? = null
+    var motionSensorManager: MotionSensorManager? = null
     var gameModel: GameModel? = null
     var controller: GameController? = null
     var performanceManager: PerformanceManager? = null
@@ -62,6 +64,9 @@ class MainViewModel(val activity: MainActivity) {
         RyujinxNative.instance.deviceSignalEmulationClose()
         gameHost?.close()
         RyujinxNative.instance.deviceCloseEmulation()
+        motionSensorManager?.unregister()
+        physicalControllerManager?.disconnect()
+        motionSensorManager?.setControllerId(-1)
     }
 
     fun loadGame(game:GameModel) : Boolean {
@@ -354,6 +359,7 @@ class MainViewModel(val activity: MainActivity) {
         activity.setFullScreen(true)
         navController?.navigate("game")
         activity.isGameRunning = true
+        motionSensorManager?.register()
     }
 
     fun setProgressStates(