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 SAMPLES 1024
#define RUMBLE_PWM 35 #define RUMBLE_PWM 35
#define EVENT_RATE 60
static retro_environment_t environCallback; static retro_environment_t environCallback;
static retro_video_refresh_t videoCallback; static retro_video_refresh_t videoCallback;
@ -38,6 +39,8 @@ static retro_input_poll_t inputPollCallback;
static retro_input_state_t inputCallback; static retro_input_state_t inputCallback;
static retro_log_printf_t logCallback; static retro_log_printf_t logCallback;
static retro_set_rumble_state_t rumbleCallback; 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); 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 size_t dataSize;
static void* savedata; static void* savedata;
static struct mAVStream stream; static struct mAVStream stream;
static bool sensorsInitDone;
static int rumbleUp; static int rumbleUp;
static int rumbleDown; static int rumbleDown;
static struct mRumble rumble; static struct mRumble rumble;
static struct GBALuminanceSource lux; 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 mLogger logger;
static struct retro_camera_callback cam; static struct retro_camera_callback cam;
static struct mImageSource imageSource; static struct mImageSource imageSource;
@ -71,6 +80,30 @@ static unsigned imcapWidth;
static unsigned imcapHeight; static unsigned imcapHeight;
static size_t camStride; static size_t camStride;
static bool deferredSetup = false; 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) { static void _reloadSettings(void) {
struct mCoreOptions opts = { struct mCoreOptions opts = {
@ -272,6 +305,19 @@ void retro_init(void) {
rumbleCallback = 0; 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; luxLevel = 0;
lux.readLuminance = _readLux; lux.readLuminance = _readLux;
lux.sample = _updateLux; lux.sample = _updateLux;
@ -298,6 +344,15 @@ void retro_init(void) {
void retro_deinit(void) { void retro_deinit(void) {
free(outputBuffer); 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) { void retro_run(void) {
@ -305,10 +360,14 @@ void retro_run(void) {
_doDeferredSetup(); _doDeferredSetup();
} }
uint16_t keys; uint16_t keys;
_initSensors();
inputPollCallback(); inputPollCallback();
bool updated = false; bool updated = false;
if (environCallback(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) { if (environCallback(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) {
envVarsUpdated = true;
struct retro_variable var = { struct retro_variable var = {
.key = "mgba_allow_opposing_directions", .key = "mgba_allow_opposing_directions",
.value = 0 .value = 0
@ -339,23 +398,25 @@ void retro_run(void) {
keys |= (!!inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L)) << 9; keys |= (!!inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L)) << 9;
core->setKeys(core, keys); core->setKeys(core, keys);
static bool wasAdjustingLux = false; if(!luxSensorUsed) {
if (wasAdjustingLux) { static bool wasAdjustingLux = false;
wasAdjustingLux = inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3) || if (wasAdjustingLux) {
inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3); wasAdjustingLux = inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3) ||
} else { inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3);
if (inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3)) { } else {
++luxLevel; if (inputCallback(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3)) {
if (luxLevel > 10) { ++luxLevelIndex;
luxLevel = 10; 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", .key = "mgba_solar_sensor_level",
.value = 0 .value = 0
}; };
bool luxVarUpdated = envVarsUpdated;
bool updated = false; if (luxVarUpdated && (!environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || !var.value)) {
if (!environCallback(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) || !updated) { luxVarUpdated = false;
return;
}
if (!environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || !var.value) {
return;
} }
char* end; if(luxVarUpdated) {
int newLuxLevel = strtol(var.value, &end, 10); luxSensorUsed = strcmp(var.value, "sensor") == 0;
if (!*end) { }
if (newLuxLevel > 10) {
luxLevel = 10; if(luxSensorUsed) {
} else if (newLuxLevel < 0) { float fLux = luxSensorEnabled ? sensorGetCallback(0, RETRO_SENSOR_ILLUMINANCE) : 0.0f;
luxLevel = 0; luxLevel = cbrtf(fLux) * 8;
} else { } else {
luxLevel = newLuxLevel; 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) { static uint8_t _readLux(struct GBALuminanceSource* lux) {
UNUSED(lux); UNUSED(lux);
int value = 0x16; return 0xFF - luxLevel;
if (luxLevel > 0) {
value += GBA_LUX_LEVELS[luxLevel - 1];
}
return 0xFF - value;
} }
static void _updateCamera(const uint32_t* buffer, unsigned width, unsigned height, size_t pitch) { 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; *stride = camStride;
*colorFormat = mCOLOR_XRGB8; *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", "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.", "Sets ambient sunlight intensity. Can be used by games that included a solar sensor in their cartridges, e.g: the Boktai series.",
{ {
{ "0", NULL }, { "sensor", "Use device sensor if available" },
{ "1", NULL }, { "0", NULL },
{ "2", NULL }, { "1", NULL },
{ "3", NULL }, { "2", NULL },
{ "4", NULL }, { "3", NULL },
{ "5", NULL }, { "4", NULL },
{ "6", NULL }, { "5", NULL },
{ "7", NULL }, { "6", NULL },
{ "8", NULL }, { "7", NULL },
{ "9", NULL }, { "8", NULL },
{ "10", NULL }, { "9", NULL },
{ NULL, NULL }, { "10", NULL },
{ NULL, NULL },
}, },
"0" "0"
}, },

View File

@ -208,18 +208,19 @@ struct retro_core_option_definition option_defs_tr[] = {
"Güneş Sensörü Seviyesi", "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.", "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 }, { "sensor", "Sensörü" },
{ "1", NULL }, { "0", NULL },
{ "2", NULL }, { "1", NULL },
{ "3", NULL }, { "2", NULL },
{ "4", NULL }, { "3", NULL },
{ "5", NULL }, { "4", NULL },
{ "6", NULL }, { "5", NULL },
{ "7", NULL }, { "6", NULL },
{ "8", NULL }, { "7", NULL },
{ "9", NULL }, { "8", NULL },
{ "10", NULL }, { "9", NULL },
{ NULL, NULL }, { "10", NULL },
{ NULL, NULL },
}, },
"0" "0"
}, },