Skip to content

项目架构概览 — 代码走读

入口点走读

WASM 入口 — AgbMain

WASM 模块的入口函数是 AgbMain,在 src/main.c 中定义(经预处理后):

c
// src/main.c(简化)
void AgbMain(void) {
    // 游戏初始化
    SetMainCallback(NULL);
    // ... 初始化各子系统
    // 进入主循环
    while (TRUE) {
        // 等待 VBlank 中断
        // 处理游戏逻辑
    }
}

在 WASM 环境中,主循环被拆分为帧执行函数 WasmRunFrame,由浏览器的 requestAnimationFrame 驱动。

浏览器端入口 — web/app.js

app.js 负责加载和运行 WASM 模块:

javascript
// 简化的初始化流程
const wasm = await WebAssembly.instantiateStreaming(fetch('pokeemerald.wasm'), {
  env: { memory: wasmMemory }
})
wasm.instance.exports.AgbMain()  // 初始化游戏
// 之后每帧调用 WasmRunFrame()

构建入口 — Makefile

make wasm 的构建步骤:

模块组织走读

源码目录结构

pokeemerald-wasm/
├── src/                       # 280+ C 源文件(游戏逻辑)
│   ├── main.c                 # 入口 AgbMain + 主循环
│   ├── overworld.c            # 地图切换与移动
│   ├── battle_*.c             # 战斗系统(10+ 文件)
│   ├── field_*.c              # 场景/地图系统
│   ├── wasm_field_effect_scripts.c  # WASM 专用适配
│   ├── wasm_display.c              # WASM 专用软件 PPU(#if WASM)
│   └── data.c, event_data.c  # 游戏数据
├── include/
│   ├── wasm/                  # WASM 兼容垫片
│   │   ├── stdio.h            # sprintf 等声明
│   │   ├── stdlib.h           # abs() 声明
│   │   └── string.h           # memcpy/memset 等声明
│   └── *.h                    # 标准 GBA 头文件
├── web/                       # 浏览器前端
│   ├── index.html             # HTML 页面(Canvas + 控件)
│   ├── app.js                 # 输入/存档/帧调度 + RGBA 搬运(渲染在 WASM 内)
│   ├── style.css              # UI 样式
│   └── server.mjs             # 开发服务器
├── tools/
│   ├── generate_wasm_assets.py    # 资源扫描生成
│   ├── wasm_asm_data.py           # 汇编数据转换
│   ├── wasm_replay.mjs            # 自动回放测试
│   ├── build_wrangler_site.mjs    # 部署打包
│   └── native/                    # 原生前端:wasm2c + raylib/bench/kindle
│       ├── native_engine.c/.h     # 无头引擎核心(BIOS 垫片/输入/存档/帧缓冲)
│       ├── raylib_main.c          # Raylib 桌面前端
│       ├── bench_main.c           # 无头 FPS + 正确性基准测试
│       └── wasm_native_kindle.c   # Kindle Scribe 帧缓冲前端
├── data/                      # 地图/事件/脚本数据
├── graphics/                  # 图形资源
├── sound/                     # 音频资源
└── constants/                 # 游戏常量

关键函数索引

函数/文件位置职责
AgbMain()src/main.c游戏初始化和主循环入口
WasmRunFrame()WASM 导出单帧执行,由 app.js 调用
WasmRenderFrame() / WasmDisplayBuffer()src/wasm_display.c在 WASM 内合成 RGBA 帧、导出缓冲区指针
web/app.jsweb/输入、存档、帧调度,把 RGBA 搬运到 Canvas(渲染在 WASM 内)
tools/native/tools/wasm2c 原生前端(raylib / bench / kindle)
generate_wasm_assets.pytools/扫描源码生成 WASM 资源文件
wasm_asm_data.pytools/转换 GBA 汇编数据为 WASM 格式
build_wrangler_site.mjstools/Cloudflare Workers 部署打包
server.mjsweb/本地开发服务器