forked from Yggdrasill-Moe/Niflheim
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2f6c7cc
commit 467f098
Showing
17 changed files
with
997 additions
and
3 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Niflheim-BALDR HEART | ||
用于处理NeXAS引擎,针对BALDR HEART | ||
## [Base on] | ||
giga_text_dump.py:https://github.com/Inori/FuckGalEngine/blob/master/GIGA/giga_text_out.py | ||
|
||
dat_dump.py:https://github.com/regomne/chinesize/blob/master/NeXAs/exTxtFromDat.py | ||
|
||
pac_unpack、pac_pack:crass源码 | ||
## [Note] | ||
#### [字库] | ||
将fnt_make_bold_ft.exe、fnt_make_ft.exe、fnt_make.ini、libpng16.dll、tbl_chs.txt和三个makefnt的bat放在同一个文件夹,新建fnt、UpdateCHS文件夹。 | ||
|
||
将fnt_build.exe、fnt_dec.exe、libpng16.dll、zlib1.dll和全部原始fnt文件放入fnt文件夹里,双击makefnt_all.bat即可。 | ||
|
||
如果不想封包,可以去掉makefnt_all.bat的最后一行“pac_pack.exe UpdateCHS”,不然自行添加pac_pack.exe相关exe和dll。 | ||
|
||
字体用的思源黑体和宋体(tutorial用的宋体),也可以自行更改fnt_make.ini用自己喜欢的字体,我个人觉得思源的字体效果不完美......。 | ||
|
||
tutorial如果想还原原字体效果,需要在fnt_make_bold_ft.exe生成png后再用ps录制一层描边再批处理,效果为RGB(255,255,255),透明度50%,1像素。 | ||
|
||
字体对应.txt为找到的fnt在游戏中使用到的地方,并非所有fnt都会使用,NeXAS_fnt_Shift-JIS.txt为所有fnt的编码对应,tbl_chs.txt用于生成中文字库使用的码表,可自行更改,本项目中使用的tbl.txt和tbl_chs.txt都为针对BALDR HEART制作。 | ||
|
||
最好都用freetype2版的程序(有ft标志),非freetype2的程序后续并没有开发,因为用Windows API生成的效果巨 屎 无 比,所有抛弃了,仅供参考。 | ||
#### [游戏主程序] | ||
用的Themida壳,脱壳就顺带也破解了.....,根据dump的方法不同,可能需要自行修复一下IAT表,一般会少了D3DXAssembleShader、D3DXQuaternionMultiply,exe中有非常多文本,想完美汉化不得不脱壳。 | ||
#### [文本] | ||
bin中除了导出程序导出的外还会有点文本,一般就一两句话会用到,测试的时候就知道了。 | ||
|
||
dat为系统文本,mek为机体文本,grp有一些文本,看会不会用到,除了bin和dat外,mek和grp都需要具体文件具体分析。 | ||
|
||
但是都没有文本长度标识,所有其实可以暴力导出然后按原地址塞回去,再进行超长或缩短后的处理。 | ||
|
||
tbl.txt为BALDR HEART的汉化码表,更改文本会影响到游戏读取图片文件的文件名,所以使用在GetGlyphOutline中进行编码转换的方式实现汉化,即可保证汉化和原版存档共存,又能保持更改文本对文件读取影响不大,也不会出现乱码。 | ||
## [New] | ||
ver 1.0 | ||
|
||
可解决BALDR HEART汉化 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# -*- coding:utf-8 -*- | ||
|
||
import struct | ||
import os | ||
import sys | ||
import io | ||
|
||
def byte2int(byte): | ||
long_tuple=struct.unpack('L',byte) | ||
long = long_tuple[0] | ||
return long | ||
|
||
def int2byte(num): | ||
return struct.pack('L',num) | ||
|
||
def FormatString(string, count): | ||
res = "○%08d○\n%s\n●%08d●\n%s\n\n"%(count, string, count, string) | ||
return res | ||
|
||
def dumpstr(src): | ||
bstr = b'' | ||
c = src.read(1) | ||
while c != b'\x00': | ||
bstr += c | ||
c = src.read(1) | ||
return bstr.decode('932') | ||
|
||
for f in os.listdir('Config'): | ||
if not f.endswith('._dat'): | ||
continue | ||
fs = open('Config/'+f,'rb') | ||
fs.seek(0, os.SEEK_END) | ||
filesize=fs.tell() | ||
fs.seek(0, os.SEEK_SET) | ||
count = byte2int(fs.read(4)) | ||
types = [byte2int(fs.read(4)) for i in range(count)] | ||
str_list = [] | ||
while fs.tell() < filesize: | ||
for t in types: | ||
if t == 2: | ||
fs.read(4) | ||
elif t == 1: | ||
l=dumpstr(fs) | ||
if len(l) != 0: | ||
str_list.append(l) | ||
if len(str_list)!=0: | ||
dstname = 'Config/' + f[:-5] + '.txt' | ||
dst = open(dstname, 'w', encoding='utf16') | ||
i = 0 | ||
for string in str_list: | ||
dst.write(FormatString(string, i)) | ||
i += 1 | ||
dst.close() | ||
fs.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# -*- coding:utf-8 -*- | ||
|
||
import struct | ||
import os | ||
import sys | ||
import io | ||
|
||
def walk(adr): | ||
mylist=[] | ||
for root,dirs,files in os.walk(adr): | ||
for name in files: | ||
if name[-5:] != '._dat': | ||
continue | ||
adrlist=os.path.join(root, name) | ||
mylist.append(adrlist) | ||
return mylist | ||
|
||
def byte2int(byte): | ||
long_tuple=struct.unpack('L',byte) | ||
long = long_tuple[0] | ||
return long | ||
|
||
def dumpstr(src): | ||
bstr = b'' | ||
c = src.read(1) | ||
while c != b'\x00': | ||
bstr += c | ||
c = src.read(1) | ||
return bstr.decode('932') | ||
|
||
def int2byte(num): | ||
return struct.pack('L',num) | ||
|
||
def main(): | ||
f_lst = walk('Config') | ||
tbl = open('tbl.txt','r',encoding='utf16') | ||
dicts = {} | ||
for rows in tbl: | ||
row = rows.rstrip('\r\n').split('=') | ||
if len(row) == 3: | ||
row[1] = '=' | ||
dicts[row[1]]=int(row[0],16) | ||
for fn in f_lst: | ||
fs = open(fn, 'rb') | ||
dstname = fn[:-5] + '.txt' | ||
txt = open(dstname, 'r', encoding='utf16') | ||
filesize=os.path.getsize(fn) | ||
dst = open(fn[:-5]+'.dat','wb') | ||
count = byte2int(fs.read(4)) | ||
types=[byte2int(fs.read(4)) for i in range(count)] | ||
dst.write(int2byte(count)) | ||
for t in types: | ||
dst.write(int2byte(t)) | ||
str_list = [] | ||
for rows in txt: | ||
if rows[0] != '●': | ||
continue | ||
row = txt.readline().rstrip('\r\n').replace('\\n','\n') | ||
str_list.append(row) | ||
i = 0 | ||
while fs.tell() < filesize: | ||
for t in types: | ||
if t == 2: | ||
dst.write(fs.read(4)) | ||
elif t == 1: | ||
l = dumpstr(fs) | ||
if len(l) != 0: | ||
try: | ||
for ch in str_list[i]: | ||
if ch == '\n': | ||
dst.write(b'\x0A') | ||
elif dicts[ch] > 0xFF: | ||
dst.write(struct.pack('>H',dicts[ch])) | ||
else: | ||
dst.write(struct.pack('B',dicts[ch])) | ||
except Exception as inst: | ||
print(str_list[i]) | ||
dst.write(struct.pack('B',0)) | ||
i += 1 | ||
else: | ||
dst.write(struct.pack('B',0)) | ||
fs.close() | ||
dst.close() | ||
txt.close() | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# -*- coding:utf-8 -*- | ||
import struct,os,fnmatch,re | ||
|
||
def walk(adr): | ||
mylist=[] | ||
for root,dirs,files in os.walk(adr): | ||
for name in files: | ||
if name[-5:] != '._bin': | ||
continue | ||
adrlist=os.path.join(root, name) | ||
mylist.append(adrlist) | ||
return mylist | ||
|
||
def byte2int(byte): | ||
long_tuple=struct.unpack('L',byte) | ||
long = long_tuple[0] | ||
return long | ||
|
||
def int2byte(num): | ||
return struct.pack('L',num) | ||
|
||
def FormatString(string, count): | ||
''' | ||
res = "★%08d★\n%s\n"%(count, string+'\n') | ||
res = "☆%08d☆\n%s★%08d★\n%s\n"%(count, string+'\n', count, string+'\n') | ||
''' | ||
|
||
#res = "○%08d○%s○\n%s●%08d●%s●\n%s\n"%(count, name, string, count, name, string) | ||
|
||
|
||
res = "○%08d○\n%s\n●%08d●\n%s\n\n"%(count, string, count, string) | ||
|
||
return res | ||
|
||
def dumpstr(src): | ||
bstr = b'' | ||
c = src.read(1) | ||
while c != b'\x00': | ||
bstr += c | ||
c = src.read(1) | ||
return bstr.decode('932') | ||
|
||
def dumptxt(src, offset, count): | ||
src.seek(offset) | ||
str_list = [] | ||
for i in range(0, count): | ||
str_list.append(dumpstr(src)) | ||
return str_list | ||
|
||
def main(): | ||
f_lst = walk('Script') | ||
for fn in f_lst: | ||
src = open(fn, 'rb') | ||
dstname = fn[:-5] + '.txt' | ||
dst = open(dstname, 'w', encoding='utf16') | ||
|
||
src.seek(4) | ||
entry_count = byte2int(src.read(4)) | ||
str_offset = (entry_count << 1) * 4 + 8 | ||
src.seek(str_offset) | ||
str_count = byte2int(src.read(4)) | ||
|
||
str_list = dumptxt(src, src.tell()+1, str_count-1) #最后一句不是文本 | ||
i = 0 | ||
for string in str_list: | ||
dst.write(FormatString(string, i)) | ||
i += 1 | ||
|
||
src.close() | ||
dst.close() | ||
#print(fn[7:]+'--> done!') | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# -*- coding:utf-8 -*- | ||
|
||
import struct | ||
import os | ||
import fnmatch | ||
|
||
def walk(adr): | ||
mylist=[] | ||
for root,dirs,files in os.walk(adr): | ||
for name in files: | ||
if name[-5:] != '._bin': | ||
continue | ||
adrlist=os.path.join(root, name) | ||
mylist.append(adrlist) | ||
return mylist | ||
|
||
def byte2int(byte): | ||
long_tuple=struct.unpack('L',byte) | ||
long = long_tuple[0] | ||
return long | ||
|
||
def dumpstr(src): | ||
bstr = b'' | ||
c = src.read(1) | ||
while c != b'\x00': | ||
bstr += c | ||
c = src.read(1) | ||
return bstr.decode('932') | ||
|
||
def dumptxt(src, offset, count): | ||
src.seek(offset) | ||
str_list = [] | ||
for i in range(0, count): | ||
str_list.append(dumpstr(src)) | ||
return str_list | ||
|
||
def main(): | ||
f_lst = walk('Update2') | ||
tbl = open('tbl.txt','r',encoding='utf16') | ||
dicts = {} | ||
for rows in tbl: | ||
row = rows.rstrip('\r\n').split('=') | ||
if len(row) == 3: | ||
row[1] = '=' | ||
dicts[row[1]]=int(row[0],16) | ||
for fn in f_lst: | ||
src = open(fn, 'rb') | ||
dstname = fn[:-5] + '.txt' | ||
txt = open(dstname, 'r', encoding='utf16') | ||
filesize=os.path.getsize(fn) | ||
src.seek(4) | ||
entry_count = byte2int(src.read(4)) | ||
str_offset = (entry_count << 1) * 4 + 8 | ||
src.seek(0) | ||
data=src.read(str_offset+5) | ||
dst = open(fn[:-5]+'.bin','wb') | ||
dst.write(data) | ||
for rows in txt: | ||
if rows[0] != '●': | ||
continue | ||
row = txt.readline().rstrip('\r\n') | ||
for ch in row: | ||
try: | ||
if dicts[ch] > 0xFF: | ||
dst.write(struct.pack('>H',dicts[ch])) | ||
else: | ||
dst.write(struct.pack('B',dicts[ch])) | ||
except Exception as inst: | ||
print(fn) | ||
print(row) | ||
dst.write(struct.pack('B',0)) | ||
src.seek(str_offset) | ||
str_count = byte2int(src.read(4)) | ||
dumptxt(src, src.tell()+1, str_count-1) | ||
data=src.read(filesize-src.tell()) | ||
dst.write(data) | ||
src.close() | ||
dst.close() | ||
txt.close() | ||
|
||
main() |
Oops, something went wrong.