【问题标题】:Can Allegro update the number of joysticks at runtime?Allegro 可以在运行时更新操纵杆的数量吗?
【发布时间】:2012-07-07 17:04:45
【问题描述】:

除了不断调用remove_joystick() 然后install_joystick 之外,还有其他方法可以更新运行时插入的操纵杆数量吗?事实证明这非常慢(从 60 FPS 下降到 5 左右)。

请只回答 Allegro 4.2...

void Joystick::Update() {
    //If joystick input was lost, attempt to reacquire.
    if(GetNumJoysticks() == 0) {
        throw InputNotAvailableException("Joystick");
    }
    //If all joysticks were deleted remove input and do nothing.
    if(_numjoysticks == 0) {
        remove_joystick();
        return;
    }

    //Update state information
    if(poll_joystick() < 0) {
        throw InputNotAvailableException("Joystick");
    }
    for(int i = 0; i < _numButtons; ++i) {
        _prevButtons[i].b = _curButtons[i].b;
        _prevButtons[i].name = _curButtons[i].name;

        _curButtons[i].b = joy[_joyNumber].button[i].b;
        _curButtons[i].name = joy[_joyNumber].button[i].name;
    }
    for(int i = 0; i < _numSticks; ++i) {
        for(int j = 0; j < joy[_joyNumber].stick[i].num_axis; ++j) {
            _prevSticks[i].axis[j].name = _curSticks[i].axis[j].name;
            _prevSticks[i].axis[j].pos = _curSticks[i].axis[j].pos;
            _prevSticks[i].axis[j].d1 = _curSticks[i].axis[j].d1;
            _prevSticks[i].axis[j].d2 = _curSticks[i].axis[j].d2;

            _curSticks[i].axis[j].name = joy[_joyNumber].stick[i].axis[j].name;
            _curSticks[i].axis[j].pos = joy[_joyNumber].stick[i].axis[j].pos;
            _curSticks[i].axis[j].d1 = joy[_joyNumber].stick[i].axis[j].d1;
            _curSticks[i].axis[j].d2 = joy[_joyNumber].stick[i].axis[j].d2;
        }
        _prevSticks[i].flags = _curSticks[i].flags;
        _prevSticks[i].name = _curSticks[i].name;

        _curSticks[i].flags = joy[_joyNumber].stick[i].flags;
        _curSticks[i].name = joy[_joyNumber].stick[i].name;
    }
}
int Joystick::GetNumJoysticks() {
    remove_joystick();
    if(install_joystick(JOY_TYPE_DIRECTX)) {
        return 0;
    }
    return (num_joysticks);
}

【问题讨论】:

  • 为什么要每帧都这样做?只在需要时才这样做不是更有意义吗?
  • @NicolBolas 定义“根据需要”。在我看来,需要插入的操纵杆是“每帧都需要”?
  • 当他们插上电源时你会怎么做?通常,PC 游戏让用户有机会通过配置 UI 随意设置他们的控件。这通常是处理这类事情的时候。或者您可以停止使用过时的 Allegro 版本并升级到 Allegro 5。
  • @NicolBolas 我希望我能更新。我已经在这个项目上投入了大约三年的时间,并切换到一个新的、不到一年的版本,更不用说完全大修的 API,尝试转换包含在 60 多个类中的 15,000 多行代码需要很多时间更多的时间是不值得的。特别是如果 API 再次更改。 4.2 暂时有效,尽管有一些解决方法。
  • @NicolBolas 我想我可以走 Microprose 路线:当用户运行(如果存在)安装程序/方法时,询问他们是否需要操纵杆支持并存储答案。未来的运行将使用这个答案,直到再次运行安装程序/方法时它发生变化。

标签: c++ allegro joystick


【解决方案1】:

4.x 系列没有。 5.x 系列可以。

您必须使用自定义平台特定代码(假设存在此类事件)侦听本机操作系统事件,并且仅在检测到更改时调用 Allegro deinit/init 函数,或者要求用户手动启动操纵杆刷新。

在 Linux 下,您可以inotify_add_watch() /dev/input 来检查更改。查看 4.4 Allegro 代码,您似乎想要调用 Win32 函数 joyGetNumDevs()joyGetPos()。比如:

int WIN_MAX_JOYSTICKS = joyGetNumDevs(); // this should never change
JOYINFO ji;
int pluggedin_count = 0;
for (int i = 0; i < WIN_MAX_JOYSTICKS; ++i)
  if (joyGetPos(i, &ji) == JOYERR_NOERROR) ++pluggedin_count;

if (pluggedin_count != last_pluggedin_count) /* reinit Allegro */

您必须每 N 秒执行一次。

这些joy* 函数是Windows 函数,因此请阅读MSDN 文档以了解如何使用它们。

【讨论】:

  • 哦,噗……嗯,有在运行时实现可选操纵杆的想法。用户只需要在开始游戏之前处理并插入它。
  • 我添加了一些示例来说明如何实施实时扫描,但我建议将这些限制在配置或标题屏幕上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多