1

I'm trying to get gamepad functionality to work in my C++ QT arcade game(yes PacMan) clone app. I'm writing and testing it in Windows for now (I don't have access to a Linux box but eventually I'll test there too hopefully). I have a protected method in my GamePanel class called "initInput" Here is the code for that method:

void GamePanel::initInput()
{
    QList<int> lstDevices = QGamepadManager::instance()->connectedGamepads();

    if(!lstDevices.isEmpty())
        setGamepad(new QGamepad(lstDevices[0], this));
}

void GamePanel::setGamepad(const QGamepad *ptrGamepad)
{
    if(mPtrGamepad != nullptr)
        delete mPtrGamepad;

    mPtrGamepad = const_cast<QGamepad *>(ptrGamepad);

    connect(mPtrGamepad, &QGamepad::buttonAChanged, this, &GamePanel::pacManAPressed);
    connect(mPtrGamepad, &QGamepad::buttonBChanged, this, &GamePanel::pacManBPressed);
    connect(mPtrGamepad, &QGamepad::buttonCenterChanged, this, &GamePanel::pacManCenterPressed);
    connect(mPtrGamepad, &QGamepad::buttonGuideChanged, this, &GamePanel::pacManGuidePressed);
    connect(mPtrGamepad, &QGamepad::buttonDownChanged, this, &GamePanel::pacManDownPressed);
    connect(mPtrGamepad, &QGamepad::buttonLeftChanged, this, &GamePanel::pacManLeftPressed);
    connect(mPtrGamepad, &QGamepad::buttonRightChanged, this, &GamePanel::pacManRightPressed);
    connect(mPtrGamepad, &QGamepad::buttonUpChanged, this, &GamePanel::pacManUpPressed);
    connect(mPtrGamepad, &QGamepad::buttonL1Changed, this, &GamePanel::pacManL1Pressed);
    connect(mPtrGamepad, &QGamepad::buttonL2Changed, this, &GamePanel::pacManL2Tilted);
    connect(mPtrGamepad, &QGamepad::buttonL3Changed, this, &GamePanel::pacManL3Pressed);
    connect(mPtrGamepad, &QGamepad::buttonR1Changed, this, &GamePanel::pacManR1Pressed);
    connect(mPtrGamepad, &QGamepad::buttonR2Changed, this, &GamePanel::pacManR2Tilted);
    connect(mPtrGamepad, &QGamepad::buttonR3Changed, this, &GamePanel::pacManR3Pressed);
    connect(mPtrGamepad, &QGamepad::axisLeftXChanged, this, &GamePanel::pacManAxisLeftXTilted);
    connect(mPtrGamepad, &QGamepad::axisLeftYChanged, this, &GamePanel::pacManAxisLeftYTilted);
    connect(mPtrGamepad, &QGamepad::axisRightXChanged, this, &GamePanel::pacManAxisRightXTilted);
    connect(mPtrGamepad, &QGamepad::axisRightYChanged, this, &GamePanel::pacManAxisRightYTilted);
}

lstDevices ends up being empty. I actually had code in to output using qDebug() and it will always print that there are no devices. Yet Windows in the Settngs/Control Panel / Devices and Printers shows my "Gamepad F310" and I just tried to play a game I have on Steam with it and it worked. What may I be doing wrong? Do I need to do any more calls to populate the connectedDevices or something?

Seth D. Fulmer
  • 490
  • 1
  • 4
  • 21
  • I'm totally aware and had since posting this changed it to a class level pointer. I only care about 1 gamepad so I'm now using the first one - The POINT though is that it's not detecting ANY devices yet Windows sees it and my other steam games see it. So I'd wonder if I was doing something wrong in my code - Using a local variable is a moot point as it's not even iterating once - It never gets inside the loop body for that to be an issue. – Seth D. Fulmer Jul 01 '20 at 12:49
  • 1
    Scheff, I updated my question to show the new code as it was changed since posting originally – Seth D. Fulmer Jul 01 '20 at 12:57
  • I saw [Qt Gamepad Simple Example](https://docs.huihoo.com/qt/5.x/qtgamepad-simple-example.html). It might be worth a try (just to confirm that it's `QGamepadManager` which causes the trouble). – Scheff's Cat Jul 01 '20 at 12:59
  • Just ran it and got in the Application Output "Did not find any connected gamepads" - Tried again my steam game I tested it before and it responded to the gamepad. There was a message in the Application Output too about the XInput thread running too. I think that's because of debug mode. But so it is the QGameManager unfortunately as I suspected. I don't understand the underlying QT-ish code (with all the Q_OBJECT and macros and stuff) and can't get the QGamepad pro project to build, or I'd try to debug it myself. – Seth D. Fulmer Jul 01 '20 at 13:26

2 Answers2

3

So it turns out that there is somewhat of a bug in the QGamepadManager as per this site: https://bugreports.qt.io/browse/QTBUG-61553?focusedCommentId=371230&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel

Evidently you have to first get the Manager's instance, then create a dummy window, show it, then delete it, then do QApplication::processEvents() then you can get the connectedDevices - there's some sort of initialization happening. Evidently this bug doesn't occur on Linux builds. Here's my new code for initInput:

QGamepadManager *ptrManager = QGamepadManager::instance();

/******************************
 * Workaround code so gamepads are detected
 *****************************/
QWindow *wnd = new QWindow();
wnd->show();
delete wnd;
qApp->processEvents();
/********************************
 * End workaround code
 ********************************/

QList<int> lstDevices = ptrManager->connectedGamepads();

if(!lstDevices.isEmpty())
    setGamepad(new QGamepad(lstDevices[0], this));

I hope this answer can help someone else! If you find that it's improved since this question/answer and the workaround is no longer necessary, feel free to comment and let me know.

Seth D. Fulmer
  • 490
  • 1
  • 4
  • 21
-2

This fix DOES NOT work on successive upgrades to Win 10, same problem. Joysticks are recognized by win 10, test ok, but for some reason a QT executable is being blocked at some permission level. The QT devs have been ignoring a fix for some time now.. Ken

  • 2
    Please do not post comments as answers but wait to have enough reputation and comment the right way – Dario Piotrowicz Jan 18 '21 at 22:46
  • I've actually had no problem with the suggestions to create a dummy window at least in version 5.15. I just upgraded to 6.2 this afternoon though and evidently QtGamePad is no longer available but as of 5.15 it seems to still work exactly as is. I don't know why your code isn't working. – Seth D. Fulmer Jun 06 '21 at 22:12
  • I'm using Qt5 on Windows 10, and while I am not using the workaround as given, I am calling `connectedGamepads()` on demand after the application is running. My controller is still not found. I am compiling on Windows in the MSys/MinGW environment. Not sure if that makes a difference. – AlastairG Feb 24 '23 at 10:44
  • I also tried the workaround exactly as given and it doesn't work either. – AlastairG Feb 24 '23 at 10:49