If the copy assignment operator is deleted, then the copy constructor
should be deleted as well, otherwise it's a hole in the API where copies
can be made (and if this were an intended case, it should be
documented).
So we delete the copy constructor and explicitly default the move
assignment and move constructor to signify this is intended to be a
move-only type.
Return a FileHandle which will automatically close the FD when
the handle goes out of scope. For the rare cases where this behaviour
is undesirable, the FD can be released from the handle.
This is the large change in the branch.
This lets us use either the host filesystem or (in the future) a NAND
image exactly the same way, and make sure the IPC emulation code
behaves identically. Less duplicated code.
Note that "FileIO" and "FS" were merged, because it actually doesn't
make a lot of sense to split them: IOS handles requests for both
/dev/fs and files in the same resource manager, and as it turns out,
/dev/fs commands can *also* be sent to non /dev/fs file descriptors!
If we kept /dev/fs and files split, there would be no way to
emulate that correctly. I'm not aware of anything that does that (yet?)
but I think it's important to be correct.
Now that we have a proper filesystem interface, it makes more sense
to return it instead of the emulated IOS device (which isn't
really usable for any purpose other than emulated IPC).
Extract the existing FS code into a HostBackend implementing
the filesystem interface.
Compared to the original code, this uses less static state.
The open host files map is now a member variable
as it should have been. Filesystem handles are now also easier
to savestate. Some variable names and log messages were cleaned up.
Nothing else has been changed.
Add a new FileSystem class that can be used to perform operations
on the emulated Wii filesystem.
This will allow separating the IPC code (reading from and writing to
memory to handle IOS FS commands) and the actual filesystem code
in a much better way.
This also paves the way for implementing another filesystem backend
in the future -- NAND images for more complete emulation, including
filesystem metadata like permissions or file orders, which some games
and homebrew actually care about -- without needing to make any more
changes to the other parts of the codebase, in addition to making
filesystem behaviour tests easier to write.
This adjusts IOS IPC timing to be closer to actual hardware:
* Emulate the IPC interrupt delay. On a real Wii, from the point of
view of the PPC, the IPC interrupt appears to fire about 100 TB ticks
after Y1/Y2 is seen.
* Fix the IPC acknowledgement delay. Dolphin was much, much too fast.
* Fix Device::GetDefaultReply to return more reasonable delays. Again,
Dolphin was way too fast. We now use a more realistic, average reply
time for most requests.
Note: the previous result from https://dolp.in/pr6374 is flawed.
GetTicketViews definitely takes more than 25µs to reply.
The reason the reply delay was so low is because an invalid
parameter was passed to the libogc wrapper, which causes it to
immediately return an error code (-4100).
* Fix the response delay for various replies that come from the kernel:
fd table full, unknown resource manager / device, invalid fd,
unknown IPC command.
Source: https://github.com/leoetlino/hwtests/blob/af320e4/iostest/ipc_timing.cpp
This commit changes devices to always return IPCCommandResult rather
than just a return code for Open() and Close() in order to be able
to better emulate reply timing.
In hindsight, I should have considered we would want to emulate
timing when I cleaned up the device interface, but alas.
This rectifies that mistake.
Unlike VEN, the endpoint is determined by the value at 8-12.
If it's non-zero, HID submits the request to the interrupt OUT
endpoint. Otherwise, the request is submitted to the IN endpoint.
This commit changes HIDv5 to keep track of endpoints (like IOS does)
and use them when submitting interrupt transfers.
This implements /dev/usb/hid v5, found in IOS57, IOS58 and IOS59.
This is an initial implementation that ignores some differences
with VEN because I lack understanding of what IOS is actually doing
sometimes. These are documented on the WiiBrew article:
https://wiibrew.org/wiki//dev/usb/hid_(v5)
One major difference that this implementation handles is about IDs.
It turns out Nintendo has decided to include the interface number in
the top byte of HIDv5 device IDs, unlike VEN -- even though everything
else about ioctl 1 is otherwise the same!
USBv5 IOS resource managers share most of their code. Some ioctls
are even completely the same! So let's separate the common code
from the VEN specific stuff to make HIDv5 easier to implement.
The descriptor copy code is not actually the same in HIDv4 and VEN,
so it did not make a lot of sense to put it in USB/Common.cpp.
Separate and move it to HIDv4 and VEN.
This cleanup is important because there are even more differences
between HIDv4 and HIDv5.
Fix the device ID struct to reflect the actual structure used by IOS.
It turns out that offset 2 is the internal device index. The reason
that field seemed to be "0x1e - interface_number" is that IOS only
keeps track of 32 devices and always looks for free entries from
the end of the internal array. With each USB interface being exposed
as a separate USBv5 device, "0x1e - interface_number" was mostly
correct... but wrong!
We also made the assumption that the interface number can be
identified from just a USBV5 device ID, which is definitely not true.
VEN (and HID) keep track of the interface number in the internal struct
instead of "reconstructing" it from the device ID (which is normally
not possible if we were generating IDs correctly)
This commit fixes all of these inaccuracies.