Use sensor interface; add sensor light core option Behavior synced from standalone mgba
p-sam p-sam@d3vs.net
Mon, 28 Oct 2019 08:40:11 +0000
3 files changed,
168 insertions(+),
60 deletions(-)
M
src/platform/libretro/libretro.c
→
src/platform/libretro/libretro.c
@@ -30,6 +30,7 @@ #include "libretro_core_options.h"
#define SAMPLES 1024 #define RUMBLE_PWM 35 +#define EVENT_RATE 60 static retro_environment_t environCallback; static retro_video_refresh_t videoCallback;@@ -38,6 +39,8 @@ static retro_input_poll_t inputPollCallback;
static retro_input_state_t inputCallback; static retro_log_printf_t logCallback; static retro_set_rumble_state_t rumbleCallback; +static retro_sensor_get_input_t sensorGetCallback; +static retro_set_sensor_state_t sensorStateCallback; static void GBARetroLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args);@@ -56,11 +59,17 @@ static void* data;
static size_t dataSize; static void* savedata; static struct mAVStream stream; +static bool sensorsInitDone; static int rumbleUp; static int rumbleDown; static struct mRumble rumble; static struct GBALuminanceSource lux; -static int luxLevel; +static struct mRotationSource rotation; +static bool rotationEnabled; +static int luxLevelIndex; +static uint8_t luxLevel; +static bool luxSensorEnabled; +static bool luxSensorUsed; static struct mLogger logger; static struct retro_camera_callback cam; static struct mImageSource imageSource;@@ -71,6 +80,30 @@ static unsigned imcapWidth;
static unsigned imcapHeight; static size_t camStride; static bool deferredSetup = false; +static bool envVarsUpdated; + +static void _initSensors(void) { + if(sensorsInitDone) { + return; + } + + struct retro_sensor_interface sensorInterface; + if (environCallback(RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE, &sensorInterface)) { + sensorGetCallback = sensorInterface.get_sensor_input; + sensorStateCallback = sensorInterface.set_sensor_state; + + if(sensorStateCallback(0, RETRO_SENSOR_ACCELEROMETER_ENABLE, EVENT_RATE) + && sensorStateCallback(0, RETRO_SENSOR_GYROSCOPE_ENABLE, EVENT_RATE)) { + rotationEnabled = true; + } + + if(sensorStateCallback(0, RETRO_SENSOR_ILLUMINANCE_ENABLE, EVENT_RATE)) { + luxSensorEnabled = true; + } + } + + sensorsInitDone = true; +} static void _reloadSettings(void) { struct mCoreOptions opts = {@@ -272,6 +305,19 @@ } else {
rumbleCallback = 0; } + sensorsInitDone = false; + sensorGetCallback = 0; + sensorStateCallback = 0; + + rotationEnabled = false; + rotation.readTiltX = _readTiltX; + rotation.readTiltY = _readTiltY; + rotation.readGyroZ = _readGyroZ; + + envVarsUpdated = true; + luxSensorUsed = false; + luxSensorEnabled = false; + luxLevelIndex = 0; luxLevel = 0; lux.readLuminance = _readLux; lux.sample = _updateLux;@@ -298,6 +344,15 @@ }
void retro_deinit(void) { free(outputBuffer); + + if(sensorStateCallback) { + sensorStateCallback(0, RETRO_SENSOR_ACCELEROMETER_DISABLE, EVENT_RATE); + sensorStateCallback(0, RETRO_SENSOR_GYROSCOPE_DISABLE, EVENT_RATE); + sensorStateCallback(0, RETRO_SENSOR_ILLUMINANCE_DISABLE, EVENT_RATE); + } + + rotationEnabled = false; + luxSensorEnabled = false; } void retro_run(void) {@@ -305,10 +360,14 @@ if (deferredSetup) {
_doDeferredSetup(); } uint16_t keys; + + _initSensors(); inputPollCallback(); bool updated = false; if (environCallback(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) { + envVarsUpdated = true; + struct retro_variable var = { .key = "mgba_allow_opposing_directions", .value = 0@@ -339,23 +398,25 @@ keys |= (!!inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R)) << 8;
keys |= (!!inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L)) << 9; core->setKeys(core, keys); - static bool wasAdjustingLux = false; - if (wasAdjustingLux) { - wasAdjustingLux = inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3) || - inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3); - } else { - if (inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3)) { - ++luxLevel; - if (luxLevel > 10) { - luxLevel = 10; - } - wasAdjustingLux = true; - } else if (inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3)) { - --luxLevel; - if (luxLevel < 0) { - luxLevel = 0; + if(!luxSensorUsed) { + static bool wasAdjustingLux = false; + if (wasAdjustingLux) { + wasAdjustingLux = inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3) || + inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3); + } else { + if (inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3)) { + ++luxLevelIndex; + if (luxLevelIndex > 10) { + luxLevelIndex = 10; + } + wasAdjustingLux = true; + } else if (inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3)) { + --luxLevelIndex; + if (luxLevelIndex < 0) { + luxLevelIndex = 0; + } + wasAdjustingLux = true; } - wasAdjustingLux = true; } }@@ -938,35 +999,47 @@ struct retro_variable var = {
.key = "mgba_solar_sensor_level", .value = 0 }; + bool luxVarUpdated = envVarsUpdated; - bool updated = false; - if (!environCallback(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) || !updated) { - return; + if (luxVarUpdated && (!environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || !var.value)) { + luxVarUpdated = false; } - if (!environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || !var.value) { - return; + + if(luxVarUpdated) { + luxSensorUsed = strcmp(var.value, "sensor") == 0; } - char* end; - int newLuxLevel = strtol(var.value, &end, 10); - if (!*end) { - if (newLuxLevel > 10) { - luxLevel = 10; - } else if (newLuxLevel < 0) { - luxLevel = 0; - } else { - luxLevel = newLuxLevel; + if(luxSensorUsed) { + float fLux = luxSensorEnabled ? sensorGetCallback(0, RETRO_SENSOR_ILLUMINANCE) : 0.0f; + luxLevel = cbrtf(fLux) * 8; + } else { + if(luxVarUpdated) { + char* end; + int newLuxLevelIndex = strtol(var.value, &end, 10); + + if (!*end) { + if (newLuxLevelIndex > 10) { + luxLevelIndex = 10; + } else if (newLuxLevelIndex < 0) { + luxLevelIndex = 0; + } else { + luxLevelIndex = newLuxLevelIndex; + } + } + } + + luxLevel = 0x16; + if (luxLevelIndex > 0) { + luxLevel += GBA_LUX_LEVELS[luxLevelIndex - 1]; } } + + envVarsUpdated = false; } static uint8_t _readLux(struct GBALuminanceSource* lux) { UNUSED(lux); - int value = 0x16; - if (luxLevel > 0) { - value += GBA_LUX_LEVELS[luxLevel - 1]; - } - return 0xFF - value; + return 0xFF - luxLevel; } static void _updateCamera(const uint32_t* buffer, unsigned width, unsigned height, size_t pitch) {@@ -1032,3 +1105,36 @@ *buffer = &camData[offset];
*stride = camStride; *colorFormat = mCOLOR_XRGB8; } + +static int32_t _readTiltX(struct mRotationSource* source) { + UNUSED(source); + int32_t tiltX = 0; + + if(rotationEnabled) { + tiltX = sensorGetCallback(0, RETRO_SENSOR_ACCELEROMETER_X) * 3e8f; + } + + return tiltX; +} + +static int32_t _readTiltY(struct mRotationSource* source) { + UNUSED(source); + int32_t tiltY = 0; + + if(rotationEnabled) { + tiltY = sensorGetCallback(0, RETRO_SENSOR_ACCELEROMETER_Y) * -3e8f; + } + + return tiltY; +} + +static int32_t _readGyroZ(struct mRotationSource* source) { + UNUSED(source); + int32_t gyroZ = 0; + + if(rotationEnabled) { + gyroZ = sensorGetCallback(0, RETRO_SENSOR_GYROSCOPE_Z) * -1.1e9f; + } + + return gyroZ; +}
M
src/platform/libretro/libretro_core_options.h
→
src/platform/libretro/libretro_core_options.h
@@ -54,18 +54,19 @@ "mgba_solar_sensor_level",
"Solar Sensor Level", "Sets ambient sunlight intensity. Can be used by games that included a solar sensor in their cartridges, e.g: the Boktai series.", { - { "0", NULL }, - { "1", NULL }, - { "2", NULL }, - { "3", NULL }, - { "4", NULL }, - { "5", NULL }, - { "6", NULL }, - { "7", NULL }, - { "8", NULL }, - { "9", NULL }, - { "10", NULL }, - { NULL, NULL }, + { "sensor", "Use device sensor if available" }, + { "0", NULL }, + { "1", NULL }, + { "2", NULL }, + { "3", NULL }, + { "4", NULL }, + { "5", NULL }, + { "6", NULL }, + { "7", NULL }, + { "8", NULL }, + { "9", NULL }, + { "10", NULL }, + { NULL, NULL }, }, "0" },
M
src/platform/libretro/libretro_core_options_intl.h
→
src/platform/libretro/libretro_core_options_intl.h
@@ -208,18 +208,19 @@ "mgba_solar_sensor_level",
"Güneş Sensörü Seviyesi", "Ortam güneş ışığının yoğunluğunu ayarlar. Boktai serisi, kartuşlarına güneş sensörü içeren oyunlar tarafından kullanılabilir.", { - { "0", NULL }, - { "1", NULL }, - { "2", NULL }, - { "3", NULL }, - { "4", NULL }, - { "5", NULL }, - { "6", NULL }, - { "7", NULL }, - { "8", NULL }, - { "9", NULL }, - { "10", NULL }, - { NULL, NULL }, + { "sensor", "Sensörü" }, + { "0", NULL }, + { "1", NULL }, + { "2", NULL }, + { "3", NULL }, + { "4", NULL }, + { "5", NULL }, + { "6", NULL }, + { "7", NULL }, + { "8", NULL }, + { "9", NULL }, + { "10", NULL }, + { NULL, NULL }, }, "0" },