3ds火紋文字高清化指北 alpha 0.1

3ds上的三作火紋一直沒有真正高清化的中文文字。這與其字庫文件的特殊性有關(guān)。其字庫文件后綴為bfnt。bfnt文件不是如bcfnt/bffnt一般被3ds游戲廣泛使用的文件格式,就目前而言僅有3ds火紋三部曲和極少數(shù)游戲例如蒸汽世界(STEAMWORLD)使用,因而也沒有現(xiàn)成的處理工具。目前唯一能部分處理bfnt的工具FEAT僅能導(dǎo)出低分辨率的紋理圖,而對碼表無能為力。
因此,我編寫了一個簡單的處理工具,該工具能夠根據(jù)bfnt文件中的碼表繪制高清的字體。
0. 前言 bfnt文件碼表解析
bfnt中的所有數(shù)字均為低位存儲,unsigned類型。
以下為絕對地址:
0x1A 該地址儲存了bfnt文件中紋理的數(shù)量,i.e.最后生成的png數(shù)量,unsigned short類型,占2個字節(jié)。
0x22 該地址儲存了bfnt文件中字符的數(shù)量, unsigned short類型,占2個字節(jié)。
0x30 碼表的開始,之后每0x10字節(jié)都是一個字符
對于碼表內(nèi)每0x10個字符而言,以下為相對地址:
0x00 該地址開始的兩個字節(jié)儲存了字符的UNICODE編碼
0x02 該地址開始的兩個字節(jié)儲存了字符屬于哪個紋理,如為0,則屬于第0個紋理。
0x04 該地址開始的兩個字節(jié)儲存了字符判定框的水平偏移值,記為x
0x06 該地址開始的兩個字節(jié)儲存了字符判定框的垂直偏移值,記為y
*原點(0, 0)為png最左上角,(x, y)為字符判定框左上角的坐標(biāo)。
0x08 該地址開始的兩個字節(jié)儲存了字符判定框的寬度,記為length。
*無效字符:碼表中,并非每個字符都有效,全部打印出來可能造成紋理被污染。
*根據(jù)目前的研究,無效字符的共同規(guī)律是length == 0x101
*if的無效字符還具有如下規(guī)律:0x0a(相對地址)與0x08(絕對地址)存儲的值相等,但是回聲并不具有以上規(guī)律。
0x0b 該地址開始的兩個字節(jié)儲存了字符判定框的高度,記為height。
1. 開始前的準(zhǔn)備
a. 解包rom得到的.bfnt文件,.bfnt.lz文件可以用FEAT轉(zhuǎn)為.bfnt
b. 目標(biāo)的字體文件
c. 打包好的bfnt-converter alpha 0.1
需要科學(xué)上網(wǎng)。
2. 了解bfnt-converter配置 Alpha 0.1
所有設(shè)置存儲在data.txt中。
X_CENTERED : bool 強制水平居中,若無把握建議開啟,對觀感影響不大。
Y_CENTERED : bool 強制豎直居中,有些紋理(如if的標(biāo)題大字庫)使用豎直居中,其他則不使用。根據(jù)具體情況開啟,強行開啟可能導(dǎo)致字體不對齊。
STROKE_WIDTH: Optional[int] 字體粗細,設(shè)為None則代表默認,一般默認比1還要細。
FONT_NAME : str 字體文件路徑,可以是絕對或相對。
*所有str類型變量不能含有#,若含有空格需要用英文雙引號或者單引號擴起來。
FONT_SIZE :int 字體大小。以16進制表示。
IN_DIR : str 輸入文件夾,該文件夾中的所有.bfnt文件都會被處理。
OUT_DIR : str 輸出文件夾,png紋理會生成在該文件夾,若有重名則自動在文件名后面加上2。
TEST : bool 開啟后會生成輔助測試的紅框。
3. 生成字庫的一般流程 Alpha 0.1
a. 將TEST設(shè)為True,拷貝字體路徑填入FONT_NAME,將bfnt文件放入input文件夾,設(shè)定好FONT_SIZE,運行main.exe生成png。
b. 從生成的png里,找出自己需要的。為了方便,可以編寫批處理文件重命名(我寫好了if和回聲的),若太小就增大字體再嘗試,若太大就減小字體再嘗試,直到文字與紅框上部緊密貼合,記下此時的字體大小并暫時保存該文件,將其余文件刪除。每張png每個字體都有適合的字庫大小,可以多嘗試幾次。
c. 等每張png都找到合適大小時,將生成的文件拖入citra的自定義紋理文件夾,運行試一試,有些問題可以在實測中發(fā)現(xiàn),例如if的標(biāo)題字庫,必須采用垂直居中才能避免顯示錯誤。
d. 等到所有設(shè)置都準(zhǔn)確無誤后,將TEST設(shè)定為True,重新生成每張png,大功告成!
效果演示:








4. 本程序的一些缺陷 Alpha 0.1
a. 沒能實現(xiàn)圖形化界面,沒有為每個紋理分別配置設(shè)置,操作較為繁瑣
b. 其實同一個紋理的不同字符也可以有不同設(shè)置,例如同一個紋理中的中文為一個字體,字母數(shù)字則為另一個字體。本程序沒能實現(xiàn)這一點。
以上,期待某位大佬能在路過時看一眼我的代碼,改進完成。