Skip to content

OAM(Object Attribute Memory)

是什么

OAM(Object Attribute Memory,对象属性内存)是 GBA 上一块 1KB 的专用内存,起始地址为 0x07000000。它用于存储最多 128 个精灵(Object)的属性信息,包括位置、大小、使用的图块编号、旋转/缩放参数、显示优先级等。GBA 的渲染硬件在每一帧扫描时根据 OAM 中的数据来绘制精灵。

为什么需要

OAM 是连接精灵逻辑与渲染输出的关键数据结构。在 pokeemerald-wasm 项目中,JavaScript 渲染代码需要读取 OAM 数据来知道:

  • 哪些精灵需要绘制:通过 OAM 中的启用/禁用标志判断。
  • 精灵在哪里:通过 X/Y 坐标确定精灵在屏幕上的位置。
  • 精灵长什么样:通过图块索引到 VRAM 中查找图形数据。
  • 精灵的显示效果:通过旋转/缩放、翻转、半透明等属性调整渲染方式。

理解 OAM 的数据格式是在浏览器端正确还原 GBA 精灵渲染的前提。

原理与实现

OAM 共 1KB(1024 字节),存储 128 个精灵条目,每个条目由 4 个 16 位属性字(Attribute)组成,共 8 字节:

属性位域内容
Attribute 0 (ATTR0)bit 0-7Y 坐标(屏幕 Y 位置)
bit 8旋转/缩放标志(0=禁用,1=启用)
bit 9双倍尺寸标志(仅当旋转/缩放启用时有效)
bit 10-11精灵模式(0=正常,1=半透明,2=窗口,3=禁用)
bit 12色深(0=16 色/4bpp,1=256 色/8bpp)
bit 13-14精灵形状(00=正方形,01=横向,10=纵向)
Attribute 1 (ATTR1)bit 0-8X 坐标(屏幕 X 位置,bit 8 为符号位,范围 -128~511)
bit 9-13旋转/缩放参数索引(0-31,指向旋转参数集)
bit 14-15精灵尺寸(与形状组合确定实际大小)
Attribute 2 (ATTR2)bit 0-9图块索引(在 VRAM 中的起始图块号)
bit 10-11显示优先级(0-3,0 最高)
bit 12-15调色板组号(仅 16 色模式)
Attribute 3 (ATTR3)旋转/缩放数据(仅当旋转/缩放启用时使用)

精灵的实际尺寸由 Attribute 0 的形状(Shape)和 Attribute 1 的尺寸(Size)组合决定:

形状\尺寸0123
正方形8×816×1632×3264×64
横向16×832×832×1664×32
纵向8×168×3216×3232×64

在 pokeemerald-wasm 中的实现

在 pokeemerald-wasm 中,OAM 的处理流程为:

  1. 内存映射:OAM 的地址 0x07000000 映射在 Wasm 线性内存中,游戏代码像在真实 GBA 上一样读写 OAM。
  2. 帧末读取:每帧执行完毕后(WasmRunFrame 返回后),JavaScript 渲染代码读取 OAM 区域的全部 1KB 数据。
  3. 精灵遍历:渲染器遍历 128 个 OAM 条目,跳过被禁用的精灵(ATTR0 的 mode=3)。
  4. 图块提取:根据 ATTR2 中的图块索引,从 VRAM 的 OBJ 区域提取对应的图块像素数据。
  5. 变换应用:如果精灵启用了旋转/缩放,根据 ATTR3 中的仿射矩阵参数对图块进行变换。
  6. Canvas 绘制:将处理后的精灵像素数据绘制到 Canvas 2D 上下文中,优先级低的精灵先绘制。

相关概念

  • Sprite — OAM 控制的可移动图形对象
  • VRAM — 存储精灵图块数据的显存
  • Tile — 构成精灵的基本 8×8 像素单元