上一主题下一主题
«12»Pages: 1/2     Go
主题 : 【求助】DC Time Stalkers汉化问题(更新汉化进展)
级别: 模拟菜鸟
UID: 322019
精华: 0
发帖: 14
威望: 0 星
金钱: 86 浮游币
贡献值: 8 点
好评度: 40 点
人气: 0 点
在线时间: 13(时)
注册时间: 2022-07-10
最后登录: 2022-07-29
楼主  发表于: 2022-07-12 11:50

【求助】DC Time Stalkers汉化问题(更新汉化进展)

首先感谢YZB大佬给我的邀请码,以及提供了一份研究资料以下是这几天分析的数据游戏的主要文本在MAIN.BIN, OPTION.BIN以及SYSTEM目录下的STATICPRESS.BIN(美版为STATICPRESSUSA.BIN)FONTDATA中有17个PVR文件,内容看起来是所有用到的日文文字,SHIFT-JIS码表。
MAIN.BINNPC对话菜单,人物属性界面文字等。其中在0X18023C开始是文字形式的码表,内容与PVR图片索引匹配
OPTINO.BIN:游戏内NPC图鉴的说明文字
STATICPRESS.BIN:加密(压缩?)存放游戏内装备,物品等的说明文字,以及NPC对话等。美版STATICPRESSUSA.BIN在文件尾端有部分未加密文本,内容是装备,物品及技能等的说明
在常规的1ST_READ.BIN中没能找到文本信息,可能是我太菜了。
由于我是初学者,现在遇到的几大问题,还望大佬们帮忙回答:1. CDI能否直接替换里面的文件,还是说只能提取并修改后重新打包?2. 像本游戏这种用PVR存储文字的方式,汉化是不是同时需要修改文本内容,BIN内码表,PVR图片码表3. PVR是可以用PS配合插件的形式修改吗?4. 我尝试过直接用WINHEX修改CDI的文本内容,日文改中文后,不在码表内的会变成绿色方框。美版修改英文为中文后,内容变成空白截断。根据之前的帖子判断,似乎还是用日版汉化容易些?5. 关于STATICPRESS.BIN的解密或解压,如果是WINDOWS程序我还能尝试用OD之类的跟一下解压解密过程,但是DC配合模拟器有相关的反汇编工具吗?
目前有些迷茫和焦虑,不知道下一步先往哪里开始了。。。
更新1:在YZB大佬的指点下,有一些进展,如下图目前完成汉化:进度保存,加载,部分NPC商店菜单,个人属性菜单。怪物的名称和介绍,技能的名称和介绍。物品的名称和属性,以及装备的属性和名称因为在STATICPRESS中加密存放,目前还是束手无策

 






[ 此帖被边缘在2022-07-19 19:55重新编辑 ]
本帖最近评分记录:
  • 金钱:+66(YZB) 辛苦了,送你 1 点人气
  • 级别: 模拟菜鸟
    UID: 322019
    精华: 0
    发帖: 14
    威望: 0 星
    金钱: 86 浮游币
    贡献值: 8 点
    好评度: 40 点
    人气: 0 点
    在线时间: 13(时)
    注册时间: 2022-07-10
    最后登录: 2022-07-29
    沙发  发表于: 2022-07-12 11:55

    我用YZB大佬帖子里提到的菜鸟工具,会提示码表读取错误,第一步就卡住了。。。不会要安装XP系统才能用吧?

    我甚至还用CE去调试模拟器,结果发现STATICPRESS.BIN里的NPC对话数据是动态解密和加载的?

    副成果
    [flycast.exe+1A349E8]+c7918ac   饥饿度的地址。。。
    YZB
    无广告位,看帖子签名
    级别: 超级版主

    UID: 12451
    精华: 6
    发帖: 18666
    威望: 173 星
    金钱: 32860 浮游币
    贡献值: 9426 点
    好评度: 53549 点
    人气: 4318 点
    在线时间: 16364(时)
    注册时间: 2004-10-02
    最后登录: 2022-09-30
    板凳  发表于: 2022-07-12 20:48

    1  cdi 镜像因为文件有edc ecc校检,所以不能直接替换文件,汉化dc游戏的最好方法当然是重构镜像,不管是gdi或者cdi都是如此
    找几篇做直读的教程看一下就行了,其实很简单

    2 如果按照原游戏的编码方式可以不用修改bin内码表,只需要修改pvr字库图以及文本即可,当然如果原字库数不够,那码表当然也要修改了

    3 有ps用的pvr插件,论坛搜索一下就有了

    4 当然是日版容易汉化,美版只有26个字母,一个字节的编码就足够了,如果以美版来汉化的话,需要修改汇编程序的地方更多

    5 dc模拟器没有调试器,你可以用od或者ce配合nulldc模拟器来调试(先定位那些寄存器以及pc pr值在内存什么位置,然后用od或者ce设置读写中断来定位),当然还需要ghidra或者ida来查看主程序中中断代码的具体流程

    这个游戏比较麻烦,主要是STATICPRESS.BIN这个文件加密比较复杂点,我没具体看过,你可以先把那些不是加密的文本翻译完最好才做这个难的
    YZB
    无广告位,看帖子签名
    级别: 超级版主

    UID: 12451
    精华: 6
    发帖: 18666
    威望: 173 星
    金钱: 32860 浮游币
    贡献值: 9426 点
    好评度: 53549 点
    人气: 4318 点
    在线时间: 16364(时)
    注册时间: 2004-10-02
    最后登录: 2022-09-30
    地板  发表于: 2022-07-12 20:52

    简单看了一下字库索引,当调出菜单的时候字库是按下面的方法寻字的,当然剧情对话也许不走这里......

    字库索引表在MAIN的0x180e00处,每4个字节一个索引,其中前2个字节为字符编码,后2个字节为坐标

    其中2字节的坐标 又分为 横坐标高4bit 和纵坐标低4bit,以及一个字节的字库页数,代表字库文件名OUTF_VOA1-17

    因为字库名是从01开始的,所以一个字节的字库页数的值需要加1

    比如某个字符E8D3=勒,  可以在0x182868那里查到D3E8 2710  
    其中D3E8是高低字节翻转后的编码,27的高4bit为2,低4bit为7,0x10为字库页面,因为是16进制,转成10进制就是16,然后字库页面是从01开始不是从0开始,所以应该需要加上1,那就是16+1=17
    所以可以推算出这个字在OUTF_VOA17.pvr这个文件 的横坐标第0x2行,纵坐标第0x7列

    ps:忘记说了,还有7个特殊的编码
    8190   
    8140    
    8197   
    81a5   
    81a4   
    8194     
    8147
    估计是表示换行 空格  换页 颜色 声音之类的特殊编码
    [ 此帖被YZB在2022-07-12 20:58重新编辑 ]
    级别: 模拟小生
    UID: 89721
    精华: 0
    发帖: 68
    威望: 0 星
    金钱: 2305 浮游币
    贡献值: 4 点
    好评度: 187 点
    人气: 1 点
    在线时间: 157(时)
    注册时间: 2005-12-22
    最后登录: 2022-09-29
    草席  发表于: 2022-07-13 13:56

    不仅可以重构cdi,还可以重构gdi,

    https冒号github点com/DerekPascarella/UniversalDreamcastPatcher
    级别: 模拟菜鸟
    UID: 322019
    精华: 0
    发帖: 14
    威望: 0 星
    金钱: 86 浮游币
    贡献值: 8 点
    好评度: 40 点
    人气: 0 点
    在线时间: 13(时)
    注册时间: 2022-07-10
    最后登录: 2022-07-29
    5楼  发表于: 2022-07-19 15:28

    图片:
    抱歉到今天才回复,大佬你给的索引表和指点非常有用,省了我很多时间,果然是前辈,随便一眼就能看出来问题。
    无奈作为一个中年汉化爱好者,每天只能挤1小时左右时间在这次汉化上,部分汉化进度已发在顶楼。

    目前在MAIN.BIN, VMSLOAD, VMSSAVE已经基本汉化完成,有一些汉化错位之类的在慢慢修。还有Option中的NPC图鉴,以及就是STAICPRESS.BIN中,由于替换了PVR字库,导致NPC对话已经基本混乱了。

    不知道我能否发个测试版出来给大伙试试还有就是要麻烦大佬你帮忙看看STATICPRESS.BIN的解密了,这个有点超出我的能力了。谢谢
    [ 此帖被边缘在2022-07-19 19:54重新编辑 ]
    YZB
    无广告位,看帖子签名
    级别: 超级版主

    UID: 12451
    精华: 6
    发帖: 18666
    威望: 173 星
    金钱: 32860 浮游币
    贡献值: 9426 点
    好评度: 53549 点
    人气: 4318 点
    在线时间: 16364(时)
    注册时间: 2004-10-02
    最后登录: 2022-09-30
    6楼  发表于: 2022-07-19 22:05

    测试版当然可以发出来,这个你随意就好,不过一般人都是等着正式版才玩的,测试版想有反馈信息,除非遇到该游戏的fans差不多

    解密问题,得过段时间有空闲了才能认真看看,你可以做完其他的先,不过这个游戏才1k7个字,够用了吗?目前用到第几张字库了?
    级别: 模拟菜鸟
    UID: 322019
    精华: 0
    发帖: 14
    威望: 0 星
    金钱: 86 浮游币
    贡献值: 8 点
    好评度: 40 点
    人气: 0 点
    在线时间: 13(时)
    注册时间: 2022-07-10
    最后登录: 2022-07-29
    7楼  发表于: 2022-07-20 11:30

    昨天晚上想了一下,测试版没法发,因为改了字库以后,装备物品的说明以及人物对话完全是错乱的。我还是自己多测试测试吧

    目前用掉了1200个字,用了4-15这几个库。1-3是一些片假名以及常规字符,暂时没动它。
    至于NPC图鉴里的文字,因为对游戏体验几乎没有影响,暂时不打算去动,我先把其他部分的BUG多测试测试。

    STATICPRESS的BIN解密,就拜托大佬您了。你有空帮忙看看就好。

    目前猜测索引如下:
    0x0  4字节索引区长度        
    0x4  索引1加密            
    0x8  索引1解密后字符串索引
    后面依次类推。
    YZB
    无广告位,看帖子签名
    级别: 超级版主

    UID: 12451
    精华: 6
    发帖: 18666
    威望: 173 星
    金钱: 32860 浮游币
    贡献值: 9426 点
    好评度: 53549 点
    人气: 4318 点
    在线时间: 16364(时)
    注册时间: 2004-10-02
    最后登录: 2022-09-30
    8楼  发表于: 2022-07-20 18:56

    回 7楼(边缘) 的帖子

    第一个4字节是加密的索引区,后面开始每8个字节一组,前4字节是文本加密区,后4字节是文本指针区,后面以此类推

    字库有点悬啊,剧情还没翻译就剩200个字来了.....

    话说这17张字库图是否打出过文本来的?
    嫖了一眼,解密的文本也不是明文,还是2字节组合的1字节字库页面索引,1字节的 横纵坐标
    级别: 模拟菜鸟
    UID: 322019
    精华: 0
    发帖: 14
    威望: 0 星
    金钱: 86 浮游币
    贡献值: 8 点
    好评度: 40 点
    人气: 0 点
    在线时间: 13(时)
    注册时间: 2022-07-10
    最后登录: 2022-07-29
    9楼  发表于: 2022-07-20 21:16

    字库字数感觉是有点悬,按英文版来说,剧情有将近600K…

    字库原来的文本需要导出来吗?我是直接替换的,写了一小段代码,从文本直接生成字库。索引用了原来的索引

    如果按你之前给我的英文版的部分解析,解密区应该是包含剧情对话的,总共好像有19段密文。每段第一段看大小应该是剧情,后面应该还有物品的名字和描述之类的
    YZB
    无广告位,看帖子签名
    级别: 超级版主

    UID: 12451
    精华: 6
    发帖: 18666
    威望: 173 星
    金钱: 32860 浮游币
    贡献值: 9426 点
    好评度: 53549 点
    人气: 4318 点
    在线时间: 16364(时)
    注册时间: 2004-10-02
    最后登录: 2022-09-30
    10楼  发表于: 2022-07-20 21:29

    回 9楼(边缘) 的帖子

    这是第一个解密的文件,应该是剧情的文本,不过不是日文编码,是直接用2字节来定位字库的

    第一个字节表示字库页面(同样要+1来表示第一个文件),后面字节高4bit为纵坐标,低4bit为横坐标,好像刚好和前面解析的字库索引相反

    另外还有一些控制符
    FF 00  换行?
    FF 01  ??
    FF 02  ??
    FF 03  这个读取以后需要跳过一个字节
    FF 04  ??
    ............
    FF F0  结束

    附件这个文件不保证准确性,需要导出文本才能知道是否完全准确

    放上第一个文本的2个截图,对应附件文件的第一个文本



    附件: 00.rar (207 K) 下载次数:2
    级别: 模拟菜鸟
    UID: 322019
    精华: 0
    发帖: 14
    威望: 0 星
    金钱: 86 浮游币
    贡献值: 8 点
    好评度: 40 点
    人气: 0 点
    在线时间: 13(时)
    注册时间: 2022-07-10
    最后登录: 2022-07-29
    11楼  发表于: 2022-07-20 21:43

    原字库索引表在这里
    解压后是CSV,字段依次是SJIS编码,横坐标,纵坐标,字库文件名索引,SJIS字符
    补充一下,文件名,坐标都是从1开始
    原字库索引表.zip (12 K) 下载次数:1
    [ 此帖被边缘在2022-07-20 22:06重新编辑 ]
    级别: 模拟菜鸟
    UID: 322019
    精华: 0
    发帖: 14
    威望: 0 星
    金钱: 86 浮游币
    贡献值: 8 点
    好评度: 40 点
    人气: 0 点
    在线时间: 13(时)
    注册时间: 2022-07-10
    最后登录: 2022-07-29
    12楼  发表于: 2022-07-20 21:57

    我核对了前4句,跟图上一样
    其中0X2D开始的049103970696,正好对应的是時計塔
    级别: 模拟菜鸟
    UID: 322019
    精华: 0
    发帖: 14
    威望: 0 星
    金钱: 86 浮游币
    贡献值: 8 点
    好评度: 40 点
    人气: 0 点
    在线时间: 13(时)
    注册时间: 2022-07-10
    最后登录: 2022-07-29
    13楼  发表于: 2022-07-20 22:39

    你附件的00.bin格式,我可以编写个文本导入导出工具

    解密的部分,就得麻烦大佬你抽空帮忙写个解密加密的工具,或者你指点我一下解密算法,我来试着写写看

    再次感谢!
    YZB
    无广告位,看帖子签名
    级别: 超级版主

    UID: 12451
    精华: 6
    发帖: 18666
    威望: 173 星
    金钱: 32860 浮游币
    贡献值: 9426 点
    好评度: 53549 点
    人气: 4318 点
    在线时间: 16364(时)
    注册时间: 2004-10-02
    最后登录: 2022-09-30
    14楼  发表于: 2022-07-20 22:53

    会写程序就好办了,我再看看汇编代码,明天发算法给你
    YZB
    无广告位,看帖子签名
    级别: 超级版主

    UID: 12451
    精华: 6
    发帖: 18666
    威望: 173 星
    金钱: 32860 浮游币
    贡献值: 9426 点
    好评度: 53549 点
    人气: 4318 点
    在线时间: 16364(时)
    注册时间: 2004-10-02
    最后登录: 2022-09-30
    15楼  发表于: 2022-07-21 09:24

    首先解密第一组加密的文本,第一个0x9c指针为需要用到的解密表,这个表已从内存dump出来了,应该是通用的,下载附件就可以了

    从第一个指针区0x65240开始,读取一个4字节指针,然后该指针加上文本区首地址也就是130,所以第一段加密文本就是从130开始的

    在0x130处,从0x6d开始解密,过程如下

    0  先初始化一个int 变量r0=0xffffffff

    1  初始化一个int   变量r14=0x17D(0x17D为常量值)

    2  判断r0的值是否为ffffffff
       是的话读取文本加密区一个字节(0x6d)(这个地址每次递增+1),并且初始化r0=7
       不是的话直接到第3步

    3  判断该字节的第r0 bit位是0还是1(其实就是从最高bit到最低bit,一共8次)
       为0,则从(r14*0xc)+4的解密表里面读取一个int到r14(变量)
      
       为1,则从(r14*0xc)+8的解密表里面读取一个int到r14(变量)
      

    4  r0--,递减

    5  判断r14的值是否大于0xff,如果是,则返回到第2步

    6  r14的值小于等于0xff,把r14以字节的显示写入到解密地址

    7  判断解密完的最后2个字节是否为fff0,不是的话跳到第1步,是的话结束循环


    以上就是一段文本的解密流程,一段文本可能是一句话也可能是N句话

    因为原文里面是针对每一段文本单独加密的,所以如果需要汉化的话最好也是对每一段文本做单独处理,这样后期加密导入打包的时候也方便点,10楼那个附件是整合在一起解密的,只能做参考处理
    [ 此帖被YZB在2022-07-21 09:30重新编辑 ]
    附件: 解密表.rar (1 K) 下载次数:2
    级别: 模拟菜鸟
    UID: 322019
    精华: 0
    发帖: 14
    威望: 0 星
    金钱: 86 浮游币
    贡献值: 8 点
    好评度: 40 点
    人气: 0 点
    在线时间: 13(时)
    注册时间: 2022-07-10
    最后登录: 2022-07-29
    16楼  发表于: 2022-07-21 16:22

    第5步的判断,是在r0的8次跑完再判断,还是8次以内就判断?
    现在得不出正确的结果,不知道是我代码写错了,还是理解错了
    下面是我的代码,写得稀烂,将就着看看

                br.BaseStream.Seek(offsetCodeStart,0);
                byte[] byteWrite = new byte[1024];
                for (int i=0;i<0x39;i++)
                {
                    byte toDecode = br.ReadByte();
                    byte lastByte=new byte();
                    byte curByte =new byte();
                    r0 = 7;
                    r14 = 0x17D;
                    while (r0 != 0xffffffff)
                    {
                        if (GetBit(toDecode, (short)r0) == 0)
                        {
                            r14 = BitConverter.ToInt32(byteEncodeTable, r14 * 0xC + 4);
                        }
                        else
                        {
                            r14 = BitConverter.ToInt32(byteEncodeTable, r14 * 0xC + 8);
                        }

                        //r14 = BitConverter.ToInt32(byteTemp, 0);
                        r0--;
                        if (r14 <= 0xff)
                        {
                            lastByte = curByte;
                            curByte = Convert.ToByte(r14);
                            byteWrite[byteOut] = curByte;
                            byteOut += 1;
                            r14 = 0x17D;
                            //if (lastByte == 0xff && curByte == 0xf0) break;
                        }
                    }

                }
    YZB
    无广告位,看帖子签名
    级别: 超级版主

    UID: 12451
    精华: 6
    发帖: 18666
    威望: 173 星
    金钱: 32860 浮游币
    贡献值: 9426 点
    好评度: 53549 点
    人气: 4318 点
    在线时间: 16364(时)
    注册时间: 2004-10-02
    最后登录: 2022-09-30
    17楼  发表于: 2022-07-21 16:51

    回 16楼(边缘) 的帖子

    8次以内都需要判断,其实就是读一个字节然后依次从最高位开始判断,判断一次就去解密表里面读取表内的数值r14是否大于100,r14大于100就继续判断下一个bit位,然后用这个r14继续从里面读一个新的r14出来,以此类推,直到r14的值小于100,才是真实的数据,期间如果r0用完则重新在加密区那里再读取一个新的字节,继续从最高bit位继续判断

    while (r0 != 0xffffffff) 这个循环错了

    并不是r0递减到0的时候就结束一个字节的解密循环,而是当if (r14 <= 0xff)的时候,结束这个字节的解密,直接写入到解密的数组里面,然后重新初始化r14=0x17d,但是这个时候如果r0还没用完的话,还要继续使用加密字节剩下的bit位,直到最后解密的2个字节为ff f0

    另外最后2字节你可以直接从解密的数组里面获取也可以的
    byteWrite[byteOut-2]          byteWrite[byteOut-1]
    [ 此帖被YZB在2022-07-21 17:31重新编辑 ]
    级别: 模拟菜鸟
    UID: 322019
    精华: 0
    发帖: 14
    威望: 0 星
    金钱: 86 浮游币
    贡献值: 8 点
    好评度: 40 点
    人气: 0 点
    在线时间: 13(时)
    注册时间: 2022-07-10
    最后登录: 2022-07-29
    18楼  发表于: 2022-07-21 20:30

    我就是按这个逻辑来的,出来的结果一直就是不对
    按你昨天发的00.bin,第一段解密出来应该是
    0000000800080121009901120003FF00FF02014201150111009504060318008800920125008800080008FF03000491039706960100012000000656015301220084054805260123FF0008570111011501180099012000910003FFF0
    但是我解密出来明显不对。
    以下是我对解密算法的理解,你看看对不对

    首先读取0x130处密文,也就是6D。
    对6D从高到低按Bit判断后读密码表,每个字节都是判断8次
    如果结果大于0xFF就判断下一个Bit.
    如果结果小于等于0xFF,就把r14的值转成byte写进解密后字节数组,r14的值重新初始化为0x17D,继续判断直到满8次。

    8位都判断结束后,读取下一个字节也就是F1,继续重复8个Bit的判断

    你方便的话,帮忙把汇编代码也贴出来我看能不能看懂。。。
    级别: 模拟菜鸟
    UID: 322019
    精华: 0
    发帖: 14
    威望: 0 星
    金钱: 86 浮游币
    贡献值: 8 点
    好评度: 40 点
    人气: 0 点
    在线时间: 13(时)
    注册时间: 2022-07-10
    最后登录: 2022-07-29
    19楼  发表于: 2022-07-21 20:35

    我好像搞定了。。。

    r0 = 0xffffffff;
                r14 = 0x17D;
                for (int i=0;i<0x39;i++)
                {
                    
                    if (r0 == 0xffffffff)
                    {
                        r0 = 7;
                        toDecode = br.ReadByte();
                    }
                        ;//第一字节密文从0x130开始
                    for (r0 = 7; r0 != 0xffffffff; r0--)
                    {
                        if (GetBit(toDecode, (short)r0) == 0)
                        {
                            r14 = BitConverter.ToInt32(byteEncodeTable, r14 * 0xC + 4);
                        }
                        else
                        {
                            r14 = BitConverter.ToInt32(byteEncodeTable, r14 * 0xC + 8);
                        }

                        if (r14 <= 0xff)
                        {
                            byteWrite[byteOut] = Convert.ToByte(r14);
                            byteOut += 1;
                            r14 = 0x17D;
                                
                            if (byteOut >= 2 && byteWrite[byteOut - 2] == 0xff && byteWrite[byteOut - 1] == 0xf0) break;
                        }
                    }
    }
    我还没批量处理,先用前面的0x39个字节测试
    [ 此帖被边缘在2022-07-21 21:02重新编辑 ]
    上一主题下一主题
    «12»Pages: 1/2     Go