In WiimoteReal.cpp, JitRegCache.cpp, lambda predicates were replaced by pointers to member functions because ranges algorithms are able invoke those.
In ConvertDialog.cpp, the `std::mem_fn` helper was removed because ranges algorithms are able to handle pointers to member functions as predicates.
In DITSpecification.cpp, MaterialAsset.cpp, and ShaderAsset.cpp, lambda predicates were replaced by pointers to member functions because ranges algorithms are able invoke those.
In NetPlayClient.cpp, the non-trivial `NetPlay::Player` elements were being passed by value in `NetPlayClient::DoAllPlayersHaveGame()`. This has been fixed.
In WIABlob.cpp, the second example's predicate was returning the `std::optional` by value instead of implicitly converting it to a bool. This has been fixed.
The read thread could call Reset, which in turn tried to join the read
thread, leading to a SIGABRT. This manifested as Dolphin consistently
crashing when disconnecting a GC adapter and having a chance of crashing
a few seconds after connecting a GC adapter.
Now that patches and codes are enabled on a case by case basis, remove patcher code blocking codes entirely in hardcore mode, and reword the warning to be more accurate.
This apparently didn't compile on macOS six years ago before c++20, but
it should be fine by now.
While I'm at it, make the constants upper case per convention.
If the host is in hardcore mode, all joining players will be set to hardcore mode; if not, all joining players will be set to softcore. This ensures all players have the same settings and remain synchroized.
The primary focus of this PR is the Eternal Darkness patch which fixes hanging at startup, which prior to this fix makes Eternal Darkness unplayable in hardcore. The MHTri patch was added as well simply because it could be.
GXAbortFrame() is problematic for Dolphin because it first writes
PI_FIFO_RESET (for which we discard our internal fifo), then disables CP
reads (for which we execute pending commands in the GP fifo in emulated
memory). I don't know whether there is a race condition on hardware, but
there is one for us. Avoid this by also doing a GPU sync here.
The value being stored must be loaded into a register. In the case of an
immediate value, this means it must be materialized. The value is
eventually byteswapped before performing the store.
This can be simplified for the value 0 for two reasons:
- ARM64 has a dedicated zero register, so does not need to be
materialized.
- Byteswapping zero is still zero, so we can skip this step.
We could skip byteswapping for other values by immediately materializing
the byteswapped value in a register, but the benefits are not so clear
there (if the value needs to be materialized anyway, it is better to do
it up front).
Before:
0x5280001b mov w27, #0x0 ; =0
0xb9404fba ldr w26, [x29, #0x4c]
0x12881862 mov w2, #-0x40c4 ; =-16580
0x0b020342 add w2, w26, w2
0x5ac00b61 rev w1, w27
0xb8226b81 str w1, [x28, x2]
After:
0xb9404fbb ldr w27, [x29, #0x4c]
0x12881862 mov w2, #-0x40c4 ; =-16580
0x0b020362 add w2, w27, w2
0xb8226b9f str wzr, [x28, x2]