5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #include <QApplication>
23 #include <QLibraryInfo>
25 #include <QMessageBox>
27 #include <QTextStream>
28 #include <QTranslator>
29 #if defined(JOYSTICKS) || defined(SIMU_AUDIO)
35 #include "appdebugmessagehandler.h"
36 #include "constants.h"
37 #include "customdebug.h"
38 #include "eeprominterface.h"
39 #include "simulator.h"
40 #include "simulatormainwindow.h"
41 #include "simulatorstartupdialog.h"
43 #include "qxtcommandoptions.h"
46 using namespace Simulator
;
48 int finish(int exitCode
);
50 void showMessage(const QString
& message
, enum QMessageBox::Icon icon
= QMessageBox::NoIcon
)
53 msgBox
.setText(message
);
58 void sharedHelpText(QTextStream
&stream
)
60 // list all available profiles
61 stream
<< endl
<< QObject::tr("Available profiles:") << endl
;
62 QMapIterator
<int, QString
> pi(g
.getActiveProfiles());
63 while (pi
.hasNext()) {
65 stream
<< "\t" << QObject::tr("ID: ") << pi
.key() << QObject::tr(" Name: ") << pi
.value() << endl
;
67 // list all available radios
68 stream
<< endl
<< QObject::tr("Available radios:") << endl
;
69 foreach(QString name
, SimulatorLoader::getAvailableSimulators()) {
70 stream
<< "\t" << name
<< endl
;
74 int main(int argc
, char *argv
[])
77 QApplication
app(argc
, argv
);
78 app
.setApplicationName(APP_SIMULATOR
);
79 app
.setOrganizationName(COMPANY
);
80 app
.setOrganizationDomain(COMPANY_DOMAIN
);
81 #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
82 app
.setAttribute(Qt::AA_EnableHighDpiScaling
);
85 Q_INIT_RESOURCE(companion
);
86 Q_INIT_RESOURCE(translations
);
88 if (AppDebugMessageHandler::instance())
89 AppDebugMessageHandler::instance()->installAppMessageHandler();
91 CustomDebug::setFilterRules();
97 QTranslator companionTranslator
;
98 companionTranslator
.load(":/companion_" + g
.locale());
99 QTranslator qtTranslator
;
100 #if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0))
101 QString qtfile
= "qtbase_";
103 QString qtfile
= "qt_";
105 qtTranslator
.load(qtfile
+ g
.locale().left(2), QLibraryInfo::location(QLibraryInfo::TranslationsPath
));
106 app
.installTranslator(&companionTranslator
);
107 app
.installTranslator(&qtTranslator
);
109 #if defined(JOYSTICKS) || defined(SIMU_AUDIO)
110 uint32_t sdlFlags
= 0;
112 sdlFlags
|= SDL_INIT_JOYSTICK
;
115 sdlFlags
|= SDL_INIT_AUDIO
;
117 if (SDL_Init(sdlFlags
) < 0) {
118 showMessage(QObject::tr("WARNING: couldn't initialize SDL:\n%1").arg(SDL_GetError()), QMessageBox::Warning
);
122 QxtCommandOptions cliOptions
;
123 bool cliOptsFound
= false;
124 int profileId
= (g
.simuLastProfId() > -1 ? g
.simuLastProfId() : g
.id());
125 SimulatorOptions simOptions
= g
.profile
[profileId
].simulatorOptions();
127 registerStorageFactories();
128 registerOpenTxFirmwares();
129 SimulatorLoader::registerSimulators();
131 if (!SimulatorLoader::getAvailableSimulators().size()) {
132 showMessage(QObject::tr("ERROR: No simulator libraries available."), QMessageBox::Critical
);
136 cliOptions
.add("profile", QObject::tr("Radio profile ID or Name to use for simulator."), QxtCommandOptions::ValueRequired
);
137 cliOptions
.alias("profile", "p");
138 cliOptions
.add("radio", QObject::tr("Radio type to simulate (usually defined in profile)."), QxtCommandOptions::ValueRequired
);
139 cliOptions
.alias("radio", "r");
140 cliOptions
.add("help", QObject::tr("show this help text"));
141 cliOptions
.alias("help", "h");
142 cliOptions
.parse(QCoreApplication::arguments());
143 if (cliOptions
.count("help") || cliOptions
.showUnrecognizedWarning()) {
144 QTextStream
stream(&resultMsg
);
145 stream
<< QObject::tr("Usage: simulator [OPTION]... [EEPROM.BIN FILE OR DATA FOLDER] ") << endl
<< endl
;
146 stream
<< QObject::tr("Options:") << endl
;
147 cliOptions
.showUsage(false, stream
);
148 sharedHelpText(stream
);
150 showMessage(resultMsg
, QMessageBox::Information
);
154 // TODO : defaults should be set in Profile::init()
155 if (simOptions
.firmwareId
.isEmpty())
156 simOptions
.firmwareId
= SimulatorLoader::findSimulatorByFirmwareName(g
.profile
[profileId
].fwType());
157 if (simOptions
.dataFolder
.isEmpty())
158 simOptions
.dataFolder
= g
.eepromDir();
159 if (simOptions
.sdPath
.isEmpty())
160 simOptions
.sdPath
= g
.profile
[profileId
].sdPath();
162 if (cliOptions
.count("profile") == 1) {
164 int pid
= cliOptions
.value("profile").toInt(&chk
);
168 profileId
= g
.getActiveProfiles().key(cliOptions
.value("profile").toString(), -1);
170 if (!g
.getActiveProfiles().contains(profileId
)) {
171 fprintf(stderr
, "Error: Profile ID %d was not found.", profileId
);
175 simOptions
= g
.profile
[profileId
].simulatorOptions();
179 if (cliOptions
.count("radio") == 1) {
180 simOptions
.firmwareId
= cliOptions
.value("radio").toString();
184 if (cliOptsFound
|| (simOptions
.dataFile
.isEmpty() && !simOptions
.firmwareId
.isEmpty()))
185 simOptions
.dataFile
= SimulatorStartupDialog::radioEepromFileName(simOptions
.firmwareId
, g
.eepromDir());
187 if (!cliOptions
.positional().isEmpty()) {
188 if (QString(cliOptions
.positional().at(0)).contains(QRegExp(".*\\.[\\w]{2,6}$"))) {
189 simOptions
.dataFile
= cliOptions
.positional()[0];
190 simOptions
.startupDataType
= SimulatorOptions::START_WITH_FILE
;
193 simOptions
.dataFolder
= cliOptions
.positional()[0];
194 simOptions
.startupDataType
= SimulatorOptions::START_WITH_FOLDER
;
199 if (!cliOptsFound
|| profileId
== -1 || simOptions
.firmwareId
.isEmpty() || (simOptions
.dataFile
.isEmpty() && simOptions
.dataFolder
.isEmpty())) {
200 SimulatorStartupDialog
* dlg
= new SimulatorStartupDialog(&simOptions
, &profileId
);
201 int ret
= dlg
->exec();
203 if (ret
!= QDialog::Accepted
) {
207 qDebug() << "profileId=" << profileId
<< simOptions
;
209 if (profileId
< 0 || simOptions
.firmwareId
.isEmpty() || (simOptions
.dataFile
.isEmpty() && simOptions
.dataFolder
.isEmpty())) {
210 resultMsg
= QObject::tr("ERROR: Couldn't start simulator, missing radio/profile/data file/folder.\n Profile ID: [%1]; Radio ID: [%2];\nData File: [%3]");
211 showMessage(resultMsg
.arg(profileId
).arg(simOptions
.firmwareId
, simOptions
.dataFile
), QMessageBox::Critical
);
214 if (!g
.getActiveProfiles().contains(profileId
) || !SimulatorLoader::getAvailableSimulators().contains(simOptions
.firmwareId
)) {
215 QTextStream
stream(&resultMsg
);
216 stream
<< QObject::tr("ERROR: Radio profile or simulator firmware not found.\nProfile ID: [%1]; Radio ID: [%2]")
217 .arg(profileId
).arg(simOptions
.firmwareId
);
218 sharedHelpText(stream
);
219 showMessage(resultMsg
, QMessageBox::Critical
);
223 current_firmware_variant
= getFirmware(simOptions
.firmwareId
);
225 g
.sessionId(profileId
);
226 g
.simuLastProfId(profileId
);
229 SimulatorMainWindow
* mainWindow
= new SimulatorMainWindow(NULL
, simOptions
.firmwareId
, SIMULATOR_FLAGS_STANDALONE
);
230 if ((result
= mainWindow
->getExitStatus(&resultMsg
))) {
231 if (resultMsg
.isEmpty())
232 resultMsg
= QObject::tr("Uknown error during Simulator startup.");
233 showMessage(resultMsg
, QMessageBox::Critical
);
235 else if (mainWindow
->setOptions(simOptions
, true)) {
240 if ((result
= mainWindow
->getExitStatus(&resultMsg
)) && !resultMsg
.isEmpty())
241 qWarning() << "Exit message from SimulatorMainWindow:" << resultMsg
;
249 return finish(result
);
252 int finish(int exitCode
)
254 SimulatorLoader::unregisterSimulators();
255 unregisterOpenTxFirmwares();
256 unregisterStorageFactories();
258 #if defined(JOYSTICKS) || defined(SIMU_AUDIO)
262 qDebug() << "SIMULATOR EXIT" << exitCode
;