Use sensor interface; add sensor light core option

Behavior synced from standalone mgba
This commit is contained in:
p-sam 2019-10-28 08:40:11 +00:00 committed by Vicki Pfau
parent 57c8ac1dd9
commit 983a482527
3 changed files with 169 additions and 61 deletions

View File

@ -30,6 +30,7 @@
#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 @@ void retro_init(void) {
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_init(void) {
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 @@ void retro_run(void) {
_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 @@ void retro_run(void) {
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;
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;
} else if (inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3)) {
--luxLevel;
if (luxLevel < 0) {
luxLevel = 0;
}
wasAdjustingLux = true;
}
}
@ -938,35 +999,47 @@ static void _updateLux(struct GBALuminanceSource* lux) {
.key = "mgba_solar_sensor_level",
.value = 0
};
bool luxVarUpdated = envVarsUpdated;
bool updated = false;
if (!environCallback(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) || !updated) {
return;
}
if (!environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || !var.value) {
return;
if (luxVarUpdated && (!environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || !var.value)) {
luxVarUpdated = false;
}
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(luxVarUpdated) {
luxSensorUsed = strcmp(var.value, "sensor") == 0;
}
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 @@ static void _requestImage(struct mImageSource* image, const void** buffer, size_
*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;
}

View File

@ -54,18 +54,19 @@ struct retro_core_option_definition option_defs_us[] = {
"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"
},

View File

@ -208,18 +208,19 @@ struct retro_core_option_definition option_defs_tr[] = {
"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"
},