Per https://en.cppreference.com/w/cpp/preprocessor/replace#.23_and_.23.23_operators the `##` behavior is a nonstandard extension; this extension seems to be supported by all compilers we care about, but IntelliSense in visual studio doesn't correctly handle it, resulting in false errors in the IDE (but not when compiling).
Per https://en.cppreference.com/w/cpp/preprocessor/replace#Function-like_macros C++20 introduced a workaround, where `__VA_OPT__(, )` generates a comma if and only if `__VA_ARGS__` is non-empty.
This PR replaces all occurrences, with the exception of Externals, DSPSpy (which is not likely to be edited in MSVC and does not target C++20 currently), and JitArm64_Integer.cpp (which uses `Function(__VA_ARGS__)`, and thus does not ever need a comma).
We use Dolphin code (specifically Common's ASSERT) from ImGui, and that will use C++20 features in the next commit, so ImGui needs to be built with C++20 for that to work properly.
Fixes https://bugs.dolphin-emu.org/issues/13017. With uCode switching, the existing instance of AXUCode is re-activated when GBAUCode is done, but if the state remains as WaitingForNextTask, it won't be able to do anything. Instead, it needs to be in WaitingForCmdListSize.
(When the AX uCode is resumed, startpc is set to 0x0030, at least for 0x07f88145; this is the same location as MAIL_RESUME jumps to, so DSP_RESUME should be sent when the resuming happens; that's already handled by AXUCode::Update.)
Prior to 7854bd7109, this was used by the debugger for the OpenGL and D3D9 plugins to control logging (via PRIM_LOG and INFO_LOG/DEBUG_LOG in VideoCommon code; PRIM_LOG was changed in 77215fd27c), and also framedumping (removed in 64927a2f81 and 2d8515c0cf), shader dumping (removed in 2d8515c0cf and this commit), and texture dumping (removed in 54aeec7a8f). Apart from shader dumping, all of these features have modern alternatives, and shader source code can be seen in RenderDoc if "Enable API Validation Layers" is checked (which also enables source attachment), so there's no point in keeping this around.
This normalization was added in 02ac5e95c8, and changed to use floats in 4bf031c064. The conversion to floats means that sometimes there is insufficient precision for the normalization process, which results in values of NaN or infinity. Performing the whole process with doubles prevents that, but games also sometimes set the values to NaN or infinity directly (possibly accidentally due to the values not being initialized due to them not being used in the current configuration?).
The version of Mesa currently in use on FifoCI (20.3.5) has issues with NaN. Although this bug has been fixed (https://gitlab.freedesktop.org/mesa/mesa/-/commit/b3f3287eac066eae16dce0e47aad3229dcff8257 in 21.2.0), FifoCI is stuck with the older version.
This change may or may not be incorrect, but it should result in the same behavior as already present in Dolphin, while working around the Mesa bug.
CARDUCode, GBAUCode, and INITUCode previously didn't have an implementation of it. In practice it's unlikely that this caused an issue, since these uCodes are only active for a few frames at most, but now that GBAUCode doesn't have global state, we can implement it there. I also implemented it for CARDUCode, although our CARDUCode implementation does not have all states handled yet - this is simply future-proofing so that when the card uCode is properly implemented, the save state version does not need to be bumped. INITUCode does not have any state to save, though.
The accuracy improvements are:
* The request mail must be 0xabba0000 exactly; both the low and high parts are checked
* The address is masked with 0x0fffffff
* Before, the global state meant that after the GBA uCode had been used once, it would accept 0xcdd1 commands immediately. Now, it only accepts them after execution has finished.
These lookup tables total 4 megabytes, and contain data that's entirely redundant to the actual cache state (as part of an optimization, though I'm not sure whether the optimization actually is useful). This change instead recomputes these lookup tables when loading the state (which involves filling the lookup table with a marker (0xff), and then setting the 128 * 8 valid entries (1 kilobyte)).
Before, we used a replace hook and didn't write anything there. Now, we write a BLR instruction to immediately return, and then use a start hook. This makes the behavior a bit clearer (though it shoudln't matter in practice).
Most of these correspond to changes made in devkitPro/libogc@b1b8ecab3a.
The numeric vlaues of ACC0 and ACC1 in Dolphin are different (see b06d38389b, though I'm not sure when this difference first appeared). Technically it's not even necessary to list the registers at the start like this anymore, but old programs do it, so it seems useful to have a test that covers it.
The binary itself does not need to be changed; the warnings were simply stating that "although you wrote $ACL0, the generated binary instead is using $ACC0" or similar; by changing the code to use $ACC0 directly the warnings are resolved.
https://bugs.dolphin-emu.org/issues/12977 indicates that this happens on startup of Spider-Man 2, even in single-core. I don't have the game, so I can't directly determine why this is happening, but presumably real hardware does not hang in this case, so we can make it less obtrusive.
I'm not sure what the XMM0 check was supposed to be, but the 0xCC008000 one is for the fifo and is handled elsewhere now (look for `optimizeGatherPipe`).
This struct is the only one in BPMemory that uses u64 as its base. These fields are to allow viewing it as two u32s instead. It's not used by Dolphin right now, but it is used in the copy of BPMemory.h used by hwtests.
This also changes the behavior for the invalid gamma value, which was confirmed to behave the same as 2.2.
Note that currently, the gamma value is only used for XFB copies, even though hardware testing indicates it also works for EFB copies. This will be changed in a later commit.
The only remaining casts for these types that I know of are in TextureInfo (where format_name is set to the int version of the format, and since that affects filenames and probably would break resource packs, I'm not changing it) and in TextureDecoder_Common's TexDecoder_DrawOverlay, which will be handled separately.
Before, Free Look would accept background input by default, which means it was easy to accidentally move the camera while typing in another window. (This is because HotkeyScheduler::Run sets the input gate to `true` after it's copied the hotkey state, supposedly for other threads (though `SetInputGate` uses a `thread_local` variable so I'm not 100% sure that's correct) and for the GBA windows (which always accept unfocused input, presumably because they won't be focused normally).
These values were obtained by setting a breakpoint at a game's entry point, and then observing the register values with Dolphin's register widget.
There are other registers that aren't handled by this PR, including CR, XER, SRR0, SRR1, and "Int Mask" (as well as most of the GPRs). They could be added in a later PR if it turns out that their values matter, but probably most of them don't.
This fixes Datel titles booting with the IPL skipped (see https://bugs.dolphin-emu.org/issues/8223), though when booted this way they are currently missing textures. Due to somewhat janky code, Datel overwrites the syscall interrupt handler and then immediately triggers it (with the `sc` instruction) before they restore the correct one. This works on real hardware due to icache, and also works in Dolphin when the IPL runs due to icache, but prior to this change `HID0.ICE` defaulted to 0 so icache was not enabled when the IPL was skipped.
DSPHLE::Initialize sets the halt and init bits to true (i.e. m_dsp_control.Hex starts as 0x804), which is reasonable behavior (this is the state the DSP will be in when starting a game from the IPL, as after `__OSStopAudioSystem` the control register is 0x804).
However, CMailHandler::m_halted defaults to false, and we only call CMailHandler::SetHalted in DSPHLE::DSP_WriteControlRegister when m_dsp_control.DSPHalt changes, so since DSPHalt defaults to true, if the first thing that happens is writing true to DSPHalt, we won't properly halt the mail handler.
Now, we call CMailHandler::SetHalted on startup. This fixes Datel titles when the IPL is skipped with DSP HLE (though this configuration only works once https://bugs.dolphin-emu.org/issues/8223 is fixed).
This fixes booting Datel titles with DSPHLE (see https://bugs.dolphin-emu.org/issues/12943). Datel messed up their DSP initialization code, so it only works by receiving a mail later on, but if halting isn't implemented then it receives the mail too early and hangs.
It's cleared whenever the uCode changes, so there's no reason to clear it in a destructor or during initialization.
I've also renamed it to ClearPending.
The # option means that 0x is prepended already, so the old code resulted in 0x0xDEADBEEF instead of the intended 0xDEADBEEF. WriteMailboxLow was already correct.
This change makes assembling DSPTestText match DSPTestBinary, though HermesText doesn't yet match HermesBinary.
The test data was originally added on April 18, 2009 in e7e4ef4481. Then, set16 and set40 were swapped on April 22, 2009 89178f411c, which updated the DSPSpy version of dsp_code, but not the version in DSPTool used for testing. So, when the test was made, the assembled data matched the text, but a few days after it no longer did.
Similarly, on Jul 7, 2009 in 1654c582ab the conditional instructions were adjusted, and 0x1706 was changed from JRL to JRNC and 0x0297 was changed from JGE to JC.
For what it's worth, devkitPro made the same changes on May 31, 2010 in https://github.com/devkitPro/gamecube-tools/commit/8a65c85c9b4748ed3dab3c0c85aeb0df95d58cfb and updated their version of the asnd ucode (which is this ucode) on June 11, 2011 in https://github.com/devkitpro/libogc/commit/b1b8ecab3af3745c8df0b401abd512bdf5fcc011 (though this update also includes other feature changes). Note that at the time, they didn't reassemble the ucode unless they made changes to it; the assembled was stored in the repo until https://github.com/devkitPro/libogc/compare/bfb705fe1607a3031d18b65d603975b68a1cffd4~...d20f9bdcfb43260c6c759f4fb98d724931443f93.
This fixes the following failures with Hermes:
!! 0015 : 8e00 vs 8f00 - set16 vs set40
!! 016f : 8e00 vs 8f00 - set16 vs set40
and with Hermes:
!! 0014 : 8e00 vs 8f00 - set16 vs set40
!! 0063 : 8e00 vs 8f00 - set16 vs set40
!! 019b : 1706 vs 1701 - jrnc $AR0 vs jrl $AR0
!! 01bf : 0297 vs 0290 - jc 0x01dc vs jge 0x01dc
!! 01d2 : 0297 vs 0290 - jc 0x01dc vs jge 0x01dc
Hermes has the remaining failures:
!! 027b : 03c0 vs 03a0 - andcf $AC1.M, #0x8000 vs andf $AC1.M, #0x8000
!! 027d : 029d vs 0294 - jlz 0x027a vs jnz 0x027a
Before, both 1441 and 147f would disassemble as `lsr $acc0, #1`, when the second should be `lsr $acc0, #-1`, and both 14c1 and 14ff would be `asr $acc0, #1` when the second should be `asr $acc0, #-1`. I'm not entirely sure whether the minus signs actually make sense here, but this change is consistent with the assembler so that's an improvement at least.
devkitPro previously changed the formatting to not require negative signs for lsr and asr; this is probably something we should do in the future: https://github.com/devkitPro/gamecube-tools/commit/8a65c85c9b4748ed3dab3c0c85aeb0df95d58cfb
This fixes the HermesText and HermesBinary tests (HermesText already wrote `lsr $ACC0, #-5`, so this is consistent with what it used before.)
For instance, ending with 0x009e (which you can do with CW 0x009e) indicates a LRI $ac0.m instruction, but there is no immediate value to load, so before whatever garbage in memory existed after the end of the file was used.
The bounds-checking also previously assumed that IRAM or IROM was being used, both of which were exactly 0x1000 long.