REXPaint 是一款用于设计用户界面和关卡预制件的 ASCII 艺术工具,它将数据存储在特定的 .xp 文件格式中。这些文件是 gzip 压缩的二进制结构,需要经过多步解码过程——先解压压缩内容,然后解析小端序(little-endian)的整数和颜色字节——来重构分层艺术。
.xp 文件结构
REXPaint .xp 文件以标准的 gzip 头部开始,由魔数 1f8b 标识。一旦解压,文件遵循简单的小端序布局,从版本号(通常为 -1)和图层数量开始。每个图层由其自身的宽度和高度定义,随后是单元格序列。

此表展示了 .xp 文件格式中使用的特定字节布局和数据类型。
文件中的每个单元格占用恰好 10 字节,由 4 字节的字符索引和两个 3 字节的 RGB 前景和背景颜色值组成。这些单元格按列主序组织,这意味着第一列从上到下写入,然后才开始写入第二列。

此代码片段演示了 REXPaint 文件格式的结构布局。
由 HN Digest 根据 tylerelton.com 报告的数字绘制的图表;数值按源文件显示。
“所有数值都是小端序,整个文件就是一串整数,后面跟着长串的单元格。”
— Decoding REXPaint Files in Odin
Odin 中的解析逻辑
要在 Odin 编程语言中解码这些文件,过程首先使用 `core:compress/gzip` 包将文件解压到字节缓冲区中。随后采用自定义的 `Reader` 结构体来维护原始字节中的当前偏移量,并提供读取 `i32` 和 `u8` 值的辅助过程,同时检查缓冲区溢出。

此代码展示了使用 Odin 压缩库进行解码过程的初始步骤。
解码器将原始数据映射到嵌套的结构体层级中:一个 `File` 结构体包含 `Layer` 结构体的切片,而 `Layer` 结构体又包含 `Cell` 结构体的切片。这使得程序能够将分层艺术表示为结构化的、可导航的对象,而不是扁平的字节流。
内存安全与验证
解码过程包含多项安全检查,以防止损坏或恶意文件导致内存耗尽。在为图层分配内存之前,代码会计算预期大小并将其与缓冲区中剩余的字节进行比较。它还强制执行 `MAX_CELLS_PER_LAYER` 限制,以确保单个图层不会超过合理的尺寸。
Odin 的 `defer` 机制用于在解析多个图层期间管理内存。如果在读取特定图层时发生错误,`defer if` 块可确保为该特定图层的单元格已分配的任何内存都被释放,从而防止内存泄漏,同时允许处理文件的其余部分或将其报告为错误。
透明度和渲染权衡
REXPaint 格式通过特定的颜色值处理透明度:亮粉色(255, 0, 255)。该格式规定,任何具有此背景颜色的单元格都被视为透明。针对基础图层有一个特定规则:如果高层上的透明单元格露出最低层上的透明单元格,最终结果将渲染为黑色。
虽然解码逻辑成功提取了这些值,但渲染引擎透明度混合的具体实现并未在解码过程中详细说明。解码器的主要重点是确保从二进制格式到 Odin 环境的数据提取的完整性。