IOS::HLE::IOCtlVRequest::Dump sometimes tries to call GetPointerForRange
with an address of 0 and a size of 0. Address 0 is valid, but we were
mistakenly also trying to check that address 3FFFFFFF is valid, which it
isn't.
Fixes https://bugs.dolphin-emu.org/issues/13514.
Typically when someone uses GetPointer, it's because they want to read
from a range of memory. GetPointer is unsafe to use for this. While it
does check that the passed-in address is valid, it doesn't know the size
of the range that will be accessed, so it can't check that the end
address is valid. The safer alternative GetPointerForRange should be
used instead.
Note that there is still the problem of many callers not checking for
nullptr.
This is part 2 of a series of changes removing the use of GetPointer
throughout the code base. After this, VideoCommon is the one major part
of Dolphin that remains.
Typically when someone uses GetPointer, it's because they want to read
from a range of memory. GetPointer is unsafe to use for this. While it
does check that the passed-in address is valid, it doesn't know the size
of the range that will be accessed, so it can't check that the end
address is valid. The safer alternative GetPointerForRange should be
used instead.
Note that there is still the problem of many callers not checking for
nullptr.
This is the first part of a series of changes that will remove the usage
of GetPointer in different parts of the code base. This commit gets rid
of every GetPointer call from our IOS code except for a particularly
tricky one in BluetoothEmuDevice.
Not sure if the behavior I'm implementing here is what real hardware
does, but since this is a buffer overflow, I'd like to get it fixed
quickly. Hardware verification can happen later.
https://bugs.dolphin-emu.org/issues/13506
Having to look up macros that are defined elsewhere makes the code
harder to reason about. The macros don't remove enough repetition to
justify their existence in my opinion.
With this, I intend to make it clearer that Auto, Force 4:3, Force 16:9
and Custom are really the same thing, just with the aspect ratio of the
simulated TV being selected in a different way. I also extended the
introduction in a way I feel will clarify things but which you are
welcome to bikeshed :)
I was thinking of this during the review of 41b19e262f, but wanted to
put it in a separate PR as to avoid blocking it on bikeshedding.
I'm a bit unsure what to do about the word "analog" in "analog TV". I
felt that repeating it for each of these options would be too
repetitive. I suppose there's a reason why we used the word originally,
but digital TVs do give you basically the same aspect ratio for GC/Wii
games as analog TVs. (Of course, whether it's 4:3-like or 16:9-like
depends on what aspect ratio you set in the TV's settings, but that's
the case for widescreen CRTs too.)
Google Play's policies require us to tell the user the size of any large
download.
The size seems to vary by just a megabyte or two across regions in my
testing, so I'm listing a rough size for all the regions.
I'm also taking the opportunity to shorten the message to make it easier
to read.
Because the wording of the Load Wii System Menu string can change
depending on the contents of the NAND, we should update that menu item in
a method that's guaranteed to get called every time the user opens the
menu rather than one that's only guaranteed to be called once.
Unlike ADD (immediate), MOV (register) treats SP as ZR. Therefore the
ADDI2R optimization that was added in 67791d227c can't optimize ADD to
MOV when exactly one of the registers is SP.
There currently isn't any code in Dolphin that calls ADDI2R with
parameters that would trigger this case.
Because the last commit made us use separate folders for GCPad and
GCKey profiles, we should also use separate game INI keys for them.
Otherwise setting e.g. PadProfile1 in a game INI will make both GCPad
and GCKey try to load it, typically with one of them succeeding and the
other one showing a panic alert due to the profile not existing in its
folder.
Better do this breaking change for GCKeys in the same PR as the other
breaking change rather than later.
After reading the previous commit, you might think "hold on, what's the
difference between GetProfileName and GetProfileDirectoryName"? These
two are being used for the exact same thing - figuring out where
profiles are stored - yet they return different values for certain
controllers like GC keyboards! As far as I can tell, the existing code
has been broken for GC keyboards since they were introduced a decade
ago. The GUI (and more recently, also InputCycler) would write and read
profiles in one location, and our code for loading profiles specified in
a game INI file would read profiles in another location.
This commit gets rid of the set of values used by the game INI code in
favor of the other set. This does breaking existing setups where a
GCKey profile has been configured in a game INI, but I think the number
of working such setups is vanishingly small. The alternative would make
existing GCKey profiles go missing from the profile dropdown in the GUI,
which I think would be more disruptive. The alternative would also force
new GCKey profiles into the same directory as GCPad profiles.
This commit also fixes a regression from d6c0f8e749. The Android GUI was
using GetProfileName to figure out what key to use in the game INI,
which made it use incorrect game INI entries for GameCube controller
profiles but not Wii Remote profiles. Now the Android GUI uses
GetProfileKey for this, fixing the problem.
By having getters for this information, other code that needs access to
the same information can call the getters instead of duplicating the
information.
This reverts the parts of commit c8c9928eb1 that made translatability
worse rather than better. Changing "Error in column %2" to "%1 in column
%2" not only means that the translators have to check the i18n comments
to know what word hides behind %1, but there's also the problem that
the translator might need to translate "Error" in this context
differently from the standalone string "Error". Having to copy-paste
some HTML tags may be annoying for translators, but it's a far less
serious problem.
This is another one of those games that has an optional screenshot
feature where the images end up all black if you have Store EFB Copies
to Texture Only turned on. Like for other such games, let's not force
Store EFB Copies to Texture Only off, since it's a large performance
impact for a feature most players won't use.
There's one wrinkle here. As part of teaching the player how to take
screenshots, the game forces the player to take a screenshot before it
lets them progress in the story. However, the game doesn't care what's
in the screenshot, so you can progress just fine even if Store EFB
Copies to Texture Only is turned on. I personally tested it.
So somehow I forgot that AArch64 uses three-operand encoding...
Fixes a regression from 6303416201 which manifested in various ways,
such as incorrect rendering of the Wind Waker title screen.
The codegen for the functions themselves, not for the emitted code.
This seems to save 32 bytes per function. We also get rid of the oddity
we had before where ANDI2R would do masking for 32-bit operations but
the other functions wouldn't.
The gate size is 79.37125 by default, and the step size is 0.5. Android
throws an exception if we try to show the slider with the value set to
something that isn't divisible by the step size. To avoid this problem,
round the value.
Combined with the previous commits, this finally fixes the bug where
Dolphin had a chance of crashing if you returned to it after Android
killed the Dolphin process.
This way, we ensure that game INI settings are properly applied. I don't
think we actually expose the affected settings on a per-game basis in
the UI, but still.
This way the Settings class doesn't contain a hardcoded reference to
a specific setting. And Settings.loadSettings no longer calls
getBoolean, which is a step towards fixing the crash when recreating
EmulationActivity after process death.
Normally we only flush registers right at the end of each PPC
instruction. However, for PPC instructions that use a lot of registers
one at a time, it's beneficial to do this flushing work in the middle
of the instruction instead, reducing the risk of register starvation
and improving pipelining.
This should have been done when rebasing 6cc4f593e5 after the merge of
3a00ff625e. There are no correctness implications as far as I know,
only very minor performance implications.
Dolphin would crash when running with a fastmem arena but without
fastmem. This regression was caused by merging 9192128c50 without
adapting it after the merge of 0606433404.
This has the same effect in the end, but in my opinion, doing it this
way makes it more clear for the reader why we can read from ppcState at
JIT time, something that makes no sense for everything else in ppcState.
By making the JIT cache check if the current state of MMCR0 and MMRC1
matches the state they had at the time the JIT block was compiled, we
solve a correctness issue (marked in a comment as a speed hack).
Not known to affect any games.
This must have broken in a rebase of one of my recently merged PRs.
Dolphin still worked correctly with this bug, for two reasons:
1. Most AArch64 users are not on Windows, and therefore normally do have
the entry points map.
2. When the bug was triggered, Dolphin would fall back to the slower
path rather than crashing.
Instead of shifting left by 1, we can first shift right by 2 and then
left by 3. This is both faster and smaller, because we get the right
shift for free with the masking and the left shift for free with the
address calculation. It also happens to match the pseudocode more
closely, which is always nice for readability.
This slightly improves instruction-level parallelism in Jit64's slow
dispatcher by shifting the PC left instead of the MSR.
In the past, this also enabled an optimization in JitArm64's fast path
where we could use LDP to load normalEntry and msrBits in one
instruction, but this was superseded by fd9c970.
Just to make the code easier to understand at a glance. I especially
found it a bit annoying to reason about whether callee-saved registers
like W28 were being used because we needed a callee-saved register or
just for no reason in particular.
X8 and up is what compilers normally use when they're not register
starved.
AArch64's handling of NaNs in arithmetic instructions matches PowerPC's
as long as no more than one of the operands is NaN. If we know that all
inputs except the last input are non-NaN, we can therefore skip checking
the last input. This is an optimization that in principle only works for
non-SIMD operations, but ps_sumX effectively is non-SIMD as far as the
arithmetic part of it is concerned, so we can use it there too.
FL_EVIL is only used for blocking instructions from being reordered.
There are three types of instructions which have FL_EVIL set:
1. CR operations. The previous commits improved our CR analysis
and removed FL_EVIL from these instructions.
2. Load/store operations. These are always blocked from reordering
due to always having canCauseException set.
3. isync. I don't know if we actually need to prevent reordering
around this one, since as far as I know we only do reorderings
that are guaranteed to not change the behavior of the program.
But just in case, I've renamed FL_EVIL to FL_NO_REORDER instead of
removing it entirely, so that it can be used for this instruction.
Other than the CR instructions, which we now analyze properly,
all the covered instructions are not integer operations and also
have either FL_ENDBLOCK or FL_EVIL set, so there are two other
checks in CanSwapAdjacentOps that will reject them.
This brings the analysis done for condition registers
more in line with the analysis done for GPRs and FPRs.
This gets rid of the old wantsCR member, which wasn't actually
used anyway. In case someone wants it again in the future, they
can compute the bitwise inverse of crDiscardable.
Instead of materializing the quiet bit in a register and ORing the NaN
with it, we can perform an arithmetic operation on the NaN. This is a
cycle or two slower on some CPUs in cases where generating the quiet bit
pipelined well, but this is farcode that rarely runs, so instruction
fetch latency is the bigger concern. And for non-SIMD cases, we also
save a register.
By using MOVI2R+MOVI2R+CSEL in the zero case instead of doing bitwise
operations on the output of the other MOVI2R+MOVI2R+CSEL, we avoid using
BFI, an instruction that takes two cycles on most CPUs. The instruction
count is the same and the pipelining should be at least equally good.