mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #11919 from t895/kotlin-controls
Android: Convert "features.input" package to Kotlin
This commit is contained in:
-52
@@ -1,52 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.ControlGroup;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractBooleanSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
public class ControlGroupEnabledSetting implements AbstractBooleanSetting
|
||||
{
|
||||
private final ControlGroup mControlGroup;
|
||||
|
||||
public ControlGroupEnabledSetting(ControlGroup controlGroup)
|
||||
{
|
||||
mControlGroup = controlGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean()
|
||||
{
|
||||
return mControlGroup.getEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoolean(@NonNull Settings settings, boolean newValue)
|
||||
{
|
||||
mControlGroup.setEnabled(newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverridden()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRuntimeEditable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(@NonNull Settings settings)
|
||||
{
|
||||
boolean newValue = mControlGroup.getDefaultEnabledValue() != ControlGroup.DEFAULT_ENABLED_NO;
|
||||
mControlGroup.setEnabled(newValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.ControlGroup
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractBooleanSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
class ControlGroupEnabledSetting(private val controlGroup: ControlGroup) : AbstractBooleanSetting {
|
||||
override val boolean: Boolean
|
||||
get() = controlGroup.getEnabled()
|
||||
|
||||
override fun setBoolean(settings: Settings, newValue: Boolean) =
|
||||
controlGroup.setEnabled(newValue)
|
||||
|
||||
override val isOverridden: Boolean = false
|
||||
|
||||
override val isRuntimeEditable: Boolean = true
|
||||
|
||||
override fun delete(settings: Settings): Boolean {
|
||||
val newValue = controlGroup.getDefaultEnabledValue() != ControlGroup.DEFAULT_ENABLED_NO
|
||||
controlGroup.setEnabled(newValue)
|
||||
return true
|
||||
}
|
||||
}
|
||||
-178
@@ -1,178 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.os.VibratorManager;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.dolphinemu.dolphinemu.DolphinApplication;
|
||||
import org.dolphinemu.dolphinemu.utils.LooperThread;
|
||||
|
||||
/**
|
||||
* This class interfaces with the native ControllerInterface,
|
||||
* which is where the emulator core gets inputs from.
|
||||
*/
|
||||
public final class ControllerInterface
|
||||
{
|
||||
private static final class InputDeviceListener implements InputManager.InputDeviceListener
|
||||
{
|
||||
@Override
|
||||
public void onInputDeviceAdded(int deviceId)
|
||||
{
|
||||
// Simple implementation for now. We could do something fancier if we wanted to.
|
||||
refreshDevices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceRemoved(int deviceId)
|
||||
{
|
||||
// Simple implementation for now. We could do something fancier if we wanted to.
|
||||
refreshDevices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceChanged(int deviceId)
|
||||
{
|
||||
// Simple implementation for now. We could do something fancier if we wanted to.
|
||||
refreshDevices();
|
||||
}
|
||||
}
|
||||
|
||||
private static InputDeviceListener mInputDeviceListener;
|
||||
private static LooperThread mLooperThread;
|
||||
|
||||
/**
|
||||
* Activities which want to pass on inputs to native code
|
||||
* should call this in their own dispatchKeyEvent method.
|
||||
*
|
||||
* @return true if the emulator core seems to be interested in this event.
|
||||
* false if the event should be passed on to the default dispatchKeyEvent.
|
||||
*/
|
||||
public static native boolean dispatchKeyEvent(KeyEvent event);
|
||||
|
||||
/**
|
||||
* Activities which want to pass on inputs to native code
|
||||
* should call this in their own dispatchGenericMotionEvent method.
|
||||
*
|
||||
* @return true if the emulator core seems to be interested in this event.
|
||||
* false if the event should be passed on to the default dispatchGenericMotionEvent.
|
||||
*/
|
||||
public static native boolean dispatchGenericMotionEvent(MotionEvent event);
|
||||
|
||||
/**
|
||||
* {@link DolphinSensorEventListener} calls this for each axis of a received SensorEvent.
|
||||
*
|
||||
* @return true if the emulator core seems to be interested in this event.
|
||||
* false if the sensor can be suspended to save battery.
|
||||
*/
|
||||
public static native boolean dispatchSensorEvent(String deviceQualifier, String axisName,
|
||||
float value);
|
||||
|
||||
/**
|
||||
* Called when a sensor is suspended or unsuspended.
|
||||
*
|
||||
* @param deviceQualifier A string used by native code for uniquely identifying devices.
|
||||
* @param axisNames The name of all axes for the sensor.
|
||||
* @param suspended Whether the sensor is now suspended.
|
||||
*/
|
||||
public static native void notifySensorSuspendedState(String deviceQualifier, String[] axisNames,
|
||||
boolean suspended);
|
||||
|
||||
/**
|
||||
* Rescans for input devices.
|
||||
*/
|
||||
public static native void refreshDevices();
|
||||
|
||||
public static native String[] getAllDeviceStrings();
|
||||
|
||||
@Nullable
|
||||
public static native CoreDevice getDevice(String deviceString);
|
||||
|
||||
@Keep
|
||||
private static void registerInputDeviceListener()
|
||||
{
|
||||
if (mLooperThread == null)
|
||||
{
|
||||
mLooperThread = new LooperThread("Hotplug thread");
|
||||
mLooperThread.start();
|
||||
}
|
||||
|
||||
if (mInputDeviceListener == null)
|
||||
{
|
||||
InputManager im = (InputManager)
|
||||
DolphinApplication.getAppContext().getSystemService(Context.INPUT_SERVICE);
|
||||
|
||||
mInputDeviceListener = new InputDeviceListener();
|
||||
im.registerInputDeviceListener(mInputDeviceListener, new Handler(mLooperThread.getLooper()));
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private static void unregisterInputDeviceListener()
|
||||
{
|
||||
if (mInputDeviceListener != null)
|
||||
{
|
||||
InputManager im = (InputManager)
|
||||
DolphinApplication.getAppContext().getSystemService(Context.INPUT_SERVICE);
|
||||
|
||||
im.unregisterInputDeviceListener(mInputDeviceListener);
|
||||
mInputDeviceListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Keep @NonNull
|
||||
private static DolphinVibratorManager getVibratorManager(InputDevice device)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
|
||||
{
|
||||
return new DolphinVibratorManagerPassthrough(device.getVibratorManager());
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DolphinVibratorManagerCompat(device.getVibrator());
|
||||
}
|
||||
}
|
||||
|
||||
@Keep @NonNull
|
||||
private static DolphinVibratorManager getSystemVibratorManager()
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
|
||||
{
|
||||
VibratorManager vibratorManager = (VibratorManager)
|
||||
DolphinApplication.getAppContext().getSystemService(Context.VIBRATOR_MANAGER_SERVICE);
|
||||
|
||||
if (vibratorManager != null)
|
||||
return new DolphinVibratorManagerPassthrough(vibratorManager);
|
||||
}
|
||||
|
||||
Vibrator vibrator = (Vibrator)
|
||||
DolphinApplication.getAppContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
|
||||
return new DolphinVibratorManagerCompat(vibrator);
|
||||
}
|
||||
|
||||
@Keep
|
||||
private static void vibrate(@NonNull Vibrator vibrator)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
{
|
||||
vibrator.vibrate(VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
|
||||
}
|
||||
else
|
||||
{
|
||||
vibrator.vibrate(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model
|
||||
|
||||
import android.content.Context
|
||||
import android.hardware.input.InputManager
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.VibrationEffect
|
||||
import android.os.Vibrator
|
||||
import android.os.VibratorManager
|
||||
import android.view.InputDevice
|
||||
import android.view.KeyEvent
|
||||
import android.view.MotionEvent
|
||||
import androidx.annotation.Keep
|
||||
import org.dolphinemu.dolphinemu.DolphinApplication
|
||||
import org.dolphinemu.dolphinemu.utils.LooperThread
|
||||
|
||||
/**
|
||||
* This class interfaces with the native ControllerInterface,
|
||||
* which is where the emulator core gets inputs from.
|
||||
*/
|
||||
object ControllerInterface {
|
||||
private var inputDeviceListener: InputDeviceListener? = null
|
||||
private lateinit var looperThread: LooperThread
|
||||
|
||||
/**
|
||||
* Activities which want to pass on inputs to native code
|
||||
* should call this in their own dispatchKeyEvent method.
|
||||
*
|
||||
* @return true if the emulator core seems to be interested in this event.
|
||||
* false if the event should be passed on to the default dispatchKeyEvent.
|
||||
*/
|
||||
external fun dispatchKeyEvent(event: KeyEvent): Boolean
|
||||
|
||||
/**
|
||||
* Activities which want to pass on inputs to native code
|
||||
* should call this in their own dispatchGenericMotionEvent method.
|
||||
*
|
||||
* @return true if the emulator core seems to be interested in this event.
|
||||
* false if the event should be passed on to the default dispatchGenericMotionEvent.
|
||||
*/
|
||||
external fun dispatchGenericMotionEvent(event: MotionEvent): Boolean
|
||||
|
||||
/**
|
||||
* [DolphinSensorEventListener] calls this for each axis of a received SensorEvent.
|
||||
*
|
||||
* @return true if the emulator core seems to be interested in this event.
|
||||
* false if the sensor can be suspended to save battery.
|
||||
*/
|
||||
external fun dispatchSensorEvent(
|
||||
deviceQualifier: String,
|
||||
axisName: String,
|
||||
value: Float
|
||||
): Boolean
|
||||
|
||||
/**
|
||||
* Called when a sensor is suspended or unsuspended.
|
||||
*
|
||||
* @param deviceQualifier A string used by native code for uniquely identifying devices.
|
||||
* @param axisNames The name of all axes for the sensor.
|
||||
* @param suspended Whether the sensor is now suspended.
|
||||
*/
|
||||
external fun notifySensorSuspendedState(
|
||||
deviceQualifier: String,
|
||||
axisNames: Array<String>,
|
||||
suspended: Boolean
|
||||
)
|
||||
|
||||
/**
|
||||
* Rescans for input devices.
|
||||
*/
|
||||
external fun refreshDevices()
|
||||
|
||||
external fun getAllDeviceStrings(): Array<String>
|
||||
|
||||
external fun getDevice(deviceString: String): CoreDevice?
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
private fun registerInputDeviceListener() {
|
||||
looperThread = LooperThread("Hotplug thread")
|
||||
looperThread.start()
|
||||
|
||||
if (inputDeviceListener == null) {
|
||||
val im = DolphinApplication.getAppContext()
|
||||
.getSystemService(Context.INPUT_SERVICE) as InputManager?
|
||||
|
||||
inputDeviceListener = InputDeviceListener()
|
||||
im!!.registerInputDeviceListener(inputDeviceListener, Handler(looperThread.looper))
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
private fun unregisterInputDeviceListener() {
|
||||
if (inputDeviceListener != null) {
|
||||
val im = DolphinApplication.getAppContext()
|
||||
.getSystemService(Context.INPUT_SERVICE) as InputManager?
|
||||
|
||||
im!!.unregisterInputDeviceListener(inputDeviceListener)
|
||||
inputDeviceListener = null
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
private fun getVibratorManager(device: InputDevice): DolphinVibratorManager {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
DolphinVibratorManagerPassthrough(device.vibratorManager)
|
||||
} else {
|
||||
DolphinVibratorManagerCompat(device.vibrator)
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
private fun getSystemVibratorManager(): DolphinVibratorManager {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
val vibratorManager = DolphinApplication.getAppContext()
|
||||
.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager?
|
||||
if (vibratorManager != null)
|
||||
return DolphinVibratorManagerPassthrough(vibratorManager)
|
||||
}
|
||||
val vibrator = DolphinApplication.getAppContext()
|
||||
.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
|
||||
return DolphinVibratorManagerCompat(vibrator)
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
private fun vibrate(vibrator: Vibrator) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
vibrator.vibrate(VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE))
|
||||
} else {
|
||||
vibrator.vibrate(100)
|
||||
}
|
||||
}
|
||||
|
||||
private class InputDeviceListener : InputManager.InputDeviceListener {
|
||||
// Simple implementation for now. We could do something fancier if we wanted to.
|
||||
override fun onInputDeviceAdded(deviceId: Int) = refreshDevices()
|
||||
|
||||
// Simple implementation for now. We could do something fancier if we wanted to.
|
||||
override fun onInputDeviceRemoved(deviceId: Int) = refreshDevices()
|
||||
|
||||
// Simple implementation for now. We could do something fancier if we wanted to.
|
||||
override fun onInputDeviceChanged(deviceId: Int) = refreshDevices()
|
||||
}
|
||||
}
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
/**
|
||||
* Represents a C++ ciface::Core::Device.
|
||||
*/
|
||||
public final class CoreDevice
|
||||
{
|
||||
/**
|
||||
* Represents a C++ ciface::Core::Device::Control.
|
||||
*
|
||||
* This class is non-static to ensure that the CoreDevice parent does not get garbage collected
|
||||
* while a Control is still accessible. (CoreDevice's finalizer may delete the native controls.)
|
||||
*/
|
||||
@SuppressWarnings("InnerClassMayBeStatic")
|
||||
public final class Control
|
||||
{
|
||||
@Keep
|
||||
private final long mPointer;
|
||||
|
||||
@Keep
|
||||
private Control(long pointer)
|
||||
{
|
||||
mPointer = pointer;
|
||||
}
|
||||
|
||||
public native String getName();
|
||||
}
|
||||
|
||||
@Keep
|
||||
private final long mPointer;
|
||||
|
||||
@Keep
|
||||
private CoreDevice(long pointer)
|
||||
{
|
||||
mPointer = pointer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected native void finalize();
|
||||
|
||||
public native Control[] getInputs();
|
||||
|
||||
public native Control[] getOutputs();
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
/**
|
||||
* Represents a C++ ciface::Core::Device.
|
||||
*/
|
||||
@Keep
|
||||
class CoreDevice private constructor(private val pointer: Long) {
|
||||
/**
|
||||
* Represents a C++ ciface::Core::Device::Control.
|
||||
*
|
||||
* This class is marked inner to ensure that the CoreDevice parent does not get garbage collected
|
||||
* while a Control is still accessible. (CoreDevice's finalizer may delete the native controls.)
|
||||
*/
|
||||
@Keep
|
||||
inner class Control private constructor(private val pointer: Long) {
|
||||
external fun getName(): String
|
||||
}
|
||||
|
||||
protected external fun finalize()
|
||||
|
||||
external fun getInputs(): Array<Control>
|
||||
|
||||
external fun getOutputs(): Array<Control>
|
||||
}
|
||||
-440
@@ -1,440 +0,0 @@
|
||||
package org.dolphinemu.dolphinemu.features.input.model;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.Build;
|
||||
import android.view.InputDevice;
|
||||
import android.view.Surface;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
import org.dolphinemu.dolphinemu.DolphinApplication;
|
||||
import org.dolphinemu.dolphinemu.utils.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DolphinSensorEventListener implements SensorEventListener
|
||||
{
|
||||
// Set of three axes. Creates a negative companion to each axis, and corrects for device rotation.
|
||||
private static final int AXIS_SET_TYPE_DEVICE_COORDINATES = 0;
|
||||
// Set of three axes. Creates a negative companion to each axis.
|
||||
private static final int AXIS_SET_TYPE_OTHER_COORDINATES = 1;
|
||||
|
||||
private static class AxisSetDetails
|
||||
{
|
||||
public final int firstAxisOfSet;
|
||||
public final int axisSetType;
|
||||
|
||||
public AxisSetDetails(int firstAxisOfSet, int axisSetType)
|
||||
{
|
||||
this.firstAxisOfSet = firstAxisOfSet;
|
||||
this.axisSetType = axisSetType;
|
||||
}
|
||||
}
|
||||
|
||||
private static class SensorDetails
|
||||
{
|
||||
public final int sensorType;
|
||||
public final String[] axisNames;
|
||||
public final AxisSetDetails[] axisSetDetails;
|
||||
public boolean isSuspended = true;
|
||||
|
||||
public SensorDetails(int sensorType, String[] axisNames, AxisSetDetails[] axisSetDetails)
|
||||
{
|
||||
this.sensorType = sensorType;
|
||||
this.axisNames = axisNames;
|
||||
this.axisSetDetails = axisSetDetails;
|
||||
}
|
||||
}
|
||||
|
||||
private static int sDeviceRotation = Surface.ROTATION_0;
|
||||
|
||||
private final SensorManager mSensorManager;
|
||||
|
||||
private final HashMap<Sensor, SensorDetails> mSensorDetails = new HashMap<>();
|
||||
|
||||
private final boolean mRotateCoordinatesForScreenOrientation;
|
||||
|
||||
private String mDeviceQualifier = "";
|
||||
|
||||
// The fastest sampling rate Android lets us use without declaring the HIGH_SAMPLING_RATE_SENSORS
|
||||
// permission is 200 Hz. This is also the sampling rate of a Wii Remote, so it fits us perfectly.
|
||||
private static final int SAMPLING_PERIOD_US = 1000000 / 200;
|
||||
|
||||
@Keep
|
||||
public DolphinSensorEventListener()
|
||||
{
|
||||
mSensorManager = (SensorManager)
|
||||
DolphinApplication.getAppContext().getSystemService(Context.SENSOR_SERVICE);
|
||||
mRotateCoordinatesForScreenOrientation = true;
|
||||
|
||||
addSensors();
|
||||
}
|
||||
|
||||
@Keep
|
||||
public DolphinSensorEventListener(InputDevice inputDevice)
|
||||
{
|
||||
mRotateCoordinatesForScreenOrientation = false;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 31)
|
||||
{
|
||||
mSensorManager = inputDevice.getSensorManager();
|
||||
|
||||
// TODO: There is a bug where after suspending sensors, onSensorChanged can get called for
|
||||
// a sensor that we never registered as a listener for. The way our code is currently written,
|
||||
// this causes a NullPointerException, but if we checked for null we would instead have the
|
||||
// problem of being spammed with onSensorChanged calls even though the sensor shouldn't be
|
||||
// enabled. For now, let's comment out the ability to use InputDevice sensors.
|
||||
|
||||
//addSensors();
|
||||
}
|
||||
else
|
||||
{
|
||||
mSensorManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void addSensors()
|
||||
{
|
||||
tryAddSensor(Sensor.TYPE_ACCELEROMETER, new String[]{"Accel Right", "Accel Left",
|
||||
"Accel Forward", "Accel Backward", "Accel Up", "Accel Down"},
|
||||
new AxisSetDetails[]{new AxisSetDetails(0, AXIS_SET_TYPE_DEVICE_COORDINATES)});
|
||||
|
||||
tryAddSensor(Sensor.TYPE_GYROSCOPE, new String[]{"Gyro Pitch Up", "Gyro Pitch Down",
|
||||
"Gyro Roll Right", "Gyro Roll Left", "Gyro Yaw Left", "Gyro Yaw Right"},
|
||||
new AxisSetDetails[]{new AxisSetDetails(0, AXIS_SET_TYPE_DEVICE_COORDINATES)});
|
||||
|
||||
tryAddSensor(Sensor.TYPE_LIGHT, "Light");
|
||||
|
||||
tryAddSensor(Sensor.TYPE_PRESSURE, "Pressure");
|
||||
|
||||
tryAddSensor(Sensor.TYPE_TEMPERATURE, "Device Temperature");
|
||||
|
||||
tryAddSensor(Sensor.TYPE_PROXIMITY, "Proximity");
|
||||
|
||||
tryAddSensor(Sensor.TYPE_GRAVITY, new String[]{"Gravity Right", "Gravity Left",
|
||||
"Gravity Forward", "Gravity Backward", "Gravity Up", "Gravity Down"},
|
||||
new AxisSetDetails[]{new AxisSetDetails(0, AXIS_SET_TYPE_DEVICE_COORDINATES)});
|
||||
|
||||
tryAddSensor(Sensor.TYPE_LINEAR_ACCELERATION,
|
||||
new String[]{"Linear Acceleration Right", "Linear Acceleration Left",
|
||||
"Linear Acceleration Forward", "Linear Acceleration Backward",
|
||||
"Linear Acceleration Up", "Linear Acceleration Down"},
|
||||
new AxisSetDetails[]{new AxisSetDetails(0, AXIS_SET_TYPE_DEVICE_COORDINATES)});
|
||||
|
||||
// The values provided by this sensor can be interpreted as an Euler vector or a quaternion.
|
||||
// The directions of X and Y are flipped to match the Wii Remote coordinate system.
|
||||
tryAddSensor(Sensor.TYPE_ROTATION_VECTOR,
|
||||
new String[]{"Rotation Vector X-", "Rotation Vector X+", "Rotation Vector Y-",
|
||||
"Rotation Vector Y+", "Rotation Vector Z+",
|
||||
"Rotation Vector Z-", "Rotation Vector R", "Rotation Vector Heading Accuracy"},
|
||||
new AxisSetDetails[]{new AxisSetDetails(0, AXIS_SET_TYPE_DEVICE_COORDINATES)});
|
||||
|
||||
tryAddSensor(Sensor.TYPE_RELATIVE_HUMIDITY, "Relative Humidity");
|
||||
|
||||
tryAddSensor(Sensor.TYPE_AMBIENT_TEMPERATURE, "Ambient Temperature");
|
||||
|
||||
// The values provided by this sensor can be interpreted as an Euler vector or a quaternion.
|
||||
// The directions of X and Y are flipped to match the Wii Remote coordinate system.
|
||||
tryAddSensor(Sensor.TYPE_GAME_ROTATION_VECTOR,
|
||||
new String[]{"Game Rotation Vector X-", "Game Rotation Vector X+",
|
||||
"Game Rotation Vector Y-", "Game Rotation Vector Y+", "Game Rotation Vector Z+",
|
||||
"Game Rotation Vector Z-", "Game Rotation Vector R"},
|
||||
new AxisSetDetails[]{new AxisSetDetails(0, AXIS_SET_TYPE_DEVICE_COORDINATES)});
|
||||
|
||||
tryAddSensor(Sensor.TYPE_GYROSCOPE_UNCALIBRATED,
|
||||
new String[]{"Gyro Uncalibrated Pitch Up", "Gyro Uncalibrated Pitch Down",
|
||||
"Gyro Uncalibrated Roll Right", "Gyro Uncalibrated Roll Left",
|
||||
"Gyro Uncalibrated Yaw Left", "Gyro Uncalibrated Yaw Right",
|
||||
"Gyro Drift Pitch Up", "Gyro Drift Pitch Down", "Gyro Drift Roll Right",
|
||||
"Gyro Drift Roll Left", "Gyro Drift Yaw Left", "Gyro Drift Yaw Right"},
|
||||
new AxisSetDetails[]{new AxisSetDetails(0, AXIS_SET_TYPE_DEVICE_COORDINATES),
|
||||
new AxisSetDetails(3, AXIS_SET_TYPE_DEVICE_COORDINATES)});
|
||||
|
||||
tryAddSensor(Sensor.TYPE_HEART_RATE, "Heart Rate");
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 24)
|
||||
{
|
||||
tryAddSensor(Sensor.TYPE_HEART_BEAT, "Heart Beat");
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 26)
|
||||
{
|
||||
tryAddSensor(Sensor.TYPE_ACCELEROMETER_UNCALIBRATED,
|
||||
new String[]{"Accel Uncalibrated Right", "Accel Uncalibrated Left",
|
||||
"Accel Uncalibrated Forward", "Accel Uncalibrated Backward",
|
||||
"Accel Uncalibrated Up", "Accel Uncalibrated Down",
|
||||
"Accel Bias Right", "Accel Bias Left", "Accel Bias Forward",
|
||||
"Accel Bias Backward", "Accel Bias Up", "Accel Bias Down"},
|
||||
new AxisSetDetails[]{new AxisSetDetails(0, AXIS_SET_TYPE_DEVICE_COORDINATES),
|
||||
new AxisSetDetails(3, AXIS_SET_TYPE_DEVICE_COORDINATES)});
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 30)
|
||||
{
|
||||
tryAddSensor(Sensor.TYPE_HINGE_ANGLE, "Hinge Angle");
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 33)
|
||||
{
|
||||
// The values provided by this sensor can be interpreted as an Euler vector.
|
||||
// The directions of X and Y are flipped to match the Wii Remote coordinate system.
|
||||
tryAddSensor(Sensor.TYPE_HEAD_TRACKER,
|
||||
new String[]{"Head Rotation Vector X-", "Head Rotation Vector X+",
|
||||
"Head Rotation Vector Y-", "Head Rotation Vector Y+",
|
||||
"Head Rotation Vector Z+", "Head Rotation Vector Z-",
|
||||
"Head Pitch Up", "Head Pitch Down", "Head Roll Right", "Head Roll Left",
|
||||
"Head Yaw Left", "Head Yaw Right"},
|
||||
new AxisSetDetails[]{new AxisSetDetails(0, AXIS_SET_TYPE_OTHER_COORDINATES),
|
||||
new AxisSetDetails(3, AXIS_SET_TYPE_OTHER_COORDINATES)});
|
||||
|
||||
tryAddSensor(Sensor.TYPE_HEADING, new String[]{"Heading", "Heading Accuracy"},
|
||||
new AxisSetDetails[]{});
|
||||
}
|
||||
}
|
||||
|
||||
private void tryAddSensor(int sensorType, String axisName)
|
||||
{
|
||||
tryAddSensor(sensorType, new String[]{axisName}, new AxisSetDetails[]{});
|
||||
}
|
||||
|
||||
private void tryAddSensor(int sensorType, String[] axisNames, AxisSetDetails[] axisSetDetails)
|
||||
{
|
||||
Sensor sensor = mSensorManager.getDefaultSensor(sensorType);
|
||||
if (sensor != null)
|
||||
{
|
||||
mSensorDetails.put(sensor, new SensorDetails(sensorType, axisNames, axisSetDetails));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent sensorEvent)
|
||||
{
|
||||
final SensorDetails sensorDetails = mSensorDetails.get(sensorEvent.sensor);
|
||||
|
||||
final float[] values = sensorEvent.values;
|
||||
final String[] axisNames = sensorDetails.axisNames;
|
||||
final AxisSetDetails[] axisSetDetails = sensorDetails.axisSetDetails;
|
||||
|
||||
int eventAxisIndex = 0;
|
||||
int detailsAxisIndex = 0;
|
||||
int detailsAxisSetIndex = 0;
|
||||
boolean keepSensorAlive = false;
|
||||
while (eventAxisIndex < values.length && detailsAxisIndex < axisNames.length)
|
||||
{
|
||||
if (detailsAxisSetIndex < axisSetDetails.length &&
|
||||
axisSetDetails[detailsAxisSetIndex].firstAxisOfSet == eventAxisIndex)
|
||||
{
|
||||
int rotation = Surface.ROTATION_0;
|
||||
if (mRotateCoordinatesForScreenOrientation &&
|
||||
axisSetDetails[detailsAxisSetIndex].axisSetType == AXIS_SET_TYPE_DEVICE_COORDINATES)
|
||||
{
|
||||
rotation = sDeviceRotation;
|
||||
}
|
||||
|
||||
float x, y;
|
||||
switch (rotation)
|
||||
{
|
||||
default:
|
||||
case Surface.ROTATION_0:
|
||||
x = values[eventAxisIndex];
|
||||
y = values[eventAxisIndex + 1];
|
||||
break;
|
||||
case Surface.ROTATION_90:
|
||||
x = -values[eventAxisIndex + 1];
|
||||
y = values[eventAxisIndex];
|
||||
break;
|
||||
case Surface.ROTATION_180:
|
||||
x = -values[eventAxisIndex];
|
||||
y = -values[eventAxisIndex + 1];
|
||||
break;
|
||||
case Surface.ROTATION_270:
|
||||
x = values[eventAxisIndex + 1];
|
||||
y = -values[eventAxisIndex];
|
||||
break;
|
||||
}
|
||||
|
||||
float z = values[eventAxisIndex + 2];
|
||||
|
||||
keepSensorAlive |= ControllerInterface.dispatchSensorEvent(mDeviceQualifier,
|
||||
axisNames[detailsAxisIndex], x);
|
||||
keepSensorAlive |= ControllerInterface.dispatchSensorEvent(mDeviceQualifier,
|
||||
axisNames[detailsAxisIndex + 1], x);
|
||||
keepSensorAlive |= ControllerInterface.dispatchSensorEvent(mDeviceQualifier,
|
||||
axisNames[detailsAxisIndex + 2], y);
|
||||
keepSensorAlive |= ControllerInterface.dispatchSensorEvent(mDeviceQualifier,
|
||||
axisNames[detailsAxisIndex + 3], y);
|
||||
keepSensorAlive |= ControllerInterface.dispatchSensorEvent(mDeviceQualifier,
|
||||
axisNames[detailsAxisIndex + 4], z);
|
||||
keepSensorAlive |= ControllerInterface.dispatchSensorEvent(mDeviceQualifier,
|
||||
axisNames[detailsAxisIndex + 5], z);
|
||||
|
||||
eventAxisIndex += 3;
|
||||
detailsAxisIndex += 6;
|
||||
detailsAxisSetIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
keepSensorAlive |= ControllerInterface.dispatchSensorEvent(mDeviceQualifier,
|
||||
axisNames[detailsAxisIndex], values[eventAxisIndex]);
|
||||
|
||||
eventAxisIndex++;
|
||||
detailsAxisIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!keepSensorAlive)
|
||||
{
|
||||
setSensorSuspended(sensorEvent.sensor, sensorDetails, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int i)
|
||||
{
|
||||
// We don't care about this
|
||||
}
|
||||
|
||||
/**
|
||||
* The device qualifier set here will be passed on to native code,
|
||||
* for the purpose of letting native code identify which device this object belongs to.
|
||||
*/
|
||||
@Keep
|
||||
public void setDeviceQualifier(String deviceQualifier)
|
||||
{
|
||||
mDeviceQualifier = deviceQualifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a sensor has been suspended to save battery, this unsuspends it.
|
||||
* If the sensor isn't currently suspended, nothing happens.
|
||||
*
|
||||
* @param axisName The name of any of the sensor's axes.
|
||||
*/
|
||||
@Keep
|
||||
public void requestUnsuspendSensor(String axisName)
|
||||
{
|
||||
for (Map.Entry<Sensor, SensorDetails> entry : mSensorDetails.entrySet())
|
||||
{
|
||||
if (Arrays.asList(entry.getValue().axisNames).contains(axisName))
|
||||
{
|
||||
setSensorSuspended(entry.getKey(), entry.getValue(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setSensorSuspended(Sensor sensor, SensorDetails sensorDetails, boolean suspend)
|
||||
{
|
||||
boolean changeOccurred = false;
|
||||
|
||||
synchronized (sensorDetails)
|
||||
{
|
||||
if (sensorDetails.isSuspended != suspend)
|
||||
{
|
||||
ControllerInterface.notifySensorSuspendedState(mDeviceQualifier, sensorDetails.axisNames,
|
||||
suspend);
|
||||
|
||||
if (suspend)
|
||||
mSensorManager.unregisterListener(this, sensor);
|
||||
else
|
||||
mSensorManager.registerListener(this, sensor, SAMPLING_PERIOD_US);
|
||||
|
||||
sensorDetails.isSuspended = suspend;
|
||||
|
||||
changeOccurred = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changeOccurred)
|
||||
{
|
||||
Log.info((suspend ? "Suspended sensor " : "Unsuspended sensor ") + sensor.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
public String[] getAxisNames()
|
||||
{
|
||||
ArrayList<String> axisNames = new ArrayList<>();
|
||||
|
||||
for (SensorDetails sensorDetails : getSensorDetailsSorted())
|
||||
{
|
||||
Collections.addAll(axisNames, sensorDetails.axisNames);
|
||||
}
|
||||
|
||||
return axisNames.toArray(new String[]{});
|
||||
}
|
||||
|
||||
@Keep
|
||||
public boolean[] getNegativeAxes()
|
||||
{
|
||||
ArrayList<Boolean> negativeAxes = new ArrayList<>();
|
||||
|
||||
for (SensorDetails sensorDetails : getSensorDetailsSorted())
|
||||
{
|
||||
int eventAxisIndex = 0;
|
||||
int detailsAxisIndex = 0;
|
||||
int detailsAxisSetIndex = 0;
|
||||
while (detailsAxisIndex < sensorDetails.axisNames.length)
|
||||
{
|
||||
if (detailsAxisSetIndex < sensorDetails.axisSetDetails.length &&
|
||||
sensorDetails.axisSetDetails[detailsAxisSetIndex].firstAxisOfSet == eventAxisIndex)
|
||||
{
|
||||
negativeAxes.add(false);
|
||||
negativeAxes.add(true);
|
||||
negativeAxes.add(false);
|
||||
negativeAxes.add(true);
|
||||
negativeAxes.add(false);
|
||||
negativeAxes.add(true);
|
||||
|
||||
eventAxisIndex += 3;
|
||||
detailsAxisIndex += 6;
|
||||
detailsAxisSetIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
negativeAxes.add(false);
|
||||
|
||||
eventAxisIndex++;
|
||||
detailsAxisIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean[] result = new boolean[negativeAxes.size()];
|
||||
for (int i = 0; i < result.length; i++)
|
||||
{
|
||||
result[i] = negativeAxes.get(i);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<SensorDetails> getSensorDetailsSorted()
|
||||
{
|
||||
ArrayList<SensorDetails> sensorDetails = new ArrayList<>(mSensorDetails.values());
|
||||
Collections.sort(sensorDetails, Comparator.comparingInt(s -> s.sensorType));
|
||||
return sensorDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called when an activity or other component that uses sensor events is resumed.
|
||||
*
|
||||
* Sensor events that contain device coordinates will have the coordinates rotated by the value
|
||||
* passed to this function.
|
||||
*
|
||||
* @param deviceRotation The current rotation of the device (i.e. rotation of the default display)
|
||||
*/
|
||||
public static void setDeviceRotation(int deviceRotation)
|
||||
{
|
||||
sDeviceRotation = deviceRotation;
|
||||
}
|
||||
}
|
||||
+504
File diff suppressed because it is too large
Load Diff
-20
@@ -1,20 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model;
|
||||
|
||||
import android.os.Vibrator;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* A wrapper around {@link android.os.VibratorManager}, for backwards compatibility.
|
||||
*/
|
||||
public interface DolphinVibratorManager
|
||||
{
|
||||
@Keep @NonNull
|
||||
Vibrator getVibrator(int vibratorId);
|
||||
|
||||
@Keep @NonNull
|
||||
int[] getVibratorIds();
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model
|
||||
|
||||
import android.os.Vibrator
|
||||
import androidx.annotation.Keep
|
||||
|
||||
/**
|
||||
* A wrapper around [android.os.VibratorManager], for backwards compatibility.
|
||||
*/
|
||||
@Keep
|
||||
interface DolphinVibratorManager {
|
||||
fun getVibrator(vibratorId: Int): Vibrator
|
||||
|
||||
fun getVibratorIds(): IntArray
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model;
|
||||
|
||||
import android.os.Vibrator;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public final class DolphinVibratorManagerCompat implements DolphinVibratorManager
|
||||
{
|
||||
private final Vibrator mVibrator;
|
||||
private final int[] mIds;
|
||||
|
||||
public DolphinVibratorManagerCompat(@Nullable Vibrator vibrator)
|
||||
{
|
||||
mVibrator = vibrator;
|
||||
mIds = vibrator != null && vibrator.hasVibrator() ? new int[]{0} : new int[]{};
|
||||
}
|
||||
|
||||
@Override @NonNull
|
||||
public Vibrator getVibrator(int vibratorId)
|
||||
{
|
||||
if (vibratorId > mIds.length)
|
||||
throw new IndexOutOfBoundsException();
|
||||
|
||||
return mVibrator;
|
||||
}
|
||||
|
||||
@Override @NonNull
|
||||
public int[] getVibratorIds()
|
||||
{
|
||||
return mIds;
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model
|
||||
|
||||
import android.os.Vibrator
|
||||
|
||||
class DolphinVibratorManagerCompat(vibrator: Vibrator) : DolphinVibratorManager {
|
||||
private val vibrator: Vibrator
|
||||
private val vibratorIds: IntArray
|
||||
|
||||
init {
|
||||
this.vibrator = vibrator
|
||||
vibratorIds = if (vibrator.hasVibrator()) intArrayOf(0) else intArrayOf()
|
||||
}
|
||||
|
||||
override fun getVibrator(vibratorId: Int): Vibrator {
|
||||
if (vibratorId > vibratorIds.size)
|
||||
throw IndexOutOfBoundsException()
|
||||
|
||||
return vibrator
|
||||
}
|
||||
|
||||
override fun getVibratorIds(): IntArray = vibratorIds
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Vibrator;
|
||||
import android.os.VibratorManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
public final class DolphinVibratorManagerPassthrough implements DolphinVibratorManager
|
||||
{
|
||||
private final VibratorManager mVibratorManager;
|
||||
|
||||
public DolphinVibratorManagerPassthrough(@NonNull VibratorManager vibratorManager)
|
||||
{
|
||||
mVibratorManager = vibratorManager;
|
||||
}
|
||||
|
||||
@Override @NonNull
|
||||
public Vibrator getVibrator(int vibratorId)
|
||||
{
|
||||
return mVibratorManager.getVibrator(vibratorId);
|
||||
}
|
||||
|
||||
@Override @NonNull
|
||||
public int[] getVibratorIds()
|
||||
{
|
||||
return mVibratorManager.getVibratorIds();
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Vibrator
|
||||
import android.os.VibratorManager
|
||||
import androidx.annotation.RequiresApi
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.S)
|
||||
class DolphinVibratorManagerPassthrough(private val vibratorManager: VibratorManager) :
|
||||
DolphinVibratorManager {
|
||||
override fun getVibrator(vibratorId: Int): Vibrator = vibratorManager.getVibrator(vibratorId)
|
||||
|
||||
override fun getVibratorIds(): IntArray = vibratorManager.vibratorIds
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.NumericSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractBooleanSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
public class InputMappingBooleanSetting implements AbstractBooleanSetting
|
||||
{
|
||||
private final NumericSetting mNumericSetting;
|
||||
|
||||
public InputMappingBooleanSetting(NumericSetting numericSetting)
|
||||
{
|
||||
mNumericSetting = numericSetting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean()
|
||||
{
|
||||
return mNumericSetting.getBooleanValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoolean(@NonNull Settings settings, boolean newValue)
|
||||
{
|
||||
mNumericSetting.setBooleanValue(newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverridden()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRuntimeEditable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(@NonNull Settings settings)
|
||||
{
|
||||
mNumericSetting.setBooleanValue(mNumericSetting.getBooleanDefaultValue());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.NumericSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractBooleanSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
class InputMappingBooleanSetting(private val numericSetting: NumericSetting) :
|
||||
AbstractBooleanSetting {
|
||||
override val boolean: Boolean
|
||||
get() = numericSetting.getBooleanValue()
|
||||
|
||||
override fun setBoolean(settings: Settings, newValue: Boolean) =
|
||||
numericSetting.setBooleanValue(newValue)
|
||||
|
||||
override val isOverridden: Boolean = false
|
||||
|
||||
override val isRuntimeEditable: Boolean = true
|
||||
|
||||
override fun delete(settings: Settings): Boolean {
|
||||
numericSetting.setBooleanValue(numericSetting.getBooleanDefaultValue())
|
||||
return true
|
||||
}
|
||||
}
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.NumericSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractFloatSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
// Yes, floats are not the same thing as doubles... They're close enough, though
|
||||
public class InputMappingDoubleSetting implements AbstractFloatSetting
|
||||
{
|
||||
private final NumericSetting mNumericSetting;
|
||||
|
||||
public InputMappingDoubleSetting(NumericSetting numericSetting)
|
||||
{
|
||||
mNumericSetting = numericSetting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat()
|
||||
{
|
||||
return (float) mNumericSetting.getDoubleValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFloat(@NonNull Settings settings, float newValue)
|
||||
{
|
||||
mNumericSetting.setDoubleValue(newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverridden()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRuntimeEditable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(@NonNull Settings settings)
|
||||
{
|
||||
mNumericSetting.setDoubleValue(mNumericSetting.getDoubleDefaultValue());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.NumericSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractFloatSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
// Yes, floats are not the same thing as doubles... They're close enough, though
|
||||
class InputMappingDoubleSetting(private val numericSetting: NumericSetting) : AbstractFloatSetting {
|
||||
override val float: Float
|
||||
get() = numericSetting.getDoubleValue().toFloat()
|
||||
|
||||
override fun setFloat(settings: Settings, newValue: Float) =
|
||||
numericSetting.setDoubleValue(newValue.toDouble())
|
||||
|
||||
override val isOverridden: Boolean = false
|
||||
|
||||
override val isRuntimeEditable: Boolean = true
|
||||
|
||||
override fun delete(settings: Settings): Boolean {
|
||||
numericSetting.setDoubleValue(numericSetting.getDoubleDefaultValue())
|
||||
return true
|
||||
}
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.NumericSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractIntSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
public class InputMappingIntSetting implements AbstractIntSetting
|
||||
{
|
||||
private final NumericSetting mNumericSetting;
|
||||
|
||||
public InputMappingIntSetting(NumericSetting numericSetting)
|
||||
{
|
||||
mNumericSetting = numericSetting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt()
|
||||
{
|
||||
return mNumericSetting.getIntValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInt(@NonNull Settings settings, int newValue)
|
||||
{
|
||||
mNumericSetting.setIntValue(newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverridden()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRuntimeEditable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(@NonNull Settings settings)
|
||||
{
|
||||
mNumericSetting.setIntValue(mNumericSetting.getIntDefaultValue());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.input.model
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.NumericSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractIntSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
class InputMappingIntSetting(private val numericSetting: NumericSetting) : AbstractIntSetting {
|
||||
override val int: Int
|
||||
get() = numericSetting.getIntValue()
|
||||
|
||||
override fun setInt(settings: Settings, newValue: Int) = numericSetting.setIntValue(newValue)
|
||||
|
||||
override val isOverridden: Boolean = false
|
||||
|
||||
override val isRuntimeEditable: Boolean = true
|
||||
|
||||
override fun delete(settings: Settings): Boolean {
|
||||
numericSetting.setIntValue(numericSetting.getIntDefaultValue())
|
||||
return true
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user