SFC中文化經驗談(二)—解壓篇— - 模擬器

Table of Contents


【雜言】

雖然實作上是以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應該是少數例子)



‧特殊型

- 有的遊戲會自己定義一些奇怪的壓縮規則,例如聖火降魔錄。
因為特性不一,在此就不提出討論,有興趣可以自行尋找。

- 另一個不討論的原因是,其實就算是特定壓縮方法,
理論上也能透過反組譯來知道壓縮流程。

==================================================================

這週大概就先介紹到此,我再想想下週要寫什麼比較順...

--

--

All Comments

Zora avatarZora2012-11-10
請受一拜 謝謝你的辛苦奉獻
Blanche avatarBlanche2012-11-15
謝謝分享
Ina avatarIna2012-11-15
推阿~
Michael avatarMichael2012-11-17
推一個,感覺我遲早會要再來參拜一次...
Dorothy avatarDorothy2012-11-21
不推不是人
Yuri avatarYuri2012-11-22
請受小弟一拜...
Vanessa avatarVanessa2012-11-24
有看有推~
Ursula avatarUrsula2012-11-27
推!
Lydia avatarLydia2012-12-02
認真看了之後..決定還是當伸手族 XD
Delia avatarDelia2012-12-06
因為有你這種人~我才知道世界的美好~Q"Q 謝謝你的奉獻
Erin avatarErin2012-12-10
真的很辛苦 感謝所有無償協助中文化的朋友
Tom avatarTom2012-12-13
感謝分享好文~~!
Enid avatarEnid2012-12-17
感謝經驗分享~~~
Anthony avatarAnthony2012-12-19
大推參拜啊,以前有碰過中文化的回過頭來看這個...淚
Una avatarUna2012-12-19
太強了,一定要推
Hardy avatarHardy2012-12-22
昨天推用完,今天補一下推
Isla avatarIsla2012-12-25
OB fan必推!好偉大的工程…
Delia avatarDelia2012-12-27
神~~~
Charlotte avatarCharlotte2012-12-29
專業好文推!
Skylar DavisLinda avatarSkylar DavisLinda2013-01-01
看不懂!你們好偉大
Poppy avatarPoppy2013-01-04
好強!!!!!!!真人神也