[心得] SFC中文化經驗談(二)—解壓篇—
【雜言】
雖然實作上是以top-down的方式,從反組譯開始找出指標、壓縮規則,
但我還是以bottom-up的方式來解說中文化技術,
因為這樣比較不會一次遇到大量名詞與觀念。
所以讓我們假設已經知道文本、字庫指標,先來看看常見的壓縮規則與觀念。
【正文】
由於早期卡匣昂貴,如何在有限的ROM裡盡量壓縮資料塞進去,
就成了早期遊戲的基本要求。
會壓縮的資料主要包括圖像、字庫、文本,
不過反正都是看成以byte為單位的連續資料,所以壓縮時沒太大差別。
事實上,因為連壓縮規則都是每個遊戲自由訂定旳,
所以沒有通則存在。不過我一般會分成下列幾種類型:
==================================================================
‧無壓縮型
- 無壓縮的資料大致只包含資料本身與控制碼。
控制碼是各遊戲各自訂定的,可能包含結束碼、換行碼、
甚至主人公名字、取得道具名等非固定資料,也會以特定代碼表示。
- 名詞文本因為太短無壓縮必要,因此通常沒被壓縮。
無壓縮圖像、字庫通常不會有控制碼,無壓縮劇情文本則一定會有。
例如:
皇家騎士團一代中,武器名稱是以未壓縮形式存放在ROM裡。
ソ ニ ッ ク ブ レ ー ド
BF C6 AF B8 19 32 DA B0 19 2E 00
從上例可見有些字的代碼長度是1 byte、有些是2 bytes。
最後的00就是用於判斷名稱末尾的控制碼。
我們要如何知道每個字的代碼是什麼?
最簡單的方法就是去找改名字的金手指,
這特別適用在文字量大、能取名的RPG與SLG遊戲。
‧字典型
- 用固定2~3個byte當作某些常用詞(例如道具名、人名)的代碼。
加上特定控制碼就會直接透過代碼取得名稱。
- 這其實應該不算壓縮,比較像引用....
因為比起等下要講的簡單多了,所以省略(逃
- 多半使用在劇情文本上,大多利用名詞文本當字典,
有時也會跟下面方法混用。
‧參照型
- 將至今解壓出的本文內容當參考對象,
指定"位移量"與"參照byte數"來得到重複出現過的句子段落。
- 圖像、字庫、劇情文本都可能使用。
- 以下舉例介紹:
========================================================
SFC中最常見的壓縮法是....
用1個壓縮byte來指示後面幾個bytes內容,
用 bit = 1 或 0 來代表哪些是未壓縮資料、哪些是參照資料。
FF 74 00 9A 00 CE 00 0E 01 FF 46 01 80 01 B1 01
D2 01 FF 10 02 51 02 88 02 9F 02 FF BB 02 E0 02
0D 03 3B 03 FF 60 03 9A 03 AC 03 D7 03 FF F9 03
25 04 5A 04 94 04 FF C9 04 08 05 38 05 78 05 FF
98 05 C0 05 FD 05 2E 06 FF 71 06 B2 06 EA 06 15
07 FF 3A 07 6A 07 A0 07 DD 07 FF 19 08 4E 08 85
08 AC 08 FF E2 08 23 09 56 09 92 09 FF CF 09 0A
0A 33 0A 66 0A FF 8D 0A BB 0A F0 0A 11 0B FF 36
0B 6C 0B B3 AB B0 DA FF DD 0D 3E FC 19 00 19 9C
FF ED A4 F6 93 9A 9F A1 0D FF 20 91 E5 E0 86 95
1A AA FF E1 9C E3 95 F8 EF 9C E0 F7 A1 00 3E 07
EE EA 19 C2 9C FF 97 19 28 C3 19 21 C8 B1 FF 19
96 19 89 E4 0D 20 18 FF 1E FC E8 19 10 E5 F8 EF
FB 9E FD 07 CA 19 A7 19 00 9F FF 93 E2 19 03 E3
92 EF 9D...(略)
以上面皇騎1代的壓縮劇情代碼為例:
當壓縮byte為FF時,就表示後面8個bytes都是未壓縮資料。
因為FF以2進位看時是 11111111,
而每個1都代表1byte的未壓縮資料。
當壓縮byte為F7時,因為F7以2進位看時是 11110111,
其中0是位在從右邊(低位)數來第4筆的位置,
表示第4筆是參照資料(2 bytes),其他7筆是1 byte未壓縮:
A1 00 3E 07 EE EA 19 C2 9C
這2 bytes參照資料轉成2進位就是 00000111 11101110。
前5 bits用來表示需複製多少byte資料。
因為參照資料本身就佔2 bytes了,最少要複製3 bytes才夠本。
因此就算前5 bits換算十進位值為0,也會複製3 bytes過來。
如果前5 bits換算十進位值為X,就會複製 X+3 bytes過來。
後11個bits表示要複製的資料離多遠。
因為111 11101110相當於十進位的-18,
因此會從已解壓的資料尾部,向前推18 bytes作為開始複製的地方。
可以參考下面的解壓資料,其中91 E5 E0就是被複製過來的資料。
0D、00都是控制碼,用於表示換行、結束。
有興趣的人可以推敲 FB 9E FD 07 CA 19 A7 19 00 9F ,
應該會得到符合下面解壓的結果。
74 00 9A 00 CE 00 0E 01 46 01 80 01 B1 01
D2 01 10 02 51 02 88 02 9F 02 BB 02 E0 02
0D 03 3B 03 60 03 9A 03 AC 03 D7 03 F9 03
25 04 5A 04 94 04 C9 04 08 05 38 05 78 05
98 05 C0 05 FD 05 2E 06 71 06 B2 06 EA 06 15
07 3A 07 6A 07 A0 07 DD 07 19 08 4E 08 85
08 AC 08 E2 08 23 09 56 09 92 09 CF 09 0A
0A 33 0A 66 0A 8D 0A BB 0A F0 0A 11 0B 36
0B 6C 0B B3 AB B0 DA DD 0D 3E FC 19 00 19 9C
ウ ォ ー レ ン 「 わ が 城
ED A4 F6 93 9A 9F A1 0D 20 91 E5 E0 86 95
へ 、 よ う こ そ 。 □ あ な た を お
1A AA E1 9C E3 95 F8 EF 9C E0 A1 00 3E 91 E5 E0
待 ち し て お り ま し た 。 「 あ な た
EA 19 C2 9C 97 19 28 C3 19 21 C8 B1 19 96 19 89
は 悪 し き ゼ テ ギ ネ ア 帝 国
E4 0D 20 18 1E FC E8 19 10 E5 F8 EF 9E FD A1 0D
と □ 戦 わ ね ば な り ま せ ん 。
20 19 A7 19 00 9F 93 E2 19 03 E3 92 EF 9D
□ 星 が そ う つ げ て い ま す
這邊要注意的一點是,參照資料的定義可能因遊戲而不同。
有的用較多bits在容許複製的byte數;
有的用較多bits在容許的位移量,
我印象中皇騎2就用了3種以上定義來壓資料。
也許有人會想問,上面紫色的是什麼。
注意看應該會發現,如果以每2個bytes為一組,
並且前後對調的話(SFC是low byte在前),會有遞增的趨勢:
(00 74) (00 9A) (00 CE) (01 0E) (01 46) (01 80) (01 B1)
....(略)
簡單來說,每一組都是"位移指標",
記錄了從某處位移的距離。
此處的第1組(00 74)表示了第1段對話的位置,
是從解壓後資料開始處算起的第 0x74 byte (十進位的116 byte),
第2段對話是在第 0x9A byte位置,....以此類推。
這樣遊戲在顯示對話時,才能很快透過位移指標找到特定對話。
中文化中有很多使用指標的機會,我們以後還會再陸續討論。
當我們要中文化遊戲劇情時,每段對話長度一定會有所變動,
所以要連位移指標都一起修改至新的正確位置才行。
之後,用最簡單的壓縮byte(FF)把改好的指標、劇情塞回去就行。
(事實上、一般應該是不會連指標都壓縮,皇騎1應該是少數例子)
‧特殊型
- 有的遊戲會自己定義一些奇怪的壓縮規則,例如聖火降魔錄。
因為特性不一,在此就不提出討論,有興趣可以自行尋找。
- 另一個不討論的原因是,其實就算是特定壓縮方法,
理論上也能透過反組譯來知道壓縮流程。
==================================================================
這週大概就先介紹到此,我再想想下週要寫什麼比較順...
--
--
※ 發信站: 批踢踢實業坊(ptt.cc)
留言