在教程的最開始就談到了文字在遊戲中是如何存儲顯示出來的:遊戲文字資訊通過將文字編碼、文字點陣資訊分離並保存到遊戲檔中,顯示文字的時候程式先讀取表示句子組成文字的一序列編碼,然後根據遊戲自身獨有的字模轉換程式通過編碼計算出字元點陣的物理位元址,然後再通過一系列的顯示程式把該字元點陣顯示到螢幕上。
我們知道了基本過程後就不難猜想到,既然要修改文字我們還是可以通過修改點陣來實現。例如句子「I love China」,可以把字元點陣「I」改為「我」,點陣「l」改為「愛」;點陣「o」改為「你」...以此類推,句子就被改為了「我愛你,中國」,多餘的字元就全部清除。理論上分析了,我們先來找個遊戲進行一下實踐《光明之魂》 :
我們就來修改一下圖片上頂部出現的那句話,按照字面意思可以修改為「請選擇一名角色」。通過我們前面所掌握的修改圖片的方法很快就能找到這些文字的位置,用TLP定位到0x8DC068,這裏就是第一個字元「キ的位置,我們可以看到該字元由4個TILE構成,排列順序為「左上」「右上」「左下」「右下」
在前面就已經說過圖片之所以會出現錯位這並不是由於TLP軟體的錯誤造成的(TLP永遠都是順序顯示的),這個和遊戲顯示程式的設計有密切的聯繫,但具體為什麼需要這樣排列的這並不在我們討論之列,我們需要做的僅僅是按照原先的順序排列好修改後的字元就可以了(字元的描繪可以使用任何一款圖像處理軟體中的文字工具來製作)。
經過導出導入修改等一系列過程,這個字元被修改為了「請」字。其他的字元按照這樣的方法依次修改,修改完後用VBA模擬器預覽效果,可以看到這樣的畫面:
看來這樣子做是相當成功的!見到了這樣的成果你心情將會如何呢?
高興之餘靜下心來還是會發現一些問題,如果把「キ」改為「請」的話,遊戲中所有出現了「キ」字符的地方都變為了「請」,但「キ」並不是「請」的意思。如果全都都照這樣子修改的話,一兩句還是可能實現,要是句子多了絕大部分句子就要混亂了。所以僅靠這樣子的修改還不行,我們還得調整每個字符的排列順序甚至出現的位置。我們再來看看字符顯示的全過程,程序是先從文件中讀取了句子文字的編碼串然後再經過一系列程序才顯示出來的,換句話說編碼串就決定了字符的排列順序,要改變文字的順序就是要改變編碼串中各個編碼的順序。例如:先假設01表示「A」、02表示「B」、03表示「C」,句子「ABC」對應的編碼是010203,如果要改為「CBA」的話我們就可以把「010203」改為「030201」。明確了這個道理,我們就必須找到句子對應的編碼串在遊戲文件中的具體位置,但我們事先並不知道每個字符對應編碼,而且每個遊戲的編碼都不盡相同,所以也不可能根據經驗來判斷,缺少了這些關鍵的信息我們就無法搜索出編碼串位置。於是我們的首要任務就是先找到一些字符的編碼,然後就可以順籐摸瓜測試出其他字符的編碼。但問題是如何知道字符編碼?這是一個巨大的難題。在開始找到「キ」字符後,留意一下就可以發現一些線索:基本上所有的文字點陣都保存在「キ」字符點陣附近的一大塊區域內,而且字符和字符之間並沒有其他雜亂信息,看來設計人員是把整個遊戲出現的字符都放在了一起。那麼這些點陣字符的首地址就很有規律了——公差為128Byte,因為1個4bpp的Tile佔用的是32Byte的空間,一個字符需要4個Tile。前面也說過,編碼是用來計算字符點陣的物理地址的。至於使用的什麼具體公式我們並不用去在意他,我們可以導出一個抽像公式來理解:
點陣地址 = 字庫首地址 + 偏移地址
偏移地址 = 比例常數 * 字符編碼 + 偏移量
比例常數 = 點陣大小 * K
所以: 點陣地址 = 字庫首地址 + 點陣大小 * K * 字符編碼 + 偏移量
對於同一遊戲來說公式中的字庫首地址和偏移量都是一個常量,唯一的變量就是中間的一段,由此看來點陣地址和字符編碼是成線性對應關係。而我們恰好可以查看得到等號左邊的點陣地址。把上面的公式通過一些數學上的變形可以得到:
△點陣地址 可以寫成△字符編號 * 點陣大小,所以又可以得到:(△字符編號就是兩個字符點陣的序號位置差,單位為「1」)
△字符編號 可以輕易知道,而係數K在同一個遊戲中是一定的,並且公式裡的其他參數全都為整數。△字符編碼 一定大於或等於 △字符編號,因而K小於等於1。點陣大小就是每個字符點陣所佔用的空間,這個例子就是128。(還不至於哪個遊戲設計者喜歡自我拔高到利用二次函數來計算吧-_-b)。只要能知道K的具體數值我們就能知道 △字符編碼了,再接下來就可以通過相對搜索來得到句子的物理地址咯。
準備好一個相對搜索工具,比較好用的是漢化高人「阿一」製作的《增強差值搜索器》和一個《字模精靈組合器》,最後再理解一下上面的推導過程。這一節先到此為止。
小結:本節開始正式涉及到文本文字的修改,內容逐步變得難以理解,光看不實踐是絕對不行的。文本文字的修改要比圖片修改更加的困難,很多時候都得靠靈活的方法才能對付。大家有了一定實踐基礎以後很容易犯迷糊,誤以為每個遊戲的文字都能按照這樣的方法修改,我一直都在強調,遊戲不可能一層不變。這一節中雖然提到了幾個數學公式,如果你對數學不太瞭解,也不用去在意幾個公式怎麼得到的,只要你能知道地址和編碼成線性比例,有這個意識就可以了。我在這兒之所以要這樣提也是為了告訴大家要調動自己所掌握的其他相關知識來思考問題,一個人的知識結構應該是網狀的。這不僅包括電腦相關知識,凡是能用上得都可以用上來,萬一此路不通還可以通過其他知識換個角度來思考。細心的人也許會注意到「キ」字符修改為「請」字符後顏色數變少了,沒有了藍色。我來解釋一下:對於大字符(一般來講8*8的字符叫小字符,除此之外就算大字符)外觀看上去比較粗大,如果只用一種主色再加上一種陰影色的話會使字符看起來有明顯的鋸齒,特別是對於筆劃比較簡單的字符(GBA可沒有全屏抗鋸齒功能喲)。所以遊戲設計者會採用一些輔助色來對字符的拐角進行前景和背景的過渡。不過這對於筆劃相對比較多的中文漢字來說用不用過渡效果並不是十分明顯,如果再增加字符光滑的處理的話漢化的成本(主要是時間,時間就是金錢嘛)就太高了吧。除非你有特殊要求,否則就沒有必要這麼做了,一般都是採用一種主體色加陰影色在加背景透明色來做漢字字模了。
留言列表