A vtable keeps a virtual method linked whether or not anything calls
it. These 18 have no caller anywhere in the tree: Device::Control's
ToInput, ToOutput, IsHidden and IsDetectable, Device::IsVirtualDevice,
ControlReference::IsInput, the real Bluetooth adapter's sync button
handling and GetWiimoteDeviceIndex, GLContext's MakeCurrent,
ClearCurrent and UpdateSurface (the frontend owns the context),
AddressSpace's ReadU64, WriteU64 and ReadF32, FileInfo's
GetTotalChildren, Volume's CheckH3TableIntegrity and VideoBackend's
GetWarningMessage. Remove them with their overrides.
GetInternalName, GetApploaderDate (and its wrapper), GetDiscNumber,
GetContentOffsets, GetPartitionType and HasWiiEncryption have no callers
in the core; being virtual, the vtables kept them. Remove them with
their overrides, and Volume::DecodeString, which only GetInternalName
used.
Volume's GetBanner, GetShortNames, GetLongNames, GetShortMakers,
GetLongMakers and GetDescriptions serve a frontend game list; nothing
in the core calls them. Being virtual, the vtables kept them and
everything behind them alive.
Remove them with their GameCube, Wii and WAD overrides, the GameCube
banner loader (LoadBannerFile, ExtractBannerInformation, the banner
structs and their lazy member), Volume::ReadWiiNames, and the files
only they used: WiiSaveBanner and Common/ColorUtil.
Every DiscIO message goes through the printf log macros, and the file
names the NFS and split-file readers open and the name of an unknown
partition type are built without fmt::format. Nothing in DiscIO uses
fmt now.
Names, game IDs, patch lists, LBA ranges and hash exceptions are passed
as pointer plus count. min/max/fill/copy become ternaries, memset and
memcpy; FST entries sort with an in-place heap sort, partitions with an
insertion sort. WAD content checks decrypt and hash in 2 KiB chunks
straight from the borrowed input; banner names read onto the stack.
A ticket, TMD or certificate holds its bytes in one malloc'd buffer and
hands them out as a span. ResizeBytes() gives the room to fill, so a
ticket or TMD is read from the NAND, a disc, a WAD or guest memory
straight into its reader instead of into a std::vector that is then
moved or copied in.
Ticket, TMD and certificate chain imports take spans, and the IPC
handlers pass the guest's buffers where they lie instead of copying
them out into vectors first. A certificate is read where it lies and
only its own bytes are copied, so parsing a chain no longer copies the
rest of the chain once per certificate. Deleting a ticket closes up the
ones kept in place. The savestate layout is unchanged.
An encrypted block of a plain image is decrypted straight from the
image's mapping; one the reader cannot lend is read into the volume's
own block buffer, not a new allocation per read. A read that covers a
block's whole data is decrypted straight into the caller's buffer; only
a partial one goes through the decrypted-block cache.
No std::thread, std::async, std::future or std::promise is left. Each
thread is an sthread with a plain entry point: Common::ThreadEntry<&C::F>
turns a member function into one, Common::JoinThread joins and clears a
handle, and Common::StartDetachedThread covers the fire-and-forget users.
Common/ParallelFor.{h,c} (C89) runs fn(ctx, i) for i in [0, count) on a
persistent pool of one worker per extra core plus the caller. Jobs are
claimed with an atomic counter, workers park on an eventcount between
batches, and the batch hand-off is a seq_cst users/active pair, so there
is no lock anywhere. A caller that finds the pool busy runs its batch
serially instead of waiting. retro_deinit joins the pool.
- VolumeWii::HashGroup spawned 64 threads per 2 MiB group and
EncryptGroup another one per core; both are now parallel_for batches
on the pool. The H1/H2 tail is a few small hashes and runs inline.
- VolumeVerifier spawned up to five std::async threads per chunk; the
chunk's tasks now go to one persistent worker that fans them out with
parallel_for, still overlapping the next read. The Redump lookup is an
sthread joined in Finish or the destructor.
- The dual-core "GPU thread" in Core only set a thread_local on itself
and exited, since the frontend runs the GPU loop. It is gone, along
with the non-libretro branches of Core.cpp.
- The emu thread is started through Core::StartEmuThread.
- CPU core counts come from cpu_features_get_core_amount().
The core never creates a NetPlay client or server; only the standalone
frontends did. Drop NetPlay with what only it used: the traversal
client, ENet, the QoS session, the NetPlay config layer and settings,
the chat and golf overlays, the netplay index, the save sync plumbing
in BootSessionData and WiiRoot, the disc sync hashes, and the Android
app's netplay feature and JNI bindings.
Yellow squiggly lines begone!
Done automatically on .cpp files through `run-clang-tidy`, with manual corrections to the mistakes.
If an import is directly used, but is technically unnecessary since it's recursively imported by something else, it is *not* removed.
The tool doesn't touch .h files, so I did some of them by hand while fixing errors due to old recursive imports.
Not everything is removed, but the cleanup should be substantial enough.
Because this done on Linux, code that isn't used on it is mostly untouched.
(Hopefully no open PR is depending on these imports...)
Previously, we had WBFS and CISO which both returned an upper bound
of the size, and other formats which returned an accurate size. But
now we also have NFS, which returns a lower bound of the size. To
allow VolumeVerifier to make better informed decisions for NFS, let's
use an enum instead of a bool for the type of data size a blob has.
Needed for the next commit. NFS disc images are hashed but not encrypted.
While we're at it, also get rid of SupportsIntegrityCheck.
It does the same thing as old IsEncryptedAndHashed and new HasWiiHashes.
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.
This improves the speed of verifying Wii WIA/RVZ files.
For me, the verification speed for LZMA2-compressed files
has gone from 11-12 MiB/s to 13-14 MiB/s.
One thing VolumeVerifier does to achieve parallelism is to
compute hashes for one chunk of data while reading the next
chunk of data. In master, when reading data from a Wii
partition, each such chunk is 32 KiB. This is normally fine,
but with WIA and RVZ it leads to rather lopsided read times
(without the compute times being lopsided): The first 32 KiB
of each 2 MiB takes a long time to read, and the remaining
part of the 2 MiB can be read nearly instantly. (The WIA/RVZ
code has to read the entire 2 MiB in order to compute hashes
which appear at the beginning of the 2 MiB, and then caches
the result afterwards.) This leads to us at times not doing
much reading and at other times not doing much computation.
To improve this, this change makes us use 2 MiB chunks
instead of 32 KiB chunks when reading from Wii partitions.
(block = 32 KiB, group = 2 MiB)
Panic alerts in DiscIO can potentially be very annoying since
large amounts of them can pop up when loading the game list
if you have some particularly weird files in your game list.
This was a much bigger problem back in 5.0 with its
"Tried to decrypt data from a non-Wii volume" panic alert, but
I figured I would take it all the way and remove the remaining
panic alerts that can show up when loading the game list.
I have exempted uses of ASSERT/ASSERT_MSG since they indicate
a bug in Dolphin rather than a malformed file.
It's possible (but rare) for a WIA or RVZ file to support
this for some partitions but not all, and for the game and
the blob code to disagree on how large a partition is.
Instead of comparing the game ID, revision, disc number and name,
we can compare a hash of important parts of the disc including
all the aforementioned data but also additional data such as the
FST. The primary reason why I'm making this change is to let us
catch more desyncs before they happen, but this should also fix
https://bugs.dolphin-emu.org/issues/12115. As a bonus, the UI can
now distinguish the case where a client doesn't have the game at
all from the case where a client has the wrong version of the game.
This is intended to catch WIA files which have been created using
wit's default parameters (40 MiB block size), once the WIA PR is
merged. The check does however also work for GCZ files – not that
I think anyone has a GCZ file with a block size that large.
Fixes using DirectoryBlob on extracted games that were unencrypted
prior to being extracted.
(One day I'll make DirectoryBlob actually support raw reads and then
the order of these two won't matter...)
The difference between Dolphin's game IDs and GameTDB's game IDs
is that GameTDB uses four characters for non-disc titles, whereas
Dolphin uses six characters for all titles.
This fixes:
- TitleDatabase considering Datel discs to be NHL Hitz 2002
- Gecko code downloading not working for discs with IDs starting with P
- Cover downloading mixing up discs with channels (e.g. Mario Kart Wii
and Mario Kart Channel) and making extra HTTP requests. (Android was
actually doing a better job at this than DolphinQt!)