Skip to content

Commit 251be55

Browse files
committed
Add different port map sorting types - only sort new devices list if not matching
1 parent 3f9c851 commit 251be55

File tree

3 files changed

+153
-65
lines changed

3 files changed

+153
-65
lines changed

main.cpp

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,26 @@ void PrintHelp()
1111
#ifdef Q_OS_WIN
1212
".exe"
1313
#endif
14-
" [-v] [-p <path>] [-c]\n\n"
14+
" [-v] [-c] [-p <path>] [-s <sort type>]\n\n"
1515
"QMamehook: A force-feedback distributor program for lightgun devices\n\n"
1616
"options:\n"
17-
" -v Enable verbose output (effectively repeating whatever the server sends)\n\n"
18-
" -p <path> Load config files from the provided <path> instead of the default location\n"
19-
" When not set, QMH will look for .ini files in the following path:\n"
20-
" %s\n\n"
21-
" -c Set QMH to exit after the server closes once,\n"
22-
" rather than wait for another connection.\n\n"
23-
" -h, --help Show this help. Helpful, huh? c:\n\n"
17+
" -v Enable verbose output (effectively repeating whatever the connected server sends)\n"
18+
"\n"
19+
" -c Set QMH to exit after the server closes once,\n"
20+
" rather than wait for another connection.\n"
21+
"\n"
22+
" -p <path> Load config files from the provided <path> instead of the default location\n"
23+
" When not set, QMH will look for .ini files in the following path:\n"
24+
" %s\n"
25+
"\n"
26+
" -s <sort type> Sort assigned ports based on selected criteria, where <sort type> can be one of:\n"
27+
" pid-ascending - Product ID in Ascending Order (lowest to highest) [default]\n"
28+
" pid-descending - Product ID in Descending Order (highest to lowest)\n"
29+
" port-ascending - System-assigned Port Number, in Ascending Order (lowest to highest)\n"
30+
" port-descending - System-assigned Port Number, in Descending Order (highest to lowest)\n"
31+
"\n"
32+
" -h, --help Show this help. Helpful, huh? c:\n"
33+
"\n"
2434
"If this software has brought any value to you, please consider supporting me (That One Seong) on Ko-fi:\n"
2535
"https://ko-fi.com/Z8Z5NNXWL\n"
2636
,
@@ -52,12 +62,12 @@ int main(int argc, char *argv[])
5262

5363
if(arguments.contains("-v")) {
5464
mainApp.verbosity = true;
55-
printf("Enabling verbose output!\n");
65+
printf("Enabling verbose output.\n");
5666
arguments.removeAt(arguments.indexOf("-v"));
5767
}
5868

5969
if(arguments.contains("-p")) {
60-
if(arguments.length() > 1) {
70+
if(arguments.indexOf("-p") < arguments.count()-1) {
6171
// QDir::fromNativeSeparators uses forwardslashes on both OSes, thank Parace
6272
mainApp.customPath = QDir::fromNativeSeparators(arguments[arguments.indexOf("-p")+1]);
6373
mainApp.customPathSet = true;
@@ -69,17 +79,14 @@ int main(int argc, char *argv[])
6979
mainApp.customPath.append('/');
7080

7181
if(QFile::exists(mainApp.customPath)) {
72-
printf("Setting search path to %s\n\n", mainApp.customPath.toLocal8Bit().constData());
73-
arguments.removeAt(arguments.indexOf("-p")+1);
74-
arguments.removeAt(arguments.indexOf("-p"));
82+
printf("Setting search path to \"%s\"\n\n", mainApp.customPath.toLocal8Bit().constData());
83+
arguments.remove(arguments.indexOf("-p"), 2);
7584
} else {
76-
PrintHelp();
77-
printf("\n\nERROR: Custom path specified does not seem to exist!\n");
85+
printf("ERROR: Specified custom path \"%s\" does not seem to exist!\n", arguments.at(arguments.indexOf("-p")+1).toLocal8Bit().constData());
7886
return 1;
7987
}
8088
} else {
81-
PrintHelp();
82-
printf("\n\nERROR: Custom path flag called without any path specified!\n");
89+
printf("ERROR: Custom path flag called without any path specified!\n");
8390
return 1;
8491
}
8592
}
@@ -89,6 +96,36 @@ int main(int argc, char *argv[])
8996
printf("This session will close upon disconnect.\n");
9097
arguments.removeAt(arguments.indexOf("-c"));
9198
}
99+
100+
if(arguments.contains("-s")) {
101+
if(arguments.indexOf("-s") < arguments.size()) {
102+
if(arguments.at(arguments.indexOf("-s")+1).toLower() == "pid-ascending")
103+
printf("Sorting devices by Product ID in ascending order.\n");
104+
else if(arguments.at(arguments.indexOf("-s")+1).toLower() == "pid-descending") {
105+
printf("Sorting devices by Product ID in descending order.\n");
106+
mainApp.sortType = qhookerMain::sortPIDdescend;
107+
} else if(arguments.at(arguments.indexOf("-s")+1).toLower() == "port-ascending") {
108+
printf("Sorting devices by port number in ascending order.\n");
109+
mainApp.sortType = qhookerMain::sortPortAscend;
110+
} else if(arguments.at(arguments.indexOf("-s")+1).toLower() == "port-descending") {
111+
printf("Sorting devices by port number in descending order.\n");
112+
mainApp.sortType = qhookerMain::sortPortDescend;
113+
} else {
114+
printf("ERROR: Sorting type \"%s\" is invalid! Sort type must be one of:\n"
115+
" pid-ascending\n"
116+
" pid-descending\n"
117+
" port-ascending\n"
118+
" port-descending\n",
119+
arguments.at(arguments.indexOf("-s")+1).toLocal8Bit().constData());
120+
return 1;
121+
}
122+
123+
arguments.remove(arguments.indexOf("-s"), 2);
124+
} else {
125+
printf("ERROR: No sorting type specified!\n");
126+
return 1;
127+
}
128+
}
92129
}
93130

94131
// connect up the signals

qhookermain.cpp

Lines changed: 89 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ void qhookerMain::SerialInit()
156156
for(auto &port : serialPort)
157157
delete port;
158158
serialPort.clear();
159+
printf("No devices found!\n");
159160
}
160161
} else {
161162
QList<QSerialPortInfo> newDevices;
@@ -176,23 +177,16 @@ void qhookerMain::SerialInit()
176177
for(auto &port : serialPort)
177178
delete port;
178179
serialPort.clear();
180+
printf("No devices found!\n");
179181
}
180182
} else {
181-
// Sort valid devices by Product ID ascending
182-
std::sort(newDevices.begin(), newDevices.end(),
183-
[](const QSerialPortInfo &a, const QSerialPortInfo &b) {
184-
return a.productIdentifier() < b.productIdentifier();
185-
});
186-
187183
if(newDevices.size() != validDevices.size()) {
188184
printf("Current ports list does not match new list, overriding...\n\n");
189-
PrintDeviceInfo(newDevices);
190185
AddNewDevices(newDevices);
191186
} else for(const auto &newPort : std::as_const(newDevices)) {
192187
if(!validIDs.contains(newPort.vendorIdentifier() | newPort.productIdentifier() << 16)) {
193188
printf("%04X:%04X not found in current ports, overriding old serial devices list...\n\n",
194189
newPort.vendorIdentifier(), newPort.productIdentifier());
195-
PrintDeviceInfo(newDevices);
196190
AddNewDevices(newDevices);
197191
break;
198192
}
@@ -202,7 +196,7 @@ void qhookerMain::SerialInit()
202196
}
203197

204198

205-
void qhookerMain::AddNewDevices(const QList<QSerialPortInfo> &newDevices)
199+
void qhookerMain::AddNewDevices(QList<QSerialPortInfo> &newDevices)
206200
{
207201
if(serialPort.count()) {
208202
for(auto &port : serialPort)
@@ -214,6 +208,92 @@ void qhookerMain::AddNewDevices(const QList<QSerialPortInfo> &newDevices)
214208
for(const auto &device : newDevices)
215209
serialPort << new QSerialPort;
216210

211+
switch(sortType) {
212+
case sortPIDascend:
213+
std::sort(newDevices.begin(), newDevices.end(),
214+
[](const QSerialPortInfo &a, const QSerialPortInfo &b) {
215+
return a.productIdentifier() < b.productIdentifier();
216+
});
217+
break;
218+
case sortPIDdescend:
219+
std::sort(newDevices.begin(), newDevices.end(),
220+
[](const QSerialPortInfo &a, const QSerialPortInfo &b) {
221+
return a.productIdentifier() > b.productIdentifier();
222+
});
223+
break;
224+
case sortPortAscend:
225+
std::sort(newDevices.begin(), newDevices.end(),
226+
[](const QSerialPortInfo &a, const QSerialPortInfo &b) {
227+
return a.portName().mid(
228+
#ifdef Q_OS_WIN
229+
3 // COM
230+
#else
231+
6 // ttyACM
232+
#endif
233+
).toInt() < b.portName().mid(
234+
#ifdef Q_OS_WIN
235+
3
236+
#else
237+
6
238+
#endif
239+
).toInt();
240+
});
241+
break;
242+
case sortPortDescend:
243+
std::sort(newDevices.begin(), newDevices.end(),
244+
[](const QSerialPortInfo &a, const QSerialPortInfo &b) {
245+
return a.portName().mid(
246+
#ifdef Q_OS_WIN
247+
3 // COM
248+
#else
249+
6 // ttyACM
250+
#endif
251+
).toInt() > b.portName().mid(
252+
#ifdef Q_OS_WIN
253+
3
254+
#else
255+
6
256+
#endif
257+
).toInt();
258+
});
259+
break;
260+
default:
261+
break;
262+
}
263+
264+
for (const QSerialPortInfo &info : newDevices) {
265+
printf("========================================\n");
266+
printf("Port Name: %s\n", info.portName().toLocal8Bit().constData());
267+
printf("Vendor Identifier: ");
268+
if(info.hasVendorIdentifier()) {
269+
printf("%04X", info.vendorIdentifier());
270+
switch(info.vendorIdentifier()) {
271+
case 9025:
272+
printf(" (GUN4IR Lightgun)\n");
273+
break;
274+
case 13939:
275+
printf(" (Blamcon Lightgun)\n");
276+
break;
277+
case 0xF143:
278+
printf(" (OpenFIRE Lightgun)\n");
279+
break;
280+
default:
281+
// unlikely to happen due to whitelisting, but just in case.
282+
printf("\n");
283+
break;
284+
}
285+
} else printf("N/A\n");
286+
287+
printf("Product Identifier: ");
288+
if(info.hasProductIdentifier())
289+
printf("%04X\n", info.productIdentifier());
290+
else printf("N/A\n");
291+
292+
if(!info.manufacturer().isEmpty() && !info.description().isEmpty())
293+
printf("Device: %s %s\n", info.manufacturer().toLocal8Bit().constData(), info.description().toLocal8Bit().constData());
294+
printf("========================================\n");
295+
}
296+
217297
printf("\n");
218298

219299
// Keep track of assigned PIDs and check for duplicates
@@ -534,39 +614,3 @@ void qhookerMain::LoadConfig(const QString &path)
534614
}
535615
settings->endGroup();
536616
}
537-
538-
void qhookerMain::PrintDeviceInfo(const QList<QSerialPortInfo> &devices)
539-
{
540-
for (const QSerialPortInfo &info : devices) {
541-
printf("========================================\n");
542-
printf("Port Name: %s\n", info.portName().toLocal8Bit().constData());
543-
printf("Vendor Identifier: ");
544-
if(info.hasVendorIdentifier()) {
545-
printf("%04X", info.vendorIdentifier());
546-
switch(info.vendorIdentifier()) {
547-
case 9025:
548-
printf(" (GUN4IR Lightgun)\n");
549-
break;
550-
case 13939:
551-
printf(" (Blamcon Lightgun)\n");
552-
break;
553-
case 0xF143:
554-
printf(" (OpenFIRE Lightgun)\n");
555-
break;
556-
default:
557-
// unlikely to happen due to whitelisting, but just in case.
558-
printf("\n");
559-
break;
560-
}
561-
} else printf("N/A\n");
562-
563-
printf("Product Identifier: ");
564-
if(info.hasProductIdentifier())
565-
printf("%04X\n", info.productIdentifier());
566-
else printf("N/A\n");
567-
568-
if(!info.manufacturer().isEmpty() && !info.description().isEmpty())
569-
printf("Device: %s %s\n", info.manufacturer().toLocal8Bit().constData(), info.description().toLocal8Bit().constData());
570-
printf("========================================\n");
571-
}
572-
}

qhookermain.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class qhookerMain : public QObject
3636

3737
void SerialInit();
3838

39-
void AddNewDevices(const QList<QSerialPortInfo> &);
39+
void AddNewDevices(QList<QSerialPortInfo> &);
4040

4141
bool GameSearching(const QString & = "");
4242

@@ -45,6 +45,13 @@ class qhookerMain : public QObject
4545
void ReadyRead();
4646

4747
public:
48+
enum {
49+
sortPIDascend = 0,
50+
sortPIDdescend,
51+
sortPortAscend,
52+
sortPortDescend
53+
} sortTypes_e;
54+
4855
explicit qhookerMain(QObject *parent = 0);
4956

5057
bool verbosity = false;
@@ -53,9 +60,9 @@ class qhookerMain : public QObject
5360

5461
bool closeOnDisconnect = false;
5562

56-
QString customPath;
63+
int sortType = sortPIDascend;
5764

58-
void PrintDeviceInfo(const QList<QSerialPortInfo> &devices);
65+
QString customPath;
5966

6067
void quit();
6168

0 commit comments

Comments
 (0)