emukidid / swiss-gc

Swiss - The swiss army knife of GameCube homebrew
GNU General Public License v2.0
1.29k stars 93 forks source link

[Feature request]: Add either a time-out or manual cancel to mounting USB Gecko/SwissServer #837

Open vaguerant opened 1 year ago

vaguerant commented 1 year ago

Describe the feature

Currently, choosing USB Gecko as a medium before SwissServer is running leads to an endless loading bar and "Waiting for PC ..." I'm not aware of any way to cancel out of this screen and it doesn't seem to have any timer attached, unless I just didn't wait long enough. Without such options, this essentially hard-locks the console, forcing a manual reset.

Ideally, it should be possible to cancel out of the mount. If you don't want to handle running an input thread while trying to mount the server, a simple timeout would also be fine. Whatever's easy. This is not a major issue, I doubt many people are using SwissServer/USB Geckos and remaining vigilant about starting up SwissServer is a valid workaround in the meantime.

EDIT: There's two of us!

<w​ebhdx> ah, one thing that bugs me every time I test USB Geckos - it would be nice to add a timeout, right now it waits indefinitely for the PC

Add screenshots

No response

webhdx commented 11 months ago

I was referring to iplboot because it does the same if you have USB Gecko connected. It was even more annoying because it wouldn't let you boot Swiss at all. I've created a PR to change this: https://github.com/redolution/iplboot/pull/38

I've tried to fix it in Swiss but for some reason it doesn't work for me: https://github.com/webhdx/swiss-gc/commit/4c2748cc578e7a897026965a3c156494fa13c83b

I think probably some underlying functions use usb_recvbuffer_safe which spins indefinitely until it receives data from PC.

vaguerant commented 11 months ago

Yeah, looks like it uses both usb_sendbuffer_safe and usb_recvbuffer_safe. This comes closer, swapping both out for their _ex equivalents with 1 attempt (fourth argument).

diff --git a/cube/swiss/source/devices/usbgecko/usbgecko.c b/cube/swiss/source/devices/usbgecko/usbgecko.c
index ed09768b..6237ca43 100644
--- a/cube/swiss/source/devices/usbgecko/usbgecko.c
+++ b/cube/swiss/source/devices/usbgecko/usbgecko.c
@@ -49,10 +49,10 @@ u8 *get_buffer() {
 // Returns 1 if the PC side is ready, 0 otherwise
 s32 usbgecko_pc_ready() {
        // Ask PC, are you ready?
-       usb_sendbuffer_safe(1, &ASK_READY, 1);
+       usb_sendbuffer_safe_ex(1, &ASK_READY, 1, 1);

        // Try get a reply
-       usb_recvbuffer_safe(1, get_buffer(), 1);
+       usb_recvbuffer_safe_ex(1, get_buffer(), 1, 1);
        if(get_buffer()[0] == ANS_READY) {
                return 1;
        }

But then a new problem arises. Forcing retries to 0 with PAD B (or just waiting, I guess? I'm not testing that) causes Swiss to jump ahead to deviceHandler_USBGecko_readDir(). I think checking the Gecko status happens after attempting to read the directory, so we never reach the point of Swiss realizing the connection has failed.

I don't know enough C (or any language) to resolve that, but it seems pretty simple.