风色幻想sp吧 关注:821贴子:18,356

风色幻想SP减速和窗口化研究(完全版)

只看楼主收藏回复

风色幻想SP减速和窗口化研究(完全版)
2L: 前言
3L~8L: 研究篇
9L~12L: 设置篇
13L: 结语


1楼2015-03-11 00:22回复
    我曾于四年前写过一个简单的心得。
    http://tieba.baidu.com/p/1053298809
    通过D3DWindower和Bandicam的组合方式对风色幻想SP进行窗口化之后,再使游戏的速度正常化。
    很高兴这个心得发表之后,给一些喜欢和热爱风色幻想SP的朋友们带来了帮助。
    然而这个心得仍然有诸多的不足、问题,甚至是错误之处。
    我一直计划找一个完全的解决方案,把问题解决的彻底一些。
    因此在之后相当长的一段时间里,断断续续的又进行了一些研究。
    现在,经过长时间的努力,已经取得了不错的成果,我认为已经适合发表出来,供大家参考。
    目前的研究成果,已经完全实现了以下功能:
    一、全屏下的减速
    二、对游戏进行任意尺寸的窗口化并减速
    三、通过快捷键,实时的调整游戏技能的速度(主要想用来加速“XX提升2倍”等各种慢的出奇的辅助技能)
    这些功能通过使用DxWnd窗口化工具来实现,它的主要原理是HOOK(钩子)技术。
    DxWnd是一个完全开源免费的绿色软件,只有2M大小,启动后只占用10M左右的内存。
    在这里我必须要感谢DxWnd程序的编写者意大利朋友Gho以及国外网友Aqrit等人的帮助,没有他们的帮助,这项研究是不可能取得现在的成果的。尤其感谢Gho无私热心的大力支持。为了实现以上看似简单的几项功能,我们前后经历了DxWnd数十个版本的修改。
    下面我将对研究过程的几个方面进行简要的记述,供有兴趣的同学参考。
    这可以在一定程度上帮助更好的理解减速和窗口化的设置,以及了解风色幻想SP执行过快的基本原因,等等。文中将具体的技术细节略去,但仍可能会涉及一些计算机术语。我本人也是业余人士,不足之处在所难免,欢迎行家里手不吝指正。:D
    如果你对这些研究毫无兴趣,可以直接看具体设置的部分。
    如果你在设置中遇到疑惑,仍然可以回来参考这些内容。


    2楼2015-03-11 00:23
    回复
      在几年前发表的心得里,我就曾考虑,风色幻想SP是一个使用早期的DirectX版本开发的游戏。要完整的分析它,就必须找到它所使用的具体技术。
      而在DX7之前,大量的2D游戏都是使用DirectDraw来开发的。
      DirectDraw是DirectX7及之前更早DX版本的重要组成部分,是用于绘制2D游戏图形图像的应用程序接口(API)。在游戏程序的编写中,各种基本框架的实现(画面、特效等等),都离不开这些API。DirectDraw在DirectX8之后被淘汰,被我们现在所熟知的Direct3D所取代,而Direct3D则是主要针对3D游戏开发的API。
      当时我推测风色幻想SP很可能也是使用DirectDraw来开发的。
      我最早在网上找到了Aqrit所编写的ddwrapper,这是一个DirectDraw的proxy dll, 它可以对DirectDraw游戏进行一些修改分析。我用它第一次打破了风色幻想SP在全屏模式下软硬不吃的局面,并成功的测出了全屏下游戏的帧数,在我电脑上大约是1500fps! 有了这一经验后,我使用Jari Komppa的dxwrapper这个专门用来分析DirectDraw的工具跟踪分析风色幻想SP程序,结果证实风色幻想SP正是使用DirectDraw的BltFast功能函数来更新绘制游戏画面的。这进一步验证了之前推测。
      我曾经感觉要从根本上解决风色幻想SP的问题,只能通过反编译修改游戏程序。
      后来经过这几次试验之后,我感觉可以采用HOOK技术,用类似于外挂的方式,在不对游戏主程序进行修改的情况下,从游戏外部控制这个游戏。
      在Aqrit的推荐下,我找到了DxWnd,这是一个SourceForge上的开源项目,尤其可贵的是项目正处于活跃的状态,作者频繁的更新,使交流成为了可能。
      使用DxWnd,正好可以实现我之前的设想,从外部控制风色幻想SP。但是在当时,DxWnd并不能够很好的支持风色幻想SP所需要的功能,为此我们开始艰辛的对DxWnd进行改进。
      我已不能完全记清反复修改的次数了,下面主要记述几个方面的研究结果。


      3楼2015-03-11 00:27
      回复
        二、移动减速的原理
        正如我们所了解的那样,我们平常看到的游戏画面都是由一帧帧的画面动态组成的,这也是为什么我们常讲,游戏帧数太低,就像看幻灯片一样的原因。风色幻想SP正好相反,它的帧数过高了,所以画面变成了快进,人物的移动成了瞬移。
        游戏画面的变化更新,常需要通过图形接口来实现。前面已经说到风色幻想SP使用的是DirectDraw BltFast功能函数。DirectDraw有一系列的功能函数,用来实现不同的功能,比如有的函数可以对图像进行缩放、旋转等等...BltFast是功能函数之一。
        根据研究的结果来看,BltFast每执行一次,风色幻想SP就更新一帧。
        在过快情况下,例如,风色幻想SP的速度是1000FPS即1000帧每秒,那么程序在每秒钟就执行了1000次的BltFast操作,每次BltFast耗时0.001秒,即1毫秒(1ms)。随着硬件性能越高,每次BltFast操作耗时就越短。
        风色幻想SP过快的原因,就在于游戏程序在开发时对BltFast的执行没有做相应的控制。随着硬件越来越好,BltFast执行越来越快,导致画面的暴走。
        现在我们通过DxWnd,在外部钩住这一函数的执行,当BltFast执行过快时,用Sleep函数把它挂起,这就相当于给它过快的执行速度踩了刹车。这种函数级别的控制是非常高效的,从源头上解决问题,远远好过CpuGrab之类的工具。
        为了方便理解,举例来讲(这里对理解后面的设置很重要):
        我们如果要把FPS控制到60帧每1秒。换算1秒=1000毫秒,1000毫秒/60帧=16.67毫秒, 也就是说速度在60帧每1秒时,每1帧应该用去16.67毫秒,亦即每次BltFast应该占用16.67毫秒的时间。之前说到,1000FPS时每次BltFast只占用了1毫秒的时间,这就太短了。此时我们用Sleep函数把BltFast操作挂起来,延长BltFast的时间间隔,使每次BltFast的时间从1毫秒延长到16.67毫秒。这样就能把游戏的1000FPS变成60FPS了。
        上面所举的例子,主要是为了方便理解原理,实际使用中,DxWnd只支持到整数,所以限制60FPS时,我们往往把时间间隔设置为17毫秒或者16毫秒,前者确保控制帧数在60以下,后者可能会超出1~2帧。在使用上对风色幻想SP这样的游戏来说,并没任何区别。
        实际上计算机在计算帧数时,并不总是那么准确的。现在DxWnd用的计时函数是GetTickCount,它的精确度大概在10毫秒级,而在风色幻想SP执行过快超过1000FPS时,每帧的时间是低于1毫秒的,这就会带来一些精确度上的问题。我在发现了一些误差问题之后,又请Gho重新设计了算法。目前来看精确度已经可以满足使用了。要彻底解决问题,可能还需要用到精确度更高的QueryPerformanceCounter,现在暂时还没有必要。


        5楼2015-03-11 00:31
        回复
          三、技能速度的调整原理
          大概玩风色幻想SP的同学们都有同样的感受,与人物的移动快的出奇构成鲜明对比的是,游戏中一些技能的施放实在是太慢了。
          研究中我们应该对这两者加以区别,因为它们并不由同一个功能函数所控制。
          技能速度的调整并不是什么新技术,原理上和变速齿轮之类的软件是相似的。
          游戏中每个技能动作都受到时间API的控制,具体的来讲,就是QueryPerformanceCounter,timeGetTime之类的函数。不管是DxWnd又或者是变速齿轮,实际上都是对时间API进行Hook修改。通过对时间API的修改,可以随意的调整技能的速度。
          按照以往的方法,我们如果要同时实现窗口化+移动减速+技能加速,可能需要D3DWindower、Bandicam,再加一个变速齿轮类软件,这就等于对风色幻想SP同时使用3个钩子程序,这是非常不稳定的,我也不知道这么做会不会出现问题。
          现在全部功能集成到DxWnd中,就免去了这些顾虑。


          6楼2015-03-11 00:34
          回复
            五、原“心得”帖子里一些错误的订正
            借此机会,我希望对原来所发表的“心得”里一些错误的说法进行订正。
            原来的帖子是在较短的时间里随意写成的,缺乏必要的调查考证。虽然总的来看,除了浮于表面不够深入外,没有根本性的大问题,但仍然有一些显而易见的主观错误。
            首先,Bandicam自带的FPS限速功能,其使用的也是HOOK(钩子)技术,而不是什么“直接作用在directx区域的filter”,这其实只要稍微仔细看一下Bandicam的设置选项就能发现。而我不仅没注意,反而主观地把它和多媒体滤镜搞混了,贻笑大方,在这里必须做个更正。
            其次,在游戏使用的DirectX版本问题上,我在以前的帖子里推测是DX6,这完全是一个主观猜测。现在根据一些官方的信息来看,风色幻想SP大概是在DX7的框架下开发的。
            然而把它单纯地定义为一个DX7游戏也并不十分合适。根据研究的结果来看,风色幻想SP在一些地方还在使用DX1的接口,但我们也不能因此说它是DX1的游戏,这里面有DirectX内部接口版本复杂性的原因。
            现在看来“风色幻想SP是一个使用DirectDraw技术开发的游戏”这样的说法比较合适。
            最后,对于D3DWindower窗口化,它的具体技术机制实际上我现在也不十分清楚,因为它并不开源,而它的编写者日本网友menopem在十年前就停止了这个软件的更新,具体技术细节已经不容易去分析了。我之前臆测的“用D3D 窗口化,等于使用一个DX7的环境来挂载”是没有任何依据的,这样通过猜测来下结论是十分错误的做法。


            8楼2015-03-11 00:36
            回复
              开始设置:
              启动DxWnd后,点击编辑-添加,会开启一个设置窗口。

              注:由于程序使用了钩子技术,部分安全软件可能会提示阻止,请设置为信任,以免影响程序运行。
              主要标签

              名称:随意按照你的需要填写。留空也可以,设置完成后会自动填为主程序名称。
              程序路径:选择你风色幻想SP的游戏程序路径,必填。
              引导程序:如果你玩繁体版,并使用AppLocale来转换到简体,那么这样填
              C:\Windows\AppPatch\AppLoc.exe "风色幻想SP的游戏程序路径" "/L0404"
              注意空格和双引号都不能少。除了这种情况之外,其它的版本都留空,不用填。
              外部模块:留空。
              不使程序获悉任务切换:风色幻想SP窗口化之后,当你切换任务时,比如切换到聊天软件,风色幻想SP窗口会自动最小化。如果你希望它继续以窗口形式保留在桌面,就选这个选项,建议勾选。
              禁用欢迎图标:用DxWnd运行游戏,最开始会显示1个Logo,依据个人喜好是否禁用显示,不影响使用。
              窗口化运行:重要!!!钩上它即使用窗口模式运行游戏,不勾选就是使用全屏模式运行。
              热补丁:使用猪猪乐园硬盘版的,必须勾选这个,其它版本不需要选。
              优化CPU:这个选项对风色幻想SP没有作用,不用选。它的名称有一定的误导性,因此我特别拿出来说一下。
              以下是游戏窗口化运行时的位置和尺寸设置。

              保持纵横比:保持图像显示的比例,建议选上。
              窗口位置和尺寸
              X,Y 用于自定义游戏窗口在屏幕位置的坐标值。必须同时选中右边的X,Y坐标选项,坐标才会生效。
              W设置窗口宽度,H设置窗口高度。
              桌面居中:游戏窗口位置在屏幕正中,不受X,Y坐标控制,建议选此项。
              桌面工作区域:保留桌面底部的开始菜单任务栏,其它桌面区域都用来显示游戏。
              桌面全屏:不要使用这个选项,这是软件模拟的全屏模式。风色幻想SP本身就能够在全屏下运行,并且不存在任何问题。如果需要全屏游戏,我们只需要直接取消勾选“窗口化运行”选项即可。


              10楼2015-03-11 00:44
              回复
                输入标签

                修正鼠标位置和启动热键注意选上。
                DirectX标签

                钩住DirectX版本:建议选自动。
                如果程序无法钩住(不能减速或窗口化),可以考虑手动选DirectX1-6或DirectX7。
                模拟:
                1.窗口游戏时建议选自动模式,如果画面有问题或者AERO被强制关闭,可以考虑手动选“主表面”。
                2.全屏模式游戏时建议选“无”。
                纹理过滤:窗口化时游戏画面的质量。重要!!!
                1.使用640x480窗口模式或全屏模式玩风色幻想SP,选ddraw默认。
                2.使用其它尺寸窗口模式玩风色幻想SP,建议选高质量双线性过滤。
                AERO处理
                设置AERO兼容模式:在系统开启了AERO特效并使用窗口模式运行游戏时勾选。
                优化AERO模式:在勾选“设置AERO兼容模式”的情况下,如果游戏窗口不是640x480,勾选此项,640x480则可不勾选。


                11楼2015-03-11 00:49
                回复
                  时间标签

                  FPS设置,勾选限制。用来限制游戏人物移动、文字显示等过快的速度。
                  延迟(毫秒):
                  限制到60FPS 1000/60 = 16.67 四舍五入,填17
                  限制到55FPS 1000/55 = 18.18 四舍五入,填18
                  限制到50FPS 1000/50 = 20 填 20
                  限制到45FPS 1000/45 = 22.22 四舍五入,填22
                  限制到40FPS 1000/40 = 25 填 25
                  以此类推。
                  Q:为什么要这样计算?
                  A:原理在上文的研究记述里已详细解释。
                  Q:为什么不直接设置帧数。
                  A:这要问程序作者。个人一点看法(仅供参考):
                  把这一步换算留给用户自己完成,可以使编程设计更方便。
                  具体技术细节这里略过不表,有兴趣的同学可以在回帖里交流。
                  在标题栏显示帧数:顾名思义,标题栏指窗口标题栏。
                  在界面上显示帧数:在游戏画面上显示,全屏模式下没标题栏,就只能用这个了。
                  两个可以同时勾选,不会冲突,不过一般很少这么做。
                  时间变速

                  可以用来调整游戏技能魔法施放的速度。
                  勾选时间变速-初始:这是游戏启动时使用的速度,建议选1,即1倍速(正常速度)。
                  进入游戏后,可以通过热键来实时调整。
                  默认情况下:
                  Alt+F3 时间开关,可以在游戏中随时根据需要开启和关闭时间变速功能。
                  Alt+F5 时间减速,最低-16倍。
                  Alt+F6 时间加速,最高16倍。
                  热键可以在dxwnd.ini文件的keymapping下修改:
                  timetoggle 对应时间开关
                  timeslow 对应时间减速
                  timefast 对应时间加速
                  例如:
                  0x70对应Alt+F1 0x71对应Alt+F2 依此类推 0x79对应Alt+F10 0x7A对应Alt+F11 0x7B对应Alt+F12。
                  其中Alt是固定的,第二个键允许自定义,更多的键位可以自行搜索“Virtual-Key Codes”,注意不要使用和系统或游戏有冲突的热键组合。
                  在界面上显示时间倍速:顾名思义,在游戏画面上显示当前的时间加速/减速状态,建议选上。
                  库标签

                  确认选中重映射MCI坐标,这样在窗口化游戏中,过场动画才能显示在正常位置。
                  撒花,设置完成!
                  点击确定,之后在DxWnd主窗口启动游戏。


                  12楼2015-03-11 00:53
                  收起回复
                    至此,风色幻想SP的减速研究就告一段落了。
                    希望这份研究能为需要给老游戏减速或者窗口化的朋友们带来启发和帮助。
                    如果你在DxWnd的使用中遇到问题,别忘记Bandicam以及虚拟机都仍可能是解决问题的可行办法。我相信,目前的方法已相对丰富。随着技术的发展,问题总是能解决的 :D
                    这篇文章的完成离不开各位网友的长期以来的问询,支持和鼓励。
                    欢迎一直以来关心窗口化、减速以及使用以往的方法遇到过问题的同学们参考。
                    @八云_灰 @横天飞狗 @tigerz4681 @魔剑深黯 @秋山泠酱


                    13楼2015-03-11 00:55
                    收起回复
                      鼓掌,撒花


                      IP属地:江苏15楼2015-03-12 00:04
                      收起回复
                        刚才试着修改字体玩……


                        16楼2015-03-12 00:25
                        回复
                          虽然我来的有点晚,但还是一个字不落地看完了,gsky君简直是技术宅+毅力帝啊!说实话之前gsky君提出的那个减速方案我也亲自使用过,个人认为已经比较完善了,没想到时隔4年,gsky君又研发出了超乎我想象的更加完美的窗口化与减速法。在帖子列表里看到这个帖子和4年前的那个帖子摆在一起,实在是太令人感慨了......
                          于是我忽然想到我上一次玩SP大概是两三年前了,刚好新的减速法出炉,不如趁着这个机会,大家陪我一起再重温一遍这款经典的游戏吧~!


                          IP属地:山东17楼2015-03-23 14:53
                          回复
                            另外还是有点其他的问题想提问,根据现在的减速原理,应该不仅限于风色SP,其他类似的老游戏都可以通过这种方法减速的吧......没错,我想说的就是风2。风2的情况是游戏的正常流程速度正常,唯独战斗伤害数值显示速度极快,估计也可能是BltFast执行速度的问题?当使用cpukiller之类的软件时,将CPU降速到2%,才能够勉强看到战斗伤害值,而这时候整个游戏已经卡得没法玩了。这样是不是意味着游戏对BltFast的执行做了相应的控制,偏偏没有控制数值显示这一部分?
                            对于这个领域我基本上算是一无所知,所以gsky君如果有空闲的话,可以试着稍作研究,也算进一步为风色系列的老玩家造福,在此我表示感激不尽TvT~~~~~~


                            IP属地:山东18楼2015-03-23 14:56
                            回复
                              感谢LZ,最近又下来怀旧一下~~另外问下怎么修改字体 - - 原来的字体确实太难看了


                              IP属地:广东23楼2015-04-19 13:08
                              收起回复