From 0b980e00d377a5f67bd4a37bb69218d96f2fcf1b Mon Sep 17 00:00:00 2001 From: Sam Ballantyne <43810437+samuelballantyne@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:38:10 +1300 Subject: [PATCH] Order PID's lowest to highest Ordering ports by the lowest to highest PID stops the possibility of opening extra serials ports and also allows for PID to port assignment for other systems not just OpenFIRE. --- qhookermain.cpp | 129 ++++++++++++++++++------------------------------ 1 file changed, 47 insertions(+), 82 deletions(-) diff --git a/qhookermain.cpp b/qhookermain.cpp index b5f6a1c..76ac33f 100644 --- a/qhookermain.cpp +++ b/qhookermain.cpp @@ -111,13 +111,13 @@ void qhookerMain::SerialInit() // Create a list to hold valid devices QList validDevices; - // Filter devices based on Vendor IDs and collect valid devices - for (const QSerialPortInfo& info : serialFoundList) { - if (info.vendorIdentifier() == 9025 || // JB - info.vendorIdentifier() == 13939 || // Props3D - info.vendorIdentifier() == 0xF143) // OpenFIRE + // Filter devices based on Vendor IDs (JB = 9025, Props3D = 13939, OpenFIRE = 0xF143) + // But we no longer treat OpenFIRE in a special way – just accept it if it matches vendorId + for (const QSerialPortInfo &info : serialFoundList) { + if (info.vendorIdentifier() == 9025 // JB + || info.vendorIdentifier() == 13939 // Props3D + || info.vendorIdentifier() == 0xF143) // OpenFIRE { - // qInfo() << "Found device @" << info.systemLocation(); validDevices.append(info); } else { @@ -133,88 +133,50 @@ void qhookerMain::SerialInit() quit(); } else { + // Sort valid devices by Product ID ascending + std::sort(validDevices.begin(), validDevices.end(), + [](const QSerialPortInfo &a, const QSerialPortInfo &b) { + return a.productIdentifier() < b.productIdentifier(); + }); - int maxIndex = -1; - foreach (const QSerialPortInfo &info, validDevices) { - int index = -1; + // Create our array of QSerialPorts, sized to the number of valid devices + serialPort = new QSerialPort[validDevices.size()]; - if (info.vendorIdentifier() == 0xF143) { - // For OpenFIRE devices, derive index from productId - int productId = info.productIdentifier(); - - if (productId == 0x1998) { - // If default OpenFIRE product ID set to 0 - index = 0; - } else { - index = productId - 1; - } - - if (index > maxIndex) { - maxIndex = index; - } - } else { - // For non-OpenFIRE (JB or Props3D), - ++maxIndex; - } - } - - serialPort = new QSerialPort[maxIndex + 1]; - - - QSet assignedIndices; + // Keep track of assigned PIDs and check for duplicates + QSet assignedPids; bool duplicateProductIds = false; - foreach (const QSerialPortInfo &info, validDevices) { - int index = -1; - - if (info.vendorIdentifier() == 0xF143) { - // OpenFIRE device - int productId = info.productIdentifier(); + // Assign indices (ports) in sorted order (lowest PID → highest PID) + for (int i = 0; i < validDevices.size(); ++i) { + const QSerialPortInfo &info = validDevices[i]; + quint16 pid = info.productIdentifier(); - if (productId == 0x1998) { - index = 0; - } else { - index = productId - 1; - } - - if (assignedIndices.contains(index)) { - duplicateProductIds = true; - qWarning() << "Duplicate Product ID" - << productId << "found on device" << info.portName(); - } - else { - assignedIndices.insert(index); - } - } - else { - // Non-OpenFIRE devices - // Start scanning from 0 until we find a free spot - index = 0; - while (assignedIndices.contains(index)) { - index++; - } - assignedIndices.insert(index); + // Check for duplicates + if (assignedPids.contains(pid)) { + duplicateProductIds = true; + qWarning() << "Duplicate Product ID" << pid + << "found on device" << info.portName(); + } else { + assignedPids.insert(pid); } - // Safety check for array bounds - if (index >= 0 && index < (maxIndex + 1)) { - serialPort[index].setPort(info); - serialPort[index].setBaudRate(QSerialPort::Baud9600); - serialPort[index].setDataBits(QSerialPort::Data8); - serialPort[index].setParity(QSerialPort::NoParity); - serialPort[index].setStopBits(QSerialPort::OneStop); - serialPort[index].setFlowControl(QSerialPort::NoFlowControl); - qInfo() << "Assigning" << info.portName() - << "to port no." << index + 1; - } - else { - qWarning() << "Index" << index << "out of bounds"; - } + // Now simply assign i as the index for this device + // (port #1 for i=0, port #2 for i=1, etc.) + serialPort[i].setPort(info); + serialPort[i].setBaudRate(QSerialPort::Baud9600); + serialPort[i].setDataBits(QSerialPort::Data8); + serialPort[i].setParity(QSerialPort::NoParity); + serialPort[i].setStopBits(QSerialPort::OneStop); + serialPort[i].setFlowControl(QSerialPort::NoFlowControl); + + qInfo() << "Assigning" << info.portName() + << "with PID" << pid + << "to port no." << (i + 1); } if (duplicateProductIds) { qWarning() << "Matching identifiers detected. " - "Make sure to assign different USB/PID identifiers for each gun "; + "To get consistant port allocations assign different PID identifiers for each gun."; } } } @@ -225,6 +187,7 @@ void qhookerMain::SerialInit() + bool qhookerMain::GameSearching(QString input) { if(buffer.isEmpty()) { @@ -471,15 +434,17 @@ void qhookerMain::LoadConfig(QString path) void qhookerMain::PrintDeviceInfo(const QList &devices) { - for(const QSerialPortInfo &info : devices) { + for (const QSerialPortInfo &info : devices) { qInfo() << "========================================"; qInfo() << "Port Name:" << info.portName(); qInfo() << "Vendor Identifier:" - << (info.hasVendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) - : "N/A"); + << (info.hasVendorIdentifier() + ? QString::number(info.vendorIdentifier(), 16) + : "N/A"); qInfo() << "Product Identifier:" - << (info.hasProductIdentifier() ? QString::number(info.productIdentifier(), 16) - : "N/A"); + << (info.hasProductIdentifier() + ? QString::number(info.productIdentifier()) // decimal instead of base-16 + : "N/A"); qInfo() << "========================================"; } }