It's been a hectic past few months for the project. In addition to the upcoming release on Steam, a lot of focus has gone into other major features. While not everything has landed yet, two very important changes to Android did arrive, one of which has been in the works for a couple years!
We're talking about a large scale rewrite to Dolphin's Android Input Handling that will eventually allow it to match the feature set users on Desktop Dolphin builds enjoy. Android users also get another major quality of life upgrade - Dolphin is now a Document Provider on Android. This means you can use Dolphin to directly copy files into and out of its per-app directory on the latest versions of Android.
In this report, we'll be going through both of these and several other important changes. Enjoy!
Over ten years ago, back in the ancient time known as "late 2012", Sonicadvance1 started development on a new Dolphin JIT that could run on ARM processors. Back then it was an incredibly bold move - there were no ARM devices that even had a prayer of running Dolphin close to full speed. It was a forward thinking project that took on many incredibly difficult hurdles.
While today the ARM JIT is mostly used on Android phones, the early ARM JIT development was done on development boards and Chromebooks running Linux. Phones simply didn't have the features/speed to even hope to run Dolphin at that point. However, once phones began to appear with the bare minimum featureset required to run Dolphin, Sonicadvance1 began work on porting Dolphin to Android using the new ARM JIT. And thus, a new challenge appeared for Sonicadvance1 - Android itself.
One of the biggest annoyances with Dolphin on Android comes from Android's interfaces being written in Java versus Dolphin's being written in C++. In order to bridge these two languages together, we have to use JNI (Java Native Interface). In order to go the path of least resistance and get things working, Sonicadvance1 decided to just make a quick reimplementation in Java. It was less code overall at the time and meant things could be working more easily. Less time spent working on input meant more time working on the fun parts.
However, the quick implementation that Sonicadvance1 threw together just... remained, with feature after feature bolted onto it over a decade. This is how Dolphin's Android's Input fell into such a problematic state. Plus, it was separate from Dolphin's C++ input implementations, so any improvements had to be manually ported over. Most of the time the latest input features simply wouldn't come to Dolphin Android.
To rectify this situation, Android's entire Input system had to be ripped out and started anew.
Android Controller Support Reborn¶
For the past couple of years, users have been desperately asking for improvements to Dolphin's Touch Controls and Android Controller Support. We've continually turned them away, promising that work was being done on it. While it was possible to hack improvements into the Java implementation, it would have been a temporary band-aid fix. These fixes would then have to be thrown out if a proper fix was ever to come into fruition, which we knew was coming.
Behind the scenes, JosJuice has been slowly removing all of the Java reimplementations of C++ parts of Dolphin on Android and moving them over to JNI. While there were multiple parts of Dolphin reimplemented in Java, input handling was one of the biggest and most convoluted. It proved to be a much more difficult task than the other sections.
Part of the problem is that input handling in Dolphin is complicated. We have to give users options to deal with motion controls, infrared, controller orientation, swapping attachments, swapping controllers, and more. Depending on what kind of controller you have, you might need entirely different features to play through a game. Worse yet, you might need entirely different settings to play two different games.
The project to port the handling over to JNI so we can use the C++ implementation directly has been a multiyear endeavor. And while the initial work has been merged, not everything is fully complete yet. JosJuice had to move out some parts of it in order to keep the pull request reviewable and to avoid regressions that haven't been hammered out quite yet. Still, the JNI port of Dolphin's input handling already has a ton of long requested features!
- You can change controller settings while emulation is running.
- You can save and load input profiles. (The old feature of per-game mappings is replaced by per-game input profiles.)
- Advanced input expressions.
- You can map your device's accelerometer and gyroscope to whatever you want, not just Wii Remote motions.
- Support for many new device sensors. (How about the ambient light level, or the hinge angle of a foldable phone?)
- If a device or gamepad has multiple motors, you can now choose between them for rumble. (Requires Android 12 or later.)
- You can set many boolean and numeric controller settings that weren't available on Android before, like Relative Input.
- The Sideways Wii Remote setting, the numeric settings for Wii Remote pointing, and the setting for disabling accelerometer/gyroscope pointing have been moved from the in-emulation settings to the regular settings.
- The touchscreen controller type setting has been overhauled. Users can now choose between all controllers 1-4, but selecting a Wii Remote extension is now done in the regular settings.
- Separate gamepads are never treated as a single gamepad anymore.
- Dolphin no longer mixes up buttons and axes that have the same ID.
- Possibly fixes for various issues with detecting axes.
Because Android now uses the same input core as desktop builds, this will allow newer input features to hit Android builds at a more consistent rate. This does come with one caveat - all configurations for the old Android Input will no longer work on new builds, meaning users will have to reconfigure controllers under the new system.
With Scoped Storage and the per-app directories in modern versions of Android, modifying Dolphin's user contents has gotten a lot harder. The days of just having a typical "User Directory" in an easy-to-access place on Android are gone. We're stuck using gated per-app directories that only Dolphin can access. The problem with that, is that if you want to modify those files to add a Texture Pack or Riivolution mod, you more or less have to use a computer or something that bypasses Android's restrictions altogether!
In an effort to mitigate these problems, JosJuice added the ability for users to import/export the entire user directory via zip files. Unfortunately, it seems many Android distributions use non-standard zip formats that our basic implementation couldn't handle for unknown reasons. A better long-term solution was needed.
Thankfully, other emulators have run into the same issues as us and have come up with some rather robust solutions. K0bin implemented Document Provider Support to allow file managers with that feature to access Dolphin's per-app directories!
5.0-19234 added some further improvements, as well as a distinction between "debug" and "release" builds in order to reduce confusion when handling user directories.
A common complaint with using Real Wii Remotes for Emulated controllers is that if the Wii Remote were to suddenly disconnect from Dolphin, sometimes the entire emulator would go down with it! Because the problem wasn't especially consistent, tracking it down was annoying until Dentomologist came up with a fairly consistent method of triggering the crash.
Once reproducing the crash was sorted out, they found a potential deadlock with device population while debugging it. By putting safeguards to prevent this deadlock, Dentomologist fixed the crash and now disconnecting Wii Remotes should be quite a bit safer.
Not all big changes are supposed to have an immediate impact. Kill Renderer is something, that if implemented correctly, should cause nothing to change for the time being. It's just a step toward some more important changes down the line, and the reason that it is necessary requires us to dive into Dolphin's history and learn a bit about this mysterious "renderer".
Renderer exists because Dolphin was originally a plugin based emulator, much akin to the Nintendo 64 emulators being developed during that era, and Renderer was the abstraction interface for those plugins. Though Dolphin moved away from plugins fairly quickly, Renderer managed to stick around, consuming work that really should have been elsewhere in the emulator.
This design philosophy did have some limitations, but for the most part it stayed out of the way. At least, until phire began working on a feature called asynchrounous presentation. Right now, all logic in Dolphin's output (including various GUI element like ImGui) are based on the framerate of the game. This is what causes Dolphin's overlays to look "choppy" in low FPS games (like in True Crime: New York City) and causes them to completely freeze during periods when a game stops outputting frames (such as during static loading screen or fadeout). Asynchorous presentation would allow us to decouple our output from the game's framerate, correcting all of those issues and paving the way for future goals.
One of those goals is to improve our framepacing. Outside of the very specific circumstance where your display happens to closely match the game's framerate, our framepacing is horrendous. While Freesync/Gsync monitors can mostly mitigate this, most monitors aren't happy with the locked 29.97, 50, or 25 framerate of many supported games. We can't really do much about this when presentation is locked to the game's framerate, so asychronous presentation will be the foundation of our efforts to improve our framepacing.
Kill Renderer is not asynchronous presentation, but it is a major step in that direction. We're highlighting it here because it is a major change to Dolphin's core, and while it shouldn't have any userfacing changes, we've already found and fixed a couple of major (and minor) bugs caused by the change.
Understanding the audio packets was a bit complicated, so the emulated portal skipped over this feature initially, but given a little more time, deReeperJosh was able to figure out how it worked and borrowed some code from Dolphin's support for Wii Remote Speaker output in order to make it play over the user's speakers.
Speaking of figurine portals, the Portal of Power wasn't the only USB portal on the Wii. And with deReeperJosh already kneedeep in USB portal work, they set their sights on another "portal" accessory for Wii. This time, it'd be the Disney Infinity Base. Disney Infinity was Disney's answer to the Toy Portal fad that hit during the 7th generation of consoles. By leveraging Disney's vast array of characters, settings, and overall brand, they set out to leverage that into a collectable figurine game.
Unlike Skylanders, which had an overall story and most figurines just inserted a new character or item, Disney Infinity uses "Playsets" that have campaigns around their various properties. You can then play through that campaign with character figures from that playset. Disney Infinity for Wii supports the original six playsets.
Probably the more interesting part of Disney Infinity is the Toybox. Here you can mix and match things you've unlocked from the campaigns to create your own levels.
Disney Infinity might be a unique game, but it's been one that's hard to justify emulating with Dolphin. Not only is this a more limited version of the game compared to other releases, this is the crown jewel of the Disney Trio of Destruction. It currently brings the most powerful machines to their knees, even more so than Cars 2. Worse yet, it's seen even less attention from developers because of the need to have external hardware and figurines to even boot into gameplay!
None of those things stopped deReeperJosh from diving in to reverse engineer the base. Fresh from their work in Skylanders, they put what they learned from the last one in action. In truth, the Infinity Base works roughly the same as the Skylander's Portal. A lot of what we explained last progress report stands. The figurines only contain a little bit of data on them, and all of the main content is already on the disc. Now, the Infinity figures (and discs) do contain a little bit more data than Skylanders figures, but the end result is the same. These are just little wireless NFC chips in these figures/discs, and the portal reads them to see what figure is on and the game loads the appropriate content off of the disc, maybe with high scores or mini-game progress with the particular figure's game saved back onto it in some cases.
deReeperJosh just had to reverse engineer the communication between the base and the Wii and leverage the same GUI used for the Portal of Power. It ended up being a fairly painless process overall, and now you can emulate the Infinity Base in Dolphin! ...That doesn't make Disney Infinity particularly playable due to performance issues, but is one more step in the right direction.
Note: The GUI isn't quite finished on Dolphin Android yet, so the feature isn't available yet there. Not that it'd be too useful considering that Disney Infinity suffers from severe performance issues even on high-end desktops.
New Post Processing Shaders¶
While Dolphin may not be known for having the most robust Post Processing shader support, over the last couple of months a few interesting shaders were added that some users might find rather nice to use in specific cases.
Older consoles didn't output square pixels. The CRT displays they were designed for can produce an image with arbitrary horizontal scaling on the signal, so every console would have different pixel aspect ratios, even varying per title! Our modern displays don't work this way - they instead use a fixed pixel grid that can't cleanly reproduce these non-square pixels. The most common solutions to handling this in emulation has been the use of Nearest Neighbor and Bilinear Filtering. Both have their compromises.
Here it is in practice in a pixel art title you may be familiar with.
But one day, someone had an idea: why not both? Sharp Bilinear is a combination of both Nearest Neighbor and Bilinear filtering that attempts a best-of-both-worlds result by using the strengths of both filtering techniques.
Sharp Bilinear is made for 2D graphics and specifically pixel art. But nothing says you can't apply it to 3D graphics as well!
Another Post Processing Shader that's been a part of Dolphin's history just won't die. That's right, we have the glorious return of the legendary ASCII Art Shader from the ashes of removal. And who would go through the effort to fix it up for modern Dolphin? Well, none other than it's original creator and long-time Dolphin contributor degasus! While they're not as active around the project, they couldn't stand to let such an injustice stand and returned to active development to right this incredible wrong. 5.0-19109 marks the return of the ASCII Art Shader!
This isn't just a straight port of the original - degasus has optimized the shader to run on modern graphics cards that support subgrouping. If you have a supported GPU, the shader is now actually somewhat performant! 8k and 60fps is now possible! (on an RTX 4090)
With this change, it is likely that degasus will return to slumber, at least until the next time we try to remove the ASCII Art Shader.
A Sixth Bounding Box Game!¶
This is a momentous occasion for us all. After the discovery of Ultimate Spider-Man's usage of bounding box, we thought that it was going to be the feature's last dance. Yet, somehow someway, despite the GameCube and Wii no longer seeing retail games, bounding box has found a way.
Solitaire and Mahjong joins the ranks of known bounding box titles after remaining anonymous for many years. It was just obscure enough that it escaped our issue tracker... at least for a time. But eventually, no matter how weird, how unassuming, or how obscure the game is, someone tests it. And if there is an issue, we can only hope that they report it to us.
The user in question didn't know that it was a bounding box issue, but by bringing up this game's broken nature to developers, we were finally able to take a look and see why it wasn't working. At first, pokechu22 thought that the issue may be XFB related, and JMC47 wondered if NAND issues were causing the save files to be hard to click.
But nope, it turned out that the menus were powered by bounding box. A helpful log message kindly pointed this out at boot, but went unnoticed through early testing.
E[Video]: BBox shall be used but it is disabled. Please use a gameini to enable it for this game.
This game being broken for all of these years was simply due to the default setting of bounding box being set to disabled.
Users also reported a "performance" regression with this game, but thankfully that turned out to be a false positive. Essentially, we changed the default values given to a game when Bounding Box was disabled, which caused the game's behavior to change. While 5.0-14326 did cause a severe performance regression in this game, turning on bounding box to cause the correct values to be sent fixes it completely. This bisect should have pointed us to this game having a Bounding Box issue, but no one realized it at the time. After all, there were only five Bounding Box titles, and this wasn't one of them! Oops.
Solitaire and Mahjong now joins Paper Mario: The Thousand Year Door, Super Paper Mario, Magical Mirror Starring Mickey Mouse, Disney's Hide and Sneak, and the aforementioned Ultimate Spider-Man as our bounding box titles.
To prevent yet another game from sneaking through, pokechu22 added "bounding box reads" to Dolphin's Usage Statistics. If any users run into this in the future while having Usage Statistics enabled, we'll know about it.