diff --git a/CHANGES b/CHANGES index e296db2e7..c547ed8fc 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,8 @@ Features: - Key autofire - Libretro: Allow blocking opposing directional input - OpenEmu core for OS X + - Libretro: Settings for using BIOS and skipping intro + - Libretro: Customizable idle loop removal Bugfixes: - Util: Fix PowerPC PNG read/write pixel order - VFS: Fix VFileReadline and remove _vfdReadline diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 6f58f8395..708e12142 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -20,6 +20,9 @@ #define SOLAR_SENSOR_LEVEL "mgba_solar_sensor_level" #define ALLOW_OPPOSING_DIRECTIONS "mgba_allow_opposing_directions" +#define USE_BIOS "mgba_use_bios" +#define SKIP_BIOS "mgba_skip_bios" +#define IDLE_OPTIMIZATION "mgba_idle_optimization" static retro_environment_t environCallback; static retro_video_refresh_t videoCallback; @@ -50,6 +53,41 @@ static int luxLevel; static struct GBACheatDevice cheats; static struct GBACheatSet cheatSet; +static void _reloadSettings(void) { + struct GBAOptions opts = { + .useBios = true, + .idleOptimization = IDLE_LOOP_REMOVE + }; + + struct retro_variable var; + + var.key = USE_BIOS; + var.value = 0; + if (environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { + opts.useBios = strcmp(var.value, "yes") == 0; + } + + var.key = SKIP_BIOS; + var.value = 0; + if (environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { + opts.skipBios = strcmp(var.value, "yes") == 0; + } + + var.key = IDLE_OPTIMIZATION; + var.value = 0; + if (environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { + if (strcmp(var.value, "don't remove") == 0) { + opts.idleOptimization = IDLE_LOOP_IGNORE; + } else if (strcmp(var.value, "remove known") == 0) { + opts.idleOptimization = IDLE_LOOP_REMOVE; + } else if (strcmp(var.value, "detect and remove") == 0) { + opts.idleOptimization = IDLE_LOOP_DETECT; + } + } + + GBAConfigLoadDefaults(&context.config, &opts); +} + unsigned retro_api_version(void) { return RETRO_API_VERSION; } @@ -60,6 +98,9 @@ void retro_set_environment(retro_environment_t env) { struct retro_variable vars[] = { { SOLAR_SENSOR_LEVEL, "Solar sensor level; 0|1|2|3|4|5|6|7|8|9|10" }, { ALLOW_OPPOSING_DIRECTIONS, "Allow opposing directional input; no|yes" }, + { USE_BIOS, "Use BIOS file if found; yes|no" }, + { SKIP_BIOS, "Skip BIOS intro; no|yes" }, + { IDLE_OPTIMIZATION, "Idle loop removal; remove known|detect and remove|don't remove" }, { 0, 0 } }; @@ -163,11 +204,6 @@ void retro_init(void) { stream.postVideoFrame = 0; GBAContextInit(&context, 0); - struct GBAOptions opts = { - .useBios = true, - .idleOptimization = IDLE_LOOP_REMOVE - }; - GBAConfigLoadDefaults(&context.config, &opts); context.gba->logHandler = GBARetroLog; context.gba->stream = &stream; if (rumbleCallback) { @@ -294,6 +330,7 @@ bool retro_load_game(const struct retro_game_info* game) { savedata = anonymousMemoryMap(SIZE_CART_FLASH1M); struct VFile* save = VFileFromMemory(savedata, SIZE_CART_FLASH1M); + _reloadSettings(); GBAContextLoadROMFromVFile(&context, rom, save); GBAContextStart(&context); return true;