mirror of https://github.com/mgba-emu/mgba.git
Use sensor interface; add sensor light core option
Behavior synced from standalone mgba
This commit is contained in:
parent
57c8ac1dd9
commit
983a482527
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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"
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue