Skip to content

New Wiimote library (WPAD2), bt-embedded#258

Draft
mardy wants to merge 4 commits intodevkitPro:masterfrom
mardy:btembedded
Draft

New Wiimote library (WPAD2), bt-embedded#258
mardy wants to merge 4 commits intodevkitPro:masterfrom
mardy:btembedded

Conversation

@mardy
Copy link
Contributor

@mardy mardy commented Mar 10, 2026

OK, this is finally ready to be shared with more eyes :-)

This PR adds two new libraries to libogc:

Motivation

Supporting more bluetooth devices other than just wiimotes. I initially tried to connect to other bluetooth devices using lwbt, but unfortunately it's impossible to install callbacks on its L2CAP layer, which is taylored around Wiimotes support only. I wrote bt-embedded to work around this limitation, designing it in such a way that different parts of the same program could independently create their BteClient instance and work each with its own bluetooth devices, without necessarily know of each other (of course, one still needs to be careful about threading and stuff, as the event loop is just one). The obex.c example in bt-embedded shows how it's possible to transfer a file from the Wii to a PC, so there isn't really anything so special about the Wii bluetooth module that would render it unsuitable for other uses too.

The secondary reason for bt-embedded was to get something that would work in the Starlet CPU, as I think there's hope to improve fakemote to support bluetooth controllers too.

Advantages of WPAD2 + bt-embedded

Please read bt-embedded's README as well, since it lists a few architectural choices that make it more efficient than lwbt and BTE (in particular to memory allocations and unnecessary copies of data). I did run a test on a simple program (a modified version of the wiimote.c from the wii-examples repo), and the exact same program uses quite some less memory when built with WPAD2:

Available MEM1 Available MEM2
wiiuse + lwbt 23617 KB 54302 KB
bt-embedded + WPAD2 23941 KB 54357 KB
Difference +324 KB +55 KB

(numbers obtained by computing SYS_GetArenaHi() - SYS_GetArenaLo() and SYS_GetArena2Hi() - SYS_GetArena2Lo())

This is mainly due to a reduction of the buffer sizes (lwbt allocates oversized buffers for the incoming packets, in respect to the actual MTU), reduction of memory allocations and static variables.

Risks

bt-embedded comes with a test suite with rather good coverage, which is also executed under valgrind. WPAD2 has no unit tests, but I can add them if required (with the limitation that they would be run on the host machine, so some mocking of tuxedo will be needed). And being completely new code, it's likely that there are bugs.

I do not own a GuitarHero3 controller or a balance board, so there might be issues there; the balance board probably won't work out of the box, as I see it's handled as a separate wiimote, and that might need more work. Feedback on this is especially welcome.

One area that might need special attention is latency. The wiiuse library is doing most of the work in the ISR routines themselves, and does not use a separate thread (other than for writing the CONF); WPAD2 + bt-embedded, on the other hand, almost don't do any work in the ISR routines: WPAD2 spawns a thread which runs bte_wait_events(), which waits for USB events and then processes them in the calling thread. While I haven't spotted any problems so far, it may be that this thread needs to be given a different priority than the main application's thread.

Deployment

Initially I was planning to reimplement wiiuse using bt-embedded, but then I noticed that, besides the WPAD_* functions, wiiuse also defines a lot of other functions (wiiuse_*) and types which publicly expose some lwip types, which are now deprecated by tuxedo. Therefore I'm not touching lwbt and wiiuse at all, but reimplementing the WPAD_* functions from scratch within WPAD2, using bt-embedded. While the growth of code in libogc might be frawn upon, this approach allows us to easily switch between the two implementations by changing

LIBS := ... -lwiiuse -lbte ...

to

LIBS := ... -lwpad2 -lbt-embedded ...

as long as the program does not directly use any wiiuse_* APIs (and, as far as I could see with a search in github, these functions are not used out there). This makes it easier to test any regression in WPAD2+bt-embedded.

State of this MR

This MR is currently marked as a draft, until I test more programs. bt-embedded is brought in as a git submodule; please let me know if this is fine (in which case I'll adjust the CI, since I doubt that it will work with submodules out of the box), or if you prefer to have a hard copy of the bt-embedded library within libogc (I can then create a script to update it). bt-embedded is not strictly tied to the Wii, it currently has a libusb backend too and it might be made to work on other devices too.

Please advise on what copyright I should set on WPAD2; it's currently a mess, but on my defense I can say that wiiuse code is also very confusing about copyright (different files have different copyrights, with many not having one at all), so I couldn't quite figure out which one it is.

I would be especially grateful is more people can review or test this. And I want to mention @Zarithya here because I know she's been doing a lot of work on the bluetooth stack, so she might be interested in this development.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant