跳转到主要内容

核心模型与原则

静态重编译到底在做什么

它不是把整个 Switch 变成一台虚拟机,也不是把游戏改写成跨平台源码。典型路径是:

Switch 原生 ARM64 程序
        │ 少量指令重写:系统寄存器、线程寄存器、SVC/调用边界
        ▼
宿主 ARM64 CPU 直接执行
        │ HLE 补出 Horizon 服务、文件、线程、内存、输入、音频
        ▼
NVN 命令和 shader 被记录、翻译、重放
        │ Metal / Vulkan 后端 + 宿主窗口生命周期
        ▼
真实画面和输入

因此性能上限很高:游戏代码不经过 CPU 指令解释;但兼容性责任也更集中。模拟器可以用统一的虚拟硬件 把差异藏起来,静态重编译必须逐项重建游戏已经依赖的语义。

工程上还要把系统拆成四层:游戏特化 profile/生成器、通用 runtime、图形后端、平台外壳。用户提供的游戏资料经过 版本校验后生成独立 game library;APK 或桌面程序本身只负责加载 runtime、资源和工具。这个边界让地址表、shader 事实和游戏 patch 不会污染下一款游戏,也让 Android 的解包、SAF、后台构建与 Mac 的窗口生命周期各自可测试。

三个必须分开的契约

游戏契约

包括 title ID、NSO build ID、patch site、模块布局、shader 表、资源格式、内存请求、存档路径和输入状态。 它们必须进入 profile 或案例,不得散落在通用 runtime 中。

平台契约

包括 AArch64 ABI、TLS/x18、线程调度、页粒度、mmap 权限、Horizon SVC/IPC、文件系统、窗口、GPU API 和驱动能力。 同一个游戏在 Mac 和 Android 上的主要差别通常在这里。

图形契约

包括 NVN 对象生命周期、command buffer 录制语义、shader stage IO、descriptor/binding、纹理 layout/swizzle、 render target、同步和 present。画面“能出一帧”只证明最小链路,不证明这些契约整体正确。

最重要的判断规则

  1. 先判定在哪一层失败,再改代码。 黑屏可能是 guest 停止、draw 没发生、target 没写、合成丢失或 present 错误。
  2. 一个可见变化不等于根因。 强制红色、固定窗口 texture、关闭深度测试都可能只是诊断证据。
  3. 优先修通用语义。 QueryMemory、对象代际、UBO 内容、线程等待和 Vulkan layout 比某个 shader hash 的特判更值得修。
  4. 游戏特例必须有来源。 每个固定地址、容量、shader hash 或 patch 都要记录 build ID 和反汇编依据。
  5. 实验需要可回滚。 临时开关、设备文件和 trace 结束后清理;失败实验也要归档。
  6. 性能优化晚于正确性。 先获得正确画面和稳定状态,再测帧时间、GPU 利用率、内存带宽和 pipeline miss。
  7. 构建产物必须可追溯。 game library 的 build ID、generator/compiler 版本、flags、patch hash 和 profile hash 必须能从日志或 manifest 还原;可恢复构建优先于“重新跑一遍”。

什么算真正突破

真正突破必须同时满足:

  • 现象边界发生稳定、可重复的变化;
  • 有证据说明哪个契约不满足;
  • 修复不依赖未记录的时序巧合;
  • 修复后的行为能进入回归测试或手册;
  • 明确哪些部分仍未解决。

“这次没有崩”但没有截图、日志或对照,不算完成;“画面变亮”但不知道为什么,也只能算诊断结果。