Appearance
项目架构概览 — 概念
分层架构
pokeemerald-wasm 采用三层边界适配架构,各层通过定义良好的接口通信:
核心组件
WASM 编译管线
topics/wasm-compilation/ 是项目的核心基础设施:
- 使用
clang --target=wasm32-unknown-unknown -DMODERN=1 -DWASM=1编译所有.c文件 - 使用 wasm-ld 链接,配置 256MB 线性内存
- 导出
AgbMain(入口)和WasmRunFrame(帧执行)函数
GBA 硬件模拟
topics/gba-hardware/ 在 WASM 模块的 256MB 线性内存中复刻了 GBA 的内存映射——游戏代码像在真机上一样按固定地址读写这些区域,渲染器再从同一片内存读取它们合成画面:
- I/O 寄存器:
0x04000000起的内存映射寄存器(DISPCNT、DISPSTAT 等) - 调色板 RAM:
0x05000000,256 色 × 2 组(BG/OBJ) - 视频内存:
0x06000000,VRAM 存储背景 Tile 和精灵图块数据 - OAM:
0x07000000,OAM 存储 128 个精灵的属性(位置、大小、Tile 索引) - Flash 存储:
0x0E000000,128KB 存档区域
资源转换管线
topics/asset-pipeline/ 负责将 GBA 特有的二进制数据转换为 WASM 可用的格式:
generate_wasm_assets.py:扫描源码中的 INCGFX / INCBIN 宏,生成 WASM 资源文件wasm_asm_data.py:将 GBA 汇编数据文件(.s)中的.word、.byte等指令转为 WASM 可链接的数据
渲染管线
topics/rendering/ 由 WASM 模块内的 src/wasm_display.c(#if WASM 守卫)实现,把 GBA 的图形输出合成成一张 240×160 的 RGBA 帧缓冲区,宿主再把它搬到屏幕:
- 背景渲染:读取 VRAM 中的 Tile 数据,根据背景模式(Mode 0-4)组合像素(
TextBgPixel/AffineBgPixel) - 精灵渲染:读取 OAM 属性,从 VRAM 提取 Sprite 图块像素,处理旋转/缩放(
RenderSprites/ObjPixel) - 调色板转换:将 GBA BGR555 格式转为 RGBA8888,写入模块内缓冲区(
GbaColor) - 导出:
WasmRenderFrame()合成一帧,WasmDisplayBuffer()返回 RGBA 指针;宿主app.js只需putImageData
数据流:帧渲染流程
与原始 GBA 构建的兼容
项目保持了与原始 GBA 构建路径的完全兼容:
make/make modern:仍可构建标准 GBA ROMmake compare:仍可校验 ROM 完整性- WASM 专用代码通过
#if WASM守卫,不影响 GBA 构建 - WASM 专用源文件包括
src/wasm_display.c(软件 PPU)、wasm_field_effect_scripts.c等,全部被#if WASM隔离
除了浏览器前端,上游还提供
make native-raylib(桌面 Raylib)、make native-bench(无头基准测试)、make native-kindle(Kindle Scribe 帧缓冲)三条原生构建路径。它们用wasm2c把同一份 WASM 转成 C 再链接各自宿主,复用相同的渲染与游戏核心。详见 构建部署概念。
相关概念
- topics/wasm-compilation/ — WASM 编译管线详解
- WebAssembly — WebAssembly 技术概述
- GBA — Game Boy Advance 硬件架构
- VRAM — 视频内存结构
- OAM — 精灵属性内存