The past two months have been quite busy with a lot of features and fixes spread out between a lot of contributors, new and old. It's only fitting then that we've seen some important fixes for ancient bugs and new ideas bringing in new features. Even if the game you've been playing is already running fine, developers are hard at work coming up with ways to make things even better. Take for instance a new infrastructure that allows Custom Texture Packs to customize what controls show up in games depending on how you've configured your controller in realtime! Also, getting that perfect angle is a bit easier with the new "virtual notches" system, perfect for difficult platforming challenges in games like Super Mario Sunshine!
Enough teasing, we've made you wait long enough. It's time for the October and November Progress Report!
5.0-12722 - Externals: Update MoltenVK to v1.1 by Stenzek and 5.0-12934 Re-enable GPU Texture Decoding under MoltenVK by Techjar¶
To start off with something relatively simple, this group of pull requests that are of great benefit to our macOS users. Using Dolphin on macOS can be a bit problematic, thanks to the operating system only giving us access to an ancient version of OpenGL and no native support for Vulkan. While we've been taking advantage of a Vulkan to Metal wrapper, MoltenVK, things haven't been perfect. Some settings, including GPU Texture Decoding, weren't working under MoltenVK and had to be disabled. Also, performance wasn't quite as good as native Vulkan on other operating systems.
We have some good news, MoltenVK has been updated to v1.1! On top of various improvements and apparent performance increases, the issues we had with GPU Texture Decoding are now resolved. With this, we've reenabled GPU Texture Decoding on macOS. This is great news for older macs, as GPU Texture Decoding offloads some work from the CPU onto the GPU and can help systems with weak CPU performance.
Note: When using GPU Texture Decoding, Arbitrary Mipmap detection does not function, so certain games that use mipmap effects may malfunction.
Custom Textures have proven to be one of Dolphin's most powerful enhancements. Ever since its introduction in 2009, users have been painstakingly going through some of their favorite games and recreating textures at a higher resolution to stunning effect. These packs allow fans to replay their favorite games like never before, with textures that may rival professional remasters! With hundreds of packs now available, the popularity of this feature is only surpassed by essentials like higher internal resolution. However, there has always been a pretty big limitation with custom texture loading - it has no idea what controller you are using. Many of our bigger packs include custom textures for different types of controllers so the button prompts the game shows will match what is in your hands, however since Dolphin doesn't understand any of this, it's up to the user to manually pick and install the textures for their controller. This leads to an increase in instruction and installation complexity, increasing the difficulty of the pack for creators and users alike.
Enter iwubcode's brainchild: Dynamic Input Textures. By marrying pieces of Dolphin's custom texture support and controller configuration, texture packs can now be aware of what control is mapped to what button and dynamically change what is displayed on screen!
With this feature, when using supported packs users will no longer need to worry about swapping out controller images. When everything is working correctly, users installing texture packs with this feature will only need to copy some files into the Load directory, and that's it! Dolphin is aware of what button you've mapped to what input and can dynamically pull textures from the texture pack in order to match things up so long as it's configured correctly. You can even swap individual buttons and watch them change in real time!
Since this is a feature for texture pack creators, users just need to wait for texture pack creators to update their packs to support it. In fact, you can move on to the next section if you'd like. But if you are a texture pack creator, a power user wanting to add support to an older pack for personal use, or just interested in the process, read on. It's time to talk about this feature in depth.
Creating a Dynamic Input Texture Pack¶
Technically you can create Dynamic Input Textures entirely on your own, but to make the process simpler iwubcode has provided a companion tool to help create these dynamic textures packs. They also made a tutorial that explains how to use it. But here is a quick summary for the sake of demonstrating how it works. First, provide the tool with the original game button textures to get the hash of each button texture into the application. Then map the emulated controller buttons to those button textures so the application knows which button each texture is, for example, mapping the Wii Remote A button texture to "Wii Remote 1, Buttons/A". Now import the custom textures for the host controller, and configure the buttons with their Xinput or Dinput buttons. For example, for the texture of the A button on the Xbox One controller, the device is XInput/0/Gamepad and the input is 'Button A' (including ticks). Repeat for any additional host controllers, then export the pack, and we're done! Now, to reiterate, this was only a summary and it absolutely simplified the process. For the full instructions, please use iwubcode's tutorial.
Now, that said, there are a lot of limitations to this feature, especially for the time being. Keep these notes in mind if you intend to use this feature in your pack.
- Texture pack creators must configure the controllers their pack supports and release a new version of the pack. Existing custom texture packs will continue to work exactly as they always have, and for compatibility reasons this is not going to change.
- The accompanying tool is in a bit of a beta state. It, and the tutorial, are improving rapidly, but as of this writing there are some bugs, quirks, and UX problems.
- The devices that the texture pack creator sets up need to match exactly with the one the user is using, otherwise it will not work. For Xinput devices like the Xbox One controller, this is trivial. Everyone supports XInput/0/Gamepad. But for devices like Playstation controllers which have many different ways of mapping, how the texture pack creator decides to map that controller will matter a lot. Please be explicit in explaining what controllers and drivers are supported in your instructions to users.
- There are some built in controller and button names to speed up common mappings. This is limited to Wii Remote, Classic Controller, and Xbox controller for now. More will be added later. Also, joysticks and motion controls are missing from this for now, and have to be entered manually.
- Controller configurations that work by pretending to be another controller will not function correctly with Dynamic Input Textures. This disqualifies all the Playstation controller mapping tools that make the Playstation controller pretend to be an Xbox controller. There's nothing we can do about this.
- Games that use color-key transparency do not cooperate with this feature. This is a known issue and a fix is planned.
- If an emulated controller input has two different textures, such two different styles of the same button, then Dolphin will pick one and always use that one for all instances of that mapping. You can see this in the gif above: the B/Circle button should be in the style of the X/Square button, but instead it is an angled style used for the main menu. The companion tool has no way to handle this at this time, but we hope to address this in the future.
- "Blank" input textures, such as a texture showing an analog stick with no inputs, are currently not supported. With a little creativity this can be worked around, such as mapping it to an analog stick direction so Dolphin knows which texture to use. This should improve in the future.
- Dynamic Input Textures can support support advanced expressions (such as "and", "or", and others) if mapped 1:1 with Dolphin, but there is no way to show it in textures. This may change later.
- Mapping bits of group textures is supported on the emulated controller side, but not on the host controller side. This is a planned feature.
- Exported results for Dolphin cannot be edited by the application. Remember to save your dynamic input projects! And since saves are also JSON files, be sure to keep them separate.
- When reopening saved dynamic input projects, the textures they expect must be in the same spot they were when it was saved. Currently, if they are missing the application will crash. That should not remain an issue for long.
While that was a lot of notes, Dynamic Input Textures has a lot of potential benefits for texture pack creators. It can offer a drag and drop experience for users, allowing pack creators to get away with FAR simpler installation instructions. And that also means support should be easier too! Plus pack creators can get much more creative with input support in their packs without worrying about ballooning complexity for users. It's a really great option for texture pack creators going forward.
It is with great sadness and regret that we announce that our beloved asciiart post processing shader has been removed from Dolphin. While we have removed many popular features in the past, such as the D3D9 backend and 32-bit support, this one by far hurt the most.
... Okay, maybe it wasn't our most popular feature, in part because of its ludicrous performance demands that made even 1x native at fullspeed impossible for... forever. And yes, it has been completely broken since the Unification of Videocommon nearly two years ago. And sure, post processing injectors like Reshade can do a similar (though much simpler) effect while being actually performant.
But still, it was a feature we loved. It was quirky, ridiculous, and pretty useless, but it was ours, and we are sad to see it go. Goodbye asciiart!
However! As a final farewell we tried it with 2020 hardware and discovered, with much surprise, that modern hardware has finally caught up to the asciiart shader! Fullspeed at 1x Native was finally possible in almost every game! It only took a 9900k and an overclocked RTX 3090.
Click HERE for a sampling of how demanding 1x Native asciiart at fullspeed is on a 3090!
Many many years ago, Dolphin's slowly improving IOS emulation mixed with Wii online infrastructure shutting down resulted in a very frustrating regression that would stop would be dancers in their tracks. The video game series, Just Dance suddenly started freezing in the main menu in most of their online enabled games. And we're not talking about one game, we're talking about over a dozen that were releasing up until last year!
These games did work in the past, however this isn't actually a Dolphin regression. Instead, the games themselves changed because the servers they were connecting to no longer exist! While this didn't result in any major problems on the Wii, Dolphin's implementation of the network modules assumed that socket operations would always complete before a socket is shut down. Since Dolphin was waiting for a reply from the Ubisoft servers and not aborting the pending operations, the game, too, was waiting for a reply that never came. The only way users could work around it was disconnecting their computer from the internet or gutting their NAND of the certificates needed to access online play.
Sepalani is no newcomer to the Wii's network services and has been steadily improving things for quite a while. This one has been quite the labor, with hardware tests made and tested across Windows, Linux, macOS and Android to make sure the behavior matched what the games expected regardless of operating system. He discovered there was missing or broken functionality on Android and macOS and has brought forth fixes so that they can pass the hardware tests as well.
The end result is better online behaviors all around and no more hanging in the Just Dance games.
The Nintendo GameCube controller is broadly speaking very close to any typical modern gamepad. Two joysticks, four face buttons on the right, triggers, dpad, etc etc. However, the GameCube controller has many unique features that most gamepads do not have. These differences can make it surprisingly hard to recreate the intended control experience on modern controllers. As developers and a community of users, we've learned to adapt to these quirks. Dolphin has many features designed to recreate these features as best as we can, and even physical differences like the face buttons can be accounted for with a little creativity. However, there was a commonly overlooked unique feature of the GameCube controller that we had no way to recreate; a feature that noticeably impacts the play experience in the majority of the GameCube's catalog. The GameCube Controller has octagonal gates.
A joystick gate is the border that limits the maximum tilt of the joystick. To put it simply, when you tilt the controller all the way and you hit that rim of plastic, you just hit the gate. Most modern controllers use perfectly circular gates, but Nintendo stuck with octagonal gates for a very long time, well after everyone else had moved onto circular gates. Because, quite frankly, octagonal gates are fantastic for 3D platformers. By having "notches" in the gate that lock the joystick into a specific angle, the player intuitively knows the exact input they are giving the game. This allows for some incredibly precise and high level play, as we've seen in speedrunning. Super Mario 64's crazy speedrun techinques are tremendously easier when using a controller with octagonal gates, as the speedrunner can go to a spot, manipulate the controller a certain way, and consistently land at the same spot, even when passing through multiple universes! However, octagonal gates can be considered annoying for games that don't need such precise movement, as they make continuous rotation less fluid. So when the 3D platforming genre slipped into the background, Nintendo finally moved to circular gates with the Wii U.
Nevertheless, the majority of the GameCube catalog benefits from the octagonal gates that they were designed for. But anyone playing these games with modern controllers will be missing that element of the experience. nick-michael was playing the GameCube version of Super Monkey Ball, and just didn't feel right on a controller without an octagonal gate. So they decided that they were going to fix this discrepancy - through emulation! nick-michael created a "virtual notch" system that emulates the effect of an octagonal gate on modern circular gate controllers by snapping some of the joystick's range to octagonal directions. It doesn't emulate the feel of an octagonal gate, so the player won't intuitively feel their input the way an octagonal gate allows, but it emulates the results of the gate shape. If you need to do a really precise set of jumps in a platformer, you can be more or less correct and the notch emulation will send the perfect inputs that you would have been gotten by pressing those almost correct directions into a GameCube Controller.
This can be customized as well, allowing for very tiny precise "notches" or really big ones that dominate the controller directions. And of course, it's all disabled by default, so you can completely ignore it if you prefer.
This isn't technically an emulation bug, but rather an unfortunate confluence of console and game behaviors in an era when the Wii Shop is no longer around to install DLC. Once we knew what was wrong it was easy to fix, but actually getting to that point was the actual difficulty.
The original issue report we were working from was simple: Mega Man 9's DLC worked in Dolphin 5.0 but at some point stopped installing correctly in the latest development builds. We believed it was an issue during the installation process as if you took the NAND you created from Dolphin 5.0 and used it in the latest development builds, the DLC would appear as per normal. A simple bisect would usually solve an issue like this, but various testers had inconsistent results where the DLC would suddenly start working, even on the latest development builds! Worse yet, we didn't know exactly why it would start working, sometimes simply running other games would be enough to jolt the DLC into working.
Eventually, AdmiralCurtiss narrowed down the behavior difference to 5.0-7422. Upon looking into it, there was one notable difference - the creation of the Wii Shop log files. Leoetlino figured we wouldn't need to create those files as the games should create them on their own regardless of if the DLC were downloaded from the Wii Shop or manually installed. However, it turns out we were proven incorrect by Mega Man 9 and likely other titles. The reason why some of us couldn't reproduce the issue is that once you access the Wii Shop Channel, the issue will completely disappear for that NAND permanently.
The reason that some of us couldn't reproduce the issue is that other games, DLC, and channels could create those files along the way and effectively fix the situation. In order to prevent this from happening again, we now ensure that the Wii Shop log files are created when installing a wad file.
This has been a requested feature by users with weaker computers for a very long time, but it was a niche use case so we resisted adding it. However, after years of hotkey improvements adding and using hotkeys has been refined so much that we're at the point where we can go "why not?". Losuc's addition of a hotkey for EFB Access from CPU can be very useful in games that only need it enabled for specific actions or scenes. Take for example Super Mario Galaxy where EFB Access is used a lot but only required for things like Pull Stars and feeding starbits. By only enabling the feature when necessary, you can make the game run on lower hardware than otherwise possible. The same goes for Wind Waker where EFB Access is only needed for the Pictobox.
To be completely honest with our readers, we really wanted to get this one merged before the end of the last progress report when Nintendo's very own emulator in Super Mario 3D All Stars was discovered to share the same bug. After all, we had the fix and knew it would make for some good screenshots. But alas, unfortunate hindrances like code review and testing got in the way of our devious plan. This particular fix has actually been in the pipeline for a long time, but got delayed and unfortunately forgotten.
For anyone who isn't familiar, during development Super Mario Sunshine had dots for traveling platforms indicating their travel, just like Super Mario 64. However, in the final game the dots were removed. Kind of. The dots are technically still present in the released game, however Sunshine makes them completely transparent. Unfortunately for anyone making a GameCube emulator, the way Sunshine accomplished this is a bit out of the ordinary.
This has been such a mysterious issue that there have been multiple working theories over the years. Everything from caching the color drawn from the previous pixel, and even wondering if the debug cubes showed up because Dolphin was reporting itself as a debug console!
So what is actually going on here? Well, this is actually related to the Cel Damage fix from a few years ago. In fact, the pull request that fixed Cel Damage is where this Sunshine fix originally came from! In Sunshine, the game is setting numColorChans (the number of color channels) to 0 for the debug cubes. However, the debug cubes have a full color index with colors that are in use. The question is clear: why is the game setting the cubes color channels to 0? Well, according to hardware testing, if numColorChans is a value lower than what is present in the color index, it will use whatever was left in the register. This is undefined behavior. A hack, to put it more bluntly. It is our best guess that they did this peculiar trick to make the debug cubes disappear late in development without editing anything that would force builds to go through QA again, but we have no way to know for sure.
Dolphin, and likely Nintendo's emulator in Super Mario 3D Allstars, made the logical assumption that if a game set numColorChans to 0, it wasn't using the lighting system for that object. But by skipping that step, we were actually skipping the very process that made the cubes invisible!
While we're not sure how Nintendo fixed the cubes on their end, our fix is quite simple. numColorChans is a register on console, so the game is relying on undefined register behavior. Registers are more or less as low level as you can get in a processor, and properly emulating bizarre register quirks would be huge performance hit. So we've hardware tested this particular case and figured out what values the console gave us, and by slipping in those values when we need it, we were able to recreate the correct behavior in Super Mario Sunshine. Maybe one day we can afford to fully emulate the registers to the degree that quirks like this will just work, but this was the best solution for now. And since it's based on hardware testing it has been very safe in our game tests.
Sadly, Nintendo managed to patch the debug cubes a few days before we did. But that's ok. As their GameCube emulator has a catalog of effectively one game, they didn't have to worry about regression testing the way we have to. It's fine, we're not mad. It wasn't fair so it doesn't count.
As a special note, this is actually our second merged fix for the debug cubes. However, severe regressions from the first attempt prompted its removal and forced the hardware tests that eventually lead to this fix. But, for fun, here's a quick reminder as to how a fix for one game can break another if you're not doing things right with Tony Hawk's Pro Skater 3.
Dolphin has had a bit of a long standing problem with the graphics configuration window. It's too damn tall. As we've added many more advanced graphical settings, the advanced tab has grown immensely. And since every tab needs to be as tall as the tallest tab (by default), everyone gets to deal with a lovely 922 pixels tall window. Admittedly, for anyone with massive resolution modern displays this doesn't even matter. But we have definitely heard the complaints of those with 768p and 720p screens. As such, to make sure everyone can see everything in the graphics configuration, resizing was added to the graphics configuration window. No matter how tiny your screen, you will be able to use and configure Dolphin... just with a bit of extra scrolling.
This is fine. It's fiiine. But it just keeps bugging us. We may have solved the usability problem, but the window is still enormous, and as new features get added in the future, will it stay fine? It isn't that far from requiring scrolling on even 1080p screens. So as we pondered this quandry, our eyes turned to the venerable description box.
The description area has been very important for us as an emulator. Dolphin has a lot of weird graphical emulation quirks and options to work around them, and we desperately need a reliable way to educate users about what these options do and why they may or may not want to use them. So, whenever a user moves their mouse over a graphical feature, a description explaining that feature will appear in the description box. It's simple, and has worked wonders for us for a lot of years now. However, some of those descriptions are (necessarily) long winded. The description area is now a huge 200 pixels of vertical height. This is contributing a lot to our window height problem!
Still though, mousing over something for more information... isn't that usually done by a tooltip? Why are we devoting so many pixels of height for something that typically would be handled with non-permanent means? That's because these descriptions used to be tooltips. And they were awful.
Dolphin 2.0 used the plain old Windows tooltip. Designed for small optional tidbits, it was entirely inadequate for our purpose of educating users about complex emulation features. Also, from a modern UI design perspective, they were just bad.
- They took a full second to appear, limiting accidental discovery.
- Faded in over a half second, then faded out over another half second. That plus the long activation time made for a slow and tedious way to get information.
- White boxes with black text over white boxes with black text made them difficult to notice and read.
- We tend to read top to bottom, and the tooltips placement below the cursor blocks the next item the user might want to read and annoyed them so they ignored and quickly dismissed the tooltip.
- Most items didn't have tooltips applied to them, so even if a user was looking for them they most likely would try, fail, and assume we didn't have any tooltips.
On and on. They were terrible, failing to adequately fulfill their purpose, so no one used them. Which just made the tooltip situation worse as developers had no reason to bother adding tooltips that no one would ever read! It was a problem, as Dolphin needed, desperately, to convey emulator-specific options to users and educate them. And so, we moved to an always visible description box model. By being literally an empty space that filled with text when a user hovered over a feature with their mouse, it is very obvious and very clear, allowing it to properly fulfill the role of conveying information to the user. The description area has played no small role in forming the knowledgeable user base that Dolphin has today.
But it still takes a lot of height, contributing greatly to the graphics config height problems. How do we fix this without losing the essential functionality that description box provides? iwubcode posed that question in Dolphin's IRC. MayImilae, our resident UI assistant, has had a long time to consider this issue. She responded with the results of years of UI pondering - the best option is to go back to tooltips, but make them good. She made a mockup demonstrating modern tooltip techniques in Dolphin, and iwubcode took on the challenge of implementing custom tooltips in Dolphin's UI. Qt limitations made it so not everything we wanted could be implemented, but iwubcode made a huge impact!
Let's go over everything that these tooltips do right compared to the ancient tooltips above.
- Appears quickly (300ms) allowing for easy accidental discovery without getting in the way.
- No fade in or fade out, allowing the user instant access to the information then gets out of the way. While this was a functional choice, it just feels better.
- High contrast allows the tooltip to stand out from the original window, making the tooltip easy to notice and the text extremely easy to read.
- The tooltip appears above the target, so it doesn't block the view of the next item the user may want to see when reading top to bottom.
- Points to the option it is referring to, further improving clarity.
- The "if you are unsure" text is contrasted even stronger with a unique color and bold font, easing at a glance guidance for casual users.
- Consistent across all desktop operating systems. Anyone who has worked with tooltips before knows just how nice that is.
By using these custom tooltips, designed for the purpose, Dolphin is able to effectively convey necessarily information to users while also freeing up the height of the description area! And thanks to the high contrast background, it's even more clear than the description area was as evident when showing them side by side! This is the have our cake and eat it too solution we've been wanting for years. Now, this is still a work in progress, and we hope to make further improvements over time. For example, it has uneven corners and complete lack of HiDPI support. Still, even where it is now it is a very good solution to our troubles. Plus, since these custom tooltips do not require adjusting the size of the window, hopefully we can finally bring descriptions to more places in our UI.
For our resident dark mode lovers, the tooltip is inverted there as well to maintain functionality. If you are annoyed by the white tooltip interrupting your black on black oasis, you can switch to a low contrast mode with an INI option.