The current approach results in the UI thread creating a graphics device
whilst the core is running, leading to races on function pointers, and
potentially crashing.
Prior to this commit, the emitter would unconditionally emit a 10-byte
instruction known as MOVABS when loading a 64-bit immediate to a
register.
0: 48 b8 ef be ad de 00 movabs rax,0xdeadbeef
7: 00 00 00
With this change, it will instead rely on the fact that on x64 writes to
32-bit registers are automatically zero extended to 64-bits, allowing
us to emit a 5 or 6-bytes instruction with the same effect for certain
immediates.
0: b8 ef be ad de mov eax,0xdeadbeef
Fixes a critical regression from 8bb08d1ca6.
In that commit, I replaced a 1024 byte buffer with a SHCIEventCommand.
However, it looks like some Bluetooth adapters actually require such
a large buffer, so this change needs to be reverted.
This fixes severe image flickering in some cutscenes of Twin Snakes. The game appears to sometimes load a previously made XFB copy as a texture before it is actually rendered to the screen, which we took as an invitation to invalidate the XFB copy.
Prior to this commit, the emitter would unconditionally emit a 10-byte
instruction known as MOVABS when loading a 64-bit immediate to a
register.
0: 48 b8 ef be ad de ff movabs rax,0xffffffffdeadbeef
7: ff ff ff
With this change, it will instead emit a 7-byte instruction when it is
possible to express the 64-bit immediate using a signed 32-bit value.
0: 48 c7 c0 ef be ad de mov rax,0xffffffffdeadbeef
If, for whatever reason, the XFB has to be loaded from console memory, it's possible that the texture is returned at native resolution instead of EFB-scaled resolution. In this case, our xfb_rect.right adjustment must also happen at native resolution instead of scaled resolution.
The header of a Wii disc can be read from two places: The
unencrypted area at the beginning of the disc, or the beginning of
the game partition. The two copies are usually identical (except
for 0x60 and 0x61), but there are exceptions. For most of Dolphin's
history, we have been reading from the header inside the game
partition when getting metadata. This was however not the case
starting with 4.0-4901 and ending with 5.0-3762. This commit once
again makes Dolphin read metadata from the unencrypted header,
because of the following reasons that I recently was informed about:
- The "pink fish" disc has the game ID 410E01 in the unencrypted
header but the placeholder game ID RELSAB in the partition header.
- The revisions of some games differ between the two headers,
with the unencrypted one making more sense.
(See https://bugs.dolphin-emu.org/issues/11387)
For better or worse, this also means that sloppily hacked games where
only the game ID in the unencrypted header has been changed now will
use that modified game ID. And unlike with the partition header,
there is no signing or hashing that can tell us whether the
unencrypted header has been modified by someone other than Nintendo.
Dolphin has traditionally treated the SI IO buffer (128 bytes) as a set of
32 little endian u32s. This works out fine if you only ever read/write
using aligned 32bit accesses. Different sized accesses or misaligned reads
will mess it up. Byte swapping reads/writes will fix this up, but all the
SI devices that use the SI IO buffer need to be adjusted.
The LogManager code had trouble detecting the "/Source/Core/" substring
for two reasons, neither of which seemed to happen a few years ago:
1. __FILE__ is in lowercase on MSVC
2. __FILE__ uses backslash as the directory separator on MSVC
Fixes https://bugs.dolphin-emu.org/issues/11366
Several functions (and one variable) were being given external linkage.
Instead, relocate them all to anonymous namespaces to make them
internally linked.
Puts the comment in the header where it's more likely to be seen
initially. We can also remove the TODO, given doing nothing or returning
an error is what is generally done for the JIT interface if the JIT
instance isn't valid.
With 7aa305ea35 merged, all that remains
within Profiler.cpp is an unused function that just forwards to the
equivalent function within JitInterface. Given that, we can just remove
the source file.
This global belongs in the JitOptions structure, as it's a conditional
setting (A.K.A. option) that changes the behavior of what the JIT does.
Plus it keeps the scope of the variable constrained to the general area
it's intended to be used and nothing further.
swap32() has a const u8* overload that swaps the data being pointed to as
if it were a 32-bit word. We can just use that instead. It gets rid of
undefined behavior, as we're not type punning a pointer and dereferencing it,
and gets rid of the need to cast entirely.
In both cases of the x64 and AArch64 JITs, these would have const casted
away from them, followed by them being placed within an emitter and
having breakpoint instructions written in them.
In this case, we shouldn't be using const period if we're writing to the
emitted data.
Similar in nature to e28d063539 in which
this same change was applied to the x64 emitter.
There's no real requirement to make this const, and this should also
be decided by the calling code, considering we had places that would
simply cast away the const and carry on
Xlib supports many mouse buttons, though there are 9 standard buttons, and they aren't arranged like other mouse APIs. Using only 5 buttons was preventing the use of buttons besides left/right/middle click and the scroll wheel. Here's what all the standard buttons are:
1. left button
2. middle button (pressing the scroll wheel)
3. right button
4. turn scroll wheel up
5. turn scroll wheel down
6. push scroll wheel left
7. push scroll wheel right
8. 4th button (aka browser backward button)
9. 5th button (aka browser forward button)
The remaining button indices are non-standard and device-specific, and technically far more than 32 are supported, but this seems like a reasonable limit to avoid cluttering the list with tons of useless mouse buttons. What mouse has more than 32 buttons anyways?
Currently, each player buffers their own inputs and sends them to the
host. The host then relays those inputs to everyone else. Every player
waits on inputs from all players to be buffered before continuing. What
this means is all clients run in lockstep, and the total latency of
inputs cannot be lower than the sum of the 2 highest client ping times
in the game (in 3+ player sessions with people across the world, the
latency can be very high).
Host input authority mode changes it so players no longer buffer their
own inputs, and only send them to the host. The host stores only the
most recent input received from a player. The host then sends inputs
for all pads at the SI poll interval, similar to the existing code. If
a player sends inputs to slowly, their last received input is simply
sent again. If they send too quickly, inputs are dropped. This means
that the host has full control over what inputs are actually read by
the game, hence the name of the mode. Also, because the rate at which
inputs are received by SI is decoupled from the rate at which players
are sending inputs, clients are no longer dependent on each other. They
only care what the host is doing. This means that they can set their
buffer individually based on their latency to the host, rather than the
highest latency between any 2 players, allowing someone with lower ping
to the host to have less latency than someone else.
This is a catch to this: as a necessity of how the host's input sending
works, the host has 0 latency. There isn't a good way to fix this, as
input delay is now solely dependent on the real latency to the host's
server. Having differing latency between players would be considered
unfair for competitive play, but for casual play we don't really care.
For this reason though, combined with the potential for a few inputs to
be dropped on a bad connection, the old mode will remain and this new
mode is entirely optional.
This was causing a warning in the shader compiler, as the rgb components
were not initialized. Which shouldn't be an issue, as the rgb is not
used in the blend equation, only the alpha. However, the lack of
initialization causes crashes in Intel's D3D shader compiler, so we'll
play nice and initialize all the channels.
Added an option in General config to enable/disable usage statistics. Added a popup on first open if
the user would like to engage in reporting. Clicking cancel or out of the box opts out. Only
clicking 'Ok' will enable reporting. Also added a new android specific values to report.
Since we don't have a way (AFAIK) to dynamically collect the list of
available art assets, we hardcode a list of gameids with available
artwork inside Dolphin. It's not great, but I don't think it's a
terrible solution either.
Art has to be manually uploaded to our Discord app configuration, and we
have a limit of ~150 assets, so most likely we'll limit ourselves to a
small set of popular games.
Type punning like this is undefined behavior. Instead, we use std::memcpy to
copy the necessary data over, which is well defined (as it treats both
the source and destination as unsigned char).
At some point SetCRFieldBit was modified to operate on RSCRATCH, but the
function was only partially changed. As such, setting SO, GT or LT would
write the right bit to cr_field, but then cr_field would just get
overwritten with RSCRATCH, undoing the work.
also did these things
fixed crash from joining user that isn't hosting via a direct connection
current game stat can now pass to override the current game in config
uses ip endpoint from dolphin.org
Behaviorally, this belongs within the netplay client. The server will
always transmit a known RTC value, so it doesn't even need a global for
this. Given the client receives the packet containing said RTC value, we can
store it as a member variable and provide an accessor for reading that
value.
This removes another global variable within the netplay code.
The idea of this code was to not unroll loops, but it was completely broken.
So we've unrolled all loops, but only up to the second iteration.
Honestly, a better check would test if we branch to code which is already in the compiling block. But this is out of scope for now.
But testing shows that this unrolling actually improve the performance. So instead of fixing this bug, this check can be dropped.
Most settings which affect determinism will now be synced on NetPlay.
Additionally, there's a strict sync mode which will sync various
enhancements to prevent desync in games that use EFB reads.
This also adds a check for all players having the IPL.bin file, and
doesn't load it for anyone if someone is missing it. This prevents
desyncs caused by mismatched system fonts.
Additionally, the NetPlay window was getting too wide with checkboxes,
so FlowLayout has been introduced to make the checkboxes take up
multiple rows dynamically. However, there's some minor vertical
centering issues I haven't been able to solve, but it's better than a
ridiculously wide window.
This is accomplished by having SConfig::GetDirectoryForRegion no longer
return nullptr, as doing that was kind silly, considering we never
check for nullptr.
Basically everything here was race conditions in Qt callbacks, so I changed the client/server instances to std::shared_ptr and added null checks. It checks that the object exists in the callback, and the shared_ptr ensures it doesn't get destroyed until we're done with it.
MD5 check would also cause a segfault if you quit without cancelling it first, which was pretty silly.
This option completely disabled the DCBZ instruction. Users are toggling
this option in dolphin forks and using that same problematic config when
launching dolphin. Removing the option from dolphin will let the config be
ignored.
This adds the functionality of sending the host's save data (raw memory
cards, as well as GCI files and Wii saves with a matching GameID) to
all other clients. The data is compressed using LZO1X to greatly reduce
its size while keeping compression/decompression fast. Save
synchronization is enabled by default, and toggleable with a checkbox
in the NetPlay dialog.
On clicking start, if the option is enabled, game boot will be delayed
until all players have received the save data sent by the host. If any
player fails to receive it properly, boot will be cancelled to prevent
desyncs.
Our usage of glFinish() can cause driver crashes and/or lockups.
Please note that this disables the background shader compilation (i.e.
all shaders will be compiled on boot). There is no way around this.
Reduces the amount of dependencies dragged in by the main window's
header. This also removes MainWindow.h includes elsewhere where they
aren't necessary, reducing the amount of UI files that need to be
recompiled if the main window's header changes.
We don't want to write this setting to disk, as SConfig has problems
with leaking settings changed by GameINI into the base configs. The
result of this is that if someone plays an N64 VC game (or other game
where we disable this setting) the branch following option can get
unintentionally disabled globally, which will reduce performance in
many games and cause NetPlay to desync with users who still have it
enabled.
Lessens the amount of files that have to be recompiled if
ConfigManager.h is modified. This also removes an indirect inclusion
within DolphinQt/Main.cpp.
AVFormatContext::filename was deprecated in lavf 58.7.100 in favor
of AVFormatContext::url. Instead of adding version-checking logic,
just use the passed-in dump path instead.
Makes it less error-prone to get state data from analog sticks (no need
to pass any locals), and also allows direct assignment, letting the
retrieved data be const.
Makes it less error-prone to get state data from tilt controls (no need
to pass any pointers to locals), and also allows direct assignment,
letting the retrieved data be const.
Makes it less error-prone to get state data from sliders (no need
to pass any locals), and also allows direct assignment, letting the
retrieved data be const.
Makes it less error-prone to get state data from cursors (no need
to pass any pointers to locals), and also allows direct assignment,
letting the retrieved data be const.
Makes it less error-prone to get state data from analog sticks (no need
to pass any locals), and also allows direct assignment, letting the
retrieved data be const.
Ensures they match their naming within the definition of the function.
In EmulateSwing's case, one parameter was erroneously named tilt_group,
when it's actually supposed to be swing_group.
These aren't necessary in the prototype, however they do apply in the
definition of the function. This just cuts down on line noise within the
prototypes.
This is only ever read from externally, so we can expose a getter that ensures that
immutability, while making the actual instance internal. Given the
filling out of these settings depends on packets received by the client
instance, it makes more sense to make it a part of the client itself.
This trims off one lingering global.
This stops clients randomly deadlocking when a spectator leaves, as the mappings construct is not thread-safe and should not be written while the game is running.
Avoids dragging in a bunch of includes from the header files, and also
reduces the amount of files that need to be recompiled if one of those
included headers' source content is ever changed.
Previously we wouldn't indicate if saving or loading these files
happened to fail. In some cases we'd only print out to the logger, but
this is a pretty poor way to tell a user of the interface that something
went wrong in a direct way (the logging messages aren't able to be localized
either).
This packet is only used by the host to detect desyncs, and we don't really need to know the exact frame we desynced on (unless you're debugging, but you can just recompile for that), so it's perfectly fine to just send it less often. This makes it so the timebase packet is sent only every 60 frames, rather than every frame, which further cuts back on unnecessary bandwidth consumption.
PowerPCState's cr_val member is an array of u64s, so we can just use the
correct printf macro specifier within cinttypes. This also avoids
truncation on operating systems that use an LLP64 data model (like
Windows), where long is actually 32 bits in size, not 64-bit, which
could result in wonky values being printed, should Trace ever be used on
it.
define how many frames constitute a high or a low swing/shake when the
button is down. Also configurable is the number of frames to execute
the swing/shake after the button is released.
When disabled only inputs from TAS dialog are used.
When enabled inputs from TAS dialog are used, except when a change in
input is detected from a real controller, in this case the TAS value is
replaced with the real controller value.
Previously there was only one function under the NetPlay namespace,
which is kind of silly considering we have all of these other types
and functions existing outside of the namespace.
This moves the rest of them into the namespace.
This gets some general names, like Player, for example, out of the global namespace.
Works around a bug in QtCore that will cause crashes when
QFileSystemWatcher::addPath is called on a directory that is located on a
removable device (USB mass storage devices, etc.)
This should make the NetPlay dialog appear as a separate window in the taskbar on most systems, which makes more sense than a parented dialog as the user will leave it open for an extended period.
We want this setting to invalidate the cache because it may affect the appearance of textures in the rendered scene, therefore one would expect changing it while the game is running to have the expected effect immediately.
Initializing GraphicsWindow layout & children requires cooperation from
the graphics stack: on my system, for example, it causes a Vulkan
context to get created in order to get driver info. This is a slow
operation, and right now it is taking about 60-70% of the Dolphin
startup time on my system.
Move instead to a lazy-initialization model where the constructor
does nothing, instead offloading work to a separate Initialize() method
called before the window is shown.
I would expect this should be done for other larger parts of the UI,
especially the ones where creating widgets ends up triggering large IO
subsystems (I suspect controller configuration might be doing that).
(I'm not super happy with how this is implemented, but right now it's a
one-off, and it's a major complaint users have with the new UI. I
prioritized getting something working quickly...)