速查 › 圖片的像素怎麼排
圖片的像素怎麼排
大頭照與臉皮那兩頁各留了一個「未解」: 知道格式代號、知道尺寸,但不知道像素是怎麼排的。 這頁把它解開 —— 而且不用寫程式,拿計算機就能驗。
先講清楚:什麼是實測,什麼只是名字
「代號叫什麼」跟「像素怎麼排」是兩件事
像素怎麼排 = 實測。照規則解出來是一張正常的人臉,就是對的; 排錯一個位元組,臉會立刻散成雜訊。
代號叫什麼名字 = 只是索引。名字對不對,不影響你能不能改圖。
這個區分不是講究 —— 本站在做這頁的時候, 發現自己工具裡那張「代號 → 名字」的表有三格是錯的。見下面。
算術自證:拿計算機就能驗
區塊壓縮的規則只有一條:畫面切成 4×4 的小方塊,每個方塊固定用同樣多的位元組。 只有兩種方塊大小 —— 8 個或 16 個位元組。
知道這條規則,就能自己算。大頭照那頁已經量到 「每張圖的像素資料都是 65,536 bytes」,代進去:
| 圖 | 尺寸 | 算式 | 結果 |
|---|---|---|---|
臉皮 0x60 | 256 × 512 | (256÷4) × (512÷4) × 8 = 64 × 128 × 8 |
65,536 ✅ |
大頭照 0x61 | 256 × 256 | (256÷4) × (256÷4) × 16 = 64 × 64 × 16 |
65,536 ✅ |
小張的 0x61 | 128 × 128 | (128÷4) × (128÷4) × 16 = 32 × 32 × 16 |
16,384 ✅ |
算式只有一種填法對得起來。 同一個代號換一個尺寸照樣成立 —— 所以不是湊出來的。
更好記的驗法:一個像素花幾個位元組
把「像素資料的位元組數 ÷ 寬 ÷ 高」算出來:
0x60 → 永遠是 0.5
0x61 → 永遠是 1.0
本站走過兩個倉庫裡全部 48,885 張圖, 沒有任何一張算出別的數字。這代表代號真的決定了像素排法。
解出來長什麼樣
本站照上面的規則實際解了兩張(EA 原廠的圖不會放上站,那是遊戲的內容。 社群自己做的模組另當別論,見球衣那一課):
| 來源 | 代號 | 解出來看到什麼 |
|---|---|---|
| portrait.big 的一張大頭照 | 0x61 | 一張正常的球員證件照 —— 球帽、隊徽、五官、膚色、帽沿陰影全部正常 |
| models.big 的一張臉皮 | 0x60 | 一張攤平的 3D 貼圖 —— 正中央是攤開的臉、兩側耳朵被拉到邊緣、 上方是頭髮、下面一條是脖子;左下角另外放了兩顆眼球、右下角放了牙齒 |
看到的東西本身就是最強的證據。一個位元組排錯,人臉會立刻散成條紋雜訊。
第二次獨立驗證:透明度層
0x61 每個方塊多出來的 8 個位元組是透明度。把它單獨畫成黑白圖:
- 得到一個乾淨的頭肩剪影,輪廓跟彩色圖完全對得上
- 65,536 個像素裡,36,194 個完全不透明、27,610 個完全透明,中間值很少
- 透明區域的連通塊:隨機 30 張裡中位數只有 1 塊
但不是上限 —— 有一張長捲髮球員的髮絲把背景切碎, 連通塊 64 塊。已確認不是解錯:那張圖解出來是完全正常的證件照。 「中位數 1 塊」可以寫,「最多只有幾塊」這種上限句不能寫 —— 30 張的抽樣抽不到極端值。
如果透明度解錯了,會得到滿版雜點、幾千個碎塊。 得到一個完整剪影,等於第二次獨立驗證。
臉皮 0x60 則相反:隨機 30 張、合計三百九十多萬個像素,
完全透明的像素是 0 個 —— 臉皮是不透明貼圖。
九個代號各是什麼
| 代號 | 每像素 | 排列方式 | 憑什麼 |
|---|---|---|---|
| 0x60 | 0.5 | 4×4 區塊,每塊 8 bytes 兩個底色 + 16 個 2 位元索引 |
實測 解出真實臉皮 |
| 0x61 | 1.0 | 4×4 區塊,每塊 16 bytes 前 8 bytes 是透明度,後 8 bytes 同上 |
實測 解出真實證件照 + 剪影 |
| 0x6D | 2.0 | 每像素 2 bytes,四個四位元:透明度、紅、綠、藍 | 實測 解 2009 台灣模組的打擊頭盔,換成 1-5-5-5 排法整張變桃紅色 |
| 0x78 | 2.0 | 每像素 2 bytes,紅 5 位元、綠 6 位元、藍 5 位元,沒有透明度 | 實測 解 2009 台灣模組的球衣,換成 1-5-5-5 顏色偏綠、換成 4-4-4-4 整片桃紅 |
| 0x7B | 1.0 | 每像素 1 個位元組 = 調色盤索引。
調色盤就在緊接著的 0x2A 區塊裡(256 筆 × 4 bytes),見下 |
實測 剛安裝好的原版裡 9 筆記錄(3 張相異的圖) |
| 0x7D | 4.0 | 每像素 4 bytes,順序是藍、綠、紅、透明度 | 實測 |
| 0x7E | — | 外部說明書說是 16 位元 1:5:5:5(含透明度) | 未解 本站在任何地方都找不到樣本,無從實測 |
| 0x7F | 3.0 | 每像素 3 bytes,順序是藍、綠、紅 | 實測 照紅綠藍解整張臉是藍的,換成藍綠紅膚色才正常 |
| 0x79 | 0.5 | 4 位元索引色(每個位元組裝兩個像素),後面接一個
0x2A 調色盤區塊 |
實測 字型 au20b_en.ffn 的
0x2A 區塊正好 16 個項目(size 欄位寫 80 =
16 + 16×4),全部是白色配 0x00 0x11 0x22 …0xff 的透明度階梯
—— 2⁴ = 16 級,一個不多一個不少。
另外量到中文字型的字圖集是 1024×512、資料量 262,368 bytes,
正好 0.500 bytes/像素 |
⚠️ 2026-08-28 訂正:0x79 本站原本寫「不是圖,永遠 1×1」
原文是這樣寫的(留著給你對照):
0x79— 不是圖。永遠 1×1,整筆記錄固定 32 個位元組。
實測uniforms.big的 431 個空球衣槽全部是它,431/431 都是 1×1
那個量測本身沒有錯 —— 球衣檔裡確實 431/431 都是 1×1。 錯在把「它在這個檔裡的用途」寫成了「這個格式的定義」。
去量中文字型之後,同一個代號長這樣:
| 樣本 | 尺寸 | 資料量 | 每像素 |
|---|---|---|---|
中文 twc14_en.ffn 的字圖集 | 1024 × 512 | 262,368 | 0.500 |
英文 au20b_en.ffn 的字圖集 | 256 × 128 | 16,592 | 0.506 |
定案的證據是調色盤,不是尺寸。
au20b_en.ffn 的像素資料後面接著一個 0x2A 區塊,
它的 size 欄位寫 80 = 16 + 16×4,
裡面正好 16 個項目,全部是白色配 00 11 22 33 …ff 的透明度階梯:
# | R G B A 0 | ff ff ff 00 ← 透明度 = 編號 × 17 1 | ff ff ff 11 2 | ff ff ff 22 … 15 | ff ff ff ff ← 16 級,一個不多一個不少
2⁴ = 16。4 位元的索引只能指到 16 個顏色,而它給的正好是 16 級抗鋸齒灰階 —— 那是字型需要的東西。這不是「數量剛好對得上」,這是格式定義本身。
本站下載腳本裡的 0x79: 'EMPTY_1x1' 已經同步改成 'PAL4'。
這一次沒有重蹈下面那一節的覆轍。這個代號的實際後果見
中文版配大球場就跳出:
Direct3D 8 沒有 4 位元貼圖格式,所以中文字型每一張都要在執行時展開,
光字型就吃掉 13.50 MB。
⚠️ 2026-08-28:那個訂正從來沒有進到程式碼
本頁下面「本站工具裡的名字有三格是錯的」那一節, 是這頁上線時就寫好的。但被指出錯的那份程式碼,一直沒有改。 同一份「代號 → 名字」字典出現在當時的五支下載腳本裡 (做新臉皮、換大頭照、裝球衣、拆封裝檔、清孤兒),五份一模一樣、五份都是舊的。
而且複驗時發現不只名字錯,還少了兩個代號:
| 代號 | 量到的每像素 | 腳本原本的字典 | 後果 |
|---|---|---|---|
| 0x6D | 2.0 | ARGB32(=4 bytes) | 顯示錯名字 |
| 0x7B | 1.0 | ARGB16_1555(=2 bytes) | 顯示錯名字 |
| 0x7D | 4.0 | RGB24(=3 bytes) | 顯示錯名字 |
| 0x7F | 3.0 | 沒有這一格 | 會擋掉真實的檔 |
| 0x79 | 0.5 | 沒有這一格 | 同上 |
後兩列有真實後果。那份字典同時被當成守門員
(if code not in FSH_FORMATS: raise …),
所以做新臉皮那支腳本會拒絕 models.big 裡
45 個真實存在的檔(g001.fsh–g045.fsh)。實測前後:
修之前 g001.fsh → ❌ 沒見過的格式代號 0x7F
修之後 g001.fsh → 0x7F (RGB24) 128x128 · 像素 49152 bytes · 每像素 3.000
128 × 128 × 3 = 49,152,算術自己對上。
名字錯的那三格只影響顯示,不會寫壞檔(寫入前另有一道尺寸守衛)。
五支腳本與頁面附錄都已同步。
(2026-09-05 補:後來又有三支腳本帶了同一份字典 ——
換掉開機畫面、
換球隊隊徽、
一整包模組自動歸位 ——
現在是八支。八份的九行逐字相同,都是改好之後的版本。)
⭐ 這個錯的形狀值得記:把錯誤寫進文件,不等於修好了它。 而且六道檢查器一道都沒抓到 —— 它們查連結、標籤、數字一致性, 但沒有一道會去比對「頁面上的結論」與「附在頁面上的程式碼」。 已補上第九道檢查專門做這件事。
⭐ 2026-08-28:一份 2002 年的說明書,把上面整張表背書了一次
上面那張表的每像素位元組數,全部是本站自己在剛安裝好的原版上量出來的。 後來在舊資料裡翻到 FSHTOOL 1.22(Denis Auroux,1998–2002)的說明書, 它直接列了格式表 —— 本站量到的每一格都對上:
| 代號 | 那份說明書寫的 | 它隱含的每像素 | 本站量到的 |
|---|---|---|---|
| 0x60 | DXT1 compressed | 0.5 | 0.5 ✅ |
| 0x61 | DXT3 compressed (with alpha channel) | 1.0 | 1.0 ✅ |
| 0x6D | 16-bit 4:4:4:4 (with alpha channel) | 2.0 | 2.0 ✅ |
| 0x78 | 16-bit 0:5:6:5 | 2.0 | 2.0 ✅ |
| 0x7B | 8-bit (with palette) | 1.0 | 1.0 ✅ |
| 0x7D | 32-bit 8:8:8:8 (with alpha channel) | 4.0 | 4.0 ✅ |
| 0x7E | 16-bit 1:5:5:5 (with alpha channel) | 2.0 | 找不到樣本 |
| 0x7F | 24-bit 0:8:8:8 | 3.0 | 3.0 ✅ |
兩邊互相獨立:那份說明書是 2002 年為另一款遊戲寫的, 本站的數字是 2026 年在這款遊戲的檔案上量的。七格全中。
⚠️ 但要照本站自己的規矩分開講:「每像素幾個位元組」是量到的,
「代號叫什麼名字」是那份說明書說的。這兩件事的強度不一樣。
0x7E 就是例子 —— 說明書給了它名字,但本站一張樣本都沒有,
所以它的徽章仍然是「未解」。
那份說明書還有一條本站原本不知道的規則: 代號 +0x80 代表「這張圖本身是壓縮過的」。 本站在兩個倉庫裡沒有遇過這種代號,記在這裡備查。
⭐ 0x7B 的調色盤找到了 —— 就在同一個檔裡,接在圖片後面
本站原本寫「每像素 1 個位元組,內部排法未解」。 缺的那一半是調色盤,而它一直都在同一個檔案裡 —— 只是不在 SHPI 目錄上,要順著圖片記錄自己的長度欄位往下走才看得到。
拿 data\igshapes\igcrsr1.fsh 走一次,每一筆的鏈都長這樣:
0x7B 圖片 16,400 bytes (128×128)
→ 0x2A 調色盤 1,040 bytes
→ 0x69 附掛文字 80 bytes
→ 0x70 結束
算術自己對上:1,040 = 16(區塊表頭)+ 256 × 4,
而那個區塊的「寬高」欄位寫的正是 256, 1 —— 就是「256 筆」。
(1040 − 16) ÷ 256 = 4.00,一個顏色四個位元組。
第二個獨立驗證:這 256 筆裡每一筆的第 4 個位元組都是 255,只有索引 0 是 0。 而索引 0 在那張 128×128 的圖裡佔了 14,433 / 16,384 個像素(88%) —— 那是游標圖的透明背景。第 4 個位元組確實是透明度, 而且「最常用的索引剛好是透明的那一個」不可能是巧合。
2026-08-29 第三個獨立驗證
「第 4 個位元組是透明度」現在有另一個格式的佐證。
字型檔裡的 0x79 圖片後面也接著一個 0x2A 調色盤,
而 au20b_en.ffn 那一張長這樣:
# | R G B A 0 | ff ff ff 00 1 | ff ff ff 11 2 | ff ff ff 22 … 15 | ff ff ff ff ← 16 筆,透明度 = 編號 × 17
RGB 三格全部是 ff(純白),只有第 4 格從 0 均勻爬到 255。
兩個不同的格式、兩批不同的檔案,都指向同一個結論。
(這也順便定死了 0x79 是 4 位元 ——
2⁴ = 16 筆,一筆不多一筆不少。)
⚠️ 沒解開的:這三個檔一共九個調色盤,其中七個是 256 筆全部灰階
(R=G=B);剩下兩個(feonlyln.big 與 igcrsr9.fsh 的
BPP4)各有 133 筆不是灰階,但那 133 筆裡有
118 筆第 1 個與第 3 個位元組相等,差的只有中間那一格 ——
而 RGB 與 BGR 兩種順序,中間那一格都是綠。
所以本站還是無法判斷前三個位元組的順序是 RGB 還是 BGR。
要判斷得找一張真正彩色的 0x7B。
2026-08-29 補掃
本站把裝滿模組的測試機也整套掃了一次(424 個封裝檔與 .fsh)
—— 還是那 9 筆,一筆不多,而且最大彩度只有 21(近乎全灰)。
所以「找不到彩色樣本」不是沒有找,是這款遊戲裡就沒有。
(2026-09-05 訂正:上面那句原本寫「這三個檔的調色盤 256 筆全部是灰階」,
那跟這一句自己量到的「最大彩度只有 21」互相矛盾 —— 真的每一筆 R=G=B 的話,
最大彩度必定是 0。結論沒有變,錯的是理由。)
未解
⚠️ 想自己寫工具的話有個坑:調色盤資料不是從區塊起點開始, 前面有 16 個位元組的區塊表頭。少扣這 16 個, 會把表頭當成前四個顏色。
我們改過這一段:0x7B 找到了
這頁上線時把 0x7B 標成「兩個倉庫裡一張都沒有,無法實測」。
後來拿到剛安裝好、從未改動的原版,
把整套安裝掃了一次 —— 52,747 筆影像記錄裡,有 9 筆是 0x7B。
它們不在大頭照或臉皮那兩個倉庫裡,所以之前才找不到。實際位置是:
| 檔案 | 筆數 | 項目名稱 | 尺寸 |
|---|---|---|---|
| data\frontend\feonlyln.big | 3 | BPP4 · BPP5 · BPP6 | 128×128 |
| data\igshapes\igcrsr9.fsh | 3 | BPP4 · BPP5 · BPP6 | 128×128 |
| data\igshapes\igcrsr1.fsh | 3 | BPP2 · BPP3 · FTM2 | 128×128 ×2、128×64 ×1 |
每像素剛好 1.000 個位元組,9 筆全部整除: 128×128 的 payload 是 16,384、128×64 的是 8,192。
要說清楚的是 9 筆記錄不等於 9 張圖 —— 把像素資料取 md5,只有 3 種(一張 128×128 出現 6 次、另一張出現 2 次、128×64 那張 1 次)。 同樣的 9 筆在原版繁中安裝裡也找得到,內容相同。
還沒解開的是它的內部排法。
每像素 1 個位元組跟 0x61 一樣,但 0x61 是 4×4 區塊,
0x7B 看起來不是 —— 本站沒有把它解出來,也不猜。
未解
項目名稱 BPP2 到 BPP6 看起來像在講「每像素幾位元」,
但這六筆格式代號全部都是 0x7B,沒有對應到不同格式。
名字是什麼意思,本站不知道。
順帶解釋一件大頭照那頁量到但沒說明原因的事:
0x7D 的 128×128 × 4 bytes 跟 0x61 的 256×256 × 1 byte
剛好一樣大。一個是每像素四個位元組的完整色彩、一個是區塊壓縮,
平均差四倍,所以能塞的面積就差四倍。
2026-08-29 再掃一次:把以前漏掉的一整類補進來
上面那次掃描是 52,747 筆影像記錄。這次重掃,加了兩類以前沒走到的地方:
- 巢狀封裝檔 —— 有些封裝檔裡只裝一個壓縮過的封裝檔 (見 執行檔裡剩下的原始碼痕跡)。 不多拆一層,裡面的東西在統計上等於不存在。
- 散裝的 FSH 與單獨壓縮的檔 —— 不在任何封裝檔裡的那些。
| 上次 | 這次 | |
|---|---|---|
| 掃到的影像記錄 | 52,747 | 105,834 |
| 來源 | 封裝檔 | 封裝檔 + 巢狀 + 散裝 |
| 掃的是哪一台 | 剛安裝好的原版 | 裝滿模組的測試機 |
0x7B | 9 | 還是 9 |
0x7E | 0 | 還是 0 |
結論沒有變,但「沒有」這句話的份量變了: 以前是「在剛安裝好的原版上掃了五萬多筆沒找到」,現在是「連裝滿模組的測試機也掃了十萬多筆、 而且把以前漏掉的一整類補進來之後,還是沒找到」。 否定句的可信度取決於你找過哪裡,不取決於你找了幾次。
(2026-09-05 訂正:上面那兩欄不是同一台機器,本頁原本沒有講。
五萬多那次掃的是剛安裝好的原版,十萬多這次掃的是裝滿模組的測試機 ——
光是 0x79 就從 431 筆變成 568 筆,
那正是這台機器多出來的球衣槽(見球衣那一課)。
本站把剛安裝好的原版照這次的口徑(含巢狀與散裝,往下拆三層)重走一次,得到
52,822 筆 —— 比上次只多 75 筆。
所以筆數會翻倍,主要來自換了機器,不是來自補進巢狀與散裝那兩類。
兩台都掃過,兩台都是 0x7B 9 筆、0x7E 0 筆,結論本身不受影響。)
兩個數字要對帳,不然讀者會被搞混
上面那次寫「掃了 424 個封裝檔與 .fsh」,是把兩種東西加在一起數。
這次分開數:真的是 BIGF 封裝檔的 387 個、
再往裡拆一層的巢狀封裝檔 2 個、磁碟上直接是 SHPI 的 22 個。
差額主要來自兩件事:這次只認檔頭不認副檔名
(這個遊戲有 17 個叫 .big 的檔根本不是封裝檔),
而且磁碟上被單獨壓縮過的 .fsh 這次是先解壓再算。
兩個數字都沒錯,只是口徑不同。本站的紀律是 兩個數字對不起來時,先確認它們是不是在數同一件事。
同一種對帳還有第二筆,方向相反:官方更新檔那頁
講的是同一份剛安裝好的原版,分母卻寫 52,719,
比本頁上面那次的 52,747 少 28 筆。
差別一樣出在口徑:那一頁只走頂層封裝檔,本頁那一次連磁碟上散裝的 SHPI 一起數。
那 28 筆已經逐檔對出來了(data\misc\textures\ 18 個各 1 筆、
igcrsr.fsh 1 筆、igcrsr1.fsh 與 igcrsr9.fsh 各 3 筆、
data\frontend\feonlyln.big(它其實是 SHPI)3 筆),
52,719 + 28 = 52,747,是同一批資料的兩種口徑;
對帳過程與逐檔清單寫在那一頁。
其餘格式這次量到:0x6D 37,633 · 0x78 32,215 ·
0x61 13,658 · 0x60 10,978 · 0x7D 10,728 ·
0x79 568 · 0x7F 45。
⭐ 每張圖後面都掛著一句 EA 自己寫的話
主圖後面接著一個附掛區塊,代號 0x69,固定 80 個位元組。
裡面是純文字,而且它自己說出自己是什麼:
EAGL64 metal bin attachment for runtime texture management
EAGL 就是 EA 自家的繪圖引擎(執行檔裡有一整排
EAGL::ViewPort::… 的符號)。這是一句給執行時貼圖管理用的註記。
| 封裝檔 | .fsh 檔 | 有這個區塊 | 內容壞掉 |
|---|---|---|---|
portrait.big | 7,542 | 7,542(100%) | 3 |
models.big | 2,331 | 2,331 | 0 |
uniforms.big | 692 | 124 | 0 |
(2026-09-05 訂正:這一欄原本的欄名寫「圖」,跟本頁其他地方的口徑不一樣。
它數的是 .fsh 檔的個數,不是子圖的張數 ——
一個 .fsh 可以裝很多張圖。models.big 那 2,331 個檔裡有
四萬多張子圖(見模型與臉皮那頁),
uniforms.big 的 692 個檔裡有 1,336 張;
portrait.big 剛好一個檔一張,所以 7,542 兩種算法一樣。
models.big 的目錄上其實有 2,332 個 .fsh,這裡只數到 2,331 ——
有一個(c333.fsh)本站的 QFS 解壓器解不開。
本頁頁尾的 48,885 用的是子圖那個口徑。)
⚠️ 本站訂正過自己的一條筆記 —— 然後那條訂正自己也錯了(2026-08-29)
本站的待辦清單上寫著「0x7C 區塊(256 bytes,只在 2653.fsh 與 2663.fsh),
不在說明書清單裡,未解」。
這裡原本寫「三個前提全錯:代號是 0x69 不是 0x7C、
長度是 80 不是 256、而且 7,542 張圖 100% 都有」。
那句訂正才是錯的,現在收回。
對的部分只有一半:0x69 那 80 個位元組的註記,上面那張表量到的
7,542 張 100% 都有,這一條成立。
錯在把它跟 0x7C 當成同一塊 —— 它們是接在同一張圖後面的兩個不同區塊。
2026-08-29 拿三份剛安裝好的原版(英文版、中文版、PK 版)逐項走過附掛鏈,
三份都是 2,391 張圖:2,389 張是
0x7D 圖 → 0x69 80 bytes → 0x70 結束,
另外 2 張在中間多一塊 0x7C、256 bytes,
而那 2 張三份都正好是 2653.fsh 與 2663.fsh。
在 portrait.big 裡,原本那條筆記三個前提都成立。
細節見大頭照 portrait.big那頁。
(2026-09-05 訂正:上面那句原本沒有限定範圍,寫成「三個前提都成立」。
其中「只在 2653.fsh 與 2663.fsh」這一個前提
只對 portrait.big 這個封裝檔成立 ——
本頁下面那節的 data\igshapes\igcrsr.fsh 也帶著一塊 0x7C,
而且長度是 576 不是 256。三份剛安裝好的原版、它那份
.bak、本站測試機都有:本尊的附掛鏈是
0x7D → 0x69 → 0x7C → 0x70,.bak 少了中間那個
0x69。這正好是同一條教訓再犯一次 ——
「只在某兩個檔出現」要先去看第三個檔,而第三個檔就在這一頁上。)
為什麼會訂正錯:上面那張表量的是本站測試機。
測試機上這兩張已經被換過(2653.fsh 原版 49,311 bytes、測試機 49,471,
2663.fsh 原版 25,600、測試機 26,124,md5 都不同),
換進去的那一份沒有帶著 0x7C,所以整台機器一張都掃不到。
「只在某兩個檔出現」這種話,要先確認自己有沒有去看第三個檔; 而「一張都沒有」這種話,要先確認自己看的那台機器還是不是原版。
⭐ 順手抓到 3 張被不同工具處理過的大頭照
7,542 張裡有 3 張的那段字是壞的:
正常 :EAGL64 metal bin attachment for runtime texture management
這 3 張:EAGL64 mel bin attachment for runtime texture management
4174.fsh、4215.fsh、4901.fsh ——
metal 少了兩個字母變成 mel。
圖本身完全正常(都是 0x61 256×256,解開後 65,680 bytes,
跟鄰居一模一樣),只有這段註解不對。
那不影響遊戲,但它是一個指紋:這三張跟其他 7,539 張 不是同一支工具做出來的。球衣庫與模型庫則一張都沒壞。
兩個抓到自己錯的地方
一、本站工具裡的名字有三格是錯的
走過兩個倉庫全部 48,885 張圖之後,有三個代號跟資料對不上:
| 代號 | 表上寫 | 實測 |
|---|---|---|
| 0x6D | 4.0 | 2.0 |
| 0x7D | 3.0 | 4.0 |
| 0x7F | 1.0 | 3.0 |
單位是「每個像素幾個位元組」。0x7D 這一格是本站上線後複驗才抓到的
—— 第一次只抓到兩個。
把 0x6D 硬當四個位元組解,相鄰像素差 50.72(雜訊);當兩個位元組解,
差 6.96 而且圖正常。
程式碼註解只能當線索,不能當證據。 這也正好證明「名字」跟「像素排法」必須分開講。
二、驗證方法自己也有盲點
本站用「相鄰像素差」當作「有沒有解錯」的檢查器 —— 自然影像數字小,雜訊數字大。 大頭照那邊很好用:
| 解法 | 相鄰像素差 |
|---|---|
| 正解 | 5.19 |
| 錯解:每塊只讀 8 bytes | 16.82 |
| 錯解:整體位移一個位元組 | 20.90 |
| 錯解:當成每像素兩個位元組 | 91.25 |
但它對臉皮 0x60 不只是失效,是會選錯邊。
故意把臉皮當成「每塊 16 bytes」讀,天真地算全圖:
誤讀 5.29 分,正解 8.99 分 —— 誤讀看起來還比較好。
原因有兩層。第一層:那樣誤讀等於「每隔一個方塊取一個真方塊」,取到的還是真顏色,圖仍然平滑。 第二層更陰險 —— 誤讀會讓下半張圖整整 256 列全黑,而全黑區的相鄰差是 0, 把平均硬生生拉下去。 就算只比對同樣的前 256 列讓條件公平(正解 9.41、誤讀 10.42), 30 張裡仍然有 4 張是誤讀分數比較好。 真正抓到它的是算術 —— 65,536 bytes 只夠 4,096 個方塊,但 256×512 需要 8,192 個, 結果是整整下半張圖 256 列完全空白。
教訓:檢查器過關不代表沒錯,要有第二種完全不同的驗法。
這頁不能告訴你什麼
解得開,不等於做得出來
知道像素怎麼排,可以把遊戲的圖讀出來看。
但要做一張新的放回去,還需要把圖壓縮回區塊格式 ——
那一半後來做了:0x60(DXT1)與 0x61(DXT3)兩種都能壓回去,用在換大頭照、做新臉皮、換開機畫面三課。其餘代號沒有做,腳本遇到會直接拒絕而不是猜。
但壓得回去不等於裝得回去:換開機畫面那一課的 splash.fsh,DXT1 壓出來的長度是對的,卡在那一筆記錄自己宣告的長度多 16 個位元組,目前匯不回去。
未解 0x7E 這個代號,
本站到目前為止在任何地方都還沒找到一張,無從實測。
⚠️ 這裡原本寫「0x7B 與 0x7E 兩個代號,
這兩個倉庫裡一張都沒有」——
但這一頁上面已經把 0x7B 找到了
(9 筆記錄,3 張相異的圖)。
這是本站訂正上半段時漏改了頁尾,同一頁自己跟自己打架。
現在只剩 0x7E。
三個沒有包在封裝檔裡的圖(2026-08-28 量的)
data\igshapes\ 是少數不用解封裝檔就看得到的圖 ——
四個檔直接躺在資料夾裡,而且沒有壓縮,
開頭就是 SHPI。
| 檔案 | 大小 | 子圖 | 格式與尺寸 |
|---|---|---|---|
igcrsr.fsh | 525,264 | 1 | 32 位元無壓縮 · 512 × 256 |
igcrsr1.fsh | 44,464 | 3 | 8 位元調色盤 · 128×128 ×2、128×64 |
igcrsr9.fsh | 52,800 | 3 | 8 位元調色盤 · 128×128 ×3 |
igcrsr.fsh.bak | 525,184 | 1 | EA 自己附的備份檔 |
驗算:512 × 256 × 4 位元組 = 524,288,加上 976 個位元組的表頭
正好是 525,264。而且每個檔的 SHPI 檔頭裡宣告的長度
都等於檔案本身的長度,四個檔全對。
⭐ EA 在出貨的遊戲裡留了一個 .bak
igcrsr.fsh.bak 是正式版光碟裡就有的檔案 ——
官方英文版與官方繁體中文版兩邊都有。
它比本尊小 80 個位元組,而且從第 4 個位元組就開始不一樣 (那一格正是 SHPI 宣告的長度)。所以它是同一張圖的前一個版本, 某個人存檔前先備份了一次,然後那份備份跟著出貨了。
這跟本站在 平安夜那次建置看到的是同一類東西: 正式產品裡留著開發現場的痕跡。
📌 重點整理
- 一句話 大頭照與臉皮的像素排法解開了,而且不用寫程式就能驗,把「像素位元組數 ÷ 寬 ÷ 高」算出來,
0x60永遠是 0.5、0x61永遠是 1.0,走過兩個倉庫全部 48,885 張圖沒有一張算出別的數字。 - 規則只有一條 畫面切成 4×4 的小方塊,每塊固定 8 或 16 個位元組。256×512 的
0x60與 256×256 的0x61都剛好是 65,536 bytes,128×128 的0x61是 16,384,同一個代號換尺寸照樣成立。第二次獨立驗證是透明度層:0x61多出來那 8 個位元組單獨畫出來是一個乾淨的頭肩剪影,65,536 個像素裡 36,194 個完全不透明、27,610 個完全透明。但「連通塊中位數 1 塊」可以寫,「最多只有幾塊」這種上限句不能寫,有一張長捲髮球員的髮絲把背景切成 64 塊,而那張圖是正常的。 - 本站訂正之一:用途不等於格式定義
0x79原本寫成「不是圖,永遠 1×1」,依據是uniforms.big的 431 個空球衣槽 431/431 都是 1×1。那個量測本身沒有錯,錯在把「它在這個檔裡的用途」寫成了「這個格式的定義」。中文字型的字圖集同一個代號是 1024×512、262,368 bytes、正好 0.500,而定案的證據是調色盤:au20b_en.ffn後面接的0x2A區塊size欄位寫 80 = 16 + 16×4,裡面正好 16 筆白色配透明度階梯,2⁴ = 16,一筆不多一筆不少。 - 本站訂正之二:訂正從來沒有進到程式碼 頁面上早就寫著「本站工具裡的名字有三格是錯的」,但被指出錯的那份程式碼一直沒有改,同一份字典出現在當時的五支下載腳本裡,五份一模一樣、五份都是舊的(今天帶著這份字典的是八支,內容都已同步)。複驗還發現不只名字錯,還少了
0x7F與0x79兩格,而那份字典同時被當成守門員,所以做新臉皮那支腳本會拒絕models.big裡 45 個真實存在的檔。修好之後g001.fsh認得出來是0x7F128×128、49,152 bytes,128 × 128 × 3 算術自己對上。⭐ 這個錯的形狀值得記:把錯誤寫進文件,不等於修好了它,而且六道檢查器一道都沒抓到,已補上第九道專門比對「頁面上的結論」與「附在頁面上的程式碼」。 - 另外兩處自己抓到的錯 一、工具表上三格的每像素位元組數是錯的,
0x6D表上 4.0 實測 2.0、0x7D表上 3.0 實測 4.0、0x7F表上 1.0 實測 3.0(0x7D那格還是上線後複驗才抓到的)。二、本站待辦清單上寫著「0x7C區塊 256 bytes,只在兩個檔出現」,本頁原本判它三個前提全錯,2026-08-29 收回那句訂正:0x69/80 bytes 的註記確實 7,542 張100% 都有,但它跟0x7C是兩個不同的區塊 —— 三份剛安裝好的原版各 2,391 張圖裡,2653.fsh與2663.fsh這 2 張真的多一塊0x7C、256 bytes,三份完全一致。在portrait.big裡,原本那條筆記是對的,掃不到是因為測試機上這兩張已經被換過(2026-09-05 訂正:但「只在那兩個檔」只對portrait.big成立 ——data\igshapes\igcrsr.fsh也帶著一塊0x7C,長度是 576 不是 256)。「只在某兩個檔出現」要先去看第三個檔;「一張都沒有」要先確認自己看的那台機器還是不是原版。 - 驗證器自己也有盲點 本站用「相鄰像素差」判斷有沒有解錯,對大頭照很好用(正解 5.19、各種錯解 16 到 91)。但它對臉皮
0x60不只是失效,是會選錯邊:誤讀 5.29 分、正解 8.99 分,誤讀看起來還比較好,因為誤讀會讓下半張圖整整 256 列全黑,而全黑區的相鄰差是 0,把平均硬生生拉下去。真正抓到它的是算術。檢查器過關不代表沒錯,要有第二種完全不同的驗法。 - 否定句的份量取決於你找過哪裡
0x7B原本標成「兩個倉庫裡一張都沒有」,後來在剛安裝好的原版裡 52,747 筆影像記錄中找到 9 筆(md5 只有 3 張相異的圖),調色盤就接在圖片後面,1,040 = 16 + 256×4,而且索引 0 佔了 88% 的像素、剛好是透明背景。2026-08-29 重掃把巢狀封裝檔與散裝檔補進來,總數從 52,747 變成 105,834,0x7B還是 9 筆、0x7E還是 0 筆 —— 但這兩個數字不是同一台機器(2026-09-05 訂正):五萬多那次是剛安裝好的原版,十萬多那次是裝滿模組的測試機,原版照同一個口徑重走只有 52,822 筆。另外每張圖後面都掛著一個 80 位元組的0x69註記,7,542 張裡有 3 張的那句字壞了(metal變mel),圖本身完全正常,那是不同工具留下的指紋。 - 本站沒驗的
0x7E這個代號在十萬多筆記錄裡一張樣本都找不到,無從實測,徽章仍然是未解。0x7B的內部排法也還沒解開,本站沒有解出來也不猜;它那九個調色盤裡有七個是 256 筆全部灰階,剩下兩個雖然各有 133 筆不是灰階,但其中 118 筆第 1 與第 3 個位元組相等、差的只有中間那一格,所以前三個位元組是 RGB 還是 BGR 本站無法判斷(連裝滿模組的測試機都掃過,最大彩度只有 21)。項目名稱BPP2到BPP6是什麼意思,本站不知道。壓縮那一半後來做了:0x60(DXT1)與0x61(DXT3)兩種都壓得回去,用在換大頭照、做新臉皮、換開機畫面三課;其餘代號沒有做,腳本遇到會直接拒絕而不是猜。最後要分開講的是強度:「每像素幾個位元組」是本站量到的,「代號叫什麼名字」是 2002 年那份 FSHTOOL 說明書說的,兩件事不一樣。
接下來
- 大頭照 portrait.big ——
0x61與0x7D的家 - 模型與臉皮 models.big ——
0x60的家 - QFS 壓縮 —— 這些圖在倉庫裡是壓縮過的,要先解開才看得到代號
- 兩套球員編號 —— 哪一張圖屬於哪一位球員