Gamepad / Controller Support - OSX / PC / Mobile

Is there any guides how to use gainput?

Look at the Usage section on the github mainpage and the samples.

Just found it.
It seem I have to use cmake.
Thank you.

So, will we get controller support for osx/pc in the v3.10?

We are over a year on, Iā€™m looking to go to steam next year with a new project. Can anyone advise me of the current position regarding joystick/pad support?

1 Like

IĀ“m working with OIS library to support gamepads. I already test on most of gamepads (xbox, ps3/4, generics) and worked.

For Xbox One (UWP apps), you probably need to wrapping c# gamepad class to c++ and then migrate to your solution.

for future ref this is a very good short tutorial on gamepad support!

thanks @SonarSystems

2 Likes

Has anyone on this thread added controller support using GLFW, SDL, Gainput, etc for an x64 build? We are working on an UWP game, targeted for both Win 10 and Xbox One and have not been able to get a Visual Studio 2015 build running yet which targets x64 using GLFW or Gainput. Will likely try SDL next. Microsoft no longer supports Win32 builds on Xbox per the following link:

I created another forum thread to track x64 builds with GLFW (specifically), since that is already bundled with cocos2d-x but is not available in x64 builds.

Thanks!
Mark

It seems like thereā€™s a whole bunch of support for controllers built in on desktop, only the button mappings arenā€™t created because ControllerImpl::ControllerImpl() in base/CCController-linux-win32.cpp never seems to get called.

I just newed a temp variable in there, and the controller listeners are working. Not sure if this is bug or what, but thought Iā€™d throw my two cents in this old thread

void Controller::startDiscoveryController()
{
    //edit to create the button mapping, dont want to lose it either because its dtor destroys all controllers
    ControllerImpl* temp = new ControllerImpl{}; //leaks this variable

Iā€™m using cocos2d-x 3.16

this was the mapping I had to add to the ctor for ControllerImpl(), to support my wired 360 controller:

			// Prepare variables:
			deviceName = "Xbox 360 Controller";
			buttonInputMap.clear();
			axisInputMap.clear();


			// Map the controller inputs to Controller::Key codes
			buttonInputMap[0] = Controller::Key::BUTTON_A;
			buttonInputMap[2] = Controller::Key::BUTTON_X;
			buttonInputMap[6] = Controller::Key::BUTTON_SELECT;
			buttonInputMap[7] = Controller::Key::BUTTON_START;
			buttonInputMap[13] = Controller::Key::BUTTON_DPAD_UP;
			buttonInputMap[14] = Controller::Key::BUTTON_DPAD_DOWN;
			buttonInputMap[11] = Controller::Key::BUTTON_DPAD_LEFT;
			buttonInputMap[12] = Controller::Key::BUTTON_DPAD_RIGHT;
			buttonInputMap[1] = Controller::Key::BUTTON_B;
			buttonInputMap[3] = Controller::Key::BUTTON_Y;
			buttonInputMap[4] = Controller::Key::BUTTON_LEFT_SHOULDER;
			buttonInputMap[5] = Controller::Key::BUTTON_RIGHT_SHOULDER;
			buttonInputMap[9] = Controller::Key::BUTTON_LEFT_THUMBSTICK;
			buttonInputMap[10] = Controller::Key::BUTTON_RIGHT_THUMBSTICK;
			axisInputMap[4] = Controller::Key::AXIS_LEFT_TRIGGER;
			axisInputMap[5] = Controller::Key::AXIS_RIGHT_TRIGGER;
			axisInputMap[0] = Controller::Key::JOYSTICK_LEFT_X;
			axisInputMap[1] = Controller::Key::JOYSTICK_LEFT_Y;
			axisInputMap[2] = Controller::Key::JOYSTICK_RIGHT_Y;
			axisInputMap[3] = Controller::Key::JOYSTICK_RIGHT_X;


			// Add the controller profile to the map
			s_controllerProfiles.insert(std::make_pair(deviceName, std::make_pair(buttonInputMap, axisInputMap)));

hope this helps someone. Donā€™t know if thereā€™s going to be a problem with the support down the line but it seems to work for the first little bit Iā€™ve been using it.

Hereā€™s some test code I used to bind the controller in my gameā€™s testing, just to get someone off the ground.

void bind_controller_support(cocos2d::Scene* scene)
{
    auto controller_listener = cocos2d::EventListenerController::create();
    controller_listener->onKeyDown = [](cocos2d::Controller* controller, int key_code, cocos2d::Event* evt) {
        CCLOG("gamepad key pressed %i", key_code);
    };
    controller_listener->onAxisEvent = [](cocos2d::Controller* controller, int key_code, cocos2d::Event* evt) {
        if (controller->getDeviceId() != 0) { return; }

        cocos2d::EventController* casted = dynamic_cast<cocos2d::EventController*>(evt);
        cocos2d::EventController::ControllerEventType type = casted->getControllerEventType();
        if (key_code == cocos2d::Controller::Key::JOYSTICK_LEFT_X || key_code == cocos2d::Controller::Key::JOYSTICK_LEFT_Y) {
            CCLOG("gamepad LEFT axis event %i, and value %f controller id %i", key_code, controller->getKeyStatus(key_code).value, controller->getDeviceId());
        } else if (key_code == cocos2d::Controller::Key::JOYSTICK_RIGHT_X || key_code == cocos2d::Controller::Key::JOYSTICK_RIGHT_Y) {
            CCLOG("gamepad RIGHT axis event %i, and value %f controller id %i", key_code, controller->getKeyStatus(key_code).value, controller->getDeviceId());
        } else {
            CCLOG("gamepad unknown axis event %i, and value %f controller id %i", key_code, controller->getKeyStatus(key_code).value, controller->getDeviceId());
        }

    };
    controller_listener->onConnected = [](cocos2d::Controller* controller, cocos2d::Event* evt) {
    };

    cocos2d::Controller::startDiscoveryController();
    //cocos2d::Controller::stopDiscoveryController();

    std::vector<cocos2d::Controller*> controllers = cocos2d::Controller::getAllController();
    for (const auto& controller : controllers) {
        CCLOG("%s", controller->getDeviceName().c_str());
    }
    scene->getEventDispatcher()->addEventListenerWithSceneGraphPriority(controller_listener, scene);
}
2 Likes