It turns out that the last byte of array entries isn't unused (as we
thought); instead, it looks like it's actually part of the main data,
and the length stored next to the name is in fact the length minus one.
Getting it wrong and always storing a null byte in there won't affect
most entries (since the last byte is zeroed most of the time), except:
- IPL.NIK: the length is stored in the last byte, and it must be kept.
- BT.DINF: u8 unknown[0x45] should be another Bluetooth device entry.
- Possibly other unknown affected entries.
It's a bit confusing to get a yes/no dialogue box without any indication
of what yes or no will do in this situation, so add a short explanatory
sentence.
Some code was calling more than one of these functions in a row
(in particular, FileUtil.cpp itself did it a lot...), which is
a waste since it's possible to call stat a single time and then
read all three values from the stat struct. This commit adds a
File::FileInfo class that calls stat once on construction and
then lets Exists/IsDirectory/GetSize be executed very quickly.
The performance improvement mostly matters for functions that
can be handling a lot of files, such as File::ScanDirectoryTree.
I've also done some cleanup in code that uses these functions.
For instance, some code had checks like !Exists() || !IsDirectory(),
which is functionally equivalent to !IsDirectory(), and some
code was using File::GetSize even though there was an IOFile
object that the code could call GetSize on.
It didn't work when there were non-ASCII characters
in the directories argument, but it worked fine with
non-ASCII characters in names of found files and folders.
c5fa470 made the extension check discard directories, but
only in the new code that currently only is used on Windows.
Let's add an equivalent check in the old code so that the
behavior is consistent across platforms.
This fixes the global-static fifo object causing infinite hangs in some
cases. Notably, failure to initialize a graphics backend would result in
BlockingLoop::Prepare being called but never executing Run(), leaving the
object in a bad state.
This one verifies bitmasks where low bits are set to 1 (hence the name).
Any stray 0 among the lower ones or any stray 1 among the higher zeros
renders the mask invalid.
The edge cases of all zeros and all ones are considered valid masks.
It uses an efficient implementation. It's the counterpart of
https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2
This allows the user to go through the Wii Menu first boot setup
screen when they launch the System Menu for the first time.
Most useful on a clean profile, after doing a full system update,
to configure settings like the console country.
This rewrites the SysConf code for several reasons:
* Modernising the SysConf class. The naming was entirely cleaned up.
constexpr for constants.
* Exposing less stuff in the header.
* Probably less efficient parsing and writing logic, but much simpler
to understand and use in my opinion. No more hardcoded offsets.
No more duplicated code for the initial SYSCONF generation.
* More flexibility. It is now possible to add and remove entries,
since we rebuild the file. This allows us to stop spamming
"section not found" panic alerts; we can now use and insert
default entries.