你能用树莓派制作 Wii U 游戏手柄吗?

Lobsters Hottest 新闻

摘要

一篇详细的技术回顾,记录了尝试将树莓派改装成 Wii U 游戏手柄克隆体的过程,重点介绍了 Wi-Fi 芯片组兼容性问题,并发现 Orange Pi Zero 2W 的表现出人意料地更好。

<p><a href="https://lobste.rs/s/fu3icq/can_you_make_wii_u_gamepad_from_raspberry">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/08/03 01:37

TL;DR:树莓派可以改造成运行 Vanilla 的 Wii U 手柄克隆,但 Wi-Fi 芯片限制、解码器延迟和性能问题使它不实用——而 Orange Pi Zero 2W 出人意料地好用得多。 ## 回顾:Vanilla 与 Wi-Fi 问题 Wii U 手柄本质上就是一台微型电脑。它通过 Wi-Fi 连接主机,使用与蓝光光盘和 YouTube 相同的视频编解码器,理论上应该很容易被复刻。最大的障碍是任天堂对 Wi-Fi 协议的混淆处理。 此前的成果是 Vanilla,一个基于十年前概念验证项目 drc-sim 的 Wii U 手柄重实现,由 memahaxx 开发,后来 rolandoislas 接手。Vanilla 主要在 Linux 上运行,因为 Linux 提供了足够的底层控制能力来执行任天堂混淆过的 Wi-Fi 握手。但桌面 Linux 并不是一个好的手柄替代品,所以真正的目标是把 Vanilla 移植到能够真正看起来、用起来都像掌上控制器的硬件上。 这意味着要面对一个混乱的硬件兼容性问题。 ## 并非所有 Wi-Fi 适配器都一样 早期测试表明,许多 Wi-Fi 适配器都能工作,但有些却莫名其妙地不行。drc-sim 只推荐了一种芯片组:Ralink RT2800,以堪称最亲 Linux 的 Wi-Fi 芯片组之一而闻名。Vanilla 的目标是支持更多。 随着用户报告陆续出现,两个规律浮现出来: - Realtek 芯片组通常不行。 - Broadcom 芯片组通常不行。 这很烦人,因为 Realtek 和 Broadcom 是世界上最常见的两个 Wi-Fi 厂商。Realtek 主导 USB Wi-Fi 适配器市场;Broadcom 主导便携设备——手机、平板、笔记本电脑、树莓派,甚至任天堂 Switch。 ### Realtek:驱动问题 Realtek 适配器在 Linux 上很特殊,因为它们需要安装驱动。大多数 Linux 硬件由内核直接支持,但 Realtek 最流行的芯片组却没有。更糟糕的是,这个驱动并不是某个随意的社区项目——它是由 Realtek 自己开发的,却始终没有进入内核。 用 Realtek 适配器测试 Vanilla 时,在尝试与 Wii U 同步时早期就失败了,出现了一个神秘的 `CTRL-EVENT-ASSOC-REJECT` 错误。 翻查驱动源码后发现有许多分支,其中一个来自 rolandoislas——drc-sim 的维护者之一——显然是在尝试让它与 Wii U 配合工作。这个分支只能在超过十年的旧 Linux 版本上编译,并且与任何现代适配器都不兼容。将其补丁移植到更新的驱动上也无济于事。 接着出现了关键发现:有一个 Realtek 驱动完全不同。它不是 Realtek 代码的分支,而是从头开始编写的新代码,属于 `wireless-next`——一个用于在主线合并前开发新驱动的 Linux 内核分支。GitHub 用户 lwfinger 维护了一个反向移植,使其能在当前 Linux 版本上使用。 那个驱动与 Vanilla 配合完美。所以 Realtek 自己的驱动写得如此错误,以至于内核开发者从头重写了一遍,而原版驱动也破坏了 Vanilla。只要安装了正确的驱动,那些极其常见的 Realtek 适配器最终还是兼容的。 ### Broadcom 与 FullMAC 之墙 Broadcom 带来了另一个问题。Broadcom 适配器实际上可以同步,然后在连接时抛出同样的 `ASSOC-REJECT` 错误。但与 Realtek 不同,Broadcom 驱动已经在内核中,而且似乎通过了 Realtek 驱动未能通过的标准。仔细检查驱动后,发现它并没有阻止 Vanilla——它实际上几乎什么都没做。 问题归结为两种类型的 Wi-Fi 适配器: - **SoftMAC 适配器** 只是“笨”无线电。它们在比特和无线电波之间转换;所有 Wi-Fi 协议工作——安全握手、解析传入数据、格式化传出数据——都在主机 CPU 上以软件方式完成,通常由 `wpa_supplicant` 之类的程序处理。SoftMAC 设备是最便宜、最简单、最常见的设计。 - **FullMAC 适配器** 有自己的 CPU、内存和固件。它们本质上是一个完整的独立片上系统,自行处理 Wi-Fi 协议处理。 FullMAC 对 Vanilla 来说是个问题,因为认证握手被固化在芯片里。没有办法修改它以兼容 Wii U。即使尝试破解芯片的二进制 blob,也意味着要在完全没有文档的代码中摸索,而且为每个 FullMAC 芯片都这么做是不切实际的。 Broadcom 是 FullMAC 芯片的老手——现在基本上只做这个——这使得它们成了 Wii U 几乎无法逾越的墙。 Realtek 适配器之所以幸免,只是因为他们制造的是 SoftMAC 硬件,却写了一个 FullMAC 风格的驱动,自带一套独立的 Wi-Fi 标准实现。他们确实是把驱动写错了,所以一个更好的驱动能立刻修复问题。 ## 将 Vanilla 移植到树莓派 对于真正的手柄形状设备,观众投票选择了树莓派。从纸面上看这很合理:它运行 Linux,而且即使是最便宜的树莓派 Zero 也有 Wi-Fi、传感器、显示器和摄像头。 问题是:树莓派的 Wi-Fi 芯片是 Broadcom 的。另外,手柄工作在 5GHz,而树莓派板载 Wi-Fi 只有 2.4GHz。所以板载 Wi-Fi 无论如何都没用。但因为树莓派运行 Linux,可以插入一个兼容的 SoftMAC USB Wi-Fi 适配器来替代。 再看看其他单板计算机,Orange Pi Zero 3 和 2W——讽刺的是颜色是蓝色——是很强的竞争者,因为它们标配 5GHz Wi-Fi 和小天线。但测试其中一个时,又出现了另一个 FullMAC Wi-Fi 芯片,给出熟悉的 `ASSOC-REJECT` 错误。这使树莓派成了主要目标。 ## 让 Pi Zero 足够快 主要挑战是让 Vanilla 在入门级硬件上运行良好。开箱即用时,它跑得很差。选定的基线是 2015 年的原版树莓派 Zero——一台拇指大小的十年旧硬件。它很慢,但如果 Vanilla 能在那里运行,那它就能在任何地方运行。 计划是把一切精简到极致: - 不要 Qt 界面 - 不要桌面环境 - 不要窗口管理器 - 以尽可能少的开销直接绘制到 GPU 在十五天的直播开发中,一个新的前端用 SDL 编写,这是一个比 Qt 底层得多的库。SDL 提供了一条直接绘制到 GPU 的路径,使用的是 Linux 内核特性 **KMSDRM**——内核模式设置直接渲染管理器。 显示视频更困难。Pi Zero 的 CPU 无法实时解码 Wii U 的 480p 视频流。但 Pi Zero 有一个独立的硬件解码器芯片,能够解码高达 1080p30,绰绰有余。目标是让硬件解码的帧直接送到 GPU,而不经过 CPU 往返。 这出奇地复杂。树莓派支持这一点,但官方文档很难找到。一个 GitHub 上的示例项目作为参考,FFmpeg 也不得不替换为分支版本,因为连 FFmpeg 都无法开箱即用地做到这一点。几天之后,视频流终于通了。 出乎意料的是,视频流很流畅。屏幕上显示的一切,除了演示者的脸,都运行在一台 2015 年的 5 美元电脑上。 ## 半秒延迟问题 视频确实有一个巨大的问题:接近半秒的延迟,足以让游戏几乎无法玩。在 PC 上完全没有延迟。 一个 2013 年的晦涩论坛帖子描述了完全相同的问题:延迟在半秒到数秒之间。有回复甚至提到了 Wii U 手柄,同时想知道如何实现零延迟视频。楼主最终发现,调整 H.264 的一个 SPS 参数就能消除所有可感知的延迟。 H.264 是世界上最大的视频压缩算法之一,用于蓝光、网络视频和 Wii U 手柄。SPS,即 **序列参数集**,是嵌入在所有 H.264 视频流中的一个组件,存储了视频编码方式以及如何解码。这里的关键参数是 `max_dec_frame_buffering`,它告诉解码器要缓冲多少帧。 Vanilla 根本没有提供这个选项,所以解码器只能靠自己的最佳判断。PC 上 FFmpeg 的软件解码器选择不缓冲帧,但树莓派解码器会缓冲。缓冲帧存在是因为 H.264 使用时间压缩——存储帧之间的差异,包括同时引用过去和未来帧的双向帧。Wii U 不使用双向帧,但树莓派解码器还是加了延迟以防万一——除非通过 `max_dec_frame_buffering` 明确告知不要。 问题是:Wii U 实际上从不发送 SPS 参数。任天堂把它们硬编码在了手柄里。Vanilla 必须自己编造这些参数。而且 SPS 参数不是以常规方式存储的——它们使用 **Exp-Golomb** 编码压缩,使得在不编写完整解析器的情况下很难修改。 解决方案是让 Vanilla 动态生成自己的 SPS 参数。这花了一整天来弄清楚编码方式、理解每个参数、处理字节序。它成功了:半秒延迟终于消失了。 但仍有 4 帧延迟——好多了,但在游戏过程中仍然明显。 ## 为弱硬件优化 Vanilla 性能优化工作更有趣。简单的性能分析工具可以识别程序的慢速部分,不过 Pi Zero 太原始了,这些工具实际上无法在它上面运行。所以测试在主 PC 上进行,理论依据是慢代码在哪里都是慢的。 ### 数据包处理中的位反转 Wii U 发送的数据包头有反转的位。drc-sim 和 Vanilla 会把整个数据包进行位反转,然后再把数据部分反转回来。位反转在 x86 上开销很大,而且 Pi Zero 太旧,无法使用 ARM 专用的位反转指令。这每帧要花掉几毫秒——而 60 FPS 的一帧也只有 16 毫秒。 只对实际读取的头字段做位反转,跳过了 99% 的处理。测试不同的反转方法后,找到了一个明显更快的优胜者,比 drc-sim 的手动方法快好几倍,使 Pi 上的位反转降到 1 毫秒以下。 ### 电池状态错误 Vanilla 尝试把 Linux 的实际电池状态发送给 Wii U,但只应每两秒发送一次。限流器包含一个致命错误,导致它什么也没做,所以 Vanilla 每帧都会读取电池状态。这对 CPU 造成了很大压力,尽管 PC 和树莓派都不是靠电池运行的。 几个月后,这个错误被重新发现,并且在另一段代码中写了第二个限流器。直到剪辑视频时,演示者才意识到两个限流器都存在。坏掉的那个被移除了。 ### 绕过管道 Vanilla 分为两部分:前端和管道。管道负责 Wii U 连接,并将数据包中继给前端。这有好处——root 权限被限制在管道内,管道可以在虚拟机或另一台计算机上运行——但在同一台机器上,它只是浪费时间复制数据。优化版本允许前端直接接收数据包,在单机运行时完全绕过管道。 ### wpa_ctrl_recv 错误 管道有一个中心循环来检测断开连接,调用 `wpa_supplicant` 的 `wpa_ctrl_recv` 函数。演示者假设这是一个阻塞函数——它会等待直到有消息到达。事实并非如此。在 while 循环中疯狂调用它,占满了一个完整的 CPU 线程,这对 Pi Zero 来说是个大问题。由于 Wi-Fi 断开不需要毫秒级响应,检查改为每秒一次,处理开销可以忽略不计。 ## 一个新的通用前端 下一步是菜单系统。原计划是为每个平台编写不同的前端,但在它们之间保持功能一致将是一场噩梦。取而代之的是,一个用 SDL 构建的前端可以在任何地方工作,专为小型触摸屏设计,并贴合 Wii U 的美学风格。 这意味着要停止原来的 Qt 界面。桌面 PC 是 Wii U 手柄最不合理的平台,为它们维护单独的前端没有意义。新的 SDL 前端成为 Vanilla 的主力前端,可在 Pi 和任何其他平台上使用。 ## Pi Zero 2:仍然不够好 所有优化都让 Vanilla 运行得更流畅,但没有解决 4 帧视频延迟。2022 年发布的 Pi Zero 2 速度明显更快,价格与原版 Pi Zero 相同。它消除了偶发的卡顿点,但它的解码器仍然有同样的 4 帧延迟。 一个发送和接收解码器帧的小测试程序揭示了原因:必须先发送三帧,解码器才会返回任何内容,而且视频流永远落后三帧。再加上一帧用于垂直同步,就解释了总共 4 帧的延迟。 FFmpeg 的软件解码器没有延迟,但对 Pi Zero 1 来说太慢了。Pi Zero 2 能处理得更好,但还不够好——CPU 勉强跟不上,导致严重的视频损坏。 结论:两款树莓派 Zero 都不是真正适合的手柄替代品。它们能做到,但体验明显更差。 ## Orange Pi 的惊喜 抽屉里那个 Orange Pi 没有关于解码器延迟的文档,但值得一试。测试程序被重新适配到 Orange Pi 的解码器——它立即返回了帧。没有强制延迟。 花了几天时间让 Orange Pi 的解码器-显示管线在 Vanilla 中工作之后,出现了新问题:Orange Pi 的 GPU 要求纹理宽度能被 64 整除。Wii U 的视频宽度不满足这个要求。解码器已经将宽度填充到能被 16 整除,但这还不够。解码器的对齐方式可以配置,但只能通过修改 Linux 驱动的源代码。 回报是:一个无延迟的手柄克隆。不是字面意义上的零延迟,但实际上与原版手柄相当。而且 Orange Pi Zero 比树莓派 Zero 强大得多,没有明显的卡顿点。 讽刺的是,让 Orange Pi 有吸引力的 5GHz Wi-Fi 最终没用上。而那个未宣传的零延迟解码器让它遥遥领先于竞争对手。 ## 这真的实用吗? 即使 Orange Pi 能工作,也有很大的保留意见。Orange Pi Zero 2W 两年前很容易买到,13 美元,但当前的存储芯片危机已使一些报价推高到 150 美元。 单板计算机本身不是手柄。它还需要: - 屏幕 - 扬声器 - 麦克风 - 运动传感器 - 摄像头 - 外壳 这些零件至少需要 100 美元,还不算你用的板子。

相似文章

Windows NT 用于 GameCube/Wii

Hacker News Top

该项目将 Windows NT 移植到任天堂 GameCube 和 Wii 主机,支持多种输入设备和驱动程序。它是开源的,可在 GitHub 上获取。

Show HN:Pokémon Emerald 移植到 Raspberry Pi Pico 2

Hacker News Top

一位开发者将 Pokémon Emerald 移植到 Raspberry Pi Pico 2 (RP2350) 微控制器上原生运行,通过将 GBA 游戏重新编译为 Cortex-M33,并在第二个核心上重新实现 PPU,实现了 60 fps 的 HDMI 输出。