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 效果如下
image

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

理解

看了UP主的文章,我对SHP数据结构体有了初步的认识

SHP 数据结构体采用 帧头 + 数据块 的方式实现

帧头

帧头存放若干帧的尺寸信息和数据块地址

image

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

数据部分

数据部分是数据块信息,即行扫描方式具体每一行的填色数据

image

当帧类型为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

image

而且由于宽度是 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 的这篇文章里发现有一个目录,看着像是国外的某个网站

image

于是我找到了原文地址

https://modenc.renegadeprojects.com/SHP

这里对 12 - 15字节有了一点说明,是一个32位深ARGB颜色值,但是具体作用未知

12-15字节,我并未破译出其中含义,猜测可能是一个校验值,如果有谁知道其含义,还请告知UP主,但是这个字节并不影响我们使用shp文件

image

祝福

其实学红警开发之前,我自己也尝试过,但是无疾而终。我有点完美主义倾向,但是这并不好。

今天努力尝试做一个不完美的实践,行动起来,思想也就逐渐有了变化。

希望看到这篇文章的人都能天天进步,努力攀登自己的能力高峰

posted @ 2025-07-12 11:00  lucky_doog  阅读(73)  评论(0)    收藏  举报