Depending upon the desktop colour scheme, the light/dark
GameList backgrounds can cause the always white text
to become unreadble.
Use the common luminance approximation algorithm to
determine whether black text should be used instead.
This adds a hash check for imported contents. IOS does it for security;
we do it for a somewhat different reason, to catch content decryption
bugs before incorrectly decrypted contents get written to the NAND,
which can cause titles to be corrupted.
Either way, we should have been doing this check in all cases.
const, when used on value type parameters in the declaration,
is superfluous. This doesn't really convey any information to take note
of when using the function. This only matters in the definition when you
want to prevent accidental modification.
e.g.
// Header
void CalculateSomething(int lhs, int rhs);
// Definition
void CalculateSomething(const int lhs, const int rhs)
{
// lhs and rhs can't accidentally be modified
}
When the TMD doesn't exist on the NAND, IOS returns -106.
This commit also changes IsValid() to not check for the TMD validity,
since this is not always something we want. (IOS can have different
error codes when the TMD is missing, or even worse, simply assume
that the TMD is valid.)
IOS determines installed titles by looking at /title, not uid.sys,
which is more like a history of installed titles. And it does not care
at all about the installed TMD (or even if it is present at all).
This moves all the byte swapping utilities into a header named Swap.h.
A dedicated header is much more preferable here due to the size of the
code itself. In general usage throughout the codebase, CommonFuncs.h was
generally only included for these functions anyway. These being in their
own header avoids dumping the lesser used utilities into scope. As well
as providing a localized area for more utilities related to byte
swapping in the future (should they be needed). This also makes it nicer
to identify which files depend on the byte swapping utilities in
particular.
Since this is a completely new header, moving the code uncovered a few
indirect includes, as well as making some other inclusions unnecessary.
Not only this is pretty pointless because there is a load and save button on the appropriate panels, but for the breakpoints one, it caused an error while mapping the memory since adding memory breakpoint requires to update the DBAT and this is done too early (right after boot). This also only worked if you had the right panel on making it even more useless because it would fail to laod if you didn't have the right panel on. It's better to just let the user click load and save.
This removes wrappers for ES_DIVerify and ES::LoadWAD. They are not
really useful as we can simply call the ES function directly, and
it is actually somewhat confusing because both functions are static
and are not tied to a particular ES instance.
This allows Dolphin to stay up-to-date about what title is currently
running, which fixes savestates, screenshots, etc. after an ES_Launch.
Same limitation as with MIOS: currently, GameINIs are not reloaded,
because it's a pain with the current config system. It'll happen
when the new config system is done, and this commit makes it much
easier to do!
Some members are shared between ES instances, and they are just global
variables in IOS.
This is more efficient than getting the installed titles or setting the
current active title tons of times for no reason.
This changes ES to keep track of the active title properly,
just like IOS:
* It is NOT changed on resource manager open/close.
* It is reset on IOS reload.
* It is changed by ES_DIVerify and ES_Launch.
IOS stores the active title in a structure like this:
struct ESTitleContext
{
Ticket* ticket;
TMD* tmd;
u32 active;
};
With this commit, we also do keep the Ticket and TMD around. This
makes some of the DI ioctlvs (which return data about the current
active title) trivial to implement in the future.
This fixes the System Menu not being able to see update partitions
and also allows us to change Dolphin's active game info in the future.
Currently, slowmem is used at any time that memory breakpoints are in use. This commit makes it so that whenever the DBAT gets updated, if the address is overllaping any memchecks, it forces the use of slowmem. This allows to keep fastmem for any other cases and noticably increases performance when using memory breakpoints.
This fixes ES_GetTMDView and ES_GetTMDViewSize to return -106
(FS_ENOENT) if the title does not exist (and more specifically when no
TMD exists in the NAND). This allows installed (or not installed) IOSes
to be detected properly.
It makes absolutely no sense to have asserts for what is obviously an
error condition. And they should definitely not cause Dolphin to crash
because it assumes that everything is valid, and Dolphin should not
report those to the user either, as it is very obviously a bug in the
emulated software and there is nothing the user (or we) can do.
This commit replaces all of the request asserts with proper checks
and adds missing checks for some ioctlvs. We still do not check sizes
yet; this will be done later.
Before #4581, an invocation of `SetBlendMode` could invoke
`glBlendEquationSeparate` and `glBlendFuncSeparate` even when it was
setting `glDisable(GL_BLEND)`. I couldn't figure out how to map the old
behavior over to the new BlendingState code, so I changed it to always
call the two blend functions.
Fixes https://bugs.dolphin-emu.org/issues/10120 : "Sonic Adventure 2
Battle: graphics crash when loading first Dark level".
Currently, slowmem is used at any time that memory breakpoints are in use. This commit makes it so that whenever the DBAT gets updated, if the address is overllaping any memchecks, it forces the use of slowmem. This allows to keep fastmem for any other cases and noticably increases performance when using memory breakpoints.
The vector was not constructed with the proper size, which results in a
buffer overflow as we were using memcpy.
This commit fixes that mistake and also uses a safer way of copying the
ticket view data (std::vector::insert instead of memcpy).
This commit fixes ES_Launch to work mostly the same as the real IOS
(except temporary, internal files such as /sys/launch.sys and title
handling; the latter will be handled in a future PR).
First of all, this adds two IOS functions, which correspond to two
IOS syscalls: 0x41 (boot_ppc) and 0x42 (boot_ios).
boot_ios() writes the new version to 0x3140, loads the new kernel,
which then proceeds to reinit IPC and load modules as part of its
boot process. Note that this doesn't include writing to any of the
other constants in the 0x3100 region.
In Dolphin, this is implemented by changing the active IOS
version variable, writing to 0x3140 and resetting all devices. This
has exactly the same effect as the real syscall.
The other syscall, boot_ppc(), writes code to the EXI boot buffer,
pokes all constants to memory before bootstrapping the PPC with a
binary from the NAND.
We skip the low level stuff and just load the DOL to memory (and set
the PPC's PC to 0x3400), which is essentially what IOS does.
The other change is mostly related to how ES_Launch is handled.
With a real IOS, if the launched title type is 00000001 (system) and
the title is not 1-2 (System Menu), ES calls boot_ios().
Otherwise, ES handles the launch as a PPC title. It reads the TMD
to determine the required IOS version. If it is the same, boot_ppc()
is called directly. If not, ES saves the title to launch to the NAND
before launching the new IOS. After the new IOS has finished booting,
it will notice the flag and then launch the requested title.
What this commit does is really just implement this logic into IOS HLE.
The result is a fix for a regression introduced by SetupMemory,
where reloading an IOS would have overwritten some OS constants.
This fixes booting games from the disc channel.
No idea why this wasn't implemented whereas ES_DeleteTicket and
ES_DeleteTitleContent were.
This probably fixes title deletion in old System Menus, and maybe
the new ones as well in some cases; I've seen 4.3 use this ioctlv.
On startup, wxWidgets pops up an assertion error:
> ./src/osx/menu_osx.cpp(648): assert ""IsAttached()"" failed in
> Refresh(): can't refresh unatteched menubar
Starting in #4916, upon startup wxWidgets pops up an assertion error:
> ./src/common/cmdline.cpp(527): assert ""Assert failure"" failed in
> FindOptionByAnyName(): Unknown option verbose
Fix this by overriding wxApp::OnCmdLineParsed to disable the default
handling (since we also disable the default options in
DolphinApp::OnInitCmdLine).
We already have a TMDReader, so let's actually use it.
And move ESFormats to IOS::ES, since it's definitely part of IOS.
This adds a DiscIO dependency on Core which will be fixed in a
follow-up PR.
The /tmp directory is cleared every time IOS boots up (when the FS
driver is initialized), *not* when /dev/fs is opened.
Although this should have no effect, it fixes the case where files
could be left in /tmp and seen before opening /dev/fs.
Gets some constants out of the ControllerEmu namespace, and modifies
ControlGroup so that it uses the enum type itself to represent the
underlying type, rather than a u32 value.
As this is a base class with virtuals, there needs to be an out-of-line
function definition to prevent the vtable of the class being placed within
every translation unit it's used in (i.e. every JIT implementation).
Getting and setting configuration from the base config layer are common
and repetitive tasks. This commit adds some simpler to use functions to
make the new system easier to work with.
Config::Get and Config::Set are intended to make switching from
SConfig a bit less painful. They always operate on the main system.
Example usage:
// before
auto base_layer = Config::GetLayer(Config::LayerType::Base);
auto core = base_layer->GetOrCreateSection(Config::System::Main, "Core");
u8 language;
core->Get("Language", &language, 0);
SetData("IPL.LNG", language);
// now
auto base_layer = Config::GetLayer(Config::LayerType::Base);
auto core = base_layer->GetOrCreateSection(Config::System::Main, "Core");
SetData("IPL.LNG", core->Get<u8>("Language", 0));
// or simply
SetData("IPL.LNG", Config::Get<u8>("Core", "Language", 0));
It is kind of silly to connect all of the configured Wii remotes (from
the user config; NOT netplay assigned remotes), then connect/disconnect
additional Wii remotes *after* the core has booted.
(The bWii check has been removed, because it's actually unneeded;
m_wiimote_map is always usable regardless of bWii. And we can't get
info about the currently running game without booting the core with our
current config system…)
This should fix Netplay trying to connect all configured Wii remotes.
Fixes a logic bug I introduced as part of #4942. We were not
handling the "read past EOF" case correctly, which caused
requested_read_length to underflow in some cases.
Also fixes a comparison (though this is unlikely to change anything).
Instead, the JitInterface namespace functions should be used instead. This
gets rid of all usages of the JIT global from the wxWidgets UI code.
The null check isn't needed as the JIT core would already need to be
initialized in order to be within a paused state. The null check is just a
remnant from 2011 that existed before the check for a paused state was
added.
This changes the read request handler to work just like IOS:
* To make things clearer, we now return early from error conditions,
instead of having nested ifs.
* IOS does an additional check on the requested read length, and
substracts the current seek position from it, if the read would
cause IOS to read past the EOF (not sure what the purpose of this
check is, but IOS does it, so we should too).
* The most significant one: IOS does *not* return the requested read
length, or update the file seek position with it. Instead, it uses
the *actual* read length.
As a result of simply doing what IOS does, this fixes _Mushroom Men_.
The game creates a save file, reads 2560 bytes from it, then
immediately writes 16384 bytes to it. With IOS, the first read does not
change the seek position at all, so the save data is written at
offset 0, not 2560. With Dolphin, the read erroneously set the
seek position to 2560, which caused the data to be written at
the wrong location.
Behavior confirmed by comparing IPC replies with IOS LLE and by looking
at the FS module in IOS.
What we actually care about is whether it's a GCZ file,
not whether it's compressed. (This commit doesn't change
the behavior, since the beginning of CompressSelection
discards items that aren't BlobType::GCZ or BlobType::PLAIN.)
- There's no clear definition of what it means for a GC/Wii game
to be compressed. GC games in GCZ are obviously compressed,
but what about formats like WBFS and CISO that just discard data?
- Hardcoded colors might have bad contrast with the used theme.
- It feels Windows XP to me.
YYCJ is one of the last titles to be completely broken in Dolphin.
It would hang right after the Wii remote screen. Looking at the
game's debug messages reveals that it was failing to find some of
its files.
IOS LLE booted the game just fine, which confirmed that it was an issue
with IOS HLE.
By comparing the ioctlv requests and responses with IOS, it turns out
that one of the very first ES replies was different between IOS HLE and
IOS: there was a mismatch for the content fd returned by ES.
Changing the initial content FD to what IOS returns fixes the issue.
IOS
000000: 00 00 00 08 00 00 00 00 00 00 00 07 00 00 00 09 ................
000010: 00 00 00 01 00 00 00 00 01 38 66 f0 00 00 00 20 .........8f....
000020: 00 00 00 00 00 00 00 00 00 00 00 00 81 36 d3 18 .............6..
000030: 81 36 d3 18 00 00 ff ff ff ff ff ff ff ff ff ff .6..............
Dolphin
000000: 00 00 00 08 06 00 00 00 00 00 00 07 00 00 00 09 ................
000010: 00 00 00 01 00 00 00 00 01 38 66 f0 00 00 00 20 .........8f....
000020: 00 00 00 00 00 00 00 00 00 00 00 00 81 36 d3 18 .............6..
000030: 81 36 d3 18 00 00 ff ff ff ff ff ff ff ff ff ff .6..............
So where did 0x6000000 come from?
4bd5674 changed "Wiimote" to "Wii Remote" in the GUI
(intentionally) but also did the same change for two INI
keys (seemingly unintentional, breaks backwards compatibility,
and is inconsistent with the INI's filename). This commit
reverts the INI keys but not the GUI strings.
This commit uses the same approach as cbd539e used for GameCube
sticks (but I made sure to avoid the bug that 56531a0 fixed).
Given a std::map can't have duplicate keys, iterating over the map
explicitly isn't necessary, and find() can just be used instead.
Also, instead of manually calling push_back() for every entry to
be added, the range constructor of std::vector can be used instead to add
the whole range all at once.
We (the Microsoft C++ team) use the dolphin project as part of our "Real world code" tests.
I noticed a few issues in windows specific code when building dolphin with the MSVC compiler
in its conformance mode (/permissive-). For more information on /permissive- see our blog
https://blogs.msdn.microsoft.com/vcblog/2016/11/16/permissive-switch/.
These changes are to address 3 different types of issues:
1) Use of qualified names in member declarations
struct A {
void A::f() { } // error C4596: illegal qualified name in member declaration
// remove redundant 'A::' to fix
};
2) Binding a non-const reference to a temporary
struct S{};
// If arg is in 'in' parameter, then it should be made const.
void func(S& arg){}
int main() {
//error C2664: 'void func(S &)': cannot convert argument 1 from 'S' to 'S &'
//note: A non-const reference may only be bound to an lvalue
func( S() );
//Work around this by creating a local, and using it to call the function
S s;
func( s );
}
3) Add missing #include <intrin.h>
Because of the workaround you are using in the code you will need to include
this. This is because of changes in the libraries and not /permissive-
This adds memory values for IOS11, 20, 30, 50, 51, 52, 60 and 70.
Unfortunately, IOS40 (in its working version) is not present on NUS, so
constants for that one are still missing.
This is something I removed by mistake. It didn't break anything in
most titles, but the Mii Channel *requires* write requests to
/dev/usb/kbd to succeed before exiting, so this commit readds the stub.
The latest version has tons of security fixes (which is expected for a
library such as mbedtls).
Updating also allows getting rid of a few deprecation warnings.
Turns out it is completely unneeded and it actually works better
*without* it.
Just try launching the system menu from the HBC; in current master, it
will disconnect the remote and not connect it automatically again. With
this change, it will.
The recent IOS initialization changes caused the Bluetooth device to
no longer exist before "starting" IOS (as it should be…), which meant
that Core could not activate Wii remotes during the boot process
anymore.
But that is actually completely useless, because we can just have the
emulated Bluetooth code itself activate Wii remotes as appropriate,
at the right moment.
wxWidgets headers don't play well with some of the macros defined in
Windows headers and perform their own magic to fix things, as long as
they're included entirely either before or after any Windows headers.
This file can cause a conflict in other DolphinWX files because NetPlay
headers directly include ENet headers, which leak Windows header macros.
To fix this, explicitly tell wxWidgets here that it needs to re-clean
macros.
We can return early from invalid conditions, which allows getting rid
of quite a few levels of indentation.
And let's not duplicate the new_position > file_size check.
ControllerEmu::Control instances have a unique_ptr<ControlReference>
member, which is passed either an InputReference or OutputReference.
Without this virtual destructor, deleting a derived class through a
pointer to the base class is undefined behavior.
This prevents Dolphin from writing to /sys/uid.sys (on the host; root
partition) when installing a WAD before starting emulation, because
the session root is not initialized at that moment.
Incidentally, this also gets rid of a singleton.
instruction tables
Previously, all of the internals that handled how the instruction tables
are initialized were exposed externally. However, this can all be made
private to each CPU backend.
If each backend has an Init() function, then this is where the instruction
tables should be initialized, it shouldn't be the responsibility of
external code to ensure internal validity.
This allows for getting rid of all the table initialization shenanigans
within JitInterface and PPCTables.
ControllerEmu, the class, is essentially acting like a namespace for
ControlGroup. This makes it impossible to forward declare any of the
internals. It also globs a bunch of classes together which is kind of a
pain to manage.
This splits ControlGroup and the classes it contains into their own source
files and situates them all within a namespace, which gets them out of
global scope.
Since this allows forward declarations for the once-internal classes, it
now requires significantly less files to be rebuilt if anything is changed
in the ControllerEmu portion of code.
It does not split out the settings classes yet, however, as it
would be preferable to make a settings base class that all settings derive
from, but this would be a functional change -- this commit only intends to
move around existing code. Extracting the settings class will be done in
another commit.
Several of the things done while performing a scan are logically their own
behavior (e.g. loading a titles file, checking if an entry should be added, etc).
The three parameter AnalogStick constructor takes an internal name, a
display name, and a default radius argument. The delegated constructor is
the one that calls the ControlGroup constructor, setting the group type,
so passing the group type here is a logic bug.
The only reason this appeared to work despite this bug is because
GROUP_TYPE_STICK has a value of 1, and the default radius value used for
attachment sticks is 1.0.
This implements MIOS's PPC bootstrapping functionality, which enables
users to start a GameCube game from the Wii System Menu.
Because we aren't doing Starlet LLE (and don't have a boot1), we can
just jump to MIOS when the emulated software does an ES_LAUNCH or uses
ioctlv 0x25 to launch BC.
Note that the process is more complex on a real Wii and goes through
several more steps before getting to MIOS:
* The System Menu detects a GameCube disc and launches BC (1-100)
instead of the game. [Dolphin does this too.]
* BC, which is reportedly very similar to boot1, lowers the Hollywood
clock speed to the Flipper's and then launches boot2.
* boot2 sees the lowered clock speed and launches MIOS (1-101) instead
of the System Menu.
MIOS runs instead of IOS in GC mode and has an embedded GC IPL (which
is the code actually responsible for loading the disc game) and a PPC
bootstrap code. To get things working properly, we simply need to load
both to memory, then jump to the bootstrap code at 0x3400.
Obviously, because of the way this works, a real MIOS is required.
It held a raw pointer to a IOS::HLE::Device::BluetoothEmu that is not
guaranteed to exist (and of course, nothing checked that it wasn't
nullptr), but what is more, it's totally unnecessary because we have
IOS::HLE::GetDeviceByName().
Since we cannot always inform the host that Wii remotes are
disconnected from ES, that is now done in BluetoothEmu's destructor.
Unless IOS failed at ES_Launch, it doesn't appear to write anything
back to the request after a launch, because the request is never
actually replied to in the normal way.
So let's just drop the writes to make things less confusing.
This ioctlv is used to launch BC. Not sure if that's useful,
since only the system menu is known to launch BC and it does that
through a regular ES_LAUNCH; but let's implement it anyway.
(Implementation based on IOS59.)
Some minor changes to make things slightly less confusing:
* Reinit doesn't actually init anything. It just adds static devices to
the map, so let's give it an actually descriptive name. And let's not
expose it in the header when it should not be.
* Reset's parameter name was changed from "force" -- which totally does
not describe what it does -- to "clear_devices".
* Add a reload function which handles the reload process properly
(reset all devices, set up memory values, re-add devices) and
without publicly exposing implementation details.
Shouldn't make any difference in practice because
both IsRecordingInput and IsNetPlayRunning should
be false if a temporary NAND isn't being set up,
but doing it this way is cleaner regardless.
Splits DVD reads up into smaller chunks so that data is available
before the final interrupt is triggered. This better simulates the DMA
that happens on a real device, which some games will take advantage of -
by either playing back data as it is loading or by using data that is
going to be overwritten shortly by an outstanding read.