RetroArch 1.9.13 – Automatic Frame Delay

Article written by Ryunam

RetroArch 1.9.13 introduces a new option called “Automatic Frame Delay”. It has been added to the Latency sub-menu (found under Settings -> Latency).

This new feature provides an effective way to avoid having to configure a specific value for the “Frame Delay” option for each and every core and individual piece of content that you may want to run, by automatically tuning down its strength based on your system performance.
This is yet another contribution that empowers our long-standing efforts in reducing input latency to the lowest extent possible. We feel this new addition also gives us a good opportunity to delve further into the inner workings behind the concept of “Frame Delay” and briefly explain what purpose this functionality serves and how we generally advise our users to apply it.

What is “Frame Delay”?

The setting known as “Frame Delay” has actually existed for some time in RetroArch. However, due to its nature and the complexity of its effect, it has always required a level of strictly manual adjustment and finetuning on the user side.

To best describe the underlying mechanism, let us briefly touch upon the timing of when a new frame is produced (including when the inputs are sampled) and then displayed on-screen.

The way frames are rendered and then displayed on video can be best understood by considering this sequence:
• each frame has a set duration, namely a “frame time” or “frame period” as it is usually called, which on a 60hz screen and in ideal circumstances corresponds to a length of 16.7 milliseconds on average;
• as per the picture shown above, once the first frame is shown the next frame starts being prepared “behind the scenes”. This rendering process includes the moment the inputs are polled and it all happens within the allotted frame period;
• in typical situations the rendering process of the next frame is finished some time before the given frame period is over;
• this results in the next frame essentially “stalling”, being left in a suspended state for a few more milliseconds than necessary, until the frame period is properly finished;
• only at that point the newly created frame is presented on-screen.

While the process described here is normal and does not usually yield a considerable impact on latency, the fact that the next frame has to be put “on hold” and wait a certain amount of time from the moment it finishes rendering until the end of the frame period does in fact contribute to the combined responsiveness of the inputs.

This is where “Frame Delay” comes into play.

Depending on the value set for the “Frame Delay” option, the creation of the new frame including the input polling can be postponed by a certain number of milliseconds, until the last moment that is realistically viable.

Doing this requires some additional CPU processing power depending on the chosen amount of delay, but it also helps decrease the number of milliseconds that the new frame – which has been prepared and is ready to be presented on video – has to remain on hold. As a consequence, adjusting the “Frame Delay” setting can offer a slight – albeit measurable – improvement to the perceived input latency.

The “Automatic Frame Delay” setting

The problem with the “Frame Delay” setting has been traditionally that the many cores and types of content available, as one may expect, are vastly different and often have varying degrees of system and CPU requirements.

Users have had to constantly tweak the “Frame Delay” values for each specific situation, often resorting to set either per-core or per-content overrides, so that the benefits of the latency reduction could be had without stumbling on framerate drops, stutter, audio crackling and all sorts of other issues.

With the introduction of the “Automatic Frame Delay” toggle, the use of this functionality becomes simpler: the amount of delay time for the rendering of the new frame will scale down automatically, if the system detects any framerate fluctuation/drop, until it reaches a value that allows your gameplay to remain stable while still retaining a certain extent of latency reduction.
Here is a quick rundown of the different ways that you can enable and apply this setting, based on your preference:

• if you set “Frame Delay” to 0 and “Automatic Frame Delay” to ON, the starting point of the delay that is applied to the new frame will be half your “frame period”. For instance, on a typical 60hz screen with a frame time of 16.7 ms, the initial value applied will be “8”, as in 8 milliseconds of delay. Afterwards, if drops or hiccups are detected in the video performance, this value will be reduced dynamically until it reaches a stable point;

• if you set “Frame Delay” to any value higher than 0 and “Automatic Frame Delay” to ON, the starting point will be the delay value that was manually set. For instance, if “Frame Delay” is set to 10, the initial amount of delay for the processing of the new frame will be 10ms. Then, it will be adjusted downwards in case any framerate drop is detected;

• if you set “Frame Delay” to any value higher than 0 and “Automatic Frame Delay” to OFF, the automated scaling of the frame delay setting will be disabled. The amount of delay applied to the rendering of the new frame will be exactly the one chosen and will not change or decrease during gameplay at all;

• if you set “Frame Delay” to 0 and “Automatic Frame Delay” to OFF, no amount of delay will be applied to the rendering of the new frame. Frame Delay will be disabled entirely.

Conclusion

While the tangible effects of “Frame Delay” on the total combined latency might be small compared to other implementations such as Runahead, this setting has the advantage of being applicable to all cores and content, albeit to varying degrees.

The added convenience of having “Frame Delay” scale down automatically is yet another asset in making sure that you can run your content with the lowest latency possible.

Hopefully this new toggle allows a greater ease of use of this particular option for our users. We definitely encourage experimenting with it and testing it with the wide array of cores available for the libretro platform!

RetroArch 1.9.12 released!


RetroArch 1.9.12 has just been released.

Grab it here.

If you’d like to learn more about upcoming releases, please consult our roadmap here.

Remember that this project exists for the benefit of our users, and that we wouldn’t keep doing this were it not for spreading the love to our users. This project exists because of your support and belief in us to keep going doing great things. If you’d like to show your support, consider donating to us. Check here in order to learn more. In addition to being able to support us on Patreon, there is now also the option to sponsor us on Github Sponsors! You can also help us out by buying some of our merch on our Teespring store!

Highlights

Steam


New cores are on the verge of being approved on Steam. First out of the gates is Picodrive, a Sega Genesis/Master System/Sega CD/32X emulator. You can grab that for RetroArch right now here.

We’d also like to remind users that are still using the RetroArch Play Test version on Steam to please migrate over to the mainline Steam release now and to stop using it. The Play Test version is outdated and won’t really be updated anymore after this point.

Miyoo – Pocket Go, PowKiddy Q90-V90 and New BittBoy – Over 28 cores now

For version 1.9.11, we added support for Miyoo devices, such as the Pocket GO, PowKiddy Q90-V90 and New BitBoy. Back then, we only had one or two cores available.

Version 1.9.12 now comes with a whopping 28 cores – quite the improvement over 1.9.11.

List of all cores so far –

  • 81
  • CAP32
  • fMSX
  • FUSE
  • Gambatte
  • Genesis Plus GX
  • GW
  • Handy
  • LRMAME2003
  • LRMAME2003 Plus
  • Mednafen PCE Fast
  • Mednafen Wswan
  • mGBA
  • NXEngine
  • O2EM
  • Picodrive
  • PokeMini
  • Potator
  • PrBoom
  • Prosystem
  • QuickNES
  • RACE
  • Retro8
  • ScummVM
  • SMS Plus
  • Stella 2014
  • Theodore
  • Vecx

NOTE: We are not affiliated or have any association with the companies behind these devices.

HID subsystem unification – improvements/bugfixes

1.9.11 added a new unified HID subsystem that works on both Mac and WiiU.

Version 1.9.12 features several crucial bugfixes and additions that were plaguing the initial implementation in 1.9.11. See the CHANGELOG at the end of this blog post for more details.

Increased backwards compatibility for macOS cores

Since the migration to our new infrastructure, the minimum OS requirements for macOS cores unintentionally went up. We have since taken steps to address this.

Here are the current minimum OS requirements:

  • 2048: 10.9
  • 81: 10.9
  • atari800: 10.9
  • bk: 10.1
  • blastem: 10.9
  • bluemsx: 10.9
  • bsnes2014_accuracy: 10.9
  • bsnes2014_balanced: 10.9
  • bsnes2014_performance: 10.9
  • bsnes_cplusplus98: 10.9
  • bsnes_hd_beta: 10.9
  • bsnes: 10.9
  • bsnes_mercury_accuracy: 10.9
  • bsnes_mercury_balanced: 10.9
  • bsnes_mercury_performance: 10.9
  • cannonball: 10.9
  • cap32: 10.9
  • craft: 10.7
  • crocods: 10.9
  • desmume: 10.7
  • dinothawr: 10.8
  • dosbox_core: 10.9
  • dosbox_pure: 10.9
  • dosbox_svn: 10.9
  • duckstation: 10.15
  • easyrpg: 10.9
  • ecwolf: 10.9
  • fbalpha2012_cps1: 10.9
  • fbalpha2012_cps2: 10.9
  • fbalpha2012_cps3: 10.9
  • fbalpha2012: 10.9
  • fbalpha2012_neogeo: 10.7
  • fbneo: 10.9
  • fceumm: 10.9
  • fixgb: 10.9
  • flycast: 10.9
  • fmsx: 10.9
  • freechaf: 10.9
  • freeintv: 10.9
  • frodo: 10.9
  • fuse: 10.9
  • gambatte: 10.9
  • gearboy: 10.9
  • gearcoleco: 10.9
  • gearsystem: 10.9
  • genesis_plus_gx: 10.9
  • genesis_plus_gx_wide: 10.9
  • gme: 10.9
  • gpsp: 10.1
  • gw: 10.9
  • handy: 10.9
  • hatari: 10.9
  • lowresnx: 10.9
  • lutro: 10.9
  • mame2000: 10.9
  • mame2003: 10.9
  • mame2003_plus: 10.9
  • mame2010: 10.9
  • mame: 10.9
  • mednafen_gba: 10.9
  • mednafen_lynx: 10.9
  • mednafen_ngp: 10.9
  • mednafen_pce_fast: 10.7
  • mednafen_pce: 10.7
  • mednafen_pcfx: 10.9
  • mednafen_psx: 10.9
  • mednafen_saturn: 10.9
  • mednafen_snes: 10.9
  • mednafen_supergrafx: 10.9
  • mednafen_vb: 10.9
  • mednafen_wswan: 10.7
  • melonds: 10.9
  • mesen-s: 10.9
  • mesen: 10.9
  • mgba: 10.9
  • mrboom: 10.9
  • mu: 10.9
  • nekop2: 10.9
  • neocd: 10.9
  • nestopia: 10.9
  • np2kai: 10.7
  • nxengine: 10.9
  • o2em: 10.9
  • oberon: 10.9
  • opera: 10.9
  • parallel_n64: 10.7
  • pcsx_rearmed: 10.9
  • picodrive: 10.6
  • play: 10.14
  • pocketcdg: 10.9
  • pokemini: 10.9
  • potator: 10.9
  • ppsspp: 10.9
  • prboom: 10.9
  • prosystem: 10.9
  • puae: 10.6
  • px68k: 10.7
  • quasi88: 10.9
  • quicknes: 10.9
  • race: 10.9
  • reminiscence: 10.9
  • retro8: 10.9
  • sameboy: 10.9
  • scummvm: 10.9
  • smsplus: 10.7
  • snes9x2002: 10.9
  • snes9x2005: 10.9
  • snes9x2005_plus: 10.9
  • snes9x2010: 10.9
  • snes9x: 10.9
  • squirreljme: 10.9
  • stella2014: 10.7
  • stella: 10.9
  • tgbdual: 10.7
  • theodore: 10.7
  • thepowdertoy: 10.15
  • tic80: 10.15
  • tyrquake: 10.9
  • uzem: 10.9
  • vba_next: 10.9
  • vbam: 10.9
  • vecx: 10.9
  • vemulator: 10.9
  • vice_x128: 10.9
  • vice_x64: 10.9
  • vice_x64sc: 10.9
  • vice_xcbm2: 10.9
  • vice_xcbm5x0: 10.9
  • vice_xpet: 10.9
  • vice_xplus4: 10.9
  • vice_xscpu64: 10.9
  • vice_xvic: 10.9
  • virtualjaguar: 10.9
  • vitaquake2: 10.9
  • x1: 10.9
  • xrick: 10.9
  • yabause: 10.9

We intend to drive down the requirements even lower in the coming months. For C++-based cores, the lowest we can go is 10.9. Going lower would require installing an older SDK version. For C-based cores, the lowest we can go is 10.4 for Intel-based architectures.

Project IO – Continued

You’ve read in our previous blog post that we were working on a long-term project to wrap/abstract all file system I/O in cores, and also correct and improve cores along the way. This work has continued for version 1.9.12, and we are happy to report that various cores have been improved substantially as a result.

Below are all the cores we managed to cover so far. The ones listed in bold are the new cores we have covered since 1.9.11.

Project IO – FCEUmm improvements

We replaced all direct file access in the core with VFS routines (libretro/RetroArch#12949)

In addition, it turned out that this core had been violating the libretro API for some time by setting need_fullpath = false but then requiring the content fullpath to detect the region of iNES v1.0 ROMs. This PR fixes the issue by setting need_fullpath = true by default, but then lifting this restriction for frontends that support the RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE environment callback (which allows a valid content name to be extracted even when using a frontend-provided data buffer)

Built-in Game Genie support

FCEUmm has long supported emulation of the Game Genie cartridge add-on, but this is currently unavailable in the libretro core. 1.9.12 wires up said functionality:

A new core option Game Genie Add-On (Restart) has been added (disabled by default)
In order for the option to apply, the Game Genie ROM file named gamegenie.nes must be present in the frontend system directory
Game Genie support is disabled for FDS and arcade content
Save states do not function (and are disabled) while the Game Genie boot screen is open
After enabling Game Genie Add-On (Restart), launching a game will cause the Game Genie boot screen to appear. Codes can be entered with the gamepad (as on real hardware): D-Pad to move, A to select, B to delete. For example:

Super Mario Bros.
YSAOPE + YEAOZA + YEAPYA Start on World 8

Why would we want this functionality, when the regular cheat interface is already available? Because:

* It provides an authentic experience
* It enables cheats when using frontends that don’t support the regular cheat interface
* All the code was already in place, and it was easy to enable 🙂

In addition, during the process of implementing this, the core’s OSD messaging code was overhauled and cleaned up. OSD warnings will be displayed when appropriate if the Game Genie ROM file is missing, and also if the FDS bios is missing. OSD message durations have been shortened a little, and the core makes use of the extended messaging interface when available.

Color palette switching

At present it is difficult to compare the core’s Color Palette options, because these can only be set via the quick menu. 1.9.12 adds the ability to switch to the next/previous colour palette by holding RetroPad L2 and pressing D-Pad Left/Right while content is running.

Memory leaks fixed

Numerous memory leaks have been fixed while going over this core. This should benefit in particular all the statically linked platforms, such as game consoles.

Project IO – SameBoy improvements

1.9.12 makes the following changes to the core:

Direct file access has been replaced with VFS routines (libretro build only) (Cores with straight stdio file I/O RetroArch#12949)

The core now sets need_fullpath = false, such that content is loaded from the frontend-supplied memory buffer. (Cores that should be turned into need_fullpath = false)

Since the core no longer receives a content path, automatic ROM type detection cannot be based on file extension (.gb, .gbc). We now therefore inspect the ROM header, which means we can also distinguish SGB-enhanced content. As a result, the System – Emulated Model core option has been modified such that the Auto settings are:

Auto Detect DMG/CGB (default): Emulated hardware will be set to either Game Boy or Game Boy Color depending upon the ROM.
Auto Detect DMG/SGB/CGB: Emulated hardware will be set to either Game Boy, Super Game Boy or Game Boy Color depending upon the ROM.
A new Auto Detected SGB Model has also been added, to enable selection of which type of SGB hardware to emulate when content is detected as being SGB-enhanced.

Since it was necessary to edit the core options anyway, these have been updated to v2 and option categories have been added.
Note that all changes here (apart from two .gitignore additions) are limited to the libretro directory – no ’emulator’ code has been modified.

Fixes issue #58 – ‘Better Auto System Model Support #58’
Fixes issue #52 (since the core no longer loads ROMs directly) – ‘Can’t load ROM files with special characters in filename’

PCSX ReARMed – Improvements

Lots of improvements have been made to PCSX ReARMEd courtesy of gameblabla –

  • Literals are deduplicated, so there’s no guarantee they will be stored next to each other, even if they’re written sequentially. verify_dirty and get_bounds must use the offsets on each instruction, instead of assuming values are stored sequentially. According to neonloop, this fixes a dynarec crash in FF7 on ARMv5 platforms like the F1C200S as used in the TrimUi handheld. Given that the old3DS is ARMv6, it may also possibly fix some crashes there as well.
  • GTE stalls/timings – This is to fix an issue with Battle Arena Toshinden 1 and Zero Divide going too fast. To test the GTE fix with Battle Arena Toshinden : Boot the game and go to “Vs.computer” at the titlescreen. Then, choose any character except rungo and select Rungo for the computer.
    Before, the game would go too fast. Now, it will run at the correct speed. (well very close, PCSX rearmed’s clock counting is still kinda finicky). The fix in question was inspired by a similar fix from PCSX-Revolution. Might also fix NBA Jam Extreme.
  • Fix for Armored Core misdetecting a Link cable being detected -fFor some reason, the game would detect that a link cable is plugged in and disables the local multiplayer as a result.
  • Various CDROM fixes from Swanstation and Mednafen. These fixes aim to address the inaccuracies of some CDROM commands and make it on par with nocash’s doc and mednafen. So far, it mostly fixes some delay issues in the Simple 1500 sound novel game as well as F1 2000 (which is notoriously time sensitive).
  • Merge several fixes from PCSX Redux and adjust delay for SetLocPending. There’s a game, PoPoLoCrois Monogatari II, that unfortunately locks up during the intro screen.
    I should have known that code was wrong as Mednafen did not have anything like that in their code either, hence the confusion.Their fix however still don’t include the Driver fix so the game would still crash if we don’t have the “+ Seektime”.
    To be honest, i’m not sure why the PCSX Reloaded team did it this way…
    In any case, i adjusted it so it doesn’t mess up the audio for Driver’s titlescreen and doesn’t crash in Worms Pinball either.
    Seems like setting it to 100000 was not enough for that game.

    I noticed the fastword and FastBackward were not being used in any way.
    Looked at Mednafen and all they do is just adjust the cursector
    and make sure that fastword & backword trigger the AUTO_REPORT code so i did the latter.

  • CDROM: Rename Reset+Init commands, fix “This is Football 2” lockup
  • CDROM: Ignore sectors with channel number 255 – This was tested on “Blue’s Clues : Blue’s Big Musical” and it fixed the missing audio there.
    Taxi 2 is also said to be affected by this.
  • ICache emulation (Interpreter) from PCSX redux. Known games to be affected by the lack of or improper ICache emulation : Formula F1 99, Formula F1 2000 (EA), Formula One Champion Season 2000
    Formula One Arcade, Formula F1 2001 (Confirmed to be fixed), Buster Bros. Collection, ISS Pro 98
  • Dare to set MDEC_BIAS to 10 – This based on an original fix by dmitrysmagin in PCSX4ALL. “This fixes graphic artifacts during cinematics in Vandal Hearts and R-Types, other games seem to be unaffected. (?)”
  • GTE: Fix gteH division and sign extension (from PCSX4ALL) – Original comment by senquack :
    “gteH register is u16, not s16. DIVIDE macro/func assumed it was
    s16 for some reason. Behavior now matches Mednafen.” I also put in there the “GTE_USE_NATIVE_DIVIDE” stuff but currently unless manually enabled, it’s not used.
    You may wish to use this on some low end platforms but that’s up to you.
  • [SPU] Emulate SPUSTAT[5:0] as a mirror of SPUCNT[5:0] – I have tested the fix against Loonies 8192 (a PSn00bSDK made homebrew game) and it no longer locks up during loading. This affects all games and demos that uses PSn00bSDK. (I’ve been told it’s unlikely this will affect games that uses the official SDK)
  • Implement fix from Mednafen for Fantastic Pinball Kyuutenkai – this also fixes ‘Multi Track games crash on .CHD’.
  • CDROM timing changes – fixes Crash Team Racing’s intro music cutting off too soon – FF8 Lunar Cry FMV freeze (Disc 3) – Worms Pinball not booting – Xenogears (Deus fight)
  • Fix CD Volume issue in Star Wars Dark Forces – CD Volume is 16-bits signed, not unsigned.
    Otherwise in Star Wars – Dark Forces : if you lower the music volume slider all the way down, the volume will wrap around and instead be set at the highest volume.

Ozone – new color themes

Solarized Light theme for Ozone menu driver
Solarized Light theme for Ozone menu driver
Solarized Light theme for Ozone menu driver
Solarized Light theme for Ozone menu driver
Solarized Dark theme - Ozone
Solarized Dark theme – Ozone

Two new color themes got added – Solarized Light and Solarized Dark.

Libretro additions – Enable SRAM for contentless cores

Before, the saving/loading of SRAM data is disabled for contentless cores – which means that cores such as 2048 have to handle save data internally instead of utilising frontend-provided functionality.

1.9.12 simply disables this artificial and unnecessary restriction.

Changelog

1.9.12

  • 3DS: Ensure parallax barrier is disabled when ‘3DS Display Mode’ is ‘2D’
  • COMMAND: Command interface should work again
  • INPUT/HID: Rewrote the HID deregistration algorithm; it should no longer cause issues when dealing with multiple pads of the same HID/VID combo
  • INPUT/HID: Fix initialization bug that caused wiimotes to fail to register without an accessory attached
  • INPUT/HID: Fix Wiimote regression
  • INPUT/HID/MAC: Get Sony Sixaxis (DualShock 3) working on MacOS
  • INPUT/UDEV: Add extra abs check for dolphinbar
  • INPUT/UDEV: Add relative left mouse button when pointer device is not abs
  • INPUT/WAYLAND: Fix keyboard input on Wayland – fixes ‘Certain cores ignore user input’
  • NETPLAY: Improvements from Cthulhu
  • OPENDINGUX: Fix HAS_ANALOG/HAS_MENU_TOGGLE defines in sdl_dingux joypad driver
  • LIBRETRO: Enable SRAM for contentless cores
  • LIBRETRO: Add environment callback to get the rate retro_run is called – GET_THROTTLE_STATE and RETRO_THROTTLE_UNBLOCKED environment callback
  • LINUX: Update metadata manifest
  • MENU/OZONE: New themes – Solarized Light, Solarized Dark
  • WINDOWS/WIN9X: Fix non-ASCII text display in window title