250712 --- 紅警開發(fā)學習 SHP 數(shù)據(jù)結(jié)構(gòu)
前言
總參考
SHP 是紅警中使用的圖像文件, 所有的 UI, 地形, 建筑, 步兵, 恐怖機器人, 都使用 SHP 格式.
主要是對B站 @養(yǎng)貓的程序員 大佬的教程的復刻,在實踐中領會知識。
https://www.bilibili.com/opus/1067600093788504089?spm_id_from=333.1387.0.0
文章主要分成2部分,第一部分是準備工作,把一些工具準備好。
第二部分,是對大佬教程的領會和理解,以及驗證。
準備工作
我們需要使用 XCC Mixer 工具提取shp文件
shp文件一般存放在壓縮包里,mix文件是壓縮包
紅警游戲目錄下有很多以 mix 為擴展名的文件,它們實際上是多個文件的集合,經(jīng)過打包形成了一個文件,就像壓縮包。
安裝 XCC Mixer
我們用 XCC Mixer工具查看 mix 壓縮包,也可以提取壓縮包的內(nèi)容
https://cnc-comm.com/command-and-conquer/downloads/modding-tools/XCC-utilities
單位-單詞對照表
有時候我們并不知道這些奇奇怪怪的縮寫代表什么含義,有人已經(jīng)整理出來詞匯表,可以參考
https://www.bilibili.com/opus/154270187277118347
找到核彈發(fā)射井SHP
終于找到了核彈發(fā)射井建造動畫的SHP文件
在 isourb.mix 壓縮包里
numislmk.shp
用 OS SHP Builder 打開 SHP 文件
我下載了一個SHP Builder
https://ppmforums.com/topic-38145/download/
打開 numislmk.shp 效果如下

默認的Palette調(diào)色盤比較丑,我參考人家的改成了 uniterm.pal 調(diào)色,如下

理解
看了UP主的文章,我對SHP數(shù)據(jù)結(jié)構(gòu)體有了初步的認識
SHP 數(shù)據(jù)結(jié)構(gòu)體采用 幀頭 + 數(shù)據(jù)塊 的方式實現(xiàn)
幀頭
幀頭存放若干幀的尺寸信息和數(shù)據(jù)塊地址

00-01字節(jié),表示此幀存在顏色信息的像素的最小X坐標,值為0x58表示88,注意坐標是從0開始的,所有坐標的范圍是0到237
02-03字節(jié),表示此幀存在顏色信息的像素的最小Y坐標,值為0x7F表示127,同樣注意坐標是從0開始的,所有坐標的范圍是0到201
04-05字節(jié),表示此幀的有效區(qū)域?qū)挾龋禐?x3E表示62,也就是最小X坐標到最大X坐標間的像素個數(shù)
06-07字節(jié),表示此幀的有效區(qū)域高度,值為0x03表示35,也就是最小Y坐標到最大Y坐標間的像素個數(shù),
08-11字節(jié),表示此幀的幀類型,目前已發(fā)現(xiàn)的有00,01和03兩種值,數(shù)據(jù)區(qū)解析時會用到這個值
01、00較少見,一般用于幀中像素個數(shù)很少的情況, 03為常見值
12-15字節(jié),我并未破譯出其中含義,猜測可能是一個校驗值,如果有誰知道其含義,還請告知UP主,但是這個字節(jié)并不影響我們使用shp文件
16-19字節(jié),表示分隔符,值均為0x0,沒有實際含義
20-23字節(jié),表示此幀畫面的數(shù)據(jù)區(qū)數(shù)據(jù)的偏移地址,比如第一幀 20-23 字節(jié)的值是 0x04E8
表示偏移地址 0x04e8 的數(shù)據(jù),是這幀數(shù)據(jù)的第一個字節(jié),即0x07
數(shù)據(jù)部分
數(shù)據(jù)部分是數(shù)據(jù)塊信息,即行掃描方式具體每一行的填色數(shù)據(jù)

當幀類型為03時,首先先判斷前2個字節(jié)值是否為0x4,如果是表示此行沒有數(shù)據(jù),需要跳過下兩個字節(jié);
如果不是04,為了方便解讀,看核彈井的例子
前兩個字節(jié)是0x07表示此行有7個字節(jié),
第3個字節(jié)00表示此行像素最小X坐標值不是幀像素X坐標最小值,
第4個字節(jié)0x19表示第一個像素X坐標大于幀最小X坐標25個像素,
第5個字節(jié)0x0A表示顏色下標,
第6個字節(jié)00表示此行像素最大X坐標值不是幀像素X坐標最大值,
第7個字節(jié)0x25表示最后一個像素X坐標小于幀最大X坐標36個像素 36=0x25-0x1,就是這么設計的
我們簡稱這個模式叫做 2+2+N+2模式,表示2個字節(jié)表示行字節(jié)長度,2個字節(jié)表示起始位置,N個字節(jié)表示像素顏色下標,2個字節(jié)表示末尾位置
驗證
我在OS SHP Builder里實際查看了
的確 位置 x = 88+25 = 113 處的顏色是 0x0a

而且由于寬度是 62, 起始位置 start+25 , 終止位置 end-37, 所以像素點的數(shù)量為 1 = 66 - 25 - 37 + 1,也是正確的。
04-05字節(jié),表示此幀的有效區(qū)域?qū)挾龋禐?x3E表示62,也就是最小X坐標到最大X坐標間的像素個數(shù)
后紀
關于壓縮方式字段的補充參考
B站的 @日小皮Fantasycho 的這篇文章對幀頭數(shù)據(jù)里的 Compression Flag 有很細致的說明
https://www.bilibili.com/read/cv36402416
CompressionFlag決定了一個幀使用什么方法存儲。存儲的方法有兩種,分別為第一種與第三種(呃……),
或者你也可以叫它逐像素存儲法與壓縮存儲法。 作者: https://www.bilibili.com/read/cv36402416/?opus_fallback=1 出處:bilibili
與 @養(yǎng)貓的程序員 的說明,異曲同工
08-11字節(jié),表示此幀的幀類型,目前已發(fā)現(xiàn)的有 01和03兩種值,數(shù)據(jù)區(qū)解析時會用到這個值
關于幀頭4字節(jié)ARGB顏色字段作用
我從B站的 @日小皮Fantasycho 的這篇文章里發(fā)現(xiàn)有一個目錄,看著像是國外的某個網(wǎng)站

于是我找到了原文地址
https://modenc.renegadeprojects.com/SHP
這里對 12 - 15字節(jié)有了一點說明,是一個32位深ARGB顏色值,但是具體作用未知
12-15字節(jié),我并未破譯出其中含義,猜測可能是一個校驗值,如果有誰知道其含義,還請告知UP主,但是這個字節(jié)并不影響我們使用shp文件

祝福
其實學紅警開發(fā)之前,我自己也嘗試過,但是無疾而終。我有點完美主義傾向,但是這并不好。
今天努力嘗試做一個不完美的實踐,行動起來,思想也就逐漸有了變化。
希望看到這篇文章的人都能天天進步,努力攀登自己的能力高峰

浙公網(wǎng)安備 33010602011771號