Skip to content

INCGFX / INCBIN

是什么

INCGFX 和 INCBIN 是 GBA 开发中使用的构建宏,用于在编译时将二进制文件(图片、音频、数据等)直接嵌入到最终的 ROM 文件中。

  • INCBIN:通用的二进制文件包含宏,将任意文件的原始字节直接插入到 ROM 的当前位置。
  • INCGFX:专用的图像处理宏,在包含之前会对图像文件进行预处理(如转换为 GBA 兼容的图块格式)。

这些宏在 pret 反编译项目(如 pokeemerald)中被广泛使用,用于嵌入 Pokémon 精灵图、背景图、字体等资源。

为什么需要

GBA 游戏的所有资源数据(图形、音频、地图数据等)都存储在 ROM 中,需要在编译时打包进去。INCGFX 和 INCBIN 宏提供了一种在 C/汇编代码中声明和引用这些资源的机制:

  • 编译时嵌入:资源在编译阶段直接写入 ROM,运行时无需额外的文件加载。
  • 符号引用:宏会生成对应的 C 符号名,代码中可以通过符号名访问嵌入的数据。
  • 类型化数据:INCGFX 会将图片转换为 GBA 的图块格式(4bpp/8bpp),使其可以直接被硬件使用。

在 pokeemerald-wasm 项目中,由于 Wasm 模块不包含 GBA ROM 结构,这些嵌入的资源需要被单独提取和转换。

原理与实现

INCBIN 的工作方式

在汇编或 C 代码中,INCBIN 通常这样使用:

c
// 在 .s 汇编文件中
.global gSprite_Ash
.section .rodata
gSprite_Ash:
    .incbin "graphics/sprites/ash.4bpp.lz"

或在 C 头文件中通过 extern 声明引用:

c
extern const u8 gSprite_Ash[];

INCGFX 的工作方式

INCGFX 是 devkitARM 工具链提供的增强宏,除了包含文件外,还可以自动处理图像格式转换:

INCGFX gGraphic_Player, "graphics/player.png"

这会在编译前将 PNG 图片转换为 GBA 兼容的图块格式。

在 Makefile 中的处理

在原始的 GBA 构建流程中,这些宏由汇编器(arm-none-eabi-as)直接处理。汇编器读取 .incbin 指令,将文件内容嵌入到目标文件的 .rodata 段中。

在 pokeemerald-wasm 中的实现

在 pokeemerald-wasm 项目的 WASM 构建路径中,INCGFX/INCBIN 的处理方式发生了根本性变化:

  1. 资源扫描generate_wasm_assets.py 脚本扫描源码中的 INCGFX 和 INCBIN 宏调用,收集所有需要嵌入的资源文件路径和对应的符号名。
  2. 格式转换:将 GBA 格式的图块数据(4bpp/8bpp)和其他资源转换为 Wasm 可加载的格式。
  3. 内存加载:在 Wasm 模块初始化时,将转换后的资源数据写入 Wasm 线性内存的对应地址,使游戏代码可以通过原有的符号地址访问这些数据。
  4. 不使用汇编器:由于 Wasm 构建使用 Clang 而非 arm-none-eabi 工具链,原始的 .incbin 汇编指令无法直接使用,需要通过 Python 脚本替代处理。

相关概念

  • devkitARM — 提供 INCGFX 等宏的 GBA 开发工具链