Skip to content

VRAM(Video RAM)

是什么

VRAM(Video RAM,视频随机存取存储器)是 GBA 专用的一块 96KB 显存,起始地址为 0x06000000。它用于存储背景图块数据、精灵图块数据以及背景映射表。GBA 的图形渲染引擎直接从 VRAM 中读取数据来生成每一帧画面。

为什么需要

VRAM 是 GBA 图形系统的核心存储区域。理解 VRAM 的布局和数据格式对于以下工作至关重要:

  • 渲染实现:浏览器端需要正确读取 Wasm 线性内存中 VRAM 区域的数据来还原图像。
  • 数据格式转换:VRAM 中的图块以 4bpp/8bpp 索引色存储,需要结合调色板转换为 Canvas 可用的 RGBA 格式。
  • 内存布局理解:VRAM 被划分为多个 Bank(Bank 0-5),不同 Bank 可分配给背景或精灵使用,这是 GBA 图形编程的基础知识。

原理与实现

VRAM 的 96KB 被组织为 6 个 16KB 的 Bank:

Bank地址范围常见用途
Bank 00x06000000–0x06003FFF背景/精灵图块
Bank 10x06004000–0x06007FFF背景/精灵图块
Bank 20x06008000–0x0600BFFF背景/精灵图块
Bank 30x0600C000–0x0600FFFF背景/精灵图块
Bank 40x06010000–0x06013FFF精灵图块 / 位图模式帧缓冲
Bank 50x06014000–0x06017FFF精灵图块 / 位图模式帧缓冲

VRAM 的使用方式取决于 GBA 的显示模式(Mode 0-5):

  • 字符模式(Mode 0-2):VRAM 存储图块数据和背景映射表(Screen Base Block + Tile Base Block)。
  • 位图模式(Mode 3-5):VRAM 直接存储像素数据作为帧缓冲。

在 pokeemerald-wasm 中的实现

在 pokeemerald-wasm 项目中,VRAM 的处理方式为:

  1. 地址映射:VRAM 的地址 0x06000000 被直接映射到 Wasm 线性内存的对应偏移位置。游戏代码中对 VRAM 的读写操作实际上是在操作 Wasm 内存。
  2. 帧数据读取:JavaScript 渲染代码通过 WebAssembly.Instance.exports.memoryDataViewUint8Array 视图读取 VRAM 区域的数据。
  3. 图块解码:渲染器从 VRAM 中读取 4bpp 或 8bpp 的图块数据,结合 Palette 转换为完整颜色。
  4. 精灵图块:精灵使用的图块数据存储在 VRAM 的 OBJ 区域(通常是 Bank 4-5),渲染器根据 OAM 中的图块索引从 VRAM 中提取对应的精灵图形。

相关概念

  • Tile — VRAM 中存储的基本 8×8 像素图块
  • Sprite — 使用 VRAM 中图块数据的可移动图形对象
  • OAM — 精灵属性内存,包含图块索引等信息
  • Palette — 颜色查找表,将图块中的索引色转换为实际颜色