The move assignment operator for a class is implicitly deleted when the
class has a non-static reference data member, which is true of
WiiSocket's m_socket_manager member.
Explicitly declaring the operator as default generates a
-Wdefaulted-function-deleted warning on Clang.
Delete the move constructor as well for consistency.
Fix -WSwitch warning about unhandled enum value SDL_NUM_LOG_PRIORITIES.
log_level is initialized to LNOTICE right before the switch statement so
this doesn't cause any behavior changes.
This makes it so that if you just want to reload the current style (eg. on program start, or in response to a system event), you don't need to know the name of the currently selected user style. It's also more consistent with the way the 'userstyle/enabled' flag works.
Before dbf5dca, the dirty flag had no meaning for an immediate value,
so we made sure to always set the dirty flag when switching a register
from Immediate to Register. But after dbf5dca, that is no longer the
case. If an immediate is marked as not dirty, we can keep the register
marked as not dirty after materializing the value. This way we skip
having to write it back to ppcState later.
Without this change, non-dirty immediates don't actually get flushed.
This can be a problem if we for instance are flushing all registers in
order to execute an interpreter fallback. If that interpreter fallback
writes to a register that contained a non-dirty immediate, the JIT will
keep using the old value instead of loading the updated value.
Dolphin's JITs have a minor terminology problem: The term "fastmem" can
refer to either the system of switching between a fast path and a slow
path using backpatching, or to the fast path itself. To hopefully make
things clearer, I'm adding some new terms, defining the old and new
terms as follows:
Fastmem: The system of switching from a fast path to a slow path by
backpatching when an invalid memory access occurs.
Fast access: A code path that accesses guest memory without calling C++
code.
Slow access: A code path that accesses guest memory by calling C++ code.
With this, situations where multiple arguments need to be moved
from multiple registers become easy to handle, and we also get
compile-time checking that the number of arguments is correct.
If dcache is enabled when the game starts, initializing the fastmem
arena is still useful in case the user changes the dcache setting.
And initializing it doesn't really cost anything.
Preparation for the next commit.
JitArm64 has been conflating these two flags. Most of the stuff that's
been guarded by fastmem_arena checks in fact requires fastmem.
When we have fastmem_arena without fastmem, it would be possible to do
things a bit more efficiently than what this commit does, but it's
non-trivial and therefore I will leave it out of this PR. With this
commit, we effectively have the same behavior as before this PR - plus
the added ability to toggle fastmem with a cache clear.
This is needed so that the checks added in the previous commit will be
reevaluated if the value of m_enable_dcache changes.
JitArm64 was already recompiling its asm routines on cache clear by
necessity. It doesn't have the same setup as Jit64 where the asm
routines are in a separate region, so clearing the JitArm64 cache
results in the asm routines being cleared too.
Some code paths in EmuCodeBlock.cpp that were checking fastmem_arena
should really also be checking m_enable_dcache.
Because JitArm64 centralizes more or less all memory access to the
EmitBackpatchRoutine function and because that function already
contained a check, JitArm64 works fine without the additional checks
added by this commit. Regardless, I added the checks to MMU.cpp instead
of EmuCodeBlock.cpp where applicable so they would be available to
JitArm64. Maybe one day JitArm64 will need them if its code gets
restructured.
The code previously did this indirectly via `std::map<double, int>`, the key being the timestamp, which required a questionable workaround for the case where multiple states have the same timestamp. By having a particular combination of timestamps in the on-disk savestates, you could cause this workaround to infinitely loop, locking up Dolphin. This avoids this completely by refactoring the logic and just using `std::vector` instead.
Since ccf92a3e56, recording fifologs multiple times after launching dolphin caused all initial state to not be saved (the initial contents of bpmem, cpmem, etc were all zeroed out). For some games, this was not noticeable, as most registers were set each frame, but for others, this resulted in completely broken fifologs. (Note that recording fifologs also required 05181f6b88 and 9e0755a598 to be cherry-picked due to other, since fixed, regressions.)
This was because previously, `Renderer::CheckFifoRecording` was called every frame, but ccf92a3e56 changed it into a callback (`m_end_of_frame_event`) that was removed when recording ended. Thus, before, `OpcodeDecoder::g_record_fifo_data = IsRecording()` was called when `IsRecording()` returned false, but after that commit `g_record_fifo_data` never got changed back to false, so the check for `was_recording` only ever passed on the first fifolog recorded (even after stopping and starting a game).
There may still be another issue lurking, as I'm not sure if all broken fifologs were caused by recording multiple fifologs (for instance, on https://bugs.dolphin-emu.org/issues/13377, only one fifolog was initially uploaded, but it was affected by an issue with the same symptoms as this).
Instructions referencing registers r8-r15 take an additional byte to
encode. `reg_downcount` may be assigned to one of these registers, so it
is a small size win to store the downcount value in `RSCRATCH` first.
Before:
33 D2 xor edx,edx
44 8B 6D 64 mov r13d,dword ptr [rbp+64h]
45 85 ED test r13d,r13d
7E 30 jle 0000023546B43F6D
44 8B B5 D4 02 00 00 mov r14d,dword ptr [rbp+2D4h]
41 8B C5 mov eax,r13d
BF 07 00 00 00 mov edi,7
F7 F7 div eax,edi
After:
33 D2 xor edx,edx
8B 45 64 mov eax,dword ptr [rbp+64h]
85 C0 test eax,eax
7E 30 jle 000001AFBBAE359D
44 8B B5 D4 02 00 00 mov r14d,dword ptr [rbp+2D4h]
44 8B E8 mov r13d,eax
BF 07 00 00 00 mov edi,7
F7 F7 div eax,edi
This value is used in a multiplication. The result of this
multiplication is then subtracted from m_base. By negating m_dec, we are
free to use an addition instead.
On x64, this saves an instruction.
Split the "welcome" messages letting players know achievements are active into a separate method that gets called (currently) after a number of frames to ensure that the emulator has started properly and has somewhere to display the messages.
A new tab is added to the Achievements dialog to chart out the leaderboards in a table. Each row of the table contains the leaderboard information and up to four relevant entries, varying based on how many entries are in the leaderboard, whether or not the player has a submitted score, and where in the leaderboard the player's score is.
FetchBoardInfo is called (via the work queue asynchronously) on a leaderboard every time it is activated or submitted to. It makes two calls to the RetroAchievements API for fetching leaderboard info, one that requests the top four entries in the leaderboard and another that requests the player's entry, the two entries above the player and the two entries below. All of these are inserted into a single map (resolving any overlaps) so the result can be exposed to the UI.
The leaderboard map created here contains information useful to displaying leaderboard stats in the Achievement dialog, including each leaderboard's name and description and a partial list of entries for display. The entire map is exposed to the UI in a single call for simplicity.
Both of these functions access `m_game_data` and don't lock themselves, so they must be called in a way that guarantees that `m_game_data` is not modified during the call.
Scope issue in the event callback from `rc_runtime_do_frame()`. The pointer points to a variable on the stack from inside `rc_runtime_do_frame()`, so that's a race condition between the thread calling `rc_runtime_do_frame()` and the event queue thread.