SDL发送了错误的控制器索引

时间:2022-02-23 12:12:11

I'm creating a simple game and I'm using SDL2 for handling inputs from controllers. The issue is that SDL is not giving me the correct index for the controller which causes my game to crash.

我正在创建一个简单的游戏,并使用SDL2处理来自控制器的输入。问题是SDL没有为控制器提供正确的索引,从而导致我的游戏崩溃。

/receive the controller index given by SDL
int cIdx = evt.cdevice.which;

switch (evt.type)
{
    case SDL_CONTROLLERAXISMOTION:
    {
        //.........
        break;
    }
    case SDL_CONTROLLERBUTTONUP:
    {

        InputButton sender = InputButton(evt.cbutton.button);

        controllerStates[cIdx]->SetButtonState(sender, false);
        break;
    }
    case SDL_CONTROLLERBUTTONDOWN:
    {
        if (evt.cbutton.button != SDL_CONTROLLER_BUTTON_INVALID)
        {
            InputButton sender = InputButton(evt.cbutton.button);

            controllerStates[cIdx]->SetButtonState(sender, true);
        }
        break;
    }
    case SDL_CONTROLLERDEVICEADDED:
    {
        if (SDL_IsGameController(cIdx))
        {
            SDL_GameController * controller = SDL_GameControllerOpen(cIdx);

            AddController(controller);
        }
        break;
    }
    case SDL_CONTROLLERDEVICEREMOVED:
    {
        RemoveController(controllers[(cIdx)]);
        break;
    }

}

}

This works just fine when the user add the controller for the first time, SDL is sending me 0 as index in the SDL_CONTROLLERDEVICEADDED event and also 0 for the other events. The problem is that if the user tries disconnect and reconnect the controller SDL send 0 as index in SDL_CONTROLLERDEVICEADDED event and 1 for the other events which causes the game to crash.

当用户第一次添加控制器时,它就可以正常工作了,SDL在sdl_controllerdeviceadd事件中将0作为索引发送给我,其他事件也是0。问题是,如果用户尝试断开连接并重新连接控制器SDL,则SDL发送0作为sdl_controllerdeviceadd事件的索引,对于导致游戏崩溃的其他事件发送1。

I can also make simple check if the index to avoid the crash but it will be useless since all controller events will be ignored.

我还可以简单地检查索引是否避免崩溃,但这将是无用的,因为所有控制器事件都将被忽略。

Any help will be appreciated.

如有任何帮助,我们将不胜感激。

Thanks

谢谢

1 个解决方案

#1


5  

According to SDL documentation, the index used on SDL_GameControllerOpen is not the index that will identify the controller in future events. So you need to use the joystick id instead.

根据SDL文档,SDL_GameControllerOpen上使用的索引不是在未来事件中标识控制器的索引。所以你需要使用操纵杆id。

    switch (evt.type)
    {
        case SDL_CONTROLLERAXISMOTION:
        {
            //...
            break;
        }
        case SDL_CONTROLLERBUTTONUP:
        {
            //Get the joystick id from the controller index 
            //....
            break;
        }
        case SDL_CONTROLLERBUTTONDOWN:
        {
            //Get the joystick id from the controller index 
            //....
            break;
        }
        case SDL_CONTROLLERDEVICEADDED:
        {
            if (SDL_IsGameController(cIdx))
            {
                SDL_GameController * controller = SDL_GameControllerOpen(cIdx);
                SDL_Joystick* j      = SDL_GameControllerGetJoystick(controller);
                SDL_JoystickID joyId = SDL_JoystickInstanceID(j);

                //Save the joystick id to used in the future events
                AddController(controller);
            }
            break;
        }
        case SDL_CONTROLLERDEVICEREMOVED:
        {
             //Get the joystick id from the controller index 

            break;
        }
   }

#1


5  

According to SDL documentation, the index used on SDL_GameControllerOpen is not the index that will identify the controller in future events. So you need to use the joystick id instead.

根据SDL文档,SDL_GameControllerOpen上使用的索引不是在未来事件中标识控制器的索引。所以你需要使用操纵杆id。

    switch (evt.type)
    {
        case SDL_CONTROLLERAXISMOTION:
        {
            //...
            break;
        }
        case SDL_CONTROLLERBUTTONUP:
        {
            //Get the joystick id from the controller index 
            //....
            break;
        }
        case SDL_CONTROLLERBUTTONDOWN:
        {
            //Get the joystick id from the controller index 
            //....
            break;
        }
        case SDL_CONTROLLERDEVICEADDED:
        {
            if (SDL_IsGameController(cIdx))
            {
                SDL_GameController * controller = SDL_GameControllerOpen(cIdx);
                SDL_Joystick* j      = SDL_GameControllerGetJoystick(controller);
                SDL_JoystickID joyId = SDL_JoystickInstanceID(j);

                //Save the joystick id to used in the future events
                AddController(controller);
            }
            break;
        }
        case SDL_CONTROLLERDEVICEREMOVED:
        {
             //Get the joystick id from the controller index 

            break;
        }
   }