Normally, SI is polled at a rate defined by the game, and we have to send the pad state to other clients on every poll or else we'll desync. This can result in fairly high bandwidth usage, especially with multiple controllers, mostly due to UDP/IP overhead.
This change introduces an option to reduce the SI poll rate to once per frame, which may introduce up to one frame of additional latency, but will reduce bandwidth usage substantially, which is useful for users on very slow internet connections.
Polling SI less frequently than the game asked for did not seem to cause any problems in my testing, so this should be perfectly safe to do.
This makes it much more straightforward to access WiimoteDevice
instances and also keeps the implementation details of accessing those
instances in one spot.
Given as all external accesses to the WiimoteDevice instances go through
this function, we can make the other two private.
These can be moved into the RegisterColumn constructor, which avoids
potential allocations in the case a std::function would otherwise need
to allocate to hold all of it's captured data.
Also tidy up the inclusion order while we're at it.
Selecting Dummy or Memory Card would pass wrong values to EXI::ChangeDevice and not work as expected
Changing path had no effect until device was changed as it didn't call EXI::ChangeDevice at all
Makes the enum values strongly-typed and prevents the identifiers from
polluting the PowerPC namespace. This also cleans up the parameters of
some functions where we were accepting an ambiguous int type and
expecting the correct values to be passed in.
Now those parameters accept a PowerPC::CPUCore type only, making it
immediately obvious which values should be passed in. It also turns out
we were storing these core types into other structures as plain ints,
which have also been corrected.
As this type is used directly with the configuration code, we need to
provide our own overloaded insertion (<<) and extraction (>>) operators
in order to make it compatible with it. These are fairly trivial to
implement, so there's no issue here.
A minor adjustment to TryParse() was required, as our generic function
was doing the following:
N tmp = 0;
which is problematic, as custom types may not be able to have that
assignment performed (e.g. strongly-typed enums), so we change this to:
N tmp;
which is sufficient, as the value is attempted to be initialized
immediately under that statement.
Rather than introduce this handling in every system instruction that modifies
the FPSCR directly, we can instead just handle it within the data structure
instead, which avoids duplicating mask handling across instructions.
This also allows handling proper masking from the debugger register
windows themselves without duplicating masking behavior there either.