mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	android: Add motion sensor
This commit is contained in:
		@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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_) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user