A deep-copy method CopyReader has been added to BlobReader (virtual) and all of its subclasses (override). This should create a second BlobReader to open the same set of data but with an independent read pointer so that it doesn't interfere with any reads done on the original Reader.
As part of this, IOFile has added code to create a deep copy IOFile pointer onto the same file, with code based on the platform in question to find the file ID from the file pointer and open a new one. There has also been a small piece added to FileInfo to enable a deep copy, but its only subclass at this time already had a copy constructor so this was relatively minor.
The achievement badges will now have a blue or gold border to identify whether they have been unlocked in softcore or hardcore mode. Similarly, the game badge will have a blue border if all achievements have been unlocked in either mode or a gold border if all achievements have been unlocked in hardcore mode.
Provided the badges are turned on in the settings, each achievement will have a badge next to it on the progress tab. There are different badges for locked and unlocked (usually locked is grayscale while unlocked is in color but not necessarily) and the badge chosen depends on the player's current unlock and hardcore status.
Provided badges are turned on, if there's a player logged in their RetroAchievements icon will appear next to their player info in the header of the Achievements dialog. If they're playing a game, so will the icon for the game. Also performed some refactoring and reorganizing to the header as a whole so that it looks consistent whether a game is running or not.
FetchBadges fetches all available badges (player, game, achievements) and stores them in AchievementManager's memory. New fields and accessors have been added as necessary. Badges for individual achievements are stored in the UnlockStatus map. The method is public so that the settings dialog can call it if badges are turned on after a game is started. Badges are deleted at game close and logout.
When evaluating whether jo.fastmem should be set to true, we check the
value of jo.fastmem_arena. However, due to a change made in 28e8117b90,
jo.fastmem_arena wasn't set until after the first time we set
jo.fastmem, so jo.fastmem would end up always being false until the next
time RefreshConfig was called.
Fixes https://bugs.dolphin-emu.org/issues/13364.
Image requests from RetroAchievements have a slightly different format from other requests, on account of being GET calls that return strings of image data, so this is a separate function that makes such calls. To handle this, I create a BadgeStatus object that ties each badge to a boolean flag for whether it is loaded and thus usable.
In some settings where the default value could not be evenly divided by the step size for the slider, there would be a crash. This increases the precision of all double numeric settings to 0.5 and now shows the decimal that you couldn't see before.
And in order to avoid a double dereference in the dispatcher, directly store
the normalEntry in the map.
The index to the block map becomes ((((DR<<1) | IR) << 30) | (address >> 2)).
This has been chosen since the msr bits change less often than the address,
thus we keep nearby entries together.
Also do not call the C dispatcher in case the assembly dispatcher didn't
find a block, since it wouldn't find a block either due to the 1:1 mapping,
except when falling back to the non shm segment lookup table.
This bug has been lurking in the code ever since I added the discard
functionality. It doesn't seem to be triggered all that often,
and on top of that the emitted code only runs conditionally, so I'm not
sure if people have been affected by this bug in practice or not.
We need to check for the address of the *previous* instruction, because
checking fifoWriteAddresses happens not at the end of the instruction
that triggered it but at the start of the next instruction.
This refactors the Rich Presence generation to store to a member field that can be exposed to the UI to display the Rich Presence in the achievement header. It still updates at its original rate of once per two minutes, but calls an update on the dialog when that ticks.
Moved AchievementManager Init further down in the MainWindow constructor; its original position was because it had an impact on the contents of the menu bar, and this is no longer the case.
By not setting a stepSize, stepSize was getting set to the default
value of 0, which is an Int. This later caused a crash when trying to
cast it to Float.
Whenever JitBaseBlockCache::Clear() got called, it threw away the memory mapping for the fast block map and created a new one. This new mapping typically got mapped at the same address at the old one, but this is not guaranteed. The pointer to the mapping gets embedded in the generated dispatcher code in Jit64AsmRoutineManager::Generate(), which is only called once on game boot, so if the new mapping ended up at a different address than the old one, the pointer in the ASM pointed at garbage, leading to a crash.
This fixes the issue by guaranteeing that the new mapping is mapped at the same address.
While both fastmem and the BLR optimization depend on fault handling,
the BLR optimization doesn't depend on fastmem, and there are cases
where you might want the BLR optimization but not fastmem. For me
personally, it's useful when I try to use a debugger on Android and have
to disable fastmem so I don't get SIGSEGVs all the time, but it would be
especially useful for iOS users.
Using GTEST_SKIP instead of just returning from the function shows that
a test was skipped in the test summary. If GTEST_SKIP is called the rest
of the function won't be run, just like with the return.
GTEST_SKIP wasn't available until gtest 1.10, and we updated to 1.12 in
597f8f1b87.
Because CPU thread config changed callbacks are no longer instant,
g_Config.iEFBScale doesn't yet contain the new value when the hotkey OSD
code tries to read it.
Should fix https://bugs.dolphin-emu.org/issues/13343.
There's no reason not to allow this now that these settings are
cleanly integrated into the new config system. (Actually, maybe
we could even have done this before the previous commit...)
This fixes a problem where changing the JIT debug settings on
Android while a game was running wouldn't cause the changed settings
to apply to code blocks that already had been compiled.
Resolve warning caused by using values from two different enums in a
conditional expression which was deprecated in c++20.
The warning in question is clang -Wdeprecated-anon-enum-enum-conversion
and gcc -Wenum-compare.
We had one implementation of this type of data structure in Arm64Emitter
and one in VideoCommon. This moves the Arm64Emitter implementation to
its own file and adds begin and end functions to it, so that VideoCommon
can use it.
You may notice that the license header for the new file is CC0. I wrote
the Arm64Emitter implementation of SmallVector, so this should be no
problem.
Modify PPCSTATE_OFF and PPCSTATE_OFF_ARRAY macros when using GCC to
avoid useless log spam. Specifically, use a consteval lambda with gcc
_Pragma statements to disable the -Winvalid-offsetof warning inside the
macros.
Each successful build (and many failing ones) on the Android buildbot
generates almost 300 cases of -Winvalid-offsetof, resulting in thousands
of lines of log spam per build. In addition to bloating the log filesize
these spurious warnings make it harder to find actual warnings.
These warnings are generated by calls to the macros PPCSTATE_OFF and
PPCSTATE_OFF_ARRAY, which in turn are used by many other macros used by
the JIT. The ultimate cause is that offsetof is only conditionally
supported on non-standard-layout types, which includes the PowerPCState
struct.
To address potential questions of whether there's a better way to handle
this:
The obvious solution would be to modify PowerPCState so that it does
have a standard layout. This is unfortunately impractical.
To have a standard layout a type can only contain other types with
standard layouts. None of the stl containers are guaranteed to have
standard layouts, and PowerPCState contains a std::tuple and std::array.
PowerPCState also contains a PowerPC::Cache and InstructionCache which
themselves contain std:arrays and std::vectors.
Furthermore InstructionCache derives from Cache, and a derived class can
only have standard layout if at most one class in its hierarchy has a
non-static data member, but both classes have such members. Making
InstructionCache have a standard layout would require duplicating all
the functionality of Cache so it no longer derived from it, as well as
replacing the stl containers. This might require having a raw pointer to
said containers, with the manual memory management that implies.
All of that would be much more disruptive than would be justified to get
rid of some warnings (however annoying they might be). This is
compounded by the fact that PowerPCState hasn't had a standard layout
for a long time, if ever, and if the PPCSTATE_OFF macros weren't working
reliably it would have become obvious a long time ago.
As to why I picked the lambda solution over other potential changes:
- Keeping the define as-is and wrapping some gcc #pragmas around it
doesn't work because the pragmas don't get included when the define is
substituted to the call site.
- Keeping the define as a non-lambda expression and using inline
_Pragma() statements would ideally be better and works fine for msvc,
but fails for GCC with "'#pragma' is not allowed here".
- Turning off -Winvalid-offsetof globally for gcc would work, but there
might be other contexts where offsetof is problematic and GCC seems to
be the only compiler warning about it.