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