SPDX standardizes how source code conveys its copyright and licensing
information. See https://spdx.github.io/spdx-spec/1-rationale/ . SPDX
tags are adopted in many large projects, including things like the Linux
kernel.
When I added the software FMA path in 2c38d64 and made us use
it when determinism is enabled, I was assuming that either the
performance impact of software FMA wouldn't be too large or CPUs
that were too old to have FMA instructions were too slow to run
Dolphin well anyway. This was wrong. To give an example, the
netplay performance went from 60 FPS to 30 FPS in one case.
This change makes netplay clients negotiate whether FMA should
be used. If all clients use an x64 CPU that supports FMA, or
AArch64, then FMA is enabled, and otherwise FMA is disabled.
In other words, we sacrifice accuracy if needed to avoid massive
slowdown, but not otherwise. When not using netplay, whether to
enable FMA is simply based on whether the host CPU supports it.
The only remaining case where the software FMA path gets used
under normal circumstances is when an input recording is created
on a CPU with FMA support and then played back on a CPU without.
This is not an especially common scenario (though it can happen),
and TASers are generally less picky about performance and more
picky about accuracy than other users anyway.
With this change, FMA desyncs are avoided between AArch64 and
modern x64 CPUs (unlike before 2c38d64), but we do get FMA
desyncs between AArch64 and old x64 CPUs (like before 2c38d64).
This desync can be avoided by adding a non-FMA path to JitArm64 as
an option, which I will wait with for another pull request so that
we can get the performance regression fixed as quickly as possible.
https://bugs.dolphin-emu.org/issues/12542
1. Comparing string_views does not behave the same as strncmp
in the case where SConfig's game ID is longer than 6 chars.
2. DTMHeader::GetGameID wasn't excluding null bytes for game IDs
shorter than 6 chars.
3. == was accidentally used instead of !=.
gameID isn't null terminated since it is just an std::array<char, 6>
and .data() returns a char* so {fmt} would go way beyond the bounds of
the array when it attempts to determine the length of the string.
The fix is to pass a std::string_view to {fmt}. This commit adds
a GetGameID() function that can also be used to simplify
string comparisons.
With the SI poll line count fixed, pretty much all games are polling
twice per frame anyways, making this option superfluous. Since it's a
bit of a gross hack and makes DTMs incompatible with console, let's
just bin it.
This fixes the desync on playback of start-from-boot input recordings
made while using the GC adapter, as well as other desyncs that could
potentially occur in other circumstances where this bit is used.
I used a previously reserved bit in the ControllerState to store the
new data, so this shouldn't significantly break backwards
compatibility. However, tools that aren't aware of this new bit may set
it to 0, which will break input recordings that contain it.
Normally, SI is polled at a rate defined by the game, and we have to send the pad state to other clients on every poll or else we'll desync. This can result in fairly high bandwidth usage, especially with multiple controllers, mostly due to UDP/IP overhead.
This change introduces an option to reduce the SI poll rate to once per frame, which may introduce up to one frame of additional latency, but will reduce bandwidth usage substantially, which is useful for users on very slow internet connections.
Polling SI less frequently than the game asked for did not seem to cause any problems in my testing, so this should be perfectly safe to do.
7f0834c9 moved the locations of the Real XFB (now XFB to RAM) and
Disabled XFB (now Immediate Mode) settings. There are programs
other than Dolphin that parse DTM headers, so this is not good.
Note that Immediate XFB actually is the inversion of Disabled XFB.
I hope that's not too much of a problem...
* Add missing Language setting loading/saving. This was added after the
original OnionConfig PR, which is why support for it was missing.
* Change MovieConfigLoader to reuse ConfigInfos. Less duplication.
* Extract MovieConfigLoader::Save into SaveToDTM. The DTM should use
the current config and not just the movie layer. This makes more
sense than just saving the movie layer, which may not always exist,
and also fixes a crash that would happen when creating a new
recording because the movie layer wouldn't exist in that case.
(Plus, having to get the loader from the layer and call ChangeDTM
on it manually is not very pretty.)
Settings that come from the SYSCONF are now included in Dolphin's
config system as part of the base layer. They are handled in a
special way compared to other settings to make sure they are only
loaded from and saved to the SYSCONF (to avoid different, possibly
contradicting sources of truth).
* Move out boot parameters to a separate struct, which is not part
of SConfig/ConfigManager because there is no reason for it to
be there.
* Move out file name parsing and constructing the appropriate params
from paths to a separate function that does that, and only that.
* For every different boot type we support, add a proper struct with
only the required parameters, with descriptive names and use
std::variant to only store what we need.
* Clean up the bHLE_BS2 stuff which made no sense sometimes. Now
instead of using bHLE_BS2 for two different things, both for storing
the user config setting and as a runtime boot parameter,
we simply replace the Disc boot params with BootParameters::IPL.
* Const correctness so it's clear what can or cannot update the config.
* Drop unused parameters and unneeded checks.
* Make a few checks a lot more concise. (Looking at you, extension
checks for disc images.)
* Remove a mildly terrible workaround where we needed to pass an empty
string in order to boot the GC IPL without any game inserted.
(Not required anymore thanks to std::variant and std::optional.)
The motivation for this are multiple: cleaning up and being able to add
support for booting an installed NAND title. Without this change, it'd
be pretty much impossible to implement that.
Also, using std::visit with std::variant makes the compiler do
additional type checks: now we're guaranteed that the boot code will
handle all boot types and no invalid boot type will be possible.
Amends the TAS callbacks to internally store functions using
std::function instead of raw function pointers. This allows binding
extra contextual state via lambda functions, as well as keeping the
dialogs internal to the main frame (on top of being a more flexible
interface).
Movie basically just wants to get the title ID of
the initally booted game, so let's set the title ID in
ConfigManager at boot like we do with the regular game ID.
Aside from being cleaner, this should make the approach to
title IDs compatible with booting non-disc software (WADs).
DVDInterface shouldn't need to know anything about
the DTM format's 40-character limitation.
Also replacing "filename" in variable names with "path"
to make it clearer which variables contain the whole path
and which ones only contain the filename.