250712 --- 红警开发学习 SHP 数据结构
前言
总参考
SHP 是红警中使用的图像文件, 所有的 UI, 地形, 建筑, 步兵, 恐怖机器人, 都使用 SHP 格式.
主要是对B站 @养猫的程序员 大佬的教程的复刻,在实践中领会知识。
https://www.bilibili.com/opus/1067600093788504089?spm_id_from=333.1387.0.0
文章主要分成2部分,第一部分是准备工作,把一些工具准备好。
第二部分,是对大佬教程的领会和理解,以及验证。
准备工作
我们需要使用 XCC Mixer 工具提取shp文件
shp文件一般存放在压缩包里,mix文件是压缩包
红警游戏目录下有很多以 mix 为扩展名的文件,它们实际上是多个文件的集合,经过打包形成了一个文件,就像压缩包。
安装 XCC Mixer
我们用 XCC Mixer工具查看 mix 压缩包,也可以提取压缩包的内容
https://cnc-comm.com/command-and-conquer/downloads/modding-tools/XCC-utilities
单位-单词对照表
有时候我们并不知道这些奇奇怪怪的缩写代表什么含义,有人已经整理出来词汇表,可以参考
https://www.bilibili.com/opus/154270187277118347
找到核弹发射井SHP
终于找到了核弹发射井建造动画的SHP文件
在 isourb.mix 压缩包里
numislmk.shp
用 OS SHP Builder 打开 SHP 文件
我下载了一个SHP Builder
https://ppmforums.com/topic-38145/download/
打开 numislmk.shp 效果如下

默认的Palette调色盘比较丑,我参考人家的改成了 uniterm.pal 调色,如下

理解
看了UP主的文章,我对SHP数据结构体有了初步的认识
SHP 数据结构体采用 帧头 + 数据块 的方式实现
帧头
帧头存放若干帧的尺寸信息和数据块地址

00-01字节,表示此帧存在颜色信息的像素的最小X坐标,值为0x58表示88,注意坐标是从0开始的,所有坐标的范围是0到237
02-03字节,表示此帧存在颜色信息的像素的最小Y坐标,值为0x7F表示127,同样注意坐标是从0开始的,所有坐标的范围是0到201
04-05字节,表示此帧的有效区域宽度,值为0x3E表示62,也就是最小X坐标到最大X坐标间的像素个数
06-07字节,表示此帧的有效区域高度,值为0x03表示35,也就是最小Y坐标到最大Y坐标间的像素个数,
08-11字节,表示此帧的帧类型,目前已发现的有00,01和03两种值,数据区解析时会用到这个值
01、00较少见,一般用于帧中像素个数很少的情况, 03为常见值
12-15字节,我并未破译出其中含义,猜测可能是一个校验值,如果有谁知道其含义,还请告知UP主,但是这个字节并不影响我们使用shp文件
16-19字节,表示分隔符,值均为0x0,没有实际含义
20-23字节,表示此帧画面的数据区数据的偏移地址,比如第一帧 20-23 字节的值是 0x04E8
表示偏移地址 0x04e8 的数据,是这帧数据的第一个字节,即0x07
数据部分
数据部分是数据块信息,即行扫描方式具体每一行的填色数据

当帧类型为03时,首先先判断前2个字节值是否为0x4,如果是表示此行没有数据,需要跳过下两个字节;
如果不是04,为了方便解读,看核弹井的例子
前两个字节是0x07表示此行有7个字节,
第3个字节00表示此行像素最小X坐标值不是帧像素X坐标最小值,
第4个字节0x19表示第一个像素X坐标大于帧最小X坐标25个像素,
第5个字节0x0A表示颜色下标,
第6个字节00表示此行像素最大X坐标值不是帧像素X坐标最大值,
第7个字节0x25表示最后一个像素X坐标小于帧最大X坐标36个像素 36=0x25-0x1,就是这么设计的
我们简称这个模式叫做 2+2+N+2模式,表示2个字节表示行字节长度,2个字节表示起始位置,N个字节表示像素颜色下标,2个字节表示末尾位置
验证
我在OS SHP Builder里实际查看了
的确 位置 x = 88+25 = 113 处的颜色是 0x0a

而且由于宽度是 62, 起始位置 start+25 , 终止位置 end-37, 所以像素点的数量为 1 = 66 - 25 - 37 + 1,也是正确的。
04-05字节,表示此帧的有效区域宽度,值为0x3E表示62,也就是最小X坐标到最大X坐标间的像素个数
后纪
关于压缩方式字段的补充参考
B站的 @日小皮Fantasycho 的这篇文章对帧头数据里的 Compression Flag 有很细致的说明
https://www.bilibili.com/read/cv36402416
CompressionFlag决定了一个帧使用什么方法存储。存储的方法有两种,分别为第一种与第三种(呃……),
或者你也可以叫它逐像素存储法与压缩存储法。 作者: https://www.bilibili.com/read/cv36402416/?opus_fallback=1 出处:bilibili
与 @养猫的程序员 的说明,异曲同工
08-11字节,表示此帧的帧类型,目前已发现的有 01和03两种值,数据区解析时会用到这个值
关于帧头4字节ARGB颜色字段作用
我从B站的 @日小皮Fantasycho 的这篇文章里发现有一个目录,看着像是国外的某个网站

于是我找到了原文地址
https://modenc.renegadeprojects.com/SHP
这里对 12 - 15字节有了一点说明,是一个32位深ARGB颜色值,但是具体作用未知
12-15字节,我并未破译出其中含义,猜测可能是一个校验值,如果有谁知道其含义,还请告知UP主,但是这个字节并不影响我们使用shp文件

祝福
其实学红警开发之前,我自己也尝试过,但是无疾而终。我有点完美主义倾向,但是这并不好。
今天努力尝试做一个不完美的实践,行动起来,思想也就逐渐有了变化。
希望看到这篇文章的人都能天天进步,努力攀登自己的能力高峰

浙公网安备 33010602011771号