diff --git a/android/native/jni/input_android.c b/android/native/jni/input_android.c index 22a52a93eb..014dd4e9d9 100644 --- a/android/native/jni/input_android.c +++ b/android/native/jni/input_android.c @@ -82,7 +82,7 @@ typedef struct android_input } android_input_t; void (*engine_handle_dpad)(void *data, AInputEvent*, size_t, int, char*, size_t, int, bool, unsigned); -static void android_input_set_sensor_state(void *data, unsigned port, unsigned action, unsigned event_rate); +static bool android_input_set_sensor_state(void *data, unsigned port, enum retro_sensor_action action, unsigned event_rate); extern float AMotionEvent_getAxisValue(const AInputEvent* motion_event, int32_t axis, size_t pointer_index); @@ -1991,7 +1991,10 @@ static int16_t android_input_state(void *data, const struct retro_keybind **bind case RETRO_DEVICE_SENSOR_ACCELEROMETER: switch (id) { - /* FIXME - these are float values - might need a separate input state function */ + // FIXME: These are float values. + // If they have a fixed range, e.g. (-1, 1), they can + // be converted to fixed point easily. If they have unbound range, this should be + // queried from a function in retro_sensor_interface. case RETRO_DEVICE_ID_SENSOR_ACCELEROMETER_X: return android->accelerometer_state.x; case RETRO_DEVICE_ID_SENSOR_ACCELEROMETER_Y: @@ -2041,7 +2044,7 @@ static void android_input_enable_sensor_manager(void *data) android_app->looper, LOOPER_ID_USER, NULL, NULL); } -static void android_input_set_sensor_state(void *data, unsigned port, unsigned action, unsigned event_rate) +static bool android_input_set_sensor_state(void *data, unsigned port, enum retro_sensor_action action, unsigned event_rate) { android_input_t *android = (android_input_t*)data; @@ -2053,7 +2056,7 @@ static void android_input_set_sensor_state(void *data, unsigned port, unsigned a case RETRO_SENSOR_ACCELEROMETER_ENABLE: if (android->sensor_state_mask & (1ULL << RETRO_SENSOR_ACCELEROMETER_ENABLE)) - return; + return true; if (android->accelerometerSensor == NULL) android_input_enable_sensor_manager(android); @@ -2067,18 +2070,22 @@ static void android_input_set_sensor_state(void *data, unsigned port, unsigned a android->sensor_state_mask &= ~(1ULL << RETRO_SENSOR_ACCELEROMETER_DISABLE); android->sensor_state_mask |= (1ULL << RETRO_SENSOR_ACCELEROMETER_ENABLE); - break; + return true; + case RETRO_SENSOR_ACCELEROMETER_DISABLE: if (android->sensor_state_mask & (1ULL << RETRO_SENSOR_ACCELEROMETER_DISABLE)) - return; + return true; ASensorEventQueue_disableSensor(android->sensorEventQueue, android->accelerometerSensor); android->sensor_state_mask &= ~(1ULL << RETRO_SENSOR_ACCELEROMETER_ENABLE); android->sensor_state_mask |= (1ULL << RETRO_SENSOR_ACCELEROMETER_DISABLE); - break; + return true; + + default: + return false; } } diff --git a/driver.c b/driver.c index 9467b87fe4..3921de7196 100644 --- a/driver.c +++ b/driver.c @@ -409,6 +409,14 @@ bool driver_set_rumble_state(unsigned port, enum retro_rumble_effect effect, uin return false; } +bool driver_set_sensor_state(unsigned port, enum retro_sensor_action action, unsigned rate) +{ + if (driver.input && driver.input_data && driver.input->set_sensor_state) + return driver.input->set_sensor_state(driver.input_data, port, action, rate); + else + return false; +} + uintptr_t driver_get_current_framebuffer(void) { #ifdef HAVE_FBO diff --git a/driver.h b/driver.h index 055cf8ba7e..98c505785d 100644 --- a/driver.h +++ b/driver.h @@ -322,7 +322,7 @@ typedef struct input_driver bool (*key_pressed)(void *data, int key); void (*free)(void *data); void (*set_keybinds)(void *data, unsigned device, unsigned port, unsigned id, unsigned keybind_action); - void (*set_sensor_state)(void *data, unsigned port, unsigned action, unsigned event_rate); + bool (*set_sensor_state)(void *data, unsigned port, enum retro_sensor_action action, unsigned rate); uint64_t (*get_capabilities)(void *data); const char *ident; @@ -504,6 +504,8 @@ retro_proc_address_t driver_get_proc_address(const char *sym); // Used by RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE bool driver_set_rumble_state(unsigned port, enum retro_rumble_effect effect, uint16_t strength); +// Used by RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE +bool driver_set_sensor_state(unsigned port, enum retro_sensor_action action, unsigned rate); extern driver_t driver; diff --git a/dynamic.c b/dynamic.c index 4e24163fab..c2aeb137d1 100644 --- a/dynamic.c +++ b/dynamic.c @@ -775,6 +775,14 @@ bool rarch_environment_cb(unsigned cmd, void *data) break; } + case RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE: + { + RARCH_LOG("Environ GET_SENSOR_INTERFACE.\n"); + struct retro_sensor_interface *iface = (struct retro_sensor_interface*)data; + iface->set_sensor_state = driver_set_sensor_state; + break; + } + // Private extensions for internal use, not part of libretro API. case RETRO_ENVIRONMENT_SET_LIBRETRO_PATH: RARCH_LOG("Environ (Private) SET_LIBRETRO_PATH.\n"); diff --git a/libretro.h b/libretro.h index 24a440bbb8..e4a03028f2 100755 --- a/libretro.h +++ b/libretro.h @@ -94,6 +94,7 @@ extern "C" { // Eventually _PRESSED will return false for an index. No further presses are registered at this point. #define RETRO_DEVICE_POINTER 6 +// FIXME: Document this. #define RETRO_DEVICE_SENSOR_ACCELEROMETER 7 // These device types are specializations of the base types above. @@ -533,7 +534,30 @@ enum retro_mod // Devices which are not handled or recognized always return 0 in retro_input_state_t. // Example bitmask: caps = (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG). // Should only be called in retro_run(). + // +#define RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE (25 | RETRO_ENVIRONMENT_EXPERIMENTAL) + // struct retro_sensor_interface * -- + // Gets access to the sensor interface. + // The purpose of this interface is to allow + // setting state related to sensors such as polling rate, enabling/disable it entirely, etc. + // Reading sensor state is done via the normal input_state_callback API. +// FIXME: Document the sensor API and work out behavior. +// It will be marked as experimental until then. +enum retro_sensor_action +{ + RETRO_SENSOR_ACCELEROMETER_ENABLE = 0, + RETRO_SENSOR_ACCELEROMETER_DISABLE, + + RETRO_SENSOR_DUMMY = INT_MAX +}; + +typedef bool (*retro_set_sensor_state_t)(unsigned port, enum retro_sensor_action action, unsigned rate); +struct retro_sensor_interface +{ + retro_set_sensor_state_t set_sensor_state; +}; +//// enum retro_rumble_effect { @@ -543,14 +567,6 @@ enum retro_rumble_effect RETRO_RUMBLE_DUMMY = INT_MAX }; -enum retro_sensor_action -{ - RETRO_SENSOR_ACCELEROMETER_ENABLE = 0, - RETRO_SENSOR_ACCELEROMETER_DISABLE, -}; - -typedef bool (*retro_set_sensor_state_t)(unsigned port, enum retro_sensor_action action, unsigned event_rate); - // Sets rumble state for joypad plugged in port 'port'. Rumble effects are controlled independently, // and setting e.g. strong rumble does not override weak rumble. // Strength has a range of [0, 0xffff].