From 9ed1dd481bff153f29d8e7c9c449a37050579d7c Mon Sep 17 00:00:00 2001 From: harry Date: Sun, 18 Feb 2024 10:37:26 -0500 Subject: [PATCH] For Qt GUI, poll SDL events immediately after initializing the joystick subsystem to process all input device add events. Added gamepad init logging. --- src/drivers/Qt/QtScriptManager.cpp | 67 +++++++++++++++++++++++++---- src/drivers/Qt/QtScriptManager.h | 1 + src/drivers/Qt/input.cpp | 29 +++++++------ src/drivers/Qt/input.h | 1 + src/drivers/Qt/sdl-joystick.cpp | 68 ++++++++++++++++++++++++++---- 5 files changed, 134 insertions(+), 32 deletions(-) diff --git a/src/drivers/Qt/QtScriptManager.cpp b/src/drivers/Qt/QtScriptManager.cpp index f35fb20d..61410278 100644 --- a/src/drivers/Qt/QtScriptManager.cpp +++ b/src/drivers/Qt/QtScriptManager.cpp @@ -1707,17 +1707,25 @@ QtScriptInstance::QtScriptInstance(QObject* parent) dialog = win; } + FCEU_WRAPPER_LOCK(); + initEngine(); QtScriptManager::getInstance()->addScriptInstance(this); + + FCEU_WRAPPER_UNLOCK(); } //---------------------------------------------------- QtScriptInstance::~QtScriptInstance() { + FCEU_WRAPPER_LOCK(); + QtScriptManager::getInstance()->removeScriptInstance(this); shutdownEngine(); + FCEU_WRAPPER_UNLOCK(); + //printf("QtScriptInstance Destroyed\n"); } //---------------------------------------------------- @@ -2773,6 +2781,17 @@ void QScriptDialog_t::clearPropertyTree() //---------------------------------------------------- void QScriptDialog_t::loadPropertyTree(QJSValue& object, JsPropertyItem* parentItem) { + const QMetaObject* objMeta = nullptr; + + if (object.isObject()) + { + auto* qobjPtr = object.toQObject(); + if (qobjPtr != nullptr) + { + objMeta = qobjPtr->metaObject(); + } + } + QJSValueIterator it(object); while (it.hasNext()) @@ -2781,6 +2800,7 @@ void QScriptDialog_t::loadPropertyTree(QJSValue& object, JsPropertyItem* parentI QJSValue child = it.value(); bool isPrototype = it.name() == "prototype"; + //printf("ProtoType: %s :: %s\n", object.toString().toLocal8Bit().constData(), child.toString().toLocal8Bit().constData()); if (!isPrototype) { @@ -2827,6 +2847,26 @@ void QScriptDialog_t::loadPropertyTree(QJSValue& object, JsPropertyItem* parentI { type = "function"; value = ""; + + if (objMeta != nullptr) + { + //printf("Function: %s::%s\n", objMeta->className(), name.toLocal8Bit().constData()); + for (int i=0; imethodCount(); i++) + { + QMetaMethod m = objMeta->method(i); + + //printf("Method: %s %s %s\n", + // m.name().constData(), + // m.typeName(), + // m.methodSignature().constData()); + + if (name == m.name()) + { + value = QString(" ") + QString(m.typeName()) + " " + + QString::fromLocal8Bit(m.methodSignature()); + } + } + } } else if (child.isDate()) { @@ -2925,6 +2965,21 @@ void QScriptDialog_t::loadPropertyTree(QJSValue& object, JsPropertyItem* parentI } } //---------------------------------------------------- +void QScriptDialog_t::reloadGlobalTree(void) +{ + if (scriptInstance != nullptr) + { + auto* engine = scriptInstance->getEngine(); + + if (engine) + { + QJSValue globals = engine->globalObject(); + + loadPropertyTree(globals); + } + } +} +//---------------------------------------------------- void QScriptDialog_t::updatePeriodic(void) { //printf("Update JS\n"); @@ -2944,17 +2999,11 @@ void QScriptDialog_t::updatePeriodic(void) emuThreadText.clear(); } - if (scriptInstance != nullptr) + if ((scriptInstance != nullptr) && scriptInstance->isRunning()) { - auto* engine = scriptInstance->getEngine(); - - if (engine) - { - QJSValue globals = engine->globalObject(); - - loadPropertyTree(globals); - } + reloadGlobalTree(); } + refreshState(); FCEU_WRAPPER_UNLOCK(); } diff --git a/src/drivers/Qt/QtScriptManager.h b/src/drivers/Qt/QtScriptManager.h index 047f0235..8c0ce5ba 100644 --- a/src/drivers/Qt/QtScriptManager.h +++ b/src/drivers/Qt/QtScriptManager.h @@ -811,6 +811,7 @@ private slots: void stopScript(void); void onLogLinkClicked(const QString&); void onScriptError(void); + void reloadGlobalTree(void); }; bool FCEU_JSRerecordCountSkip(); diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index 5df0d426..d91a7420 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -1288,8 +1288,8 @@ void GetMouseRelative(int32 (&d)[3]) /** * Handles outstanding SDL events. */ -static void -UpdatePhysicalInput() +void +pollEventsSDL() { SDL_Event event; @@ -1646,7 +1646,7 @@ void FCEUD_UpdateInput(void) updateGamePadKeyMappings(); - UpdatePhysicalInput(); + pollEventsSDL(); KeyboardCommands(); for (x = 0; x < 2; x++) @@ -2598,7 +2598,7 @@ int loadInputSettingsFromFile(const char *filename) void UpdateInput(Config *config) { char buf[64]; - std::string device, prefix, guid, mapping; + std::string device, prefix; InitJoysticks(); @@ -2686,19 +2686,20 @@ void UpdateInput(Config *config) // input device key. int type, devnum, button; + // This is now done in InitJoysticks // gamepad 0 - 3 - for (unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) - { - char buf[64]; - snprintf(buf, sizeof(buf) - 1, "SDL.Input.GamePad.%u.", i); - prefix = buf; + //for (unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) + //{ + // char buf[64]; + // snprintf(buf, sizeof(buf) - 1, "SDL.Input.GamePad.%u.", i); + // prefix = buf; - config->getOption(prefix + "DeviceType", &device); - config->getOption(prefix + "DeviceGUID", &guid); - config->getOption(prefix + "Profile", &mapping); + // config->getOption(prefix + "DeviceType", &device); + // config->getOption(prefix + "DeviceGUID", &guid); + // config->getOption(prefix + "Profile", &mapping); - GamePad[i].init(i, guid.c_str(), mapping.c_str()); - } + // GamePad[i].init(i, guid.c_str(), mapping.c_str()); + //} // PowerPad 0 - 1 for (unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) diff --git a/src/drivers/Qt/input.h b/src/drivers/Qt/input.h index 8ed5ff38..da154d39 100644 --- a/src/drivers/Qt/input.h +++ b/src/drivers/Qt/input.h @@ -143,6 +143,7 @@ void UpdateInput(Config *config); const char* ButtonName(const ButtConfig* bc); +void pollEventsSDL(); int getInputSelection( int port, int *cur, int *usr ); int saveInputSettingsToFile( const char *fileBase = NULL ); int loadInputSettingsFromFile( const char *filename = NULL ); diff --git a/src/drivers/Qt/sdl-joystick.cpp b/src/drivers/Qt/sdl-joystick.cpp index ea536744..50dec3c8 100644 --- a/src/drivers/Qt/sdl-joystick.cpp +++ b/src/drivers/Qt/sdl-joystick.cpp @@ -50,6 +50,7 @@ static const char *buttonNames[GAMEPAD_NUM_BUTTONS] = "dpup", "dpdown", "dpleft", "dpright", "turboA", "turboB"}; +extern Config* g_config; //******************************************************************************** // Joystick Device jsDev_t::jsDev_t(void) @@ -155,6 +156,8 @@ void jsDev_t::init(int idx) guidStr.assign(stmp); + FCEU_printf("Added Joystick: devIdx:%i name:'%s' GUID:'%s'\n", idx, name.c_str(), guidStr.c_str() ); + // If game controller, save default mapping if it does not already exist. if (gc) { @@ -360,7 +363,7 @@ int GamePad_t::init(int port, const char *guid, const char *profile) portNum = port; - //printf("Init: %i %s %s \n", port, guid, profile ); + FCEU_printf("GamePad[%i].init Requested: GUID:'%s' Profile:'%s' \n", port, guid, profile ); // First look for a controller that matches the specific GUID // that is not already in use by another port. @@ -381,9 +384,12 @@ int GamePad_t::init(int port, const char *guid, const char *profile) if (strcmp(jsDev[i].getGUID(), guid) == 0) { + FCEU_printf("GamePad[%i].init Matched GUID to JS device %i \n", port, i ); + setDeviceIndex(i); if (loadProfile(profile, guid)) { + FCEU_printf("GamePad[%i].init Using default profile.\n", port ); loadDefaults(); } break; @@ -407,9 +413,12 @@ int GamePad_t::init(int port, const char *guid, const char *profile) if (jsDev[i].isGameController()) { + FCEU_printf("GamePad[%i].init Using JS device %i \n", port, i ); + setDeviceIndex(i); if (loadProfile(profile)) { + FCEU_printf("GamePad[%i].init Using default profile.\n", port ); loadDefaults(); } break; @@ -421,8 +430,10 @@ int GamePad_t::init(int port, const char *guid, const char *profile) // game controller, then load default keyboard. if ((portNum == 0 || strnlen(profile, 1) > 0) && (devIdx < 0)) { + FCEU_printf("GamePad[%i].init Using keyboard device\n", port ); if (loadProfile(profile)) { + FCEU_printf("GamePad[%i].init Using default profile.\n", port ); loadDefaults(); } } @@ -603,10 +614,16 @@ int GamePad_t::getMapFromFile(const char *filename, nesGamePadMap_t *gpm) FILE *fp; char line[256]; + bool fileExists = QFile::exists( QString(filename) ); + fp = ::fopen(filename, "r"); if (fp == NULL) { + if (fileExists) + { + FCEU_printf("GamePad[%i]: Failed to open binding map from file: %s\n", portNum, filename); + } return -1; } while (fgets(line, sizeof(line), fp) != 0) @@ -634,6 +651,8 @@ int GamePad_t::getMapFromFile(const char *filename, nesGamePadMap_t *gpm) ::fclose(fp); + FCEU_printf("GamePad[%i]: Loaded Button Binding Map from File: %s\n", portNum, filename); + return 0; } //******************************************************************************** @@ -665,6 +684,7 @@ int GamePad_t::loadHotkeyMapFromFile(const char *filename) if (fp == NULL) { + FCEU_printf("Gamepad[%i]: Error: Failed to Load HotKey Map From File: %s\n", portNum, filename ); return -1; } deleteHotKeyMappings(); @@ -775,6 +795,7 @@ int GamePad_t::loadHotkeyMapFromFile(const char *filename) } ::fclose(fp); + FCEU_printf("Gamepad[%i]: Loaded HotKey Map From File: %s NumBindings:%zi\n", portNum, filename, gpKeySeqList.size() ); return 0; } //******************************************************************************** @@ -1268,24 +1289,48 @@ int KillJoysticks(void) return -1; } + for (unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) + { + GamePad[i].setDeviceIndex(-1); + } + for (n = 0; n < MAX_JOYSTICKS; n++) { jsDev[n].close(); } - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + FCEU_printf("Shutting down SDL joystick/game constroller subsystem\n"); + SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); s_jinited = 0; return 0; } +//******************************************************************************** +void initGamepadBindings() +{ + std::string device, prefix, guid, mapping; + + for (unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) + { + char buf[64]; + snprintf(buf, sizeof(buf) - 1, "SDL.Input.GamePad.%u.", i); + prefix = buf; + + g_config->getOption(prefix + "DeviceType", &device); + g_config->getOption(prefix + "DeviceGUID", &guid); + g_config->getOption(prefix + "Profile", &mapping); + + GamePad[i].init(i, guid.c_str(), mapping.c_str()); + } +} //******************************************************************************** int AddJoystick(int which) { //printf("Add Joystick: %i \n", which ); if (jsDev[which].isConnected()) { - //printf("Error: Joystick already exists at device index %i \n", which ); + //FCEU_printf("Error: Joystick already exists at device index %i \n", which ); return -1; } else @@ -1296,12 +1341,12 @@ int AddJoystick(int which) if (jsDev[which].gc == NULL) { - printf("Could not open game controller %d: %s.\n", + FCEU_printf("Could not open game controller %d: %s.\n", which, SDL_GetError()); } else { - //printf("Added Joystick: %i \n", which ); + //FCEU_printf("Added Joystick: %i \n", which ); jsDev[which].init(which); //jsDev[which].print(); //printJoystick( s_Joysticks[which] ); @@ -1313,12 +1358,12 @@ int AddJoystick(int which) if (jsDev[which].js == NULL) { - printf("Could not open joystick %d: %s.\n", + FCEU_printf("Could not open joystick %d: %s.\n", which, SDL_GetError()); } else { - //printf("Added Joystick: %i \n", which ); + //FCEU_printf("Added Joystick: %i \n", which ); jsDev[which].init(which); //jsDev[which].print(); //printJoystick( s_Joysticks[which] ); @@ -1339,7 +1384,7 @@ int RemoveJoystick(int which) { if (SDL_JoystickInstanceID(jsDev[i].getJS()) == which) { - printf("Remove Joystick: %i \n", which); + FCEU_printf("Remove Joystick: %i \n", which); jsDev[i].close(); return 0; } @@ -1376,7 +1421,8 @@ int InitJoysticks(void) { return 1; } - SDL_InitSubSystem(SDL_INIT_JOYSTICK); + FCEU_printf("Initializing SDL joystick/game constroller subsystem\n"); + SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); total = SDL_NumJoysticks(); if (total > MAX_JOYSTICKS) @@ -1390,6 +1436,10 @@ int InitJoysticks(void) AddJoystick(n); } + pollEventsSDL(); // Run event processing here to ensure that all joystick add events are processed. + + initGamepadBindings(); + s_jinited = 1; return 1; }