mirror of https://github.com/mgba-emu/mgba.git
Libretro: Support solar sensor
This commit is contained in:
parent
903a8a654d
commit
3a31577cab
|
@ -9,6 +9,8 @@
|
||||||
#include "gba/serialize.h"
|
#include "gba/serialize.h"
|
||||||
#include "util/hash.h"
|
#include "util/hash.h"
|
||||||
|
|
||||||
|
const int GBA_LUX_LEVELS[10] = { 5, 11, 18, 27, 42, 62, 84, 109, 139, 183 };
|
||||||
|
|
||||||
static void _readPins(struct GBACartridgeHardware* hw);
|
static void _readPins(struct GBACartridgeHardware* hw);
|
||||||
static void _outputPins(struct GBACartridgeHardware* hw, unsigned pins);
|
static void _outputPins(struct GBACartridgeHardware* hw, unsigned pins);
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,8 @@ struct GBARotationSource {
|
||||||
int32_t (*readGyroZ)(struct GBARotationSource*);
|
int32_t (*readGyroZ)(struct GBARotationSource*);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const int GBA_LUX_LEVELS[10];
|
||||||
|
|
||||||
struct GBALuminanceSource {
|
struct GBALuminanceSource {
|
||||||
void (*sample)(struct GBALuminanceSource*);
|
void (*sample)(struct GBALuminanceSource*);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "util/common.h"
|
#include "util/common.h"
|
||||||
|
|
||||||
#include "gba/gba.h"
|
#include "gba/gba.h"
|
||||||
|
#include "gba/interface.h"
|
||||||
#include "gba/renderers/video-software.h"
|
#include "gba/renderers/video-software.h"
|
||||||
#include "gba/serialize.h"
|
#include "gba/serialize.h"
|
||||||
#include "gba/supervisor/overrides.h"
|
#include "gba/supervisor/overrides.h"
|
||||||
|
@ -18,6 +19,8 @@
|
||||||
#define SAMPLES 1024
|
#define SAMPLES 1024
|
||||||
#define RUMBLE_PWM 35
|
#define RUMBLE_PWM 35
|
||||||
|
|
||||||
|
#define SOLAR_SENSOR_LEVEL "mgba_solar_sensor_level"
|
||||||
|
|
||||||
static retro_environment_t environCallback;
|
static retro_environment_t environCallback;
|
||||||
static retro_video_refresh_t videoCallback;
|
static retro_video_refresh_t videoCallback;
|
||||||
static retro_audio_sample_batch_t audioCallback;
|
static retro_audio_sample_batch_t audioCallback;
|
||||||
|
@ -31,6 +34,8 @@ static void GBARetroLog(struct GBAThread* thread, enum GBALogLevel level, const
|
||||||
static void _postAudioBuffer(struct GBAAVStream*, struct GBAAudio* audio);
|
static void _postAudioBuffer(struct GBAAVStream*, struct GBAAudio* audio);
|
||||||
static void _postVideoFrame(struct GBAAVStream*, struct GBAVideoRenderer* renderer);
|
static void _postVideoFrame(struct GBAAVStream*, struct GBAVideoRenderer* renderer);
|
||||||
static void _setRumble(struct GBARumble* rumble, int enable);
|
static void _setRumble(struct GBARumble* rumble, int enable);
|
||||||
|
static uint8_t _readLux(struct GBALuminanceSource* lux);
|
||||||
|
static void _updateLux(struct GBALuminanceSource* lux);
|
||||||
|
|
||||||
static struct GBA gba;
|
static struct GBA gba;
|
||||||
static struct ARMCore cpu;
|
static struct ARMCore cpu;
|
||||||
|
@ -44,6 +49,8 @@ static struct GBAAVStream stream;
|
||||||
static int rumbleLevel;
|
static int rumbleLevel;
|
||||||
static struct CircleBuffer rumbleHistory;
|
static struct CircleBuffer rumbleHistory;
|
||||||
static struct GBARumble rumble;
|
static struct GBARumble rumble;
|
||||||
|
static struct GBALuminanceSource lux;
|
||||||
|
static int luxLevel;
|
||||||
|
|
||||||
unsigned retro_api_version(void) {
|
unsigned retro_api_version(void) {
|
||||||
return RETRO_API_VERSION;
|
return RETRO_API_VERSION;
|
||||||
|
@ -51,6 +58,13 @@ unsigned retro_api_version(void) {
|
||||||
|
|
||||||
void retro_set_environment(retro_environment_t env) {
|
void retro_set_environment(retro_environment_t env) {
|
||||||
environCallback = env;
|
environCallback = env;
|
||||||
|
|
||||||
|
struct retro_variable vars[] = {
|
||||||
|
{ SOLAR_SENSOR_LEVEL, "Solar sensor level; 0|1|2|3|4|5|6|7|8|9|10" },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
environCallback(RETRO_ENVIRONMENT_SET_VARIABLES, vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
void retro_set_video_refresh(retro_video_refresh_t video) {
|
void retro_set_video_refresh(retro_video_refresh_t video) {
|
||||||
|
@ -130,6 +144,11 @@ void retro_init(void) {
|
||||||
rumbleCallback = 0;
|
rumbleCallback = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
luxLevel = 0;
|
||||||
|
lux.readLuminance = _readLux;
|
||||||
|
lux.sample = _updateLux;
|
||||||
|
_updateLux(&lux);
|
||||||
|
|
||||||
struct retro_log_callback log;
|
struct retro_log_callback log;
|
||||||
if (environCallback(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log)) {
|
if (environCallback(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log)) {
|
||||||
logCallback = log.log;
|
logCallback = log.log;
|
||||||
|
@ -151,6 +170,7 @@ void retro_init(void) {
|
||||||
if (rumbleCallback) {
|
if (rumbleCallback) {
|
||||||
gba.rumble = &rumble;
|
gba.rumble = &rumble;
|
||||||
}
|
}
|
||||||
|
gba.luminanceSource = &lux;
|
||||||
rom = 0;
|
rom = 0;
|
||||||
|
|
||||||
const char* sysDir = 0;
|
const char* sysDir = 0;
|
||||||
|
@ -401,3 +421,40 @@ static void _setRumble(struct GBARumble* rumble, int enable) {
|
||||||
CircleBufferWrite8(&rumbleHistory, enable);
|
CircleBufferWrite8(&rumbleHistory, enable);
|
||||||
rumbleCallback(0, RETRO_RUMBLE_STRONG, rumbleLevel * 0xFFFF / RUMBLE_PWM);
|
rumbleCallback(0, RETRO_RUMBLE_STRONG, rumbleLevel * 0xFFFF / RUMBLE_PWM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _updateLux(struct GBALuminanceSource* lux) {
|
||||||
|
UNUSED(lux);
|
||||||
|
struct retro_variable var = {
|
||||||
|
.key = SOLAR_SENSOR_LEVEL,
|
||||||
|
.value = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
bool updated = false;
|
||||||
|
if (!environCallback(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) || !updated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || !var.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t _readLux(struct GBALuminanceSource* lux) {
|
||||||
|
UNUSED(lux);
|
||||||
|
int value = 0x16;
|
||||||
|
if (luxLevel > 0) {
|
||||||
|
value += GBA_LUX_LEVELS[luxLevel - 1];
|
||||||
|
}
|
||||||
|
return 0xFF - value;
|
||||||
|
}
|
||||||
|
|
|
@ -29,8 +29,6 @@ extern "C" {
|
||||||
using namespace QGBA;
|
using namespace QGBA;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
const int GameController::LUX_LEVELS[10] = { 5, 11, 18, 27, 42, 62, 84, 109, 139, 183 };
|
|
||||||
|
|
||||||
GameController::GameController(QObject* parent)
|
GameController::GameController(QObject* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_drawContext(new uint32_t[256 * 256])
|
, m_drawContext(new uint32_t[256 * 256])
|
||||||
|
@ -794,7 +792,7 @@ void GameController::setLuminanceValue(uint8_t value) {
|
||||||
value = std::max<int>(value - 0x16, 0);
|
value = std::max<int>(value - 0x16, 0);
|
||||||
m_luxLevel = 10;
|
m_luxLevel = 10;
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
if (value < LUX_LEVELS[i]) {
|
if (value < GBA_LUX_LEVELS[i]) {
|
||||||
m_luxLevel = i;
|
m_luxLevel = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -806,7 +804,7 @@ void GameController::setLuminanceLevel(int level) {
|
||||||
int value = 0x16;
|
int value = 0x16;
|
||||||
level = std::max(0, std::min(10, level));
|
level = std::max(0, std::min(10, level));
|
||||||
if (level > 0) {
|
if (level > 0) {
|
||||||
value += LUX_LEVELS[level - 1];
|
value += GBA_LUX_LEVELS[level - 1];
|
||||||
}
|
}
|
||||||
setLuminanceValue(value);
|
setLuminanceValue(value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,8 +207,6 @@ private:
|
||||||
uint8_t m_luxValue;
|
uint8_t m_luxValue;
|
||||||
int m_luxLevel;
|
int m_luxLevel;
|
||||||
|
|
||||||
static const int LUX_LEVELS[10];
|
|
||||||
|
|
||||||
GBARTCGenericSource m_rtc;
|
GBARTCGenericSource m_rtc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue