杀出重围吧 关注:3,131贴子:38,401

准备自己上手汉化《杀出重围》初代作品,仅演示,不会发布

只看楼主收藏回复

《杀出重围》是24年前的一个游戏,上个月才刚刚下载回来,全英文,玩起来费劲,具体没细玩
网上搜罗一圈,未发现《杀出重围》汉化版,讨论的也少,看了铰链公司,玩评还挺高的,期待汉化的玩家也很多
在某视频站有别人玩的流程,还挺详细的,还后期给录屏配上翻译字幕,有兴趣的可自己去搜
先说明,汉化仅演示,不会发布,所以不要各种回复索要


IP属地:广西1楼2024-08-07 12:51回复
    汉化项目概要:
    先说说这个游戏,到现在都没人汉化,可想而知,是块难啃的硬骨头
    如果游戏的开发过程没将游戏的多语言考虑进去,或者游戏后续一直没跟进,对世界范围的游戏爱好者来说,想获得本地语言支持,实现的难度就很高
    这个游戏是用DirectX 7写的,纵观整个游戏市场,很多初代的初代都没有汉化,或者说很难在非官方提供接口支持的基础上汉化,跟DirectX 7的接口有一定的关系。
    DirectX 7的寿命是比较短暂的,后来逐渐被更改版本的DirectX代替,后续的版本接口,即便游戏的开发者没有提供,也比较容易找到解决方法。
    涉及到的接口一般是Direct3D场景的结束绘制EndScene,然而,DirectX 7及更早期的版本,EndScene是相对而言不暴露出来的,所以想通过劫持EndScene,在EndScene之前添加自己的内容,是比较困难的,这就阻挡了大部分的汉化或者编程工作者。


    IP属地:广西2楼2024-08-07 13:23
    收起回复
      也许有人直接改游戏所加载的资源里面的英文字符串,例如改成中文,结果,会变成乱码,无从下手。绝大多数汉化者就止步于此。
      乱码!!!为何是这样呢?
      由于游戏设计的是英文或者说是字节为单位处理要显示的文本,所以如果是汉字(双字节),就会变成两个字节分开进行处理。我们都知道英文及标点等合起来的范围是很窄的,国际上称这部分范围为ASCII码范围,是0~255(0x00-0xFF),而中文的范围是双字节开始的,如果是ANSI,或者UNICODE(不清楚ANSI和UNICODE的自己去网上了解)


      IP属地:广西3楼2024-08-07 13:34
      回复
        所以要想比较原生的DirectX支持汉化这种游戏:
        1. 找到DirectX的EndScene接口(对于7及以下的DirectX版本,这已经难倒99%的人)
        2.找到游戏中对ASCII文本处理的地方,加入判断,如果传过来的是双字节文字,就要另外去处理
        3.往1找到的接口线传入要进行显示的数据(这需要对DirectX要求的数据格式足够了解)
        尤其是步骤3,对于不同的DirectX,传入的数据格式又不一样,所以得对DirectX游戏开发涉及到的数据结构很清楚才行。DirectX 7要传进去的数据又因为DirectX 7的各个版本有所不同,还得进一步判断,也就是得找到开发这个游戏用的是7的哪个版本,去啃开发文档作研究。这已经超出绝大多数能将英文字符串换成中文的汉化者的能力范围。除此以外,相应的还得懂得低级编程语言,高级编程语言,HOOK,Reverse Engineering。
        DirectX 7游戏传进去的数据可能是一个对象,你可能得额外生成他,并在对象里面设置好要显示的位置之类的,而不是简单的在接口位置就能轻易传进去。


        IP属地:广西4楼2024-08-07 13:52
        回复
          汉字显示的原理:
          朴素的原理就是,在游戏的3D场景中加载一个带贴图的材质,我们称这张贴图为纹理(texture),他跟游戏里面的其他纹理在计算机看来并没有什么不一样。关键是我们用这个材质来做什么。那么,我们将这张图P上很多中文文字,根据需要进行显示就可以了……这个怎么“根据需要进行显示”,下面会说原理。。。
          由于在3D里面处理多边形,是可以交由GPU(或者说是显卡)进行处理的,所以CPU可以没有任何负担。但是,材质及贴图在3D里面是不直接显示出来的,必须借助附着在多边形——也就是,我们在3D场景里面看到一个物体,那么这个物体的构成肯定是包含了:多边形+材质(即应用了材质的多边形)
          我说了这么多,是想表达什么呢?
          我想说的是,我们游戏中看到的文字,其实是个物体,是由(多边形+材质)构成的。
          看到这里,是否有点豁然开朗了呢?
          接下来解析上面埋的坑——怎么“根据需要进行显示”:
          我们可以在3D场景里面添加多边形面片,假设我要显示一个“我”字,那我在里面生成两个直角三角形组成的正方形,然后应用一张包含有“我”字图案的材质到上面,并且恰到好处的调整好纹理坐标,使带有“我”字图案的地方贴在这个正方形上,那我就看到了这个“我”字。显示“我们”呢?那就生成两个带这个材质的正方形,分别调整好纹理坐标即可。要显示更多的文章就以此类推。


          IP属地:广西5楼2024-08-07 14:21
          收起回复
            有人会问,还得调整每个字的纹理坐标,这多麻烦,我一张贴图一个字不更好?
            其实不然,如果这样,你就得每个字都做一个图,而且每张图都得去做一个材质并把这放进去,如果你这个游戏用到10000个字(不重复的字),那你得在3D场景里面生成10000个材质,会消耗相当多的3D资源。而我如果一张图里面印有很多字,我只想要弄好这些字的位置和纹理坐标的对应关系,就可以显示我需要的字,而且只需创建1个材质和1个贴图(字多的话,可以做寥寥几个材质并分别载入对应贴图),这几乎不会影响游戏的开销,只需额外代码去实现调整纹理坐标。


            IP属地:广西6楼2024-08-07 14:32
            回复
              这一切太难了!我实现不了!!!我只想让游戏实时的显示一些中文文本,我不在乎游戏运行效率,有没有降低难度的其他汉化方法?
              有。
              回头看看我上面发4楼的,第1点,卡住了99%的人,我们去的这点;第3点也跟第1点相关,也去掉。
              难度会降低不少,对吧
              “2.找到游戏中对ASCII文本处理的地方,加入判断,如果传过来的是双字节文字,就要另外去处理”
              如果你找到了游戏文本处理的地方,你在这个地方HOOK下来,然后我们直接用GDI进行显示!
              不过得注意,有些游戏不一定加载游戏文本的时候就马上要显示出来,不过这相对而已是比较少的。
              我们可以在游戏窗口上层创建一个透明windows窗口(游戏启动时就创建一次),然后将系统字体加载到这个窗口里,我们就可以用TextOut输出文本到窗口上,或者可能更绝的,我们获取游戏窗口句柄,直接在游戏的3D窗口里面TextOut,不过,在什么地方显示,显示多久之类的,都得自己去实现。这些文本输出是通过GDI进行的,会很耗CPU资源,文字一多,游戏会感觉有明显卡的现象,如果是游戏开发者,是不愿意选择使用这种方式输出文本的,很影响玩家游戏体验。


              IP属地:广西7楼2024-08-07 14:53
              回复
                上面说了一大堆,看麻木吧老弟?
                这还只是汉化游戏的预备前奏,是能进行汉化的必要前提。否则,如果文本无法显示,后续的翻译文字根本派不上用场。
                最后说说这个游戏要汉化的对话语句,一共有9000多行,是封装在DeusExUI.u文件里面的,用你认为合适的方法将它们准确的提取出来汉化,并回写回去,要保证不可以超过原来的字串长度。
                至此,所有汉化完成!
                其他的游戏汉化原理也可以借鉴本文。
                外提一句:此游戏《杀出重围》初代里面有些场景和对话不合当下时宜,具体就不在此过多阐述。


                IP属地:广西8楼2024-08-07 15:05
                回复
                  试过了,你猜是什么问题,你可能想不到。


                  IP属地:广西来自Android客户端9楼2024-08-07 17:07
                  回复
                    说的不错,但还是对着DX实践一下


                    IP属地:浙江10楼2024-08-07 21:13
                    回复
                      不管别的,先上制作组来压场


                      IP属地:广西11楼2024-08-08 14:28
                      回复
                        问个问题,有没有办法直接外接机翻来实时翻译,实在不行我就日语化补丁+视频攻略了。
                        对了,这游戏是有日语化补丁的,不知道能不能用这个来当切入点()。


                        IP属地:浙江来自Android客户端12楼2024-08-09 00:50
                        收起回复

                          @静听风语丶
                          我试了一下改个贴图,修改成功。
                          图中的“快”和“加”是我新换的字体贴图上的,其他字体是日文原来自带的


                          IP属地:广西13楼2024-08-09 01:05
                          收起回复
                            你看看能不能解决图中的问题,翻译是翻译的,基础用的也是日语补丁,但是日语补丁改过引擎渲染


                            IP属地:广西来自Android客户端14楼2024-08-09 08:02
                            收起回复
                              我的建议制作自己位图字体配区方案步骤是:
                              1.先按我国ANSI的标准制作0x81-0xFE所有区的位图字体(或说纹理,贴图)
                              2.将0xA0,0xA1,0xA2,……0xDF区生成的位图字体全部删除.(更正上面说的日文没有0xA0-0xE区为0xA0-0xE0之间的区,即到0xE0前面为止, 0xE0区开始编码恢复正常)
                              3.因为除了0xA0-0xE0,其他区我们都做了位图字体,意思编码已满。但是0xA0-0xE0的总共64个区,缺少的汉字肯定不少,但应该也不多,将一些我们几乎在游戏里面不可能用到的字,例如:鱼字旁,酉字旁等等的字的码位处贴图改为我们在游戏里面用到,却已经被日文ANSI编码范围给剔除出0xA0-0xE0区外的字。
                              总结:这样做有个好处,就是汉化时,那些不在0xA0-0xE0区的字,我们就可以映射到这些什么鱼字旁阿,酉字旁阿之类的码位上,不过bin文件里面汉化掉的大部分明码内容能直接看得懂,只是偶尔出现一些(鱼字旁,酉字旁)的字,因为这些字映射到了0xA0-0xE0没有定义的汉字贴图上。
                              我打个比方,假设“你”字和“我”字显示不了,我用“醍”“鲧”的编码去替代,“醍”“鲧”编码对应的码位处贴的是“你”“我”的位图,这样,资源里面想写“你在跟我说话吗?”,那汉化时就该写成“醍在跟鲧说话吗?“,在游戏里面会显示正确的【你在跟我说话吗?】


                              IP属地:广西15楼2024-08-09 10:46
                              回复