== DETAILS
For local netplay, it's useful to have your IP address easily
available. This commit makes the Information > Network Information
menu display the Wii U's IP address.
Change summary:
- Fix the logging init to be reentrant to avoid socket consumption
- Add implementation of POSIX `getifaddrs()` and `freeifaddrs()`
to `missing_libc_functions.c`
- Remove compiler directives protecting the code paths that call
`getifaddrs()` from being used in Wii U builds
== TESTING
Have tested locally, successfully get IP address information in
the Information > Network Information.
I think this may also fix NAT traversal. Will need to be tested.
== DETAILS
- remove extraneous '+' from a manually applied diff
- fix the net_listen.sh script so it works properly on
Mac OSX
== TESTING
Works locally.
- Did a test build to ensure RA built
- Copied over to my FTPservU sources and ensured no compile issues there
Looks solid. A lot cleaner, too.
@aliaspider
I used the code in `wiiu/` to bootstrap my own WiiU homebrew app; this
PR reflects some changes I needed to make, that might be useful upstream.
1. Clean up filesystem initialization
Filesystem driver initialization was lumped in with filesystem mounting;
and that was a problem in my project, because I needed to be able to remount
the SD card on the fly. So, now it's split up.
I've added a callback object named "hooks" that can be used by consuming
applications to handle filesystem mounting and unmounting. If these hooks are
not provided, then the existing default behavior occurs.
2. Expand socket handling
- add `SO_NONBLOCK` flag for non-blocking socket I/O
- add normal errno defines like `EWOULDBLOCK` `EAGAIN`.
3. Remove RetroArch dependencies
- the exception handler protects usage of version_git with
`#ifdef HAVE_GIT_VERSION` but not the include, so I added that.
It also technically depends on version.h, but I'm not touching that.
It's easy enough to implement and I needed the same functionality. I'm
not sure what the best solution for that dependency is.
- missing_libc_functions.c included features/features_cpu.h which is
a libretro include. This appears to be a stale include though, because
everything compiles and works without it.
- an ifdef referencing the RA "WIIU" define, rather than the devkitpro
"__wiiu__" define
== DETAILS
The broadcast address is a standard part of TCP/IP that is used to
send messages to everyone on the subnet. This patch updates the
logging code to do the following:
1. Derive the broadcast address from the Wii U's own IP address
and subnet mask. These can all be obtained at runtime, which
means we can...
2. Remove the PC_DEVELOPMENT_IP_ADDRESS define from Wii U's
Makefile, because compiling in an IP is no longer needed.
3. Rewrite the net_listen script to listen for broadcast packets
and print them out with timestamps.
Since it's using the broadcast address, the only requirement is
that the PC be on the same network subnet as the Wii U.
Because of the low overhead of UDP, I've made logging on by
default. This will make it a ton easier to get useful bug
reports from users.
=== DETAILS
Replaced includes for things that aren't standard library headers so
they use quotes instead of brackets.
Also fixed up a couple of headers that had include-order dependencies.
=== DETAILS
Since @aliaspider wants the `wiiu/` to be something of a mini-SDK, I've
reorganized the code I put in there:
- `wiiu/main.c` now only has the ELF/RPX entrypoints, and the code used
by those entrypoints, with RA code removed (e.g. swapped retro_sleep()
for usleep()). These entrypoints then call main() ...
- Moved `main()` and its support functions back into `frontend/drivers/platform_wiiu.c`
I also renamed some of the support functions I wrote, and better
organized them within the code.
- Moved `wiiu/input/` into the `input/` hierarchy:
* The joypad drivers now live in `input/drivers_joypad/wiiu/`
* The HID driver now lives in `input/drivers_hid/`
* The Wii U specific headers now live in `input/include/wiiu`
* I added `input/include` into the include search path to avoid
using really ugly relative includes
== DETAILS
The Wii U main entrypoints were embedded in the frontend driver,
which isn't a great place for them. Also, the `main()` method was
pretty long and monolithic. Now it's (much) less so.
Changes:
- Refactor out the main entrypoints into their own source files
(`wiiu/main.c` and `wiiu/main.h`)
- Optimize includes in both files, so only the minimum needed to
compile are included.
- The `main()` method is a lot easier to understand now. It's no longer
a confusing mess of ifdefs.
- There's a small amount of changes in the headers for future work, which
is switching kpad_driver to be callback-driven. The only change here is
to import the function that will be used, and define some data types.
Testing:
- Did local builds and confirmed build is successful
- Successfully loaded a core and switched among a few games
== DETAILS
So, the KPadRead function will sometimes return 0, but this doesn't mean
the wiimote is actually disconnected. It's usually something transient, like
the BT chip has nothing to send or whatever. I don't know.
So, I added a buffer so that it won't disconnect the pad without 5
consecutive 0-reads.
This is a temporary hack; a proper solution will use the Wii U's callback
mechanisms to do wiimote detection. But that's a separate project. This at
least prevents OSD spam.
== TESTING
Tested locally. Verified that connecting/disconnecting nunchuk during play
still works properly.
== DETAILS
This is the wiimote version of the same bug I previously fixed in the HID
driver, where disconnected pads didn't actually invoke the unregister task.
This has an extra wrinkle, in that we *also* need to invoke the unregister
task when the wiimote device changes (e.g. user plugs in a nunchuk or
classic controller).
Now, there's still the problem of the "disconnect" detection being broken; so
a consequence of this commit is OSD spam. However, the actual wiimote input
is processed successfully and there's no noticeable issues in the pad
handling.
== TESTING
Using Mario 3, I played a level in which I started as bare wiimote, then
hot-plugged the nunchuk, and the input switched automatically. At the
end of the level, I hot-unplugged the nunchuk and it automatically reverted
to horizontal layout; and the pad remained 100% responsive the entire time.
== DETAILS
- DS3 analog wasn't working mainly because I forgot to actually declare the
axes in input/input_autoconfig.c when declaring the pad. Whoops.
- I also moved the axis decoding logic to a more central place, because it
clearly is not Wii U specific.
- Removed some dead commented-out code
== TESTING
Can use analog inputs on both GCA and DS3. Tested in Mario 3 on Nestopia core.
Haven't tested with any actual analog games, but I did confirm via logging
that the correct ranges are produced.
== DETAILS
The Wii U GC adapter doesn't seem to like doing async reads if it is connected
via a USB hub. It seems to be device-specific, though, because my DS3 works
just fine through the same hub.
I tried creating a fallback to synchronous reads, but it resulted in a hard
lock of the system. So, for the time being, it's going to be a known
limitation. Might be solved by using a powered USB hub.
Learned that the cache alignment is 64, not 32, so the alignment math has
been updated. Thanks, @aliaspider for that info.
This should fix the issue where R/L buttons didn't register when doing
input detection.
This also brings the GC pad in line with the rest of the gamepads in
input_autodetect_builtin.c.
Also fixed a really stupid bug that was part of why analog inputs aren't
being read. Analog still isn't working, mind, but it's a lot closer to
working now that it's actually getting down into the pad driver level!
== DETAILS
TIL that it's bad to call synchronization code from callbacks.
To avoid that, I made the following changes:
- Implemented an atomic swap (see previous commit) to avoid explicit
locking when working with the event list
- ensure locks are only acquired in either the main thread or the
I/O polling thread
- use an explicit polling loop; we still use async reads, but the
read doesn't immediately re-invoke itself.
- remove the sleep in the polling thread.
- remove unnecessary locking in the thread cleanup call--verified that
the list can't be modified while it is being executed.
== TESTING
I tested locally, and was able to disconnect/reconnect USB devices several times without the worker thread getting deadlocked.
Fortunately, the gcc port implements the builtins and, from basic
testing, they seem to work.
This is only really useful on Wii U--other platforms have more
robust atomic operations, or aren't using gcc to build.
== DETAILS
- fix the bitshift math
- read the right bytes out of the ds3 data packet
- remove verbose logging in critical path
- stop caring about errors in the hid read loop -- seems to just
be benign "device not ready" -- or at least, that's what I'm assuming
given that the read eventually succeeds.
== TESTING
Played Mario 3 with the DS3 with no issues.
== DETAILS
- update to not try starting the read loop until after the device
is successfully initialized
- add new HID wrapper macros needed by ds3 driver
- add some debug logging to help with troubleshooting
- add button map for DS3
== TESTING
Tested with local build. DS3 init is not working.
== DETAILS
Whereas the last commit had a hack (that disabled the wiimote
driver in the process), this has.. well, a *different* hack that
allows pads to register in any order.
Note that due to the initialization routines, the gamepad will still
likely always get slot 0. Not sure if this can be overridden via config
or not.
== TESTING
Tested locally with GC adapter
== DETAILS
Now that I have a working implementation, it's time to tidy up a bit:
- there was no need for the HID subsystem's object data to have a reference
to the global hid state (since it's global), so removed it.
- refactored the users of that member to use the global state, defining
reusable macros.
- reorganized the information in *.h files
- removing the hid state also made the constructor changes to the hid driver
unneeded, so I reverted those changes.
== TESTING
Confirmed clean build. Haven't tested the build yet to make sure everything
still works, though.
== DETAILS
- Added a new method to the joypad_connection_t interface for
getting a single button
- wired everything into the hidpad driver
- for testing purposes, hacking the top-level joypad driver
so that kpad isn't used
- add a new RARCH_LOG_BUFFER method to verbosity for logging the
contents of a binary buffer (useful for writing/debugging pad drivers)
- fix a few bugs in the wiiu GC pad driver
The button mapping isn't quite right, and I'm not sure what's
going wrong.
== DETAILS
Trying to do weird pad math just wasn't working so I bit the bullet and just
let it allocate all 16 pads in the slot list, then just mark 0-4 as
connected so that the slot allocator would start at 5.
I can see it detect the pad, but no idea if it works. Out of time for
today.
== DETAILS
Turns out freeing memory that's already been freed is.. bad.
Fix two double-free instances; one due to over-freeing and the other
due to wrong order-of-operations causing a double free.
Also updated logging a little.
== TESTING
The GC adapter still clobbers slot 0, but the "emergency exit" sequence
works to quit RA cleanly.
== DETAILS
(I think)
- Uncomment the call in the read loop to start feeding packets to the
driver
- implement the GCA packet driver
- implement the pad interface
- fix indentations in GCA driver
== TESTING
Compiles. Haven't tested yet.
== DETAILS
Turns out the cause of the crash was a bad cast, resulting in a
function call to nowhere.
Also, I think the DSI exception handler only works on the primary core;
when this was happening in the background thread, I got a black
screen error instead.
Next up: finishing up the GCA driver.
== DETAILS
We're at a point where we need to do more than just
clean up a local data structure, so I've started
implementing the "detach" part of the code so that
everything gets cleaned up properly.
Also, added error handling inside the polling
thread.
== TESTING
Have not tested yet.
== DETAILS
I've created the concept of a hid_driver_instance_t which is basically
a central place to store the hid pad driver, hid subsystem driver,
the pad list, and the instance data for the above in a central location.
The HID pad device drivers can use it to perform HID operations in a
generic manner.
This is more-or-less a pause point so I can catch up with upstream.
== TESTING
Haven't tested this yet. Compiles without warnings though!
== DETAILS
- detect() methods in device_* files now check for VID/PID
instead of just returning false
- add "name" field on hid device, mainly for logging purposes
== TESTING
Verified my WiiU GC adapter detected properly
Add some timing functions so that we can know the time (woo-hoo?)
I use errno here, which worries me a bit. I wouldn't put it past
devkitPPC to have it as a null pointer or something.
Can confirm this makes XMB's clock work, much to @cucholix's delight;
I'm sure ;D
== DETAILS
When I split out wiiu_gamepad into multiple sub-drivers, I missed a spot.
The code expects the device type to be initialized to a magic number
(0xfd), and instead it was getting initalized to zero, which meant it
never triggered the detection process.
I re-added the initialization, and now it works.
== TESTING
Tested with nestopia core to confirm autodetect and game response works.
== DETAILS
1. Noticed that the HID driver wasn't loading after setting WIIU_HID=1. Found
that the HID driver init was ifdef'd out. Removed that.
2. Current theory around "System Memory Error 160-2203" is in-memory
corruption. So, to try to identify it:
- Created a routine that does a hex dump of the RPX over the logger. (I
have a python3 script that can extract the hex dump back into a binary
file). If a SME occurs with this routine enabled, we can see if the
corruption is happening at read-time, or somewhere between when we send
the RPX to the loader and try to execute it.
- I noticed that we allocate slightly more memory than the RPX actually
needs, and we don't zero the memory, which means there's a handful of
bytes at the end that could be anything. I added a call to memset() to
zero out the memory prior to loading the RPX off the SD card.
And, of course, after adding those, I haven't been able to reproduce the
System Memory Error, so maybe the uninitialized memory was the problem?
Here's hoping.