JRickey/BattleShip

GitHub: JRickey/BattleShip

BattleShip 是一款基于反编译技术构建的《任天堂明星大乱斗 N64》原生 PC 移植版,支持多平台运行并提供竞技增强与模组扩展能力。

Stars: 324 | Forks: 27

BattleShip

# BattleShip **BattleShip** 是 **Super Smash Bros. (N64)** 的 PC 移植版 —— 同时支持 **美版** (US) (NTSC-U v1.0) 和 **日版** (Japanese) (Nintendo All-Star! Dairantou Smash Brothers) 发行版 —— 基于 [VetriTheRetri/ssb-decomp-re](https://github.com/vetritheretri/ssb-decomp-re) 反编译项目构建,使用 [libultraship](https://github.com/Kenix3/libultraship) 实现原生 PC 的渲染 / 音频 / 输入,并使用 [Torch](https://github.com/HarbourMasters/Torch) 在构建时从 ROM 中提取资源。 原生运行于 macOS (Apple Silicon)、Linux、Windows 和 Android。 从 [GhostlyDark](https://github.com/GhostlyDark) [这里!](https://evilgames.eu/texture-packs/ssb-reloaded.htm#pc) 下载高清纹理包。 ## 本仓库不包含任何受版权保护的资源 **Nintendo 的任何资源(代码、纹理、音频、模型、文本、ROM 数据)均未提交到本仓库,也未随构建版本分发。** 本移植版是纯粹的 C/C++ 源代码树;每一字节的 Nintendo 所属数据都是在构建时从*您*提供的 ROM 中提取的。如果您没有合法的 Nintendo 64 版 Super Smash Bros. 副本,您将无法构建或运行本项目。 您需要提供自己的 ROM。反编译的游戏代码是按区域编译的,因此 US 和 JP 是独立的构建版本 —— 请构建与您的 ROM 匹配的版本 (`-DSSB64_VERSION=us|jp`,参见 [BUILDING.md](BUILDING.md))。受支持的标准 转储(内部名称 `SMASH BROTHERS`): | 版本 | 游戏代码 | SHA‑1 | MD5 | |---------|-----------|-------|-----| | **US** — NTSC-U v1.0 | `NALE` | `e2929e10fccc0aa84e5777227e798abc07cedabf` | `f7c52568a31aadf26e14dc2b6416b2ed` | | **JP** — Nintendo All-Star! Dairantou Smash Brothers v1.0 | `NALJ` | `4b71f0e01878696733eefa9c80d11c147ecb4984` | `66db457b130d31a286a23d6e4dd9726e` | 如果您的转储哈希值与其对应版本不匹配,则无法运行。 ## 功能 以下所有功能均可在游戏内的 ESC 菜单中切换。 ### 输入增强(按玩家设置) - **禁用摇杆跳跃** - **C 摇杆猛击** - **十字键跳跃** - **NRage 模拟摇杆重映射**,支持自定义各轴范围 ### 游戏玩法与对战选项 - **经典双人合作** — 以 2 人本地合作模式游玩原本为单人模式的经典模式,附带友军伤害开关 - **Z 取消辅助** — 自动 Z 取消以及 Z 取消失败时闪烁(L 取消练习辅助工具) - **竞技规则集** — 一键应用锦标赛规则,并在 Dream Land 启用中立复活点 - **禁用场景危险物** - **判定框视图** — 可视化攻击判定框 / 受击判定框 / 碰撞体 - **启动后直接进入 VS 角色选择界面**,**跳过结果界面**,**强制 CPU 等级为 9** - **解锁** — 解锁全部内容,或单独解锁角色(Captain Falcon, Jigglypuff, Luigi, Ness)及功能(Mushroom Kingdom,道具开关菜单,声音测试) ### 音频 - **音乐随机播放器** — 随机化场景背景音乐 - **音乐选择界面** — 为每个场景选择音轨 - 独立的主音量 / 音乐 / 音效 / 语音音量滑块 ### 渲染(由 libultraship / Fast3D 驱动) - 内部分辨率缩放,MSAA 抗锯齿,三点纹理过滤 - 完整的宽屏支持,包括超宽分辨率。 - 渲染后端选择(OpenGL / Metal / Direct3D),VSync,窗口化全屏,多窗口 - **后处理着色器支持**,内置着色器包下载器 ### 纹理与模组 - 桌面端*和* Android 端的**高清纹理包**(可选,直接从 `.zip` 中读取)。从 [evilgames.eu](https://evilgames.eu/texture-packs/ssb-reloaded.htm#pc) 下载 GhostlyDark 的纹理包。 - **原生 C 模组支持** — 使用 C 语言编写模组,在运行时编译(TinyCC),支持热重载、函数 detour 以及已记录的引擎/斗士事件目录。请参阅 [`docs/modding.md`](docs/modding.md)。*(仅限桌面版;Android 上已禁用脚本。)* ### 控制 - 由 **SDL2** 提供支持的手柄及震动功能,支持最多 4 个手柄即插即用路由 - 通过 **hidapi** 原生支持 **Raphnet** 适配器,最多 4 个通道 - 每个手柄独立的配置 UI 以及内置的 `gamecontrollerdb.txt` 映射数据库 ### 平台与体验优化 - 原生运行于 **macOS (Apple Silicon)、Linux、Windows 和 Android** - 首次运行时的 ROM 提取向导,内置更新检查器/下载器,以及 Discord Rich Presence ### 回滚 netcode 与联机对战 开发中。 ## 作者说明 ### 关于本项目 这是一个我独自开发并使用 Claude 辅助直到发布 v0.3-beta 的项目。为了发布第一个测试版,我夜以继日地工作了一个多月,随后又进行了长达 4 天的全天冲刺,修复从 v0.3-beta 到 v0.7-beta 的漏洞。时至今日,这已经不再是一个纯粹的 AI 项目。许多人贡献了他们的时间进行游戏测试,分享他们对游戏的理解,或是提供关于模组制作和竞技对战的经验;为项目带来了改进、漏洞修复、新功能建议和内容扩充。没有他们,项目就不会有今天的面貌。 如果您发现任何希望改进的地方,请在 Github 上创建 issue。我会进行修复。 本移植版启动时,原始的反编译进度仅有 96% 仅包含代码。剩余的 4% 是内部调试菜单和移植游戏本身不需要的 Libultra 函数。当时可重定位数据也尚未被反编译。移植工作正是基于这一前提设计的,这也是必须做出某些特定设计决策的原因。显然,我喜欢快速推进。 本项目使用了经过大量修改的 LibUltraShip 和 Torch,这两个模块显然无法开箱即用地支持所有的 N64 游戏,许多针对特定游戏的实现是必不可少的。原版游戏非常独特,它使用的渲染技术和 N64 硬件技巧是其他 LUS 项目从未需要考虑的。 对我来说,这是一个充满激情的项目。并非出于情怀,而是为了真正创造出些什么。我对原版游戏并没有太多的怀旧情结,因为小时候我并没有这款游戏,但我记得在朋友家玩过几次。激励我进行这项工作的原因是我有能力做到。因为这很困难,因为以前从未有人做过(至少没有开源过)。它耗费了我大量的个人时间,即使使用了 AI 也是如此。它迫使我发挥创造力,设计定制工具,并将 AI agents 限制在特定的框架内。 人们可能因为使用了 AI 而不喜欢它,这没关系。我不会与您的观点争辩,也不会试图说我的方式是做事的正确方式。它对我有效,这才是对我最重要的。我的代码是开源的,它是免费的,采用 MIT 许mo证,每个人都可以从中学习。这才是对您来说应该重要的。 希望您喜欢这个项目。 ## 构建 如果您想手动编译 BattleShip,请参阅[构建说明](BUILDING.md)。 ## 架构 本移植版分为三层,并且刻意保持分离: ``` ┌──────────────────────────────────────────────────────────────┐ │ decompiled game code (decomp/src/) │ │ Unmodified C produced by the decomp project. Talks to the │ │ N64 the same way the original ROM did: GBI display lists, │ │ ALSeqPlayer audio, OS threads, OSContPad input. │ ├──────────────────────────────────────────────────────────────┤ │ port layer (port/) │ │ Modern C++ glue. Translates N64-shaped APIs into LUS calls, │ │ fixes endianness on freshly-loaded data, owns Ship::Context │ │ and the resource factories, and quarantines every change │ │ the decomp doesn't need to know about. │ ├──────────────────────────────────────────────────────────────┤ │ libultraship (libultraship/) │ │ PC-native runtime: Fast3D renderer (OpenGL / Metal / D3D), │ │ SDL2 input, miniaudio output, OTR/O2R resource manager, │ │ ImGui overlay. │ └──────────────────────────────────────────────────────────────┘ ``` ### 资源 pipeline `baserom.us.z64` 绝不会在运行时被读取。在构建时,**Torch** 使用 `yamls/us/` 下的 YAML 文件遍历 ROM,并生成 `BattleShip.o2r` —— 一个包含各种类型资源(纹理、序列、采样库、动画、reloc 文件)的 zip 格式归档。启动时,libultraship 的资源管理器会挂载 `BattleShip.o2r` + `f3d.o2r`,随后移植版代码通过路径请求资源。这与 Ship of Harkinian、Starship、SpaghettiKart 等使用的 pipeline 相同。 可重定位数据文件(fighter 表、item 表、effect、sprite)是 SSB64 特有的,需要在 Torch 端定制工厂,并在运行时端定制加载器(`port/resource/RelocFileFactory.cpp`)。 ### 构建时代码生成 少量生成的代码存放在源码树之外(被 gitignore 忽略),并在每次构建时从 `tools/reloc_data_symbols.us.txt` 重新生成: - `include/reloc_data.h` — 每个可重定位符号的 extern 声明 - `yamls/us/reloc_*.yml` — Torch 提取配置 - `port/resource/RelocFileTable.cpp` — 运行时符号表 如果您遇到“undefined reference to `dFooBarReloc`”,说明您重新生成了表却没有重新编译,或者反之。 ## 代码规范 ### `#ifdef PORT` — 是什么与不是什么 对反编译源文件的每一处实质性修改都被包裹在 `#ifdef PORT` / `#else` / `#endif` 中。这强制执行了以下纪律: - **原始的反编译代码路径保持完整且可编译**,可在真实的 N64 构建下使用 IDO 工具链。这一点是无可商量的 —— 如果情况发生改变,将改进回馈给上游反编译项目将变得不可能。 - **允许 PORT 分支看起来不够优雅** —— 显式的端序转换、结构体重写、函数垫片 —— 只要它向文件其余部分提供的契约与 N64 分支相同即可。 - **Reloc token 与原生 pointer**:如果在 `#ifdef PORT` 下声明为 `u32` 的字段,而在 N64 分支中声明为 `T*`,则它是一个 reloc token,而不是原生 pointer。解析它需要使用 `PORT_RESOLVE(token)`。如果使用 `(uintptr_t)ptr` 赋值真实的 pointer,在 LP64 下会被静默截断 —— 请将加载后的写入操作包裹在 `PORT_REGISTER` 中。 ### 反编译保留原则:保留行为,而非字节 对于修改 `decomp/src/`,本仓库遵循一个原则: 这意味着编码了原始 N64 语义的 IDO 习惯用法 —— 奇怪的强制转换、`goto` 流程、刻意使用的临时变量 —— 都是核心承重部分,必须保留。但是,那些在现代 LP64 工具链上掩盖真实漏洞的**编译器兼容垫片**(抑制警告、宽松标志、头文件快捷方式)*决不*保留。本项目最惨痛的教训是,`-Wno-implicit-function-declaration` 在数十个地方将 64 位 pointer 返回值静默截断成了 32 位 `int` —— 参见 `docs/bugs/item_arrow_gobj_implicit_int_2026-04-20.md`。该垫片已被移除;真实的声明已被补全。 ### 命名前缀 反编译代码通篇使用了双字母模块前缀。了解它们有助于更好地浏览源码树: | 前缀 | 含义 | |--------|---------| | `ft` | Fighter (`ftMario`, `ftKirby`, `ftFox`, …) | | `it` | Item (`itAttribute`, `itManager`) | | `wp` | Weapon | | `ef` | Effect / particle | | `gm` | Game mode | | `gr` | Stage (ground) | | `mp` | Map / collision | | `mn` | Menu | | `sc` | Scene | | `sy` | System (engine internals) | | `sf` | Saved-state / save file | | `db` | Debug | | `cm` | Camera | | `lb` | Library (low-level utilities) | | `obj` | GObj / DObj / OMObj — game-object wrappers | 完整参考:[`docs/c_conventions.md`](docs/c_conventions.md)。 ### 字节序处理 N64 是大端序;PC 平台是小端序。本移植版分三层处理此问题: 1. **加载时的整体字节交换** — `lbRelocLoadAndRelocFile` 在加载过程中按字(word)对可重定位文件进行字节交换。 2. **逐结构体修复** — 小巧的 `portFixupStructU16` / `portFixupStructU8` 辅助函数用于修复整体交换处理错误的子字字段(例如,在 `{u16, u8, u8}` 结构模式下,两个 `u8` 被错误交换的情况)。 3. **逐流 walker — 动画事件、样条插值器和其他可变长度流在文件打包阶段进行了半字节交换,并在首次访问时需要进行逐流的反向半字节交换。它们位于 `port/port_aobj_fixup.{h,cpp}` 及相关文件中。 如果您发现某个新的结构体读取出乱码,`docs/n64_reference.md` 中的指南会告诉您它属于哪一层。 ### 位域布局 IDO 编译器会将小位域打包到前面 `u16` 填充间隙中,最高有效位(MSB)优先。现代编译器(Clang, GCC)在小端序(LE)目标上会将它们最低有效位(LSB)优先打包到下一个存储单元中。随文件数据传输的位域结构体必须在 `#ifdef PORT` 下**重写**以匹配 IDO 的物理布局 —— 关于工作流,请参阅 `docs/debug_ido_bitfield_layout.md`(在移植前通过编译 + rabbitizer 反汇编验证位位置)。 团队政策禁止修改游戏代码中的读取操作而不是布局;这样漏洞总会再次出现。有关详细说明,请参阅项目记忆中的 `feedback_struct_rewrite_over_overrides.md`。 ## 为什么子模块是 Fork 版本 `libultraship` 和 `torch` 均固定在**个人 Fork** 上,而不是上游 Harbour Masters 的仓库,因为它们各自都需要上游尚不存在的 SSB64 特有修改。 ### [`libultraship`](https://github.com/JRickey/libultraship/tree/ssb64) — [Kenix3/libultraship](https://github.com/Kenix3/libultraship) 的 Fork SSB64 驱动 RDP 的方式与 libultraship 最初为之构建的 Zelda / Mario 64 / Star Fox 64 游戏不同 —— 特别是在 tile mask、`SetTileSize` 范围、IA/I4 纹理上传、用于 2D 分层的 `gDPSetPrimDepth` 以及用于 matanim CC 的 Metal 采样器绑定方面。将修复推送到上游已在计划中,但在此之前,该 Fork 包含: - 将 `ImportTexture*` 的上传宽高限制在当前激活的 `SetTileSize` 范围内(修复了 fighter 的“黑块”漏洞以及 IA8/I4 拉伸漏洞) - 在 Import* 路径中遵循 `SetTile` 的 mask/maskt - `gDPSetPrimDepth` 的真正实现(上游之前一直是个 `TODO Implement` 桩 —— 导致所有 `G_ZS_PRIM` 2D sprite 崩溃) - 为采样器槽位提供 1×1 黑色回退纹理,否则在 Metal 上会导致屏幕 drawable 产生别名(修复了 Whispy canopy 条纹问题) - `IResource` 析构函数中的无日志路径,用于防止关闭时发生崩溃 ### [`torch`](https://github.com/JRickey/Torch/tree/ssb64) — [HarbourMasters/Torch](https://github.com/HarbourMasters/Torch) 的 Fork Torch 是读取 ROM 并生成 `BattleShip.o2r` 的工具。上游支持 OoT、MM、SF64、MK64、PM64 等,但对 SSB64 的文件格式一无所知。该 Fork 添加了: - `SSB64` 构建标志和游戏目标 - 用于 SSB64 可重定位数据块(fighter、item、effect、sprite)的 reloc 文件工厂 - 集成 `libvpk0` 以处理 VPK0 压缩片段 这两个 Fork 都作为子模块存在,因此它们可以保留自己的提交历史,并且当(如果)修复被接受时,可以干净地合并上游更改。 ## 仓库布局 ``` port/ modern C++ port layer — Ship::Context, resource factories, endian fixups, bridges between decomp code and libultraship port/hooks/ engine/fighter event system (all platforms) port/mods/ native C mod loader + hook backend (funchook) workspace/ worked example mods (hooktest, playertint, template) include/ headers (some generated: reloc_data.h) decomp/ submodule — decompiled SSB64 C source (largely unchanged game logic). Major subdirs inside the submodule: src/sys/ main loop, DMA, scheduling, audio, controllers, threading src/ft/ fighters (ftmario/, ftkirby/, ftfox/, …) src/sc/ gm/ gr/ scene / game modes / stage rendering src/mn/ it/ ef/ menus / items / effects src/relocData/ reloc data sources libultraship/ submodule — PC-native render / audio / input / resource mgr torch/ submodule — asset extractor (ROM → BattleShip.o2r) yamls/us/ Torch YAML extraction configs (some generated) tools/ Python helpers: reloc stubs, YAML gen, credits encoder docs/ architecture notes, bug write-ups, debugging guides debug_tools/ optional disasm / diff utilities (not required for a build) scripts/ packaging (.dmg / .AppImage / .zip), worktree helper ``` ### 延伸阅读 - [`docs/modding.md`](docs/modding.md) — 编写原生 C 模组:事件目录、函数 detour 以及 fighter override 点 - [`docs/architecture.md`](docs/architecture.md) — 项目状态、ROM 信息、依赖图、源码树布局 - [`docs/c_conventions.md`](docs/c_conventions.md) — 反编译命名前缀、需保留的 IDO 习惯用法、代码风格、宏 - [`docs/n64_reference.md`](docs/n64_reference.md) — RDRAM, RSP/RDP, GBI, 音频, 线程, 字节序入门 - [`docs/build_and_tooling.md`](docs/build_and_tooling.md) — CMake 细节, reloc stub 重新生成, 运行时日志, LP64 兼容性说明 - [`docs/debug_gbi_trace.md`](docs/debug_gbi_trace.md) — 从移植版和 M64P 插件捕获 GBI 跟踪,并使用 `gbi_diff.py` 进行对比 - [`docs/debug_ido_bitfield_layout.md`](docs/debug_ido_bitfield_layout.md) — 通过 rabbitizer 验证移植后的结构体位位置与 IDO 输出是否一致 - [`docs/bugs/README.md`](docs/bugs/README.md) — 包含每个漏洞的根本原因和修复说明的已解决漏洞索引(约 45 条记录) ## 许可协议 本仓库中的源代码(即 `decomp/`、`libultraship/` 和 `torch/` 子模块之外的所有内容——这些子模块各自带有其归属说明)均采用 [MIT 许mo证](LICENSE) 发布 —— 可自由使用、修改和再分发,不提供任何担保和责任。完整文本请参见 [`LICENSE`](LICENSE)。 MIT 授权仅涵盖特定于移植版的代码(`port/` 层、构建脚本、工具、文档)。它**不**适用于: - Nintendo / HAL Laboratory 拥有的游戏资产、代码、音频、纹理、模型或任何其他内容 —— 这些均不在本仓库中。 - 作为 `decomp/` 子模块引入的反编译代码,源自 [VetriTheRetri/ssb-decomp-re](https://github.com/VetriTheRetri/ssb-decomp-re)。上游项目目前未发布明确的许可协议;本仓库不对反编译的源代码主张版权,并仅以引用方式将其纳入。有关重复使用的任何权利或限制,请遵从上游项目及其贡献者。 - 源码树中其他地方来源于反编译的内容(由反编译的符号/文件名表引入或自动生成):`tools/reloc_data_symbols.us.txt`、`tools/relocFileDescriptions.us.txt`、`include/reloc_data.h`、`port/resource/RelocFileTable.cpp` 和 `yamls/us/reloc_*.yml`。它们遵循与 `decomp/` 子模块相同的遵从上游原则。生成这些内容的脚本(`tools/generate_*.py`)由移植版作者编写,并保留 MIT 许可。 - `libultraship` 子模块 —— 版权所有 (c) 2022 kenix3,MIT 许mo证(由 Harbour Masters 团队发起)。 - `torch` 子模块 —— 版权所有 (c) 2023 Lywx (Harbour Masters),MIT 许mo证。 - `assets/custom/fonts/` 下内置的菜单字体,采用 SIL Open Font License 1.1 授权(各字体的许可文件位于该目录下)。 - 内置的控制器映射数据库 `gamecontrollerdb.txt`,源自 [SDL_GameControllerDB](https://github.com/mdqinc/SDL_GameControllerDB) 项目 —— 在 zlib 许可下分发。完整文本及归属说明见 [`LICENSE`](LICENSE)。
标签:C/C++, libultraship, UML, 事务性I/O, 任天堂64, 任天堂明星大乱斗, 反编译移植, 游戏