2012-01-12 70 views
1

我正在通过Adobe AIR(3.1)将基于Flash Player的游戏移植到桌面(OSX和Windows)。移植到AIR本身已经非常顺利。我已经处理的一个问题是游戏将通过Steam网络进行分发。为了与Steam客户端进行交互,我必须编写一个本地扩展来将Steam SDK API公开到AS3。本机扩展支持已针对两种平台实施,并且我已根据需要启动应用程序并与Steam进行通信。Adob​​e AIR 3.1蒸汽叠加层渲染/输入问题(Windows)

我遇到麻烦的区域是处理Steam的叠加层,当它被激活时会使游戏超过游戏。从本质上讲,当游戏启动时,Steam客户端会暂停该进程,以便将Overlay库挂接到D3D或OpenGL。最初,由于AIR应用程序描述符的默认渲染模式设置为“auto”,所以Overlay未能完全显示。但是,一旦我将渲染模式切换到“gpu”,Overlay将按需要显示。

在OSX的东西方面,一切都按预期工作。我可以切换进入和退出覆盖图就好了。在光谱的窗口一端,当我激活叠加层时,我遇到了一些问题。具体来说,当Overlay被启用(它渲染高于游戏),并且我移动鼠标或生成键盘输入时,Overlay和游戏都会“冻结”(渲染停止)2-3秒。另外,我注意到当我打开运行游戏的任务管理器时,CPU使用率大约为75-80%。当我第一次激活覆盖(这是所需的)时,CPU使用率保持不变。但是,当我移动鼠标光标或按下键盘上的某个键时,CPU使用率将下降到大约1%。这个问题发生在我们测试过的5台Windows机器(2个XP,3个Win 7)上。当然,我首先与Valve联系了解这个问题,因为这只有在Overlay被启用时才会发生。我已经上传了OSX和Windows版本,供他们的开发人员进行调试;然而,我的联系人建议我找出更多关于AIR渲染/输入。

这是一个带蒸汽开发,详细覆盖的工作原理后的一个片段:

“的Windows上的覆盖要求如下:

  1. 游戏必须使用D3D7, D3D8,D3D9,D3D10,D3D11或OpenGL
  2. 游戏必须快速定期调用D3D Present()或OpenGL SwapBuffers()(这些调用被覆盖层挂钩并给它做工作的机会),例如2D只有在鼠标移动发生时才调用这些函数的游戏或屏幕上的图形实际上会改变,而不是每一帧都不能正常运行。
  3. 游戏应该使用标准的Win32输入消息,原始的Win32输入消息或DirectInput作为输入,然后叠加层将在活动时检测热键并隐藏/阻止来自游戏的输入事件。

听起来你的游戏可能会违反#2,并且有时会在覆盖层处于活动状态时停止调用Present/SwapBuffers。如果您调用这些函数来响应用户输入,而这些用户输入现在因叠加被激活而被阻止,则可能会发生这种情况。你应该保证你一直抽帧,并以一定的间隔交换即使输入事件没有发生。”

多一点打回原形后,阀门开发者异型我的应用程序,以确定是否有任何具体问题发生的历史不幸的是,他们无法找到Overlay本身发生的任何事情,这很大程度上意味着Windows上的AIR不喜欢Overlay阻止Win32输入消息。这里是阀门开发的回应:

“我得到了你的仓库,并做了一些测试没有什么不寻常发生在覆盖与同时出现问题xpref剖析你的应用程序,并采取了一些小型转储检查调用堆栈它看起来像。应用程序完全阻塞并在被阻塞的时候使用零CPU,当它发生时,它只会以大约1秒的间隔调用Present()直到它恢复(也许AIR代码中某处存在1秒的超时)。以获得更多的细节,因为我没有AIR运行时库的任何符号

但它看起来像某种方式与输入状态有关,AIR对win32输入消息停止不满意如果我改变覆盖一旦激活就不会阻止任何输入(这显然在可用性方面存在一些相当大的问题,但仅用于测试目的),则不会发生该问题。 AIR代码有可能存在一些奇怪的逻辑,如果它看到某个特定的WM_WHATVER消息,它会期待另一个消息,然后以某种方式阻止它。

希望你能在你身边或与Adobe工作了,为什么应用程序在这些情况下,行为恶劣,并开始阻止和定期不呈现。”

我已经张贴在Adobe论坛,但在那里没有这样的运气,主要是希望有人或者以前处理过这个问题,或者有一个关于如何解决问题的想法,任何建议,意见或想法都将不胜感激!

回答

2

事实证明,AIR核心框架存在深层错误,这是此问题的根源.Adobe已确认错误, nd他们正在为Cyril(AIR 3.3)发布一个修复程序。错误(#3089755)的状态可以在Adobe AIR错误列表中查看。

在短期内,我被迫检测到SteamOverlay正在使用的Windows消息,并传递虚假消息以阻止AIR锁定。我通过使用Windows API SetWindowsHookEx以及WH_DEBUG和WH_GETMESSAGE钩子来完成此任务。这绝对不是一种理想的方法,但在短期内需要Adobe才能发布修复程序。