`std::erase` is a replacement for the remove-erase idiom.
Changes to `OpenModeToAndroid` inadvertently revealed that the prior implementation had UB (potentially deleting the end iterator). This is now fixed.
Three bugs specific to older Wii games:
- The size difference between high-pass and biquad filter was not
accounted for, causing wiimote related fields to be corrupted.
- Wiimote sample buffer pointers were advanced by 32 samples per
millisecond instead of 6 samples. Usually hidden by the first bug.
- PB updates on Wii were being byte-swapped twice, but I've not actually
found any Wii games that make use of PB updates.
This fixes wiimote audio in at least the following games:
- Excite Truck
- Ice Age 2: The Meltdown
- Kororinpa: Marble Mania
- Rapala Tournament Fishing
- Shrek the Third
- Super Monkey Ball: Banana Blitz
- Tiger Woods PGA Tour 07
- WarioWare: Smooth Moves (issue 11725)
- Wing Island
Fixes LIT (https://bugs.dolphin-emu.org/issues/13635). The text does not include normals, but has lighting enabled. With the previous default of (0, 0, 0), lighting was always black (as dot(X, (0, 0, 0)) is always 0). It seems like the normal from the map in the background (0, 0, 1) is re-used.
LIT also has the vertex color enabled while vertex color is not specified, the same as SMS's debug cubes; the default MissingColorValue GameINI value of solid white seems to work correctly in this case.
No need to materialize the immediate if it is zero, we can just use WZR.
Before:
mov w27, #0x0 ; =0
str w27, [x29, #0x1178]
After:
str wzr, [x29, #0x1178]
In VolumeVerifier.cpp, constructing a `std::string_view` of the volume's GameID is unnecessary, as `std::`(`ranges::`)`binary_search` supports heterogeneous lookup. The usage in GameFile.cpp is a perfect example.
In OGLConfig.cpp, `std::views::reverse` is used rather than sorting using `std::ranges::greater` in order to parallel other instances of reverse iteration in the function.
In DSPCore.cpp, there were two `std::fill` uses that could be simplified using `std::fill_n`. Due to their proximity with other `std::fill` algorithms being modernized with ranges, I chose to make these examples into the rare `std::ranges::fill_n`.
In StringUtil.h, the lambdas wrapping `Common::ToLower(char)` and `Common::ToUpper(char)` were only necessary due to the function names being overloaded.
Many games call GXSetGPFifo() without first waiting for the GP to finish
consuming outstanding commands in the previous GP fifo. Normally,
Dolphin runs OpcodeDecoding in 1000-cycle time slices. In that time
frame, GXSetGPFifo() has probably completed and the GP read pointer now
points to entirely new memory. If the last GP fifo copy ended in an
incomplete command, the new GP fifo would most likely desync for a
while. To avoid all this, give the GP a time slice right now to copy the
remaining data from the previous GP fifo.
Indexed XF loads specify the number of 32-bit words (generally floats, but light data has some integers) to load, not the number of bytes. This was only a mistake in the fifo analyzer text; the actual implementation already loaded words.
The light LIT fifolog from https://bugs.dolphin-emu.org/issues/13635 has position data at physical address 11ae3180. This works fine when using the memory viewer in physical mode, but the corresponding virtual address (91ae3180) previously didn't show anything in effective mode. It works fine now though.
This shouldn't affect playback of fifologs as everything in there uses physical addresses; this only impacts the memory viewer.
This logic was copied from CBoot::SetupBAT.
This reverts the revert commit bc67fc97c3,
except for the changes in BaseConfigLoader.cpp, which caused the bug
that made us revert 72cf2bdb87. PR 12917
contains an improved change to BaseConfigLoader.cpp, which can be merged
(or rejected) independently.
A few changes have also been made based on review comments.
Found this bug while testing; if I manually edit the config files while Dolphin is closed I was able to get debug and hardcore on at the same time, this resolves that.
AchievementManager::SetHardcoreMode now handles the (non-Qt) settings disabled by hardcore mode, instead of doing this on the Qt layer. Also ensured Init/Enable Achievements paths run this code, fixing the bug wherein the player can manipulate things when achievements are disabled that persist when turned back on.
Prevent potential issues when creating the Graphics window (and thus
calling PopulateBackendInfo) while the core state is Stopping, like we
already do while it's Starting or Running.
Remove the PopulateBackendInfoFromUI function, which had a single caller
(GraphicsWindow::OnBackendChanged) and checked that the core wasn't
running or starting before calling PopulateBackendInfo.
Move the core state check into PopulateBackendInfo and have
OnBackendChanged call that instead. This guarantees the check is
performed by all callers of PopulateBackendInfo, preventing
potential reintroduction of the crash fixed in 3d4ae63f if another call
to PopulateBackendInfo is added.
As of the previous commit the only other caller of PopulateBackendInfo
is Core::Init shortly before s_state is set to Starting, so it will
always pass the check and so maintain its current behavior.
Remove the second of two calls to PopulateBackendInfo during emulation
startup. This call was originally the only one, but b214e0e added an
earlier call to handle the backend being changed by the GameINI.
The PR discussion doesn't explain why the original call was left in; I
suspect it was just overlooked.
As a bonus, this removes one of the extra copies of the "Video Info" On
Screen Display message at startup when using OpenGL.
Fix a crash when opening the Graphics window for the first time during
emulation startup when the backend is Vulkan, D3D11, or D3D12.
Don't call PopulateBackendInfo() from the Host thread when the core is
starting up. First, the function has already been called in Core::Init()
so we don't need to again. More importantly, PopulateBackendInfo() calls
g_video_backend->InitBackendInfo(), and the Vulkan and D3D
implementations of those functions load and then unload libraries (and
their associated function pointers) which are potentially in use by
other threads.
This crash was reliably reproducible with the following steps:
1) Select an affected backend.
2) Enable "Compile Shaders Before Starting"
3) Delete the cached shaders (but not the .uidcache file) for the game
you're testing.
4) Close and reopen Dolphin.
5) Start the game.
6) While the game is still booting or compiling shaders, open the
Graphics window for the first time in that Dolphin session.
Fixes https://bugs.dolphin-emu.org/issues/13634.
Before, Dolphin would randomly crash when updating the cheat search when automatic refresh was enabled. (Having a large number of addresses listed, e.g. by starting with an "any value" search, may contribute). The crash was due to QTableWidget::item returning nullptr in RefreshGUICurrentValues, presumably due to the table being resized on the UI thread while the emulated CPU thread was updating the values. I've fixed this by pausing the CPU thread for the entirety of OnNextScanClicked; this eliminated crashes in my testing.
With 12 uses of `JoinStrings` in the codebase vs 36 uses of `fmt::join`, fmtlib's range adapter for string concatenation with delimiters is clearly the preferred option.
Migrating `Common::CaseInsensitiveLess` to StringUtil.h will hopefully discourage rolling one's own solution in the future for case-insensitive associative containers when this (quite robust!) solution already exists.
`Common::CaseInsensitiveStringCompare::IsEqual` was removed in favor of using the `Common::CaseInsensitiveEquals` function.
The `a.size() != b.size()` condition in `Common::CaseInsensitiveEquals` can be removed, since `std::ranges::equal` already checks this condition (confirmed in libc++).
There were three distinct mechanisms for signaling breakpoint changes in DolphinQt, and the wiring had room for improvement. The behavior of these signals has been consolidated into the new `Host::PPCBreakpointsChanged` signal, which can be emitted from anywhere in DolphinQt to properly update breakpoints everywhere in DolphinQt.
This improves a few things:
- For the `CodeViewWidget` and `MemoryViewWidget`, signals no longer need to propagate through the `CodeWidget` and `MemoryWidget` (respectively) to reach their destination (incoming or outgoing).
- For the `BreakpointWidget`, by self-triggering from its own signal, it no longer must manually call `Update()` after all of the emission sites.
- For the `BranchWatchDialog`, it now has one less thing it must go through the `CodeWidget` for, which is a plus.