[其他] 光榮遊戲頭像儲存格式解析

看板Koei作者 (征服世界中)時間1年前 (2023/04/05 00:05), 編輯推噓22(2200)
留言22則, 21人參與, 1年前最新討論串1/1
之前說到要來寫一篇介紹光榮頭像儲存格式的文章,想不到工作一忙又拖了一個月左右。 趁著這波連假才有一點閒暇時間可以來寫。 在進入正文之前先聊點歷史。其實個人對於光榮遊戲的頭像格式研究可以追溯到上個世紀 末,聽起來很遙遠,不過那時候已經是三國志六代(1998 發行)的時候了。在 1999 年三 月,還是大學生的我用 Visual Basic 寫了個可以看四代五代頭像的「光榮三國志臉譜瀏 覽程式」,並且上傳到巴哈姆特 BBS 站的 KOEI 板,沒錯,這個 BBS 站就是今天「巴哈 姆特電玩資訊站」的前身。幾年前巴哈姆特 BBS 的資料還可以透過 Web 版查看,並且直 接連結到文章,可惜今天站內的文章都不能網址直連了,只能登入 BBS 後查看。 https://i.imgur.com/8HWIWfo.png
已經是 24 年前的文章了 這個小程式是我的第一個 Side Project,也就是並非為了工作或學校功課,純粹出於自 己個人喜好的小 Project。可惜程式碼已經遺失,也沒有截圖,只記得是個一次顯示一張 頭像,可以切換上一張下一張的小程式。這個小程式比大家熟悉 van 修改器還早出來, 也比 van 2004 年在軒轅春秋發的一篇〈三国志系列图像文件格式浅析〉還要早上許多。 接下來停滯了好一段時間,一直到 2013 年初(天啊已經十年前),那時候剛好有點空 閒,於是研究起三國志三代的遊戲資料,特別是各劇本武將資料以及武將頭像,並且也 解出了大眾臉的產生規則,相關的文章版上還可以找到,算是解了小時候玩遊戲的謎團 之一。 再來便是今年,年初的時候在整理電腦裡的舊檔案,意外發現之前 2013 年的研究資料, 但只有殘餘的部分結果,少了原始程式碼與部分過程檔案,於是決定重啟計畫,研究如何 導出三國志的歷代頭像,並將計劃規模擴及到光榮其他的早期遊戲,也順便把這次的研究 結果紀錄到 Github 上,方便日後有人有興趣可以繼續深入。 ### 基本原理 ### 說回正題,光榮早期遊戲的圖片格式在不同的遊戲裡可能有些許差異,但基本原理相同。 圖片格式的基本原理不難,難點在於沒有線索的情況下找出其規律。當年也是因為四代五 代有了威力加強版,可以自訂頭像,於是靈機一動,想到可以藉由更改頭像造成的檔案變 化,來反推出其規則。但即便如此,當年仍花了我不少時間研究,研究出來後寫程式碼反 倒不需要多少時間。 下面便開始說明其格式,往下看之前最好有些「位元(bit)」「位元組(byte)」的基本概 念,並熟悉一些可以編輯二進位的編輯器。這些資料網路上都可以找到許多教學,這裡就 不贅述。 https://i.imgur.com/AXSSUb2.png
三國志三代 `KAODATA.DAT` 以二進位編輯器打開後的樣子 首先我們透過觀察三代的頭像,或是透過四代威力加強版的臉譜編輯功能, 不難發現,每個頭像只用到了八種顏色, 在電腦中只需要 3 個 bit 便可以表現出 8 種變化(2的3次方), 所以頭像中每個點只需要 3 個 bit。 但是一個 byte 有 8 個 bit,3 個 3 個一組放會無法對齊。 光榮的工程師在這邊用的方式是,將 3 個 byte 當作一組, 每一組三個 byte 可以表示八個點,假設這三個 byte 分別是 A, B, C。 第一個點用 A, B, C 最高位的 bit 來組合, 第二個點用 A, B, C 第二高位的 bit 來組合,以此類推, 到第八個點用 A, B, C 最低位的 bit 來組合。 換個更容易理解的方式。 以三國志三代的頭像檔案 `KAODATA.DAT` 為例,用二進位編輯器打開後, 可以看到其前三個 byte 分別為 `FF 00 77`, 我們把它用二進位方式寫下來: ``` FF -> 1111 1111 00 -> 0000 0000 77 -> 0111 0111 FF 00 77 二進位 顏色代碼 == == == =========== =========== 1 0 0 -> 100(二進位) = 4(十進位), 第一個像素點 1 0 1 -> 101(二進位) = 5(十進位), 第二個像素點 1 0 1 -> 101(二進位) = 5(十進位), 第三個像素點 1 0 1 -> 101(二進位) = 5(十進位), 第四個像素點 1 0 0 -> 100(二進位) = 4(十進位), 第五個像素點 1 0 1 -> 101(二進位) = 5(十進位), 第六個像素點 1 0 1 -> 101(二進位) = 5(十進位), 第七個像素點 1 0 1 -> 101(二進位) = 5(十進位), 第八個像素點 ``` 對照三國志三代伊籍的頭像, 我們便可發現一開始的確是一個藍色像素,後面接著三個青色像素, 然後又一個藍色像素,再接三個青色像素。 所以「顏色代碼 4(十進位)」對應的是藍色像素, 而「顏色代碼 5(十進位)」對應的是青色像素。 https://i.imgur.com/UYUbKKT.png
三代伊籍的頭像放大 接著只要按照以上方式,將所有顏色代碼找出,並將代碼替換成色碼畫在圖片上即可。 三代四代五代的人物頭像大小是 64x80 像素, 然後每 3 bytes 代表 8 個像素, 因此一個武將的頭像只要 64x80/8x3 = 1920 bytes。 三國志三的 `KAODATA.DAT` 檔案大小是 589,440, 故可以得知這個檔案裡面有 307 (589440/1920) 張頭像。 ### 其他變化 ### 不止頭像,其實光榮早期的遊戲都是透過這種方式儲存圖像資料,只是放在不同的檔案中 。然而這些遊戲的開發前後跨度長達十幾年,每個遊戲在實際儲存資料上也會有些不一樣 的差異。 首先是顏色數。更早期的光榮遊戲只有四色,因此只要兩個 bit 就夠,也就是說每兩個 byte 存放八個像素點的顏色。例如三國志初代的 DOS 版就是只有用到四色。 https://i.imgur.com/WaPFIwj.png
三國志一的孔明,只有黑黃紅綠四色 再來是圖像資料是否只有一半高度(Half Height, 以下簡稱「半高」)。例如三國志二 代,它每個頭像只有 64x40 的寬高資料,但在遊戲中的顯示卻是 64x80,也就是說它的 高度拉扯了兩倍,每一橫列的像素都重複畫了兩次。有這種特徵的除三國志二,還有維新 之嵐、大航海時代初代、拿破崙等早期遊戲 https://i.imgur.com/hApfgX6.png
拿破崙,左上角是 4x4 的正方格,可以看出每兩列的顏色是重複的 又或者是頭像檔案經過壓縮,這種壓縮方式是光榮自家的 `LS11` 壓縮演算法,不是我們 常見的 ZIP 或 RAR 等公開算法。像這類的檔案就無法透過上面方式直接取得圖像資料, 要先解壓縮後才可進一步解析頭像資料。像是大航海時代二代以及三國志十代就都有用到 `LS11` 壓縮法。這類有壓縮過的檔案,可以在檔案開頭發現 `LS11` 或 `Ls12` 的字樣 。 https://i.imgur.com/gOgkUWN.png
大航海時代二代的頭像檔,`LS11` 開頭 最後,為了避免多年後檔案遺失,又得從頭研究,我這次把相關代碼都放上 Github 了, 除了各個遊戲的頭像提取方式外,也包含了部分遊戲的人物資料匯出,以及關於這些 DOS 遊戲裡使用的中文字型研究。只是目前同時要兼顧工作,時間有限,文件與說明都還 很不足,希望之後陸續有時間補上。有興趣的人歡迎直接看程式碼,有任何建議或是想法 也歡迎透過 Github 上的 issue 交流。感謝大家看到這邊。 Github 專案頁面,原始碼 https://github.com/tzengyuxio/kaodata -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 112.104.53.35 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Koei/M.1680624307.A.E0D.html

04/05 02:34, 1年前 , 1F
讚 強強強
04/05 02:34, 1F

04/05 02:58, 1年前 , 2F
04/05 02:58, 2F

04/05 07:30, 1年前 , 3F
04/05 07:30, 3F

04/05 08:02, 1年前 , 4F
04/05 08:02, 4F

04/05 09:54, 1年前 , 5F
+推+
04/05 09:54, 5F

04/05 12:23, 1年前 , 6F
強者
04/05 12:23, 6F

04/05 13:39, 1年前 , 7F
專業 強
04/05 13:39, 7F

04/05 13:58, 1年前 , 8F
04/05 13:58, 8F

04/05 14:53, 1年前 , 9F
推專業
04/05 14:53, 9F

04/05 15:03, 1年前 , 10F
推大神
04/05 15:03, 10F

04/05 16:21, 1年前 , 11F
雖然我看不懂,還是跪著看完了
04/05 16:21, 11F

04/05 17:38, 1年前 , 12F
04/05 17:38, 12F

04/05 18:56, 1年前 , 13F
看不懂也沒看還是推一個 XD
04/05 18:56, 13F

04/05 19:26, 1年前 , 14F
雖然看不懂還是推
04/05 19:26, 14F

04/05 20:00, 1年前 , 15F
原po獲得稱號:「藝術支援家」
04/05 20:00, 15F

04/05 23:42, 1年前 , 16F
看到 ASCII 碼真的很爽XDD
04/05 23:42, 16F

04/06 09:38, 1年前 , 17F
推!
04/06 09:38, 17F

04/06 16:16, 1年前 , 18F
神人!
04/06 16:16, 18F

04/06 20:47, 1年前 , 19F
不明覺厲
04/06 20:47, 19F

04/06 21:42, 1年前 , 20F
這太專業了
04/06 21:42, 20F

04/07 18:03, 1年前 , 21F
04/07 18:03, 21F

04/07 18:46, 1年前 , 22F
04/07 18:46, 22F
文章代碼(AID): #1aB4gpuD (Koei)