diff --git a/installer/installbuilder/swift-plugin-simulators.xml b/installer/installbuilder/swift-plugin-simulators.xml
index 86f9aabb8..15ea38b8d 100644
--- a/installer/installbuilder/swift-plugin-simulators.xml
+++ b/installer/installbuilder/swift-plugin-simulators.xml
@@ -93,6 +93,9 @@ This plugin acts as the interface between swift and MSFS.
../../dist/bin/plugins/simulator/simulatormsfs.dll
+
+ ../../dist/bin/plugins/simulator/simulatormsfsconfig.dll
+
diff --git a/src/config/buildconfig.h b/src/config/buildconfig.h
index a5bf357df..55606eee4 100644
--- a/src/config/buildconfig.h
+++ b/src/config/buildconfig.h
@@ -38,6 +38,9 @@ namespace swift::config
//! with FG support?
static constexpr bool isCompiledWithFGSupport(); // defined in buildconfig_gen.inc.in
+ //! with MSFS support?
+ static constexpr bool isCompiledWithMSFSSupport(); // defined in buildconfig_gen.inc.in
+
//! with FSUIPC support?
static constexpr bool isCompiledWithFsuipcSupport(); // defined in buildconfig_gen.inc.in
diff --git a/src/config/buildconfig.inc b/src/config/buildconfig.inc
index 19b9a8d33..4fe255d02 100644
--- a/src/config/buildconfig.inc
+++ b/src/config/buildconfig.inc
@@ -14,7 +14,7 @@ namespace swift::config
{
constexpr bool CBuildConfig::isCompiledWithMsFlightSimulatorSupport()
{
- return CBuildConfig::isCompiledWithFs9Support() || CBuildConfig::isCompiledWithFsxSupport() || CBuildConfig::isCompiledWithP3DSupport();
+ return CBuildConfig::isCompiledWithFs9Support() || CBuildConfig::isCompiledWithFsxSupport() || CBuildConfig::isCompiledWithP3DSupport() || isCompiledWithMSFSSupport();
}
constexpr bool CBuildConfig::isCompiledWithFlightSimulatorSupport()
diff --git a/src/config/buildconfig_gen.inc.in b/src/config/buildconfig_gen.inc.in
index 9215abe01..4e9af4d24 100644
--- a/src/config/buildconfig_gen.inc.in
+++ b/src/config/buildconfig_gen.inc.in
@@ -40,7 +40,7 @@ constexpr bool swift::config::CBuildConfig::isCompiledWithFsxSupport()
constexpr bool swift::config::CBuildConfig::isCompiledWithFsuipcSupport()
{
- return isCompiledWithFsxSupport() || isCompiledWithP3DSupport() || isCompiledWithFs9Support() || SWIFTCONFIG_${SWIFT_BUILD_MSFS_PLUGIN};
+ return isCompiledWithFsxSupport() || isCompiledWithP3DSupport() || isCompiledWithFs9Support() || isCompiledWithMSFSSupport();
}
constexpr bool swift::config::CBuildConfig::isCompiledWithXPlaneSupport()
@@ -53,6 +53,11 @@ constexpr bool swift::config::CBuildConfig::isCompiledWithFGSupport()
return SWIFTCONFIG_${SWIFT_BUILD_FLIGHTGEAR_PLUGIN};
}
+constexpr bool swift::config::CBuildConfig::isCompiledWithMSFSSupport()
+{
+ return SWIFTCONFIG_${SWIFT_BUILD_MSFS_PLUGIN};
+}
+
constexpr bool swift::config::CBuildConfig::isCompiledWithGui()
{
return SWIFTCONFIG_${SWIFT_BUILD_GUI};
diff --git a/src/core/fsd/fsdclient.cpp b/src/core/fsd/fsdclient.cpp
index e828d5c40..8b099d2be 100644
--- a/src/core/fsd/fsdclient.cpp
+++ b/src/core/fsd/fsdclient.cpp
@@ -213,6 +213,7 @@ namespace swift::core::fsd
case CSimulatorInfo::FS9: m_simType = SimType::MSFS2004; break;
case CSimulatorInfo::FG: m_simType = SimType::FlightGear; break;
case CSimulatorInfo::XPLANE: m_simType = SimType::XPLANE11; break;
+ case CSimulatorInfo::MSFS: m_simType = SimType::MSFS; break;
default: m_simType = SimType::Unknown; break;
}
m_simTypeInfo = CSimulatorInfo(simulator);
diff --git a/src/gui/components/configsimulatorcomponent.cpp b/src/gui/components/configsimulatorcomponent.cpp
index afe9777a5..cce27084b 100644
--- a/src/gui/components/configsimulatorcomponent.cpp
+++ b/src/gui/components/configsimulatorcomponent.cpp
@@ -56,6 +56,7 @@ namespace swift::gui::components
const bool p3d = (sims.isP3D() || !CFsDirectories::p3dDir().isEmpty()) && CBuildConfig::isCompiledWithP3DSupport();
const bool fsx = (sims.isFSX() || !CFsDirectories::fsxDir().isEmpty()) && CBuildConfig::isCompiledWithFsxSupport();
const bool fs9 = (sims.isFS9() || !CFsDirectories::fs9Dir().isEmpty()) && CBuildConfig::isCompiledWithFs9Support();
+ const bool msfs = (sims.isMSFS() || !CFsDirectories::msfsDir().isEmpty()) && CBuildConfig::isCompiledWithMSFSSupport();
const bool xp = sims.isXPlane() && CBuildConfig::isCompiledWithXPlaneSupport();
const bool fg = sims.isFG() && CBuildConfig::isCompiledWithFGSupport();
@@ -64,24 +65,28 @@ namespace swift::gui::components
ui->cb_FS9->setChecked(fs9);
ui->cb_XP->setChecked(xp);
ui->cb_FG->setChecked(fg);
+ ui->cb_MSFS->setChecked(msfs);
ui->cb_P3D->setEnabled(CBuildConfig::isCompiledWithP3DSupport());
ui->cb_FSX->setEnabled(CBuildConfig::isCompiledWithFsxSupport());
ui->cb_FS9->setEnabled(CBuildConfig::isCompiledWithFs9Support());
ui->cb_XP->setEnabled(CBuildConfig::isCompiledWithXPlaneSupport());
ui->cb_FG->setEnabled(CBuildConfig::isCompiledWithFGSupport());
+ ui->cb_MSFS->setEnabled(CBuildConfig::isCompiledWithMSFSSupport());
CGuiUtility::checkBoxReadOnly(ui->cb_P3D, !CBuildConfig::isCompiledWithP3DSupport());
CGuiUtility::checkBoxReadOnly(ui->cb_FSX, !CBuildConfig::isCompiledWithFsxSupport());
CGuiUtility::checkBoxReadOnly(ui->cb_FS9, !CBuildConfig::isCompiledWithFs9Support());
CGuiUtility::checkBoxReadOnly(ui->cb_XP, !CBuildConfig::isCompiledWithXPlaneSupport());
CGuiUtility::checkBoxReadOnly(ui->cb_FG, !CBuildConfig::isCompiledWithFGSupport());
+ CGuiUtility::checkBoxReadOnly(ui->cb_MSFS, !CBuildConfig::isCompiledWithMSFSSupport());
if (p3d) { ui->comp_SettingsSimulator->setSimulator(CSimulatorInfo(CSimulatorInfo::P3D)); }
else if (fsx) { ui->comp_SettingsSimulator->setSimulator(CSimulatorInfo(CSimulatorInfo::FSX)); }
else if (fs9) { ui->comp_SettingsSimulator->setSimulator(CSimulatorInfo(CSimulatorInfo::FS9)); }
else if (xp) { ui->comp_SettingsSimulator->setSimulator(CSimulatorInfo(CSimulatorInfo::XPLANE)); }
else if (fg) { ui->comp_SettingsSimulator->setSimulator(CSimulatorInfo(CSimulatorInfo::FG)); }
+ else if (msfs) { ui->comp_SettingsSimulator->setSimulator(CSimulatorInfo(CSimulatorInfo::MSFS)); }
}
QStringList CConfigSimulatorComponent::selectedSimsToPluginIds()
@@ -94,6 +99,7 @@ namespace swift::gui::components
if (ui->cb_P3D->isChecked()) { ids << CSimulatorPluginInfo::p3dPluginIdentifier(); }
if (ui->cb_XP->isChecked()) { ids << CSimulatorPluginInfo::xplanePluginIdentifier(); }
if (ui->cb_FG->isChecked()) { ids << CSimulatorPluginInfo::fgPluginIdentifier(); }
+ if (ui->cb_MSFS->isChecked()) { ids << CSimulatorPluginInfo::msfsPluginIdentifier(); }
return ids;
}
diff --git a/src/gui/components/configsimulatorcomponent.ui b/src/gui/components/configsimulatorcomponent.ui
index b159d7bdc..5d91c1b22 100644
--- a/src/gui/components/configsimulatorcomponent.ui
+++ b/src/gui/components/configsimulatorcomponent.ui
@@ -85,6 +85,13 @@
+ -
+
+
+ MSFS (64-bit)
+
+
+
diff --git a/src/gui/components/dbownmodelscomponent.cpp b/src/gui/components/dbownmodelscomponent.cpp
index c593cf4a0..43bde4a10 100644
--- a/src/gui/components/dbownmodelscomponent.cpp
+++ b/src/gui/components/dbownmodelscomponent.cpp
@@ -309,7 +309,7 @@ namespace swift::gui::components
QPointer ownModelsComp(qobject_cast(this->parent()));
Q_ASSERT_X(ownModelsComp, Q_FUNC_INFO, "Cannot access parent");
- if (m_loadActions.isEmpty()) { m_loadActions = QList({ nullptr, nullptr, nullptr, nullptr, nullptr }); }
+ if (m_loadActions.isEmpty()) { m_loadActions = QList({ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }); }
menuActions.addMenuSimulator();
if (sims.isFSX())
{
@@ -376,12 +376,25 @@ namespace swift::gui::components
}
menuActions.addAction(m_loadActions[4], CMenuAction::pathSimulator());
}
+ if (sims.isMSFS())
+ {
+ if (!m_loadActions[5])
+ {
+ m_loadActions[5] = new QAction(CIcons::appModels16(), "MSFS models", this);
+ connect(m_loadActions[5], &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) {
+ if (!ownModelsComp) { return; }
+ Q_UNUSED(checked)
+ ownModelsComp->setSimulator(CSimulatorInfo::msfs(), true);
+ });
+ }
+ menuActions.addAction(m_loadActions[5], CMenuAction::pathSimulator());
+ }
// with models loaded I allow a refresh reload
// I need those models because I want to merge with DB data in the loader
if (sGui && sGui->getWebDataServices() && sGui->getWebDataServices()->getModelsCount() > 0)
{
- if (m_reloadActions.isEmpty()) { m_reloadActions = QList({ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }); }
+ if (m_reloadActions.isEmpty()) { m_reloadActions = QList({ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }); }
menuActions.addMenu(CIcons::refresh16(), "Force model reload", CMenuAction::pathSimulatorModelsReload());
if (sims.isFSX())
{
@@ -512,6 +525,31 @@ namespace swift::gui::components
menuActions.addAction(m_reloadActions[8], CMenuAction::pathSimulatorModelsReload());
menuActions.addAction(m_reloadActions[9], CMenuAction::pathSimulatorModelsReload());
}
+ if (sims.isMSFS())
+ {
+ if (!m_reloadActions[10])
+ {
+ m_reloadActions[10] = new QAction(CIcons::appModels16(), "MSFS models", this);
+ connect(m_reloadActions[10], &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) {
+ if (!ownModelsComp) { return; }
+ Q_UNUSED(checked)
+ ownModelsComp->requestSimulatorModels(CSimulatorInfo::msfs(), IAircraftModelLoader::InBackgroundNoCache);
+ });
+ m_reloadActions[11] = new QAction(CIcons::appModels16(), "MSFS models from directoy", this);
+ connect(m_reloadActions[11], &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) {
+ if (!ownModelsComp) { return; }
+ Q_UNUSED(checked)
+ const CSimulatorInfo sim(CSimulatorInfo::MSFS);
+ const QString dir = ownModelsComp->directorySelector(sim);
+ if (!dir.isEmpty())
+ {
+ ownModelsComp->requestSimulatorModels(sim, IAircraftModelLoader::InBackgroundNoCache, QStringList(dir));
+ }
+ });
+ }
+ menuActions.addAction(m_reloadActions[10], CMenuAction::pathSimulatorModelsReload());
+ menuActions.addAction(m_reloadActions[11], CMenuAction::pathSimulatorModelsReload());
+ }
}
else
{
@@ -520,7 +558,7 @@ namespace swift::gui::components
a.setActionEnabled(false); // gray out
}
- if (m_clearCacheActions.isEmpty()) { m_clearCacheActions = QList({ nullptr, nullptr, nullptr, nullptr, nullptr }); }
+ if (m_clearCacheActions.isEmpty()) { m_clearCacheActions = QList({ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }); }
menuActions.addMenu(CIcons::delete16(), "Clear model caches", CMenuAction::pathSimulatorModelsClearCache());
if (sims.isFSX())
{
@@ -587,6 +625,19 @@ namespace swift::gui::components
}
menuActions.addAction(m_clearCacheActions[4], CMenuAction::pathSimulatorModelsClearCache());
}
+ if (sims.isMSFS())
+ {
+ if (!m_clearCacheActions[5])
+ {
+ m_clearCacheActions[5] = new QAction(CIcons::appModels16(), "Clear MSFS cache", this);
+ connect(m_clearCacheActions[5], &QAction::triggered, ownModelsComp, [ownModelsComp](bool checked) {
+ if (!ownModelsComp) { return; }
+ Q_UNUSED(checked)
+ ownModelsComp->clearSimulatorCache(CSimulatorInfo::msfs());
+ });
+ }
+ menuActions.addAction(m_clearCacheActions[5], CMenuAction::pathSimulatorModelsClearCache());
+ }
if (sims.isXPlane() && CBuildConfig::isRunningOnWindowsNtPlatform() && CBuildConfig::buildWordSize() == 64)
{
diff --git a/src/gui/components/dbownmodelsetcomponent.cpp b/src/gui/components/dbownmodelsetcomponent.cpp
index 6c03959f1..2423aa0cd 100644
--- a/src/gui/components/dbownmodelsetcomponent.cpp
+++ b/src/gui/components/dbownmodelsetcomponent.cpp
@@ -590,6 +590,22 @@ namespace swift::gui::components
});
m_setNewActions.append(a);
}
+ if (sims.isMSFS())
+ {
+ QAction *a = new QAction(CIcons::appModels16(), "MSFS models", this);
+ connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](bool checked) {
+ Q_UNUSED(checked)
+ ownModelSetComp->setSimulator(CSimulatorInfo(CSimulatorInfo::MSFS));
+ });
+ m_setActions.append(a);
+
+ a = new QAction(CIcons::appModels16(), "New set MSFS models", this);
+ connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](bool checked) {
+ Q_UNUSED(checked)
+ ownModelSetComp->setModelSet(CAircraftModelList(), CSimulatorInfo(CSimulatorInfo::MSFS));
+ });
+ m_setNewActions.append(a);
+ }
QAction *a = new QAction(CIcons::appDistributors16(), "Apply distributor preferences", this);
connect(a, &QAction::triggered, ownModelSetComp, &CDbOwnModelSetComponent::distributorPreferencesChanged, Qt::QueuedConnection);
diff --git a/src/gui/components/distributorpreferencescomponent.cpp b/src/gui/components/distributorpreferencescomponent.cpp
index 59c74ecf3..599aafb70 100644
--- a/src/gui/components/distributorpreferencescomponent.cpp
+++ b/src/gui/components/distributorpreferencescomponent.cpp
@@ -121,6 +121,14 @@ namespace swift::gui::components
preferences.setDistributors(distributors, simulator);
const CStatusMessage m = m_distributorPreferences.setAndSave(preferences);
CLogMessage::preformatted(m);
+ if (m.isSuccess())
+ {
+ this->showOverlayHTMLMessage("Saved settings", 5000);
+ }
+ else
+ {
+ this->showOverlayMessage(m);
+ }
}
void CDistributorPreferencesComponent::onSimulatorChanged(const CSimulatorInfo &simulator)
diff --git a/src/gui/components/simulatorselector.cpp b/src/gui/components/simulatorselector.cpp
index 4297e9a02..109a2cefe 100644
--- a/src/gui/components/simulatorselector.cpp
+++ b/src/gui/components/simulatorselector.cpp
@@ -36,12 +36,14 @@ namespace swift::gui::components
connect(ui->rb_P3D, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
connect(ui->rb_FG, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
connect(ui->rb_XPlane, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
+ connect(ui->rb_MSFS, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
connect(ui->cb_FS9, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
connect(ui->cb_FSX, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
connect(ui->cb_P3D, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
connect(ui->cb_FG, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
connect(ui->cb_XPlane, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
+ connect(ui->cb_MSFS, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
connect(ui->cb_Simulators, &QComboBox::currentTextChanged, this, &CSimulatorSelector::comboBoxChanged);
}
@@ -75,8 +77,8 @@ namespace swift::gui::components
switch (m_mode)
{
default:
- case CheckBoxes: return CSimulatorInfo(ui->cb_FSX->isChecked(), ui->cb_FS9->isChecked(), ui->cb_XPlane->isChecked(), ui->cb_P3D->isChecked(), ui->cb_FG->isChecked());
- case RadioButtons: return CSimulatorInfo(ui->rb_FSX->isChecked(), ui->rb_FS9->isChecked(), ui->rb_XPlane->isChecked(), ui->rb_P3D->isChecked(), ui->rb_FG->isChecked());
+ case CheckBoxes: return CSimulatorInfo(ui->cb_FSX->isChecked(), ui->cb_FS9->isChecked(), ui->cb_XPlane->isChecked(), ui->cb_P3D->isChecked(), ui->cb_FG->isChecked(), ui->cb_MSFS->isChecked());
+ case RadioButtons: return CSimulatorInfo(ui->rb_FSX->isChecked(), ui->rb_FS9->isChecked(), ui->rb_XPlane->isChecked(), ui->rb_P3D->isChecked(), ui->rb_FG->isChecked(), ui->rb_MSFS->isChecked());
case ComboBox: return CSimulatorInfo(ui->cb_Simulators->currentText());
}
}
@@ -92,6 +94,7 @@ namespace swift::gui::components
ui->cb_XPlane->setChecked(simulator.isXPlane());
ui->cb_P3D->setChecked(simulator.isP3D());
ui->cb_FG->setChecked(simulator.isFG());
+ ui->cb_MSFS->setChecked(simulator.isMSFS());
// Combo
ui->cb_Simulators->setCurrentText(simulator.toQString(true));
@@ -122,6 +125,11 @@ namespace swift::gui::components
ui->rb_FG->setChecked(simulator.isFG());
return;
}
+ if (simulator.isMSFS())
+ {
+ ui->rb_MSFS->setChecked(simulator.isMSFS());
+ return;
+ }
}
void CSimulatorSelector::setToLastSelection()
@@ -202,6 +210,7 @@ namespace swift::gui::components
ui->cb_XPlane->setChecked(true);
ui->cb_P3D->setChecked(true);
ui->cb_FG->setChecked(true);
+ ui->cb_MSFS->setChecked(true);
// radio
ui->rb_P3D->setChecked(true);
@@ -215,6 +224,7 @@ namespace swift::gui::components
ui->cb_XPlane->setChecked(false);
ui->cb_P3D->setChecked(false);
ui->cb_FG->setChecked(false);
+ ui->cb_MSFS->setChecked(false);
}
bool CSimulatorSelector::isUnselected() const
@@ -224,10 +234,10 @@ namespace swift::gui::components
{
default:
case CheckBoxes:
- c = ui->cb_FSX->isChecked() || ui->cb_FS9->isChecked() || ui->cb_XPlane->isChecked() || ui->cb_P3D->isChecked() || ui->cb_FG->isChecked();
+ c = ui->cb_FSX->isChecked() || ui->cb_FS9->isChecked() || ui->cb_XPlane->isChecked() || ui->cb_P3D->isChecked() || ui->cb_FG->isChecked() || ui->cb_MSFS->isChecked();
break;
case RadioButtons:
- c = ui->rb_FSX->isChecked() || ui->rb_FS9->isChecked() || ui->rb_XPlane->isChecked() || ui->rb_P3D->isChecked() || ui->rb_FG->isChecked();
+ c = ui->rb_FSX->isChecked() || ui->rb_FS9->isChecked() || ui->rb_XPlane->isChecked() || ui->rb_P3D->isChecked() || ui->rb_FG->isChecked() || ui->rb_MSFS->isChecked();
break;
case ComboBox:
const int i = ui->cb_Simulators->currentIndex();
@@ -244,7 +254,7 @@ namespace swift::gui::components
{
default:
case CheckBoxes:
- c = ui->cb_FSX->isChecked() && ui->cb_FS9->isChecked() && ui->cb_XPlane->isChecked() && ui->cb_P3D->isChecked() && ui->cb_FG->isChecked();
+ c = ui->cb_FSX->isChecked() && ui->cb_FS9->isChecked() && ui->cb_XPlane->isChecked() && ui->cb_P3D->isChecked() && ui->cb_FG->isChecked() && ui->cb_MSFS->isChecked();
break;
case RadioButtons:
// actually this should never be true
@@ -296,6 +306,7 @@ namespace swift::gui::components
ui->rb_XPlane->setEnabled(!readOnly);
ui->rb_P3D->setEnabled(!readOnly);
ui->rb_FG->setEnabled(!readOnly);
+ ui->rb_MSFS->setEnabled(!readOnly);
ui->cb_Simulators->setEnabled(!readOnly);
@@ -385,5 +396,6 @@ namespace swift::gui::components
ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::p3d().toQString());
ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::xplane().toQString());
ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::fg().toQString());
+ ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::msfs().toQString());
}
} // ns
diff --git a/src/gui/components/simulatorselector.ui b/src/gui/components/simulatorselector.ui
index 8a026e05c..b309b86de 100644
--- a/src/gui/components/simulatorselector.ui
+++ b/src/gui/components/simulatorselector.ui
@@ -6,8 +6,8 @@
0
0
- 188
- 66
+ 271
+ 74
@@ -88,6 +88,13 @@
+ -
+
+
+ MSFS2020
+
+
+
@@ -159,6 +166,13 @@
+ -
+
+
+ MSFS2020
+
+
+
diff --git a/src/misc/simulation/aircraftmodel.cpp b/src/misc/simulation/aircraftmodel.cpp
index 76b6f8ff8..14c35e3b9 100644
--- a/src/misc/simulation/aircraftmodel.cpp
+++ b/src/misc/simulation/aircraftmodel.cpp
@@ -93,6 +93,8 @@ namespace swift::misc::simulation
obj.insert("simp3d", QJsonValue(flag));
flag = CDatastoreUtility::boolToDbYN(sim.isFS9());
obj.insert("simfs9", QJsonValue(flag));
+ flag = CDatastoreUtility::boolToDbYN(sim.isMSFS());
+ obj.insert("simmsfs", QJsonValue(flag));
flag = CDatastoreUtility::boolToDbYN(sim.isXPlane());
obj.insert("simxplane", QJsonValue(flag));
flag = CDatastoreUtility::boolToDbYN(sim.isFG());
diff --git a/src/misc/simulation/aircraftmodellist.h b/src/misc/simulation/aircraftmodellist.h
index 062139272..5f36e2f2c 100644
--- a/src/misc/simulation/aircraftmodellist.h
+++ b/src/misc/simulation/aircraftmodellist.h
@@ -256,10 +256,10 @@ namespace swift::misc
//! Find duplicate model strings and return those models with at least 1 duplicate model string
CAircraftModelList findDuplicateModelStrings() const;
- //! All models of the FS (FSX, P3D, FS9) family
+ //! All models of the FS (FSX, P3D, FS9, MSFS) family
CAircraftModelList findFsFamilyModels() const;
- //! All models NOT of the FS (FSX, P3D, FS9) family
+ //! All models NOT of the FS (FSX, P3D, FS9, MSFS) family
CAircraftModelList findNonFsFamilyModels() const;
//! @{
@@ -296,10 +296,10 @@ namespace swift::misc
//! Which simulators are supported in this model list
CSimulatorInfo simulatorsSupported() const;
- //! Is this here a FS family (P3D/FSX/FS9) model list?
+ //! Is this here a FS family (P3D/FSX/FS9/MSFS) model list?
bool isLikelyFsFamilyModelList() const;
- //! Is this here a FS family (P3D/FSX) model list?
+ //! Is this here a FSX family (P3D/FSX/MSFS) model list?
bool isLikelyFsxFamilyModelList() const;
//! Is this here a XPlane model list?
@@ -357,12 +357,12 @@ namespace swift::misc
//! \return number of elements removed
int removeByAircraftAndAirline(const aviation::CAircraftIcaoCode &aircraftIcao, const aviation::CAirlineIcaoCode &airline);
- //! Remove if NOT FS family model, ie. FSX/P3D/FS9
+ //! Remove if NOT FS family model, ie. FSX/P3D/FS9/MSFS
//! \return number of elements removed
int removeIfNotFsFamily();
//! Remove those models of a particular file, but not in the given set
- //! \remark mostly used for FSX/FS9/P3D consolidation
+ //! \remark mostly used for FSX/FS9/P3D/MSFS consolidation
CAircraftModelList removeIfFileButNotInSet(const QString &fileName, const QSet &modelStrings);
//! Replace or add based on model string
diff --git a/src/misc/simulation/aircraftmodelloaderprovider.cpp b/src/misc/simulation/aircraftmodelloaderprovider.cpp
index a44502cab..e135f46b2 100644
--- a/src/misc/simulation/aircraftmodelloaderprovider.cpp
+++ b/src/misc/simulation/aircraftmodelloaderprovider.cpp
@@ -62,6 +62,11 @@ namespace swift::misc::simulation
if (!m_loaderFG) { m_loaderFG = this->initLoader(CSimulatorInfo::fg()); }
return m_loaderFG;
}
+ case CSimulatorInfo::MSFS:
+ {
+ if (!m_loaderMsfs) { m_loaderMsfs = this->initLoader(CSimulatorInfo::msfs()); }
+ return m_loaderMsfs;
+ }
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong simulator");
break;
diff --git a/src/misc/simulation/aircraftmodelloaderprovider.h b/src/misc/simulation/aircraftmodelloaderprovider.h
index 758556d62..6bae8536b 100644
--- a/src/misc/simulation/aircraftmodelloaderprovider.h
+++ b/src/misc/simulation/aircraftmodelloaderprovider.h
@@ -34,6 +34,7 @@ namespace swift::misc::simulation
IAircraftModelLoader *modelLoaderXP() const { return m_loaderXP; }
IAircraftModelLoader *modelLoaderFS9() const { return m_loaderFS9; }
IAircraftModelLoader *modelLoaderFG() const { return m_loaderFG; }
+ IAircraftModelLoader *modelLoaderMsfs() const { return m_loaderMsfs; }
//! @}
signals:
@@ -55,6 +56,7 @@ namespace swift::misc::simulation
IAircraftModelLoader *m_loaderXP = nullptr;
IAircraftModelLoader *m_loaderFS9 = nullptr;
IAircraftModelLoader *m_loaderFG = nullptr;
+ IAircraftModelLoader *m_loaderMsfs = nullptr;
//! Init the loader
IAircraftModelLoader *initLoader(const CSimulatorInfo &simulator);
diff --git a/src/misc/simulation/aircraftmodelutils.cpp b/src/misc/simulation/aircraftmodelutils.cpp
index 8e4ab714a..d5f28d91d 100644
--- a/src/misc/simulation/aircraftmodelutils.cpp
+++ b/src/misc/simulation/aircraftmodelutils.cpp
@@ -179,6 +179,11 @@ namespace swift::misc::simulation
const CStatusMessageList specificTests2 = fscommon::CFsCommonUtil::validateFSXSimObjectsPath(models, validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, wasStopped, simulatorDir);
specificTests.push_back(specificTests2);
}
+ else if (simulator.isMSFS())
+ {
+ const CStatusMessageList specificTests2 = fscommon::CFsCommonUtil::validateMSFSSimObjectsPath(models, validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, wasStopped, simulatorDir);
+ specificTests.push_back(specificTests2);
+ }
}
else if (simulator.isXPlane() || models.isLikelyXPlaneModelList())
{
diff --git a/src/misc/simulation/autopublishdata.cpp b/src/misc/simulation/autopublishdata.cpp
index 0693fdd1e..eebf9bc6d 100644
--- a/src/misc/simulation/autopublishdata.cpp
+++ b/src/misc/simulation/autopublishdata.cpp
@@ -217,6 +217,7 @@ namespace swift::misc::simulation
this->insert("testModelString4", CSimulatorInfo::p3d());
this->insert("testModelString5", CSimulatorInfo::fsx());
this->insert("testModelString6", CSimulatorInfo::fsx());
+ this->insert("testModelString7", CSimulatorInfo::msfs());
}
const QString &CAutoPublishData::fileBaseName()
diff --git a/src/misc/simulation/data/modelcaches.cpp b/src/misc/simulation/data/modelcaches.cpp
index 73c2c6309..f258796cb 100644
--- a/src/misc/simulation/data/modelcaches.cpp
+++ b/src/misc/simulation/data/modelcaches.cpp
@@ -34,8 +34,11 @@ namespace swift::misc::simulation::data
QString IMultiSimulatorModelCaches::getInfoStringFsFamily() const
{
- static const QString is("FSX: %1 P3D: %2 FS9: %3");
- return is.arg(this->getCachedModelsCount(CSimulatorInfo::FSX)).arg(this->getCachedModelsCount(CSimulatorInfo::P3D)).arg(this->getCachedModelsCount(CSimulatorInfo::FS9));
+ static const QString is("FSX: %1, P3D: %2, FS9: %3, MSFS: %4");
+ return is.arg(this->getCachedModelsCount(CSimulatorInfo::FSX))
+ .arg(this->getCachedModelsCount(CSimulatorInfo::P3D))
+ .arg(this->getCachedModelsCount(CSimulatorInfo::FS9))
+ .arg(this->getCachedModelsCount(CSimulatorInfo::MSFS));
}
QString IMultiSimulatorModelCaches::getCacheCountAndTimestamp(const CSimulatorInfo &simulator) const
@@ -59,6 +62,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: m_syncP3D = synchronized; break;
case CSimulatorInfo::XPLANE: m_syncXPlane = synchronized; break;
case CSimulatorInfo::FG: m_syncFG = synchronized; break;
+ case CSimulatorInfo::MSFS: m_syncMsfs = synchronized; break;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator");
break;
@@ -89,6 +93,7 @@ namespace swift::misc::simulation::data
if (this->hasOtherVersionFile(info, CSimulatorInfo::fs9())) { sim.addSimulator(CSimulatorInfo::fs9()); }
if (this->hasOtherVersionFile(info, CSimulatorInfo::fg())) { sim.addSimulator(CSimulatorInfo::fg()); }
if (this->hasOtherVersionFile(info, CSimulatorInfo::xplane())) { sim.addSimulator(CSimulatorInfo::xplane()); }
+ if (this->hasOtherVersionFile(info, CSimulatorInfo::msfs())) { sim.addSimulator(CSimulatorInfo::msfs()); }
return sim;
}
@@ -101,6 +106,7 @@ namespace swift::misc::simulation::data
this->getFilename(CSimulatorInfo::P3D),
this->getFilename(CSimulatorInfo::XPLANE),
this->getFilename(CSimulatorInfo::FG),
+ this->getFilename(CSimulatorInfo::MSFS),
});
}
@@ -199,6 +205,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: return m_modelCacheP3D.get();
case CSimulatorInfo::XPLANE: return m_modelCacheXP.get();
case CSimulatorInfo::FG: return m_modelCacheFG.get();
+ case CSimulatorInfo::MSFS: return m_modelCacheMsfs.get();
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator");
return CAircraftModelList();
@@ -219,6 +226,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: msg = m_modelCacheP3D.set(setModels); break;
case CSimulatorInfo::XPLANE: msg = m_modelCacheXP.set(setModels); break;
case CSimulatorInfo::FG: msg = m_modelCacheFG.set(setModels); break;
+ case CSimulatorInfo::MSFS: msg = m_modelCacheMsfs.set(setModels); break;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator");
return CStatusMessage();
@@ -243,6 +251,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: return m_syncP3D;
case CSimulatorInfo::XPLANE: return m_syncXPlane;
case CSimulatorInfo::FG: return m_syncFG;
+ case CSimulatorInfo::MSFS: return m_syncMsfs;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator");
break;
@@ -276,6 +285,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: return m_modelCacheP3D.getAvailableTimestamp();
case CSimulatorInfo::XPLANE: return m_modelCacheXP.getAvailableTimestamp();
case CSimulatorInfo::FG: return m_modelCacheFG.getAvailableTimestamp();
+ case CSimulatorInfo::MSFS: return m_modelCacheMsfs.getAvailableTimestamp();
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator");
return QDateTime();
@@ -293,6 +303,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: return m_modelCacheP3D.set(m_modelCacheP3D.get(), ts.toMSecsSinceEpoch());
case CSimulatorInfo::XPLANE: return m_modelCacheXP.set(m_modelCacheXP.get(), ts.toMSecsSinceEpoch());
case CSimulatorInfo::FG: return m_modelCacheFG.set(m_modelCacheFG.get(), ts.toMSecsSinceEpoch());
+ case CSimulatorInfo::MSFS: return m_modelCacheMsfs.set(m_modelCacheMsfs.get(), ts.toMSecsSinceEpoch());
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong simulator");
break;
@@ -320,6 +331,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: return m_modelCacheP3D.getFilename();
case CSimulatorInfo::XPLANE: return m_modelCacheXP.getFilename();
case CSimulatorInfo::FG: return m_modelCacheFG.getFilename();
+ case CSimulatorInfo::MSFS: return m_modelCacheMsfs.getFilename();
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator");
break;
@@ -337,6 +349,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: return m_modelCacheP3D.isSaved();
case CSimulatorInfo::XPLANE: return m_modelCacheXP.isSaved();
case CSimulatorInfo::FG: return m_modelCacheFG.isSaved();
+ case CSimulatorInfo::MSFS: return m_modelCacheMsfs.isSaved();
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator");
break;
@@ -356,6 +369,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: m_modelCacheP3D.synchronize(); break;
case CSimulatorInfo::XPLANE: m_modelCacheXP.synchronize(); break;
case CSimulatorInfo::FG: m_modelCacheFG.synchronize(); break;
+ case CSimulatorInfo::MSFS: m_modelCacheMsfs.synchronize(); break;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator");
break;
@@ -376,6 +390,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: m_modelCacheP3D.admit(); break;
case CSimulatorInfo::XPLANE: m_modelCacheXP.admit(); break;
case CSimulatorInfo::FG: m_modelCacheFG.admit(); break;
+ case CSimulatorInfo::MSFS: m_modelCacheMsfs.admit(); break;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator");
break;
@@ -418,6 +433,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: return m_modelCacheP3D.get();
case CSimulatorInfo::XPLANE: return m_modelCacheXP.get();
case CSimulatorInfo::FG: return m_modelCacheFG.get();
+ case CSimulatorInfo::MSFS: return m_modelCacheMsfs.get();
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator");
return CAircraftModelList();
@@ -455,6 +471,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: msg = m_modelCacheP3D.set(orderedModels); break;
case CSimulatorInfo::XPLANE: msg = m_modelCacheXP.set(orderedModels); break;
case CSimulatorInfo::FG: msg = m_modelCacheFG.set(orderedModels); break;
+ case CSimulatorInfo::MSFS: msg = m_modelCacheMsfs.set(orderedModels); break;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong simulator");
return CStatusMessage();
@@ -473,6 +490,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: return m_modelCacheP3D.getAvailableTimestamp();
case CSimulatorInfo::XPLANE: return m_modelCacheXP.getAvailableTimestamp();
case CSimulatorInfo::FG: return m_modelCacheFG.getAvailableTimestamp();
+ case CSimulatorInfo::MSFS: return m_modelCacheMsfs.getAvailableTimestamp();
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong simulator");
return QDateTime();
@@ -490,6 +508,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: return m_modelCacheP3D.set(m_modelCacheP3D.get(), ts.toMSecsSinceEpoch());
case CSimulatorInfo::XPLANE: return m_modelCacheXP.set(m_modelCacheXP.get(), ts.toMSecsSinceEpoch());
case CSimulatorInfo::FG: return m_modelCacheFG.set(m_modelCacheFG.get(), ts.toMSecsSinceEpoch());
+ case CSimulatorInfo::MSFS: return m_modelCacheMsfs.set(m_modelCacheMsfs.get(), ts.toMSecsSinceEpoch());
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong simulator");
break;
@@ -517,6 +536,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: return m_modelCacheP3D.getFilename();
case CSimulatorInfo::XPLANE: return m_modelCacheXP.getFilename();
case CSimulatorInfo::FG: return m_modelCacheFG.getFilename();
+ case CSimulatorInfo::MSFS: return m_modelCacheMsfs.getFilename();
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong simulator");
break;
@@ -534,6 +554,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: return m_modelCacheP3D.isSaved();
case CSimulatorInfo::XPLANE: return m_modelCacheXP.isSaved();
case CSimulatorInfo::FG: return m_modelCacheFG.isSaved();
+ case CSimulatorInfo::MSFS: return m_modelCacheMsfs.isSaved();
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong simulator");
break;
@@ -553,6 +574,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: m_modelCacheP3D.synchronize(); break;
case CSimulatorInfo::XPLANE: m_modelCacheXP.synchronize(); break;
case CSimulatorInfo::FG: m_modelCacheFG.synchronize(); break;
+ case CSimulatorInfo::MSFS: m_modelCacheMsfs.synchronize(); break;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong simulator");
break;
@@ -573,6 +595,7 @@ namespace swift::misc::simulation::data
case CSimulatorInfo::P3D: m_modelCacheP3D.admit(); break;
case CSimulatorInfo::XPLANE: m_modelCacheXP.admit(); break;
case CSimulatorInfo::FG: m_modelCacheFG.admit(); break;
+ case CSimulatorInfo::MSFS: m_modelCacheMsfs.admit(); break;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong simulator");
break;
diff --git a/src/misc/simulation/data/modelcaches.h b/src/misc/simulation/data/modelcaches.h
index 61599f38b..4b1feee83 100644
--- a/src/misc/simulation/data/modelcaches.h
+++ b/src/misc/simulation/data/modelcaches.h
@@ -66,6 +66,13 @@ namespace swift::misc::simulation::data
static const char *key() { return "modelcachefg"; }
};
+ //! MSFS
+ struct TModelCacheMsfs : public TModelCache
+ {
+ //! Key in data cache
+ static const char *key() { return "modelcachemsfs"; }
+ };
+
//! Last selection
struct TModelCacheLastSelection : public TDataTrait
{
@@ -118,6 +125,13 @@ namespace swift::misc::simulation::data
static const char *key() { return "modelsetfg"; }
};
+ //! MSFS
+ struct TModelSetCacheMsfs : public TModelCache
+ {
+ //! Key in data cache
+ static const char *key() { return "modelsetmsfs"; }
+ };
+
//! Last selection
struct TSimulatorLastSelection : public TDataTrait
{
@@ -281,6 +295,7 @@ namespace swift::misc::simulation::data
void changedP3D() { this->emitCacheChanged(CSimulatorInfo::p3d()); }
void changedXP() { this->emitCacheChanged(CSimulatorInfo::xplane()); }
void changedFG() { this->emitCacheChanged(CSimulatorInfo::fg()); }
+ void changedMsfs() { this->emitCacheChanged(CSimulatorInfo::msfs()); }
//! @}
//! Is the cache already synchronized?
@@ -297,6 +312,7 @@ namespace swift::misc::simulation::data
std::atomic_bool m_syncFS9 { false };
std::atomic_bool m_syncFG { false };
std::atomic_bool m_syncXPlane { false };
+ std::atomic_bool m_syncMsfs { false };
//! @}
};
@@ -332,6 +348,7 @@ namespace swift::misc::simulation::data
CData m_modelCacheP3D { this, &CModelCaches::changedP3D }; //!< P3D cache
CData m_modelCacheXP { this, &CModelCaches::changedXP }; //!< XP cache
CData m_modelCacheFG { this, &CModelCaches::changedFG }; //!< XP cache
+ CData m_modelCacheMsfs { this, &CModelCaches::changedMsfs }; //!< MSFS cache
//! Non virtual version (can be used in ctor)
void synchronizeCacheImpl(const CSimulatorInfo &simulator);
@@ -373,6 +390,7 @@ namespace swift::misc::simulation::data
CData m_modelCacheP3D { this, &CModelSetCaches::changedP3D }; //!< P3D cache
CData m_modelCacheXP { this, &CModelSetCaches::changedXP }; //!< XP cache
CData m_modelCacheFG { this, &CModelSetCaches::changedFG }; //!< FG cache
+ CData m_modelCacheMsfs { this, &CModelSetCaches::changedMsfs }; //!< MSFS cache
//! Non virtual version (can be used in ctor)
void synchronizeCacheImpl(const CSimulatorInfo &simulator);
diff --git a/src/misc/simulation/distributor.cpp b/src/misc/simulation/distributor.cpp
index cf934e280..6f2609e2f 100644
--- a/src/misc/simulation/distributor.cpp
+++ b/src/misc/simulation/distributor.cpp
@@ -221,7 +221,7 @@ namespace swift::misc::simulation
const QSet &CDistributor::standardAllFsFamily()
{
- static const QSet fsFamily({ standardFS9(), standardFSX(), standardP3D() });
+ static const QSet fsFamily({ standardFS9(), standardFSX(), standardP3D(), standardMsfs() });
return fsFamily;
}
@@ -243,6 +243,12 @@ namespace swift::misc::simulation
return k;
}
+ const QString &CDistributor::standardMsfs()
+ {
+ static const QString k("MSFS");
+ return k;
+ }
+
QString CDistributor::unifyKeyOrAlias(const QString &value)
{
return removeChars(value.trimmed().toUpper(), [](QChar c) { return !c.isLetterOrNumber(); });
diff --git a/src/misc/simulation/distributor.h b/src/misc/simulation/distributor.h
index 7e2ae9a3b..667b27cf5 100644
--- a/src/misc/simulation/distributor.h
+++ b/src/misc/simulation/distributor.h
@@ -130,6 +130,7 @@ namespace swift::misc::simulation
static const QSet &xplaneMostPopular();
static const QString &xplaneBlueBell();
static const QString &xplaneXcsl();
+ static const QString &standardMsfs();
//! @}
private:
diff --git a/src/misc/simulation/distributorlistpreferences.cpp b/src/misc/simulation/distributorlistpreferences.cpp
index 2f49f2b35..eb252f5a1 100644
--- a/src/misc/simulation/distributorlistpreferences.cpp
+++ b/src/misc/simulation/distributorlistpreferences.cpp
@@ -21,6 +21,7 @@ namespace swift::misc::simulation
case CSimulatorInfo::FS9: return m_distributorsFs9;
case CSimulatorInfo::FG: return m_distributorsFG;
case CSimulatorInfo::XPLANE: return m_distributorsXPlane;
+ case CSimulatorInfo::MSFS: return m_distributorsMsfs;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong simulator");
break;
@@ -49,6 +50,7 @@ namespace swift::misc::simulation
case CSimulatorInfo::FS9: m_distributorsFs9 = d; break;
case CSimulatorInfo::FG: m_distributorsFG = d; break;
case CSimulatorInfo::XPLANE: m_distributorsXPlane = d; break;
+ case CSimulatorInfo::MSFS: m_distributorsMsfs = d; break;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong simulator");
break;
diff --git a/src/misc/simulation/distributorlistpreferences.h b/src/misc/simulation/distributorlistpreferences.h
index a9daeb4f8..4ffb74ad0 100644
--- a/src/misc/simulation/distributorlistpreferences.h
+++ b/src/misc/simulation/distributorlistpreferences.h
@@ -52,6 +52,7 @@ namespace swift::misc::simulation
CDistributorList m_distributorsFs9;
CDistributorList m_distributorsXPlane;
CDistributorList m_distributorsFG;
+ CDistributorList m_distributorsMsfs;
CSimulatorInfo m_lastUpdatedSimulator;
SWIFT_METACLASS(
@@ -61,6 +62,7 @@ namespace swift::misc::simulation
SWIFT_METAMEMBER(distributorsFs9),
SWIFT_METAMEMBER(distributorsXPlane),
SWIFT_METAMEMBER(distributorsFG),
+ SWIFT_METAMEMBER(distributorsMsfs),
SWIFT_METAMEMBER(lastUpdatedSimulator));
};
} // namespace
diff --git a/src/misc/simulation/fscommon/aircraftcfgparser.cpp b/src/misc/simulation/fscommon/aircraftcfgparser.cpp
index 39780ab26..46ec5edd1 100644
--- a/src/misc/simulation/fscommon/aircraftcfgparser.cpp
+++ b/src/misc/simulation/fscommon/aircraftcfgparser.cpp
@@ -149,7 +149,8 @@ namespace swift::misc::simulation::fscommon
// set directory with name filters, get aircraft.cfg and sub directories
static const QString NoNameFilter;
QDir dir(directory, NoNameFilter, QDir::Name, QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot);
- dir.setNameFilters(fileNameFilters());
+ // for MSFS we only need aircraft.cfg
+ dir.setNameFilters(fileNameFilters(getSimulator().isMSFS()));
if (!dir.exists())
{
return CAircraftCfgEntriesList(); // can happen if there are shortcuts or linked dirs not available
@@ -469,9 +470,9 @@ namespace swift::misc::simulation::fscommon
return content;
}
- const QStringList &CAircraftCfgParser::fileNameFilters()
+ const QStringList &CAircraftCfgParser::fileNameFilters(bool isMSFS)
{
- if (CBuildConfig::buildWordSize() == 32)
+ if (CBuildConfig::buildWordSize() == 32 || isMSFS)
{
static const QStringList f({ "aircraft.cfg" });
return f;
diff --git a/src/misc/simulation/fscommon/aircraftcfgparser.h b/src/misc/simulation/fscommon/aircraftcfgparser.h
index 1d5e4ee8f..676c896bf 100644
--- a/src/misc/simulation/fscommon/aircraftcfgparser.h
+++ b/src/misc/simulation/fscommon/aircraftcfgparser.h
@@ -89,7 +89,7 @@ namespace swift::misc
static QString getFixedIniLineContent(const QString &line);
//! Files to be used
- static const QStringList &fileNameFilters();
+ static const QStringList &fileNameFilters(bool isMSFS);
//! Exclude the sub directories not to be parsed
static bool isExcludedSubDirectory(const QString &excludeDirectory);
diff --git a/src/misc/simulation/fscommon/fscommon.h b/src/misc/simulation/fscommon/fscommon.h
index e0b7321a7..7b6c2b9ba 100644
--- a/src/misc/simulation/fscommon/fscommon.h
+++ b/src/misc/simulation/fscommon/fscommon.h
@@ -9,7 +9,7 @@
/*!
* \namespace FsCommon
- * \brief Utility classes for FSX, P3D and FS9, OS and driver independent code
+ * \brief Utility classes for FSX, P3D, MSFS and FS9, OS and driver independent code
*/
#endif // guard
diff --git a/src/misc/simulation/fscommon/fscommonutil.cpp b/src/misc/simulation/fscommon/fscommonutil.cpp
index 8e0a51eea..0ddd63949 100644
--- a/src/misc/simulation/fscommon/fscommonutil.cpp
+++ b/src/misc/simulation/fscommon/fscommonutil.cpp
@@ -182,6 +182,13 @@ namespace swift::misc::simulation::fscommon
return CFsCommonUtil::validateSimObjectsPath(QSet(simObjectPaths.begin(), simObjectPaths.end()), models, validModels, invalidModels, ignoreEmptyFileNames, stopAtFailedFiles, stopped);
}
+ CStatusMessageList CFsCommonUtil::validateMSFSSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &stopped, const QString &simulatorDir)
+ {
+ Q_UNUSED(simulatorDir)
+ const QStringList simObjectPaths = CFsDirectories::msfsSimObjectsDirPlusAddOnXmlSimObjectsPaths();
+ return CFsCommonUtil::validateSimObjectsPath(QSet(simObjectPaths.begin(), simObjectPaths.end()), models, validModels, invalidModels, ignoreEmptyFileNames, stopAtFailedFiles, stopped);
+ }
+
CStatusMessageList CFsCommonUtil::validateSimObjectsPath(
const QSet &simObjectDirs, const CAircraftModelList &models,
CAircraftModelList &validModels, CAircraftModelList &invalidModels,
diff --git a/src/misc/simulation/fscommon/fscommonutil.h b/src/misc/simulation/fscommon/fscommonutil.h
index 5801f5b07..a631d1acb 100644
--- a/src/misc/simulation/fscommon/fscommonutil.h
+++ b/src/misc/simulation/fscommon/fscommonutil.h
@@ -16,7 +16,7 @@
namespace swift::misc::simulation::fscommon
{
- //! FS9/FSX/P3D utils
+ //! FS9/FSX/P3D/MSFS utils
class SWIFT_MISC_EXPORT CFsCommonUtil
{
public:
@@ -36,7 +36,7 @@ namespace swift::misc::simulation::fscommon
static int copyFsxTerrainProbeFiles(const QString &simObjectDir, CStatusMessageList &messages);
//! Validate aircraft.cfg entries (sometimes also sim.cfg)
- //! \remark only for FSX/P3D/FS9 models
+ //! \remark only for FSX/P3D/FS9/MSFS models
static CStatusMessageList validateAircraftConfigFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &wasStopped);
//! Validate if known SimObjects path are used
@@ -47,6 +47,10 @@ namespace swift::misc::simulation::fscommon
//! \remark only for FSX
static CStatusMessageList validateFSXSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &wasStopped, const QString &simulatorDir);
+ //! Validate if known SimObjects path are used
+ //! \remark only for MSFS
+ static CStatusMessageList validateMSFSSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, std::atomic_bool &wasStopped, const QString &simulatorDir);
+
private:
//! Validate if known SimObjects path are used
//! \remark only for P3D/FSX
diff --git a/src/misc/simulation/fscommon/fsdirectories.cpp b/src/misc/simulation/fscommon/fsdirectories.cpp
index e8836a0e9..0ddb20575 100644
--- a/src/misc/simulation/fscommon/fsdirectories.cpp
+++ b/src/misc/simulation/fscommon/fsdirectories.cpp
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
using namespace swift::config;
@@ -88,6 +89,54 @@ namespace swift::misc::simulation::fscommon
return dir;
}
+ QString msfsDirImpl()
+ {
+ const QStringList locations = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
+ for (const QString &path : locations)
+ {
+ const QString msfsPackage = CFileUtils::appendFilePaths(CFileUtils::appendFilePaths(path, "Packages"), "Microsoft.FlightSimulator_8wekyb3d8bbwe");
+ const QDir d(msfsPackage);
+ if (!d.exists()) { continue; }
+ return msfsPackage;
+ }
+ return {};
+ }
+
+ const QString &CFsDirectories::msfsDir()
+ {
+ static const QString dir(msfsDirImpl());
+ return dir;
+ }
+
+ QString msfsPackagesDirImpl()
+ {
+ QString msfsDirectory(CFsDirectories::msfsDir());
+ const QString userCfg = CFileUtils::appendFilePaths(CFileUtils::appendFilePaths(msfsDirectory, "LocalCache"), "UserCfg.opt");
+ QFile file(userCfg);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return {}; }
+
+ QTextStream in(&file);
+ while (!in.atEnd())
+ {
+ QString line = in.readLine();
+ if (line.contains("InstalledPackagesPath"))
+ {
+ QStringList split = line.split(" ");
+ if (split.size() != 2) { return {}; }
+ QString packagePath = split[1].remove("\"");
+ const QDir dir(packagePath);
+ if (dir.exists()) { return packagePath; }
+ }
+ }
+ return {};
+ }
+
+ const QString &CFsDirectories::msfsPackagesDir()
+ {
+ static const QString dir(msfsPackagesDirImpl());
+ return dir;
+ }
+
QString fsxSimObjectsDirFromRegistryImpl()
{
const QString fsxPath = CFileUtils::normalizeFilePathToQtStandard(CFsDirectories::fsxDirFromRegistry());
@@ -108,18 +157,37 @@ namespace swift::misc::simulation::fscommon
return CFsDirectories::fsxSimObjectsDirFromSimDir(dir);
}
+ QString msfsSimObjectsDirImpl()
+ {
+ QString dir(CFsDirectories::msfsDir());
+ if (dir.isEmpty()) { return {}; }
+ return CFsDirectories::msfsSimObjectsDirFromSimDir(dir);
+ }
+
const QString &CFsDirectories::fsxSimObjectsDir()
{
static const QString dir(fsxSimObjectsDirImpl());
return dir;
}
+ const QString &CFsDirectories::msfsSimObjectsDir()
+ {
+ static const QString dir(msfsSimObjectsDirImpl());
+ return dir;
+ }
+
QString CFsDirectories::fsxSimObjectsDirFromSimDir(const QString &simDir)
{
if (simDir.isEmpty()) { return {}; }
return CFileUtils::appendFilePaths(CFileUtils::normalizeFilePathToQtStandard(simDir), "SimObjects");
}
+ QString CFsDirectories::msfsSimObjectsDirFromSimDir(const QString &simDir)
+ {
+ if (simDir.isEmpty()) { return {}; }
+ return CFileUtils::appendFilePaths(CFileUtils::normalizeFilePathToQtStandard(simDir), "SimObjects");
+ }
+
const QStringList &CFsDirectories::fsxSimObjectsExcludeDirectoryPatterns()
{
static const QStringList exclude {
@@ -131,6 +199,33 @@ namespace swift::misc::simulation::fscommon
return exclude;
}
+ const QStringList &CFsDirectories::msfs20SimObjectsExcludeDirectoryPatterns()
+ {
+ static const QStringList exclude {
+ "OneStore/asobo-discovery",
+ "OneStore/asobo-flight",
+ "OneStore/asobo-landingchallenge",
+ "OneStore/asobo-mission",
+ "OneStore/asobo-tutorials",
+ "OneStore/asobo-vcockpits",
+ "OneStore/asobo-simobjects",
+ "OneStore/asobo-services",
+ "OneStore/asobo-vcockpits",
+ "OneStore/asobo-l",
+ "OneStore/asobo-m",
+ "OneStore/asobo-vfx",
+ "OneStore/fs",
+ "OneStore/esd",
+ "OneStore/microsoft-airport",
+ "OneStore/microsoft-bushtrip",
+ "OneStore/microsoft-discovery",
+ "landingchallenge",
+ "tutorials",
+
+ };
+ return exclude;
+ }
+
QString p3dDirFromRegistryImpl()
{
QString p3dPath;
@@ -226,6 +321,23 @@ namespace swift::misc::simulation::fscommon
return allPaths;
}
+ QStringList CFsDirectories::msfsSimObjectsDirPlusAddOnXmlSimObjectsPaths(const QString &simObjectsDir)
+ {
+ // finding the user settings only works on P3D machine
+ QStringList allPaths = CFsDirectories::allMsfsSimObjectPaths().values();
+ const QString sod = CFileUtils::normalizeFilePathToQtStandard(simObjectsDir.isEmpty() ? CFsDirectories::msfsSimObjectsDir() : simObjectsDir);
+ if (!sod.isEmpty() && !allPaths.contains(sod, Qt::CaseInsensitive))
+ {
+ // case insensitive is important here
+ allPaths.push_front(sod);
+ }
+
+ allPaths.removeAll({}); // remove all empty
+ allPaths.removeDuplicates();
+ allPaths.sort(Qt::CaseInsensitive);
+ return allPaths;
+ }
+
QStringList CFsDirectories::p3dSimObjectsDirPlusAddOnXmlSimObjectsPaths(const QString &simObjectsDir, const QString &versionHint)
{
// finding the user settings only works on P3D machine
@@ -490,6 +602,11 @@ namespace swift::misc::simulation::fscommon
return CFsDirectories::fsxSimObjectsPaths(CFsDirectories::findFsxConfigFiles(), true);
}
+ QSet CFsDirectories::allMsfsSimObjectPaths()
+ {
+ return CFsDirectories::msfsSimObjectsPaths(CFsDirectories::findMsfsConfigFiles(), true);
+ }
+
QStringList CFsDirectories::findFsxConfigFiles()
{
const QStringList locations = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
@@ -507,6 +624,24 @@ namespace swift::misc::simulation::fscommon
return files;
}
+ QStringList CFsDirectories::findMsfsConfigFiles()
+ {
+ const QStringList locations = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
+ QStringList files;
+ for (const QString &path : locations)
+ {
+ // TODO this acts as a placeholder. the file msfs.cfg doesn't exist
+ const QString file = CFileUtils::appendFilePaths(CFileUtils::pathUp(path), "Microsoft/MSFS/msfs.cfg");
+ const QFileInfo fi(file);
+ if (fi.exists())
+ {
+ files.push_back(fi.absoluteFilePath());
+ if (logConfigPathReading()) { CLogMessage(static_cast(nullptr)).info(u"MSFS config file: '%1'") << fi.absoluteFilePath(); }
+ }
+ }
+ return files;
+ }
+
QSet CFsDirectories::fsxSimObjectsPaths(const QStringList &fsxFiles, bool checked)
{
QSet paths;
@@ -517,6 +652,16 @@ namespace swift::misc::simulation::fscommon
return paths;
}
+ QSet CFsDirectories::msfsSimObjectsPaths(const QStringList &msfsFiles, bool checked)
+ {
+ QSet paths;
+ for (const QString &msfsFile : msfsFiles)
+ {
+ paths.unite(CFsDirectories::msfsSimObjectsPaths(msfsFile, checked));
+ }
+ return paths;
+ }
+
QSet CFsDirectories::fsxSimObjectsPaths(const QString &fsxFile, bool checked)
{
const QString fileContent = CFileUtils::readFileToString(fsxFile);
@@ -565,6 +710,54 @@ namespace swift::misc::simulation::fscommon
return paths;
}
+ QSet CFsDirectories::msfsSimObjectsPaths(const QString &msfsFile, bool checked)
+ {
+ const QString fileContent = CFileUtils::readFileToString(msfsFile);
+ if (fileContent.isEmpty()) { return QSet(); }
+ const QList lines = splitLinesRefs(fileContent);
+ static const QString p("SimObjectPaths.");
+
+ const QFileInfo fsxFileInfo(msfsFile);
+ const QString relPath = fsxFileInfo.absolutePath();
+
+ QSet paths;
+ for (const QStringRef &line : lines)
+ {
+ const int i1 = line.lastIndexOf(p, -1, Qt::CaseInsensitive);
+ if (i1 < 0) { continue; }
+ const int i2 = line.lastIndexOf('=');
+ if (i2 < 0 || i1 >= i2 || line.endsWith('=')) { continue; }
+ const QStringRef path = line.mid(i2 + 1);
+ QString soPath = QDir::fromNativeSeparators(path.toString());
+ if (logConfigPathReading()) { CLogMessage(static_cast(nullptr)).info(u"MSFS SimObjects path checked: '%1' in '%2'") << line << msfsFile; }
+
+ // ignore exclude patterns
+ if (containsAny(soPath, CFsDirectories::fsxSimObjectsExcludeDirectoryPatterns(), Qt::CaseInsensitive)) { continue; }
+
+ // make absolute
+ if (!QStringView(soPath).left(3).contains(':')) { soPath = CFileUtils::appendFilePaths(relPath, soPath); }
+
+ const QDir dir(soPath); // always absolute path now
+ if (checked && !dir.exists())
+ {
+ // skip, not existing
+ if (logConfigPathReading()) { CLogMessage(static_cast(nullptr)).info(u"FSX SimObjects path skipped, not existing: '%1' in '%2'") << dir.absolutePath() << msfsFile; }
+ continue;
+ }
+
+ const QString afp = dir.absolutePath().toLower();
+ if (!CDirectoryUtils::containsFileInDir(afp, airFileFilter(), true))
+ {
+ if (logConfigPathReading()) { CLogMessage(static_cast(nullptr)).info(u"FSX SimObjects path: Skipping '%1' from '%2', no '%3' file") << afp << msfsFile << airFileFilter(); }
+ continue;
+ }
+
+ paths.insert(afp);
+ if (logConfigPathReading()) { CLogMessage(static_cast(nullptr)).info(u"FSX SimObjects path: '%1' from '%2'") << afp << msfsFile; }
+ }
+ return paths;
+ }
+
const QString &CFsDirectories::airFileFilter()
{
static const QString a("*.air");
diff --git a/src/misc/simulation/fscommon/fsdirectories.h b/src/misc/simulation/fscommon/fsdirectories.h
index 0602a62b3..4c9cda198 100644
--- a/src/misc/simulation/fscommon/fsdirectories.h
+++ b/src/misc/simulation/fscommon/fsdirectories.h
@@ -37,15 +37,27 @@ namespace swift::misc::simulation::fscommon
//! FSX's simobject dir, resolved from multiple sources
static const QString &fsxSimObjectsDir();
+ //! MSFS's simobject dir, resolved from multiple sources
+ static const QString &msfsSimObjectsDir();
+
//! FSX aircraft dir, relative to simulator directory
static QString fsxSimObjectsDirFromSimDir(const QString &simDir);
+ //! MSFS aircraft dir, relative to simulator directory
+ static QString msfsSimObjectsDirFromSimDir(const QString &simDir);
+
//! Exclude directories for simObjects
static const QStringList &fsxSimObjectsExcludeDirectoryPatterns();
+ //! Exclude directories for simObjects
+ static const QStringList &msfs20SimObjectsExcludeDirectoryPatterns();
+
//! FSX's simObject dir and the add on dirs
static QStringList fsxSimObjectsDirPlusAddOnXmlSimObjectsPaths(const QString &simObjectsDir = "");
+ //! MSFS's simObject dir and the add on dirs
+ static QStringList msfsSimObjectsDirPlusAddOnXmlSimObjectsPaths(const QString &simObjectsDir = "");
+
//! P3D's simObject dir and the add on dirs
static QStringList p3dSimObjectsDirPlusAddOnXmlSimObjectsPaths(const QString &simObjectsDir, const QString &versionHint);
@@ -70,6 +82,12 @@ namespace swift::misc::simulation::fscommon
//! Exclude directories for simObjects
static const QStringList &p3dSimObjectsExcludeDirectoryPatterns();
+ //! MSFS directory from different sources
+ static const QString &msfsDir();
+
+ //! MSFS's packages dir
+ static const QString &msfsPackagesDir();
+
//! FS9 directory obtained from registry
static const QString &fs9DirFromRegistry();
@@ -110,18 +128,33 @@ namespace swift::misc::simulation::fscommon
//! Get all the SimObjects paths from all config files
static QSet allFsxSimObjectPaths();
+ //! Get all the SimObjects paths from all config files
+ static QSet allMsfsSimObjectPaths();
+
//! Find the config files (fsx.cfg)
// C:/Users/Joe Doe/AppData/Roaming/Microsoft/FSX/fsx.cfg
static QStringList findFsxConfigFiles();
+ //! Find the config files (fsx.cfg)
+ // C:/Users/Joe Doe/AppData/Roaming/Microsoft/FSX/fsx.cfg
+ static QStringList findMsfsConfigFiles();
+
//! Get all the SimObjects paths from fsx.cfg
// SimObjectPaths.0=SimObjects\Airplanes
static QSet fsxSimObjectsPaths(const QStringList &fsxFiles, bool checked);
+ //! Get all the SimObjects paths from msfs.cfg
+ // SimObjectPaths.0=SimObjects\Airplanes
+ static QSet msfsSimObjectsPaths(const QStringList &msfsFiles, bool checked);
+
//! Get all the SimObjects files from fsx.cfg
// SimObjectPaths.0=SimObjects\Airplanes
static QSet fsxSimObjectsPaths(const QString &fsxFile, bool checked);
+ //! Get all the SimObjects files from fsx.cfg
+ // SimObjectPaths.0=SimObjects\Airplanes
+ static QSet msfsSimObjectsPaths(const QString &msfsFile, bool checked);
+
//! .air file filter
static const QString &airFileFilter();
diff --git a/src/misc/simulation/settings/simulatorsettings.cpp b/src/misc/simulation/settings/simulatorsettings.cpp
index 3ee28900e..889be3abd 100644
--- a/src/misc/simulation/settings/simulatorsettings.cpp
+++ b/src/misc/simulation/settings/simulatorsettings.cpp
@@ -207,6 +207,7 @@ namespace swift::misc::simulation::settings
case CSimulatorInfo::FS9: return m_simSettingsFs9.get();
case CSimulatorInfo::FSX: return m_simSettingsFsx.get();
case CSimulatorInfo::P3D: return m_simSettingsP3D.get();
+ case CSimulatorInfo::MSFS: return m_simSettingsMsfs.get();
case CSimulatorInfo::XPLANE: return m_simSettingsXP.get();
default:
@@ -230,6 +231,7 @@ namespace swift::misc::simulation::settings
case CSimulatorInfo::FS9: return m_simSettingsFs9.set(settings);
case CSimulatorInfo::FSX: return m_simSettingsFsx.set(settings);
case CSimulatorInfo::P3D: return m_simSettingsP3D.set(settings);
+ case CSimulatorInfo::MSFS: return m_simSettingsMsfs.set(settings);
case CSimulatorInfo::XPLANE: return m_simSettingsXP.set(settings);
default:
Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
@@ -265,6 +267,7 @@ namespace swift::misc::simulation::settings
case CSimulatorInfo::FS9: break;
case CSimulatorInfo::FSX: break;
case CSimulatorInfo::P3D: break;
+ case CSimulatorInfo::MSFS: break;
case CSimulatorInfo::XPLANE:
{
if (settings.hasModelDirectories())
@@ -290,6 +293,7 @@ namespace swift::misc::simulation::settings
case CSimulatorInfo::FS9: return m_simSettingsFs9.setAndSave(settings);
case CSimulatorInfo::FSX: return m_simSettingsFsx.setAndSave(settings);
case CSimulatorInfo::P3D: return m_simSettingsP3D.setAndSave(settings);
+ case CSimulatorInfo::MSFS: return m_simSettingsMsfs.setAndSave(settings);
case CSimulatorInfo::XPLANE: return m_simSettingsXP.setAndSave(settings);
default:
Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
@@ -312,6 +316,7 @@ namespace swift::misc::simulation::settings
case CSimulatorInfo::FS9: return m_simSettingsFs9.save();
case CSimulatorInfo::FSX: return m_simSettingsFsx.save();
case CSimulatorInfo::P3D: return m_simSettingsP3D.save();
+ case CSimulatorInfo::MSFS: return m_simSettingsMsfs.save();
case CSimulatorInfo::XPLANE: return m_simSettingsXP.save();
default:
Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
@@ -389,6 +394,11 @@ namespace swift::misc::simulation::settings
this->emitSettingsChanged(CSimulatorInfo::fs9());
}
+ void CMultiSimulatorSettings::onMsfsSettingsChanged()
+ {
+ this->emitSettingsChanged(CSimulatorInfo::msfs());
+ }
+
void CMultiSimulatorSettings::onXPSettingsChanged()
{
this->emitSettingsChanged(CSimulatorInfo::xplane());
@@ -690,6 +700,13 @@ namespace swift::misc::simulation::settings
static const QStringList md = CFsDirectories::p3dSimObjectsDirPlusAddOnXmlSimObjectsPaths(p3d, versionHint);
return md;
}
+ case CSimulatorInfo::MSFS:
+ {
+ static const QString msfs = CFsDirectories::msfsPackagesDir();
+ if (msfs.isEmpty()) { return e; }
+ static const QStringList md { msfs };
+ return md;
+ }
case CSimulatorInfo::XPLANE:
{
return CXPlaneUtil::xplaneModelDirectories();
@@ -711,6 +728,7 @@ namespace swift::misc::simulation::settings
case CSimulatorInfo::FS9: return CFsDirectories::fs9Dir();
case CSimulatorInfo::FSX: return CFsDirectories::fsxDir();
case CSimulatorInfo::P3D: return CFsDirectories::p3dDir();
+ case CSimulatorInfo::MSFS: return CFsDirectories::msfsDir();
case CSimulatorInfo::XPLANE: return CXPlaneUtil::xplaneRootDir();
default:
Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
@@ -730,6 +748,7 @@ namespace swift::misc::simulation::settings
case CSimulatorInfo::FSX: return CFsDirectories::fsxSimObjectsExcludeDirectoryPatterns();
case CSimulatorInfo::P3D: return CFsDirectories::p3dSimObjectsExcludeDirectoryPatterns();
case CSimulatorInfo::XPLANE: return CXPlaneUtil::xplaneModelExcludeDirectoryPatterns();
+ case CSimulatorInfo::MSFS: return CFsDirectories::msfs20SimObjectsExcludeDirectoryPatterns();
default:
Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
break;
diff --git a/src/misc/simulation/settings/simulatorsettings.h b/src/misc/simulation/settings/simulatorsettings.h
index f26a9f67f..63200f51b 100644
--- a/src/misc/simulation/settings/simulatorsettings.h
+++ b/src/misc/simulation/settings/simulatorsettings.h
@@ -331,6 +331,20 @@ namespace swift::misc::simulation::settings
}
};
+ //! Trait for simulator settings
+ struct TSimulatorMsfs : public TSettingTrait
+ {
+ //! \copydoc swift::misc::TSettingTrait::key
+ static const char *key() { return "settingssimulatormsfs"; }
+
+ //! \copydoc swift::misc::TSettingTrait::humanReadable
+ static const QString &humanReadable()
+ {
+ static const QString name("MSFS settings");
+ return name;
+ }
+ };
+
//! Selected P3D version (64bit)
struct TP3DVersion : public TSettingTrait
{
@@ -515,6 +529,7 @@ namespace swift::misc::simulation::settings
CSetting m_simSettingsFsx { this, &CMultiSimulatorSettings::onFsxSettingsChanged }; //!< FSX settings
CSetting m_simSettingsFs9 { this, &CMultiSimulatorSettings::onFs9SettingsChanged }; //!< FS9 settings
CSetting m_simSettingsP3D { this, &CMultiSimulatorSettings::onP3DSettingsChanged }; //!< P3D settings
+ CSetting m_simSettingsMsfs { this, &CMultiSimulatorSettings::onMsfsSettingsChanged }; //!< MSFS settings
CSetting m_simSettingsXP { this, &CMultiSimulatorSettings::onXPSettingsChanged }; //!< XP settings
CSetting m_simSettingsFG { this, &CMultiSimulatorSettings::onFGSettingsChanged }; //!< FG settings
@@ -523,6 +538,7 @@ namespace swift::misc::simulation::settings
void onFsxSettingsChanged();
void onFs9SettingsChanged();
void onP3DSettingsChanged();
+ void onMsfsSettingsChanged();
void onXPSettingsChanged();
void onFGSettingsChanged();
//! @}
diff --git a/src/misc/simulation/simulatorinfo.cpp b/src/misc/simulation/simulatorinfo.cpp
index b9f5cd1e0..efbda1971 100644
--- a/src/misc/simulation/simulatorinfo.cpp
+++ b/src/misc/simulation/simulatorinfo.cpp
@@ -40,7 +40,7 @@ namespace swift::misc::simulation
CSimulatorInfo::CSimulatorInfo(Simulator simulator) : m_simulator(static_cast(simulator))
{}
- CSimulatorInfo::CSimulatorInfo(bool fsx, bool fs9, bool xp, bool p3d, bool fg) : m_simulator(boolToFlag(fsx, fs9, xp, p3d, fg))
+ CSimulatorInfo::CSimulatorInfo(bool fsx, bool fs9, bool xp, bool p3d, bool fg, bool msfs) : m_simulator(boolToFlag(fsx, fs9, xp, p3d, fg, msfs))
{}
CSimulatorInfo::CSimulatorInfo(int flagsAsInt) : m_simulator(flagsAsInt)
@@ -83,7 +83,7 @@ namespace swift::misc::simulation
bool CSimulatorInfo::isAnySimulator() const
{
- return isFSX() || isFS9() || isXPlane() || isP3D() || isFG();
+ return isFSX() || isFS9() || isXPlane() || isP3D() || isFG() || isMSFS();
}
bool CSimulatorInfo::isSingleSimulator() const
@@ -103,12 +103,12 @@ namespace swift::misc::simulation
bool CSimulatorInfo::isAllSimulators() const
{
- return isFSX() && isFS9() && isXPlane() && isP3D() && isFG();
+ return isFSX() && isFS9() && isXPlane() && isP3D() && isFG() && isMSFS();
}
bool CSimulatorInfo::isMicrosoftSimulator() const
{
- return isFSX() || isFS9();
+ return isFSX() || isFS9() || isMSFS();
}
bool CSimulatorInfo::isMicrosoftOrPrepare3DSimulator() const
@@ -118,7 +118,7 @@ namespace swift::misc::simulation
bool CSimulatorInfo::isFsxP3DFamily() const
{
- return isFSX() || isP3D();
+ return isFSX() || isP3D() || isMSFS();
}
int CSimulatorInfo::numberSimulators() const
@@ -128,6 +128,7 @@ namespace swift::misc::simulation
if (isXPlane()) { c++; }
if (isP3D()) { c++; }
if (isFG()) { c++; }
+ if (isMSFS()) { c++; }
return c;
}
@@ -162,7 +163,8 @@ namespace swift::misc::simulation
(s.testFlag(FS9) ? QStringLiteral("FS9 ") : QString()) %
(s.testFlag(P3D) ? QStringLiteral("P3D ") : QString()) %
(s.testFlag(XPLANE) ? QStringLiteral("XPlane ") : QString()) %
- (s.testFlag(FG) ? QStringLiteral("FG ") : QString());
+ (s.testFlag(FG) ? QStringLiteral("FG ") : QString()) %
+ (s.testFlag(MSFS) ? QStringLiteral("MSFS ") : QString());
return str.trimmed();
}
@@ -190,6 +192,7 @@ namespace swift::misc::simulation
if (m_simulator & P3D) { set.insert(CSimulatorInfo(P3D)); }
if (m_simulator & FG) { set.insert(CSimulatorInfo(FG)); }
if (m_simulator & XPLANE) { set.insert(CSimulatorInfo(XPLANE)); }
+ if (m_simulator & MSFS) { set.insert(CSimulatorInfo(MSFS)); }
return set;
}
@@ -208,13 +211,14 @@ namespace swift::misc::simulation
return m.info(u"Simulators OK for model");
}
- CSimulatorInfo::Simulator CSimulatorInfo::boolToFlag(bool fsx, bool fs9, bool xp, bool p3d, bool fg)
+ CSimulatorInfo::Simulator CSimulatorInfo::boolToFlag(bool fsx, bool fs9, bool xp, bool p3d, bool fg, bool msfs)
{
Simulator s = fsx ? FSX : None;
if (fs9) { s |= FS9; }
if (xp) { s |= XPLANE; }
if (p3d) { s |= P3D; }
if (fg) { s |= FG; }
+ if (msfs) { s |= MSFS; }
return s;
}
@@ -275,6 +279,7 @@ namespace swift::misc::simulation
bool fsx = false;
bool p3d = false;
bool fg = false;
+ bool msfs = false;
if (CBuildConfig::isRunningOnWindowsNtPlatform())
{
@@ -287,11 +292,14 @@ namespace swift::misc::simulation
p3d =
!CFsDirectories::p3dDir().isEmpty() &&
!CFsDirectories::p3dSimObjectsDir().isEmpty();
+ msfs =
+ !CFsDirectories::msfsDir().isEmpty() &&
+ !CFsDirectories::msfsPackagesDir().isEmpty();
}
const bool xp = !CXPlaneUtil::xplaneRootDir().isEmpty();
- sim.setSimulator(CSimulatorInfo::boolToFlag(fsx, fs9, xp, p3d, fg));
+ sim.setSimulator(CSimulatorInfo::boolToFlag(fsx, fs9, xp, p3d, fg, msfs));
return sim;
}
@@ -325,6 +333,7 @@ namespace swift::misc::simulation
const QJsonValue jxp = json.value(prefix % u"simxplane");
const QJsonValue jp3d = json.value(prefix % u"simp3d");
const QJsonValue jfg = json.value(prefix % u"simfg");
+ const QJsonValue jmsfs = json.value(prefix % u"simmsfs");
// we handle bool JSON values and bool as string
const bool fsx = jfsx.isBool() ? jfsx.toBool() : CDatastoreUtility::dbBoolStringToBool(jfsx.toString());
@@ -332,8 +341,9 @@ namespace swift::misc::simulation
const bool xp = jxp.isBool() ? jxp.toBool() : CDatastoreUtility::dbBoolStringToBool(jxp.toString());
const bool p3d = jp3d.isBool() ? jp3d.toBool() : CDatastoreUtility::dbBoolStringToBool(jp3d.toString());
const bool fg = jfg.isBool() ? jfg.toBool() : CDatastoreUtility::dbBoolStringToBool(jfg.toString());
+ const bool msfs = jmsfs.isBool() ? jmsfs.toBool() : CDatastoreUtility::dbBoolStringToBool(jmsfs.toString());
- const CSimulatorInfo simInfo(fsx, fs9, xp, p3d, fg);
+ const CSimulatorInfo simInfo(fsx, fs9, xp, p3d, fg, msfs);
return simInfo;
}
@@ -358,12 +368,12 @@ namespace swift::misc::simulation
int CCountPerSimulator::getCountForFsFamilySimulators() const
{
- return this->getCount(CSimulatorInfo::fsx()) + this->getCount(CSimulatorInfo::p3d()) + this->getCount(CSimulatorInfo::fs9());
+ return this->getCount(CSimulatorInfo::fsx()) + this->getCount(CSimulatorInfo::p3d()) + this->getCount(CSimulatorInfo::fs9()) + this->getCount(CSimulatorInfo::msfs());
}
int CCountPerSimulator::getCountForFsxFamilySimulators() const
{
- return this->getCount(CSimulatorInfo::fsx()) + this->getCount(CSimulatorInfo::p3d());
+ return this->getCount(CSimulatorInfo::fsx()) + this->getCount(CSimulatorInfo::p3d()) + this->getCount(CSimulatorInfo::msfs());
}
int CCountPerSimulator::getMaximum() const
@@ -402,7 +412,8 @@ namespace swift::misc::simulation
u" P3D: " % QString::number(m_counts[1]) %
u" FS9: " % QString::number(m_counts[2]) %
u" XPlane: " % QString::number(m_counts[3]) %
- u" FG: " % QString::number(m_counts[4]);
+ u" FG: " % QString::number(m_counts[4]) %
+ u" MSFS: " % QString::number(m_counts[5]);
}
void CCountPerSimulator::setCount(int count, const CSimulatorInfo &simulator)
@@ -415,7 +426,7 @@ namespace swift::misc::simulation
if (simulator.isNoSimulator() || simulator.isUnspecified())
{
// unknown count
- m_counts[5]++;
+ m_counts[6]++;
return;
}
if (simulator.isFSX()) { m_counts[0]++; }
@@ -423,6 +434,7 @@ namespace swift::misc::simulation
if (simulator.isFS9()) { m_counts[2]++; }
if (simulator.isXPlane()) { m_counts[3]++; }
if (simulator.isFG()) { m_counts[4]++; }
+ if (simulator.isMSFS()) { m_counts[5]++; }
}
int CCountPerSimulator::internalIndex(const CSimulatorInfo &simulator)
@@ -435,6 +447,7 @@ namespace swift::misc::simulation
case CSimulatorInfo::FS9: return 2;
case CSimulatorInfo::XPLANE: return 3;
case CSimulatorInfo::FG: return 4;
+ case CSimulatorInfo::MSFS: return 5;
default: return CSimulatorInfo::NumberOfSimulators; // unknown
}
}
@@ -448,6 +461,7 @@ namespace swift::misc::simulation
case 2: return CSimulatorInfo(CSimulatorInfo::FS9);
case 3: return CSimulatorInfo(CSimulatorInfo::XPLANE);
case 4: return CSimulatorInfo(CSimulatorInfo::FG);
+ case 5: return CSimulatorInfo(CSimulatorInfo::MSFS);
default: return CSimulatorInfo(CSimulatorInfo::None);
}
}
diff --git a/src/misc/simulation/simulatorinfo.h b/src/misc/simulation/simulatorinfo.h
index 173ba883b..636168d06 100644
--- a/src/misc/simulation/simulatorinfo.h
+++ b/src/misc/simulation/simulatorinfo.h
@@ -57,7 +57,7 @@ namespace swift::misc::simulation
Q_DECLARE_FLAGS(Simulator, SimulatorFlag)
//! Number of known individual simulators
- static constexpr int NumberOfSimulators = 5;
+ static constexpr int NumberOfSimulators = 6;
//! Default constructor
CSimulatorInfo();
@@ -75,7 +75,7 @@ namespace swift::misc::simulation
CSimulatorInfo(int flagsAsInt);
//! Constructor
- CSimulatorInfo(bool isFSX, bool isFS9, bool xp, bool isP3D, bool fg);
+ CSimulatorInfo(bool isFSX, bool isFS9, bool xp, bool isP3D, bool fg, bool msfs);
//! Unspecified simulator
bool isUnspecified() const;
@@ -172,7 +172,7 @@ namespace swift::misc::simulation
CStatusMessage validateSimulatorsForModel() const;
//! Bool flags to enum
- static Simulator boolToFlag(bool isFSX, bool isFS9, bool xp, bool isP3D, bool fg);
+ static Simulator boolToFlag(bool isFSX, bool isFS9, bool xp, bool isP3D, bool fg, bool msfs);
//! Identifer, as provided by plugin
static Simulator identifierToSimulator(const QString &identifier);
@@ -225,6 +225,11 @@ namespace swift::misc::simulation
static const CSimulatorInfo s(XPLANE);
return s;
}
+ static const CSimulatorInfo &msfs()
+ {
+ static const CSimulatorInfo s(MSFS);
+ return s;
+ }
//! @}
private:
@@ -248,10 +253,10 @@ namespace swift::misc::simulation
//! Unknown count
int getCountForUnknownSimulators() const;
- //! P3D, FSX, or FS9
+ //! P3D, FSX, MSFS or FS9
int getCountForFsFamilySimulators() const;
- //! P3D or FSX
+ //! P3D, MSFS or FSX
int getCountForFsxFamilySimulators() const;
//! Set count
diff --git a/src/misc/simulation/simulatorinfolist.cpp b/src/misc/simulation/simulatorinfolist.cpp
index ff780eb84..382254a97 100644
--- a/src/misc/simulation/simulatorinfolist.cpp
+++ b/src/misc/simulation/simulatorinfolist.cpp
@@ -55,6 +55,7 @@ namespace swift::misc::simulation
if (sim.isFS9()) { sims.push_back(CSimulatorInfo(CSimulatorInfo::FS9)); }
if (sim.isFSX()) { sims.push_back(CSimulatorInfo(CSimulatorInfo::FSX)); }
if (sim.isP3D()) { sims.push_back(CSimulatorInfo(CSimulatorInfo::P3D)); }
+ if (sim.isMSFS()) { sims.push_back(CSimulatorInfo(CSimulatorInfo::MSFS)); }
if (sim.isXPlane()) { sims.push_back(CSimulatorInfo(CSimulatorInfo::XPLANE)); }
return sims;
}
diff --git a/src/misc/simulation/simulatorplugininfo.cpp b/src/misc/simulation/simulatorplugininfo.cpp
index 1f3352160..b7303da13 100644
--- a/src/misc/simulation/simulatorplugininfo.cpp
+++ b/src/misc/simulation/simulatorplugininfo.cpp
@@ -71,6 +71,7 @@ namespace swift::misc::simulation
if (s.testFlag(CSimulatorInfo::P3D)) { return CSimulatorPluginInfo::p3dPluginIdentifier(); }
if (s.testFlag(CSimulatorInfo::XPLANE)) { return CSimulatorPluginInfo::xplanePluginIdentifier(); }
if (s.testFlag(CSimulatorInfo::FG)) { return CSimulatorPluginInfo::fgPluginIdentifier(); }
+ if (s.testFlag(CSimulatorInfo::MSFS)) { return CSimulatorPluginInfo::msfsPluginIdentifier(); }
return e;
}
diff --git a/src/plugins/simulator/CMakeLists.txt b/src/plugins/simulator/CMakeLists.txt
index eac6f8718..fc35574aa 100644
--- a/src/plugins/simulator/CMakeLists.txt
+++ b/src/plugins/simulator/CMakeLists.txt
@@ -26,7 +26,7 @@ if(SWIFT_BUILD_FSX_PLUGIN OR SWIFT_BUILD_P3D_PLUGIN OR SWIFT_BUILD_MSFS_PLUGIN)
add_subdirectory(fsxcommon)
endif()
-if(SWIFT_WIN32 AND (SWIFT_BUILD_FS9_PLUGIN OR SWIFT_BUILD_FSX_PLUGIN OR SWIFT_BUILD_P3D_PLUGIN OR SWIFT_BUILD_MSFS_PLUGIN))
+if(SWIFT_WIN32 AND (SWIFT_BUILD_FS9_PLUGIN OR SWIFT_BUILD_FSX_PLUGIN OR SWIFT_BUILD_P3D_PLUGIN))
add_subdirectory(fsuipc32)
endif()
@@ -45,6 +45,7 @@ endif()
if(SWIFT_BUILD_MSFS_PLUGIN)
add_subdirectory(msfs)
+ add_subdirectory(msfsconfig)
endif()
if(SWIFT_BUILD_FSX_PLUGIN)
diff --git a/src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp b/src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp
index ecd5db14a..47331725c 100644
--- a/src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp
+++ b/src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp
@@ -13,6 +13,7 @@
using namespace swift::misc;
using namespace swift::misc::aviation;
+using namespace swift::misc::simulation;
using namespace swift::simplugin::fscommon;
namespace swift::simplugin::fsxcommon
@@ -69,7 +70,7 @@ namespace swift::simplugin::fsxcommon
CSimConnectDefinitions::CSimConnectDefinitions() {}
- HRESULT CSimConnectDefinitions::initDataDefinitionsWhenConnected(const HANDLE hSimConnect)
+ HRESULT CSimConnectDefinitions::initDataDefinitionsWhenConnected(const HANDLE hSimConnect, const CSimulatorInfo &simInfo)
{
HRESULT hr = s_ok();
hr += initOwnAircraft(hSimConnect);
@@ -78,6 +79,10 @@ namespace swift::simplugin::fsxcommon
hr += initRemoteAircraftSimDataSet(hSimConnect);
hr += initSimulatorEnvironment(hSimConnect);
hr += initSbDataArea(hSimConnect);
+ if (simInfo.isMSFS())
+ {
+ hr += initMSFSTransponder(hSimConnect);
+ }
return hr;
}
@@ -289,6 +294,18 @@ namespace swift::simplugin::fsxcommon
return hr;
}
+ HRESULT CSimConnectDefinitions::initMSFSTransponder(const HANDLE hSimConnect)
+ {
+ HRESULT hr = s_ok();
+ hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataTransponderModeMSFS, "TRANSPONDER STATE:1", "Enum");
+ hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataTransponderModeMSFS, "TRANSPONDER IDENT:1", "Bool");
+ if (isFailure(hr))
+ {
+ CLogMessage(static_cast(nullptr)).error(u"SimConnect error: MSFS transponder data definitions %1") << hr;
+ }
+ return hr;
+ }
+
DataDefinitionRemoteAircraftPartsWithoutLights::DataDefinitionRemoteAircraftPartsWithoutLights()
{
this->resetToInvalid();
diff --git a/src/plugins/simulator/fsxcommon/simconnectdatadefinition.h b/src/plugins/simulator/fsxcommon/simconnectdatadefinition.h
index 3c090d777..25ba99f8f 100644
--- a/src/plugins/simulator/fsxcommon/simconnectdatadefinition.h
+++ b/src/plugins/simulator/fsxcommon/simconnectdatadefinition.h
@@ -9,6 +9,7 @@
#include "plugins/simulator/fsxcommon/fsxcommonexport.h"
#include "plugins/simulator/fsxcommon/simconnectwindows.h"
#include "misc/aviation/aircraftlights.h"
+#include "misc/simulation/simulatorinfo.h"
#include
#include
@@ -255,6 +256,13 @@ namespace swift::simplugin::fsxcommon
QString toQString() const;
};
+ //! Data structure for MSFS transponder mode information
+ struct DataDefinitionMSFSTransponderMode
+ {
+ double transponderMode = 1; //!< transponder state simvar
+ double ident = 0; //!< ident
+ };
+
//! Client areas
enum ClientAreaId
{
@@ -277,6 +285,7 @@ namespace swift::simplugin::fsxcommon
DataRemoteAircraftModelData, //!< model data eventually used and reported back from simulator
DataRemoteAircraftSetData, //!< set model data such as airline
DataSimEnvironment,
+ DataTransponderModeMSFS,
DataClientAreaSb, //!< whole SB area, see http://squawkbox.ca/doc/sdk/fsuipc.php
DataClientAreaSbIdent, //!< SB ident single value 0x7b93/19
DataClientAreaSbStandby, //!< SB standby 0x7b91/17
@@ -291,6 +300,7 @@ namespace swift::simplugin::fsxcommon
RequestOwnAircraftTitle,
RequestSimEnvironment,
RequestSbData, //!< SB client area / XPDR mode
+ RequestMSFSTransponder, //!< MSFS XPDR mode/ident
RequestFacility,
RequestEndMarker //!< free request ids can start here
};
@@ -318,7 +328,7 @@ namespace swift::simplugin::fsxcommon
CSimConnectDefinitions();
//! Initialize all data definitions
- static HRESULT initDataDefinitionsWhenConnected(const HANDLE hSimConnect);
+ static HRESULT initDataDefinitionsWhenConnected(const HANDLE hSimConnect, const swift::misc::simulation::CSimulatorInfo &simInfo);
private:
//! Initialize data definition for our own aircraft
@@ -338,6 +348,9 @@ namespace swift::simplugin::fsxcommon
//! Initialize the SB data are
static HRESULT initSbDataArea(const HANDLE hSimConnect);
+
+ //! Initialize data definition for MSFS transponder
+ static HRESULT initMSFSTransponder(const HANDLE hSimConnect);
};
} // namespace
diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp
index 1b36f7086..5c8c50ac2 100644
--- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp
+++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp
@@ -194,6 +194,25 @@ namespace swift::simplugin::fsxcommon
}
changed = true;
}
+ else if (this->getSimulatorPluginInfo().getSimulatorInfo().isMSFS())
+ {
+ DataDefinitionMSFSTransponderMode t;
+ t.transponderMode = (newTransponder.isInStandby() ? 1 : 4);
+ t.ident = newTransponder.isIdentifying();
+
+ HRESULT hr = s_ok();
+
+ hr += SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataTransponderModeMSFS,
+ SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0,
+ sizeof(DataDefinitionMSFSTransponderMode), &t);
+
+ if (isFailure(hr))
+ {
+ CLogMessage(this).warning(u"Setting transponder mode failed (MSFS)");
+ }
+
+ changed = true;
+ }
}
// avoid changes of cockpit back to old values due to an outdated read back value
@@ -468,32 +487,48 @@ namespace swift::simplugin::fsxcommon
const CFsxP3DSettings settings = m_detailsSettings.getSettings(this->getSimulatorInfo());
m_useAddSimulatedObj = settings.isAddingAsSimulatedObjectEnabled();
m_useSbOffsets = settings.isSbOffsetsEnabled();
+ if (this->getSimulatorPluginInfo().getSimulatorInfo().isMSFS())
+ {
+ m_useSbOffsets = false; // Always disable SbOffsets for MSFS. Using new transponder mode property directly
+ }
- const HRESULT hr1 = this->logAndTraceSendId(
+ HRESULT hr = s_ok();
+ hr += this->logAndTraceSendId(
SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraft,
CSimConnectDefinitions::DataOwnAircraft, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME),
"Cannot request own aircraft data", Q_FUNC_INFO, "SimConnect_RequestDataOnSimObject");
- const HRESULT hr2 = this->logAndTraceSendId(
+ hr += this->logAndTraceSendId(
SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraftTitle,
CSimConnectDefinitions::DataOwnAircraftTitle,
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND, SIMCONNECT_DATA_REQUEST_FLAG_CHANGED),
"Cannot request title", Q_FUNC_INFO, "SimConnect_RequestDataOnSimObject");
- const HRESULT hr3 = this->logAndTraceSendId(
+ hr += this->logAndTraceSendId(
SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestSimEnvironment,
CSimConnectDefinitions::DataSimEnvironment,
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND, SIMCONNECT_DATA_REQUEST_FLAG_CHANGED),
"Cannot request sim.env.", Q_FUNC_INFO, "SimConnect_RequestDataOnSimObject");
- // Request the data from SB only when its changed and only ONCE so we don't have to run a 1sec event to get/set this info ;)
- // there was a bug with SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET, see https://www.prepar3d.com/forum/viewtopic.php?t=124789
- const HRESULT hr4 = this->logAndTraceSendId(
- SimConnect_RequestClientData(m_hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::RequestSbData,
- CSimConnectDefinitions::DataClientAreaSb, SIMCONNECT_CLIENT_DATA_PERIOD_SECOND, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED),
- "Cannot request client data", Q_FUNC_INFO, "SimConnect_RequestClientData");
+ if (!this->getSimulatorPluginInfo().getSimulatorInfo().isMSFS())
+ {
+ // Request the data from SB only when its changed and only ONCE so we don't have to run a 1sec event to get/set this info ;)
+ // there was a bug with SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET, see https://www.prepar3d.com/forum/viewtopic.php?t=124789
+ hr += this->logAndTraceSendId(
+ SimConnect_RequestClientData(m_hSimConnect, ClientAreaSquawkBox, CSimConnectDefinitions::RequestSbData,
+ CSimConnectDefinitions::DataClientAreaSb, SIMCONNECT_CLIENT_DATA_PERIOD_SECOND, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED),
+ "Cannot request client data", Q_FUNC_INFO, "SimConnect_RequestClientData");
+ }
+ else
+ {
+ hr += this->logAndTraceSendId(
+ SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestMSFSTransponder,
+ CSimConnectDefinitions::DataTransponderModeMSFS,
+ SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME, SIMCONNECT_DATA_REQUEST_FLAG_CHANGED),
+ "Cannot request MSFS transponder data", Q_FUNC_INFO, "SimConnect_RequestDataOnSimObject");
+ }
- if (isFailure(hr1, hr2, hr3, hr4)) { return; }
+ if (isFailure(hr)) { return; }
this->emitSimulatorCombinedStatus(); // force sending status
}
@@ -929,6 +964,27 @@ namespace swift::simplugin::fsxcommon
this->updateCockpit(myAircraft.getCom1System(), myAircraft.getCom2System(), xpdr, this->identifier());
}
+ void CSimulatorFsxCommon::updateTransponderMode(const CTransponder::TransponderMode xpdrMode)
+ {
+ if (m_skipCockpitUpdateCycles > 0) { return; }
+ const CSimulatedAircraft myAircraft(this->getOwnAircraft());
+ const bool changed = (myAircraft.getTransponderMode() != xpdrMode);
+ if (!changed) { return; }
+ CTransponder myXpdr = myAircraft.getTransponder();
+ myXpdr.setTransponderMode(xpdrMode);
+ this->updateCockpit(myAircraft.getCom1System(), myAircraft.getCom2System(), myXpdr, this->identifier());
+ }
+
+ void CSimulatorFsxCommon::updateMSFSTransponderMode(const DataDefinitionMSFSTransponderMode transponderMode)
+ {
+ auto mode = CTransponder::StateIdent;
+ if (!transponderMode.ident)
+ {
+ qRound(transponderMode.transponderMode) >= 3 ? mode = CTransponder::ModeC : mode = CTransponder::StateStandby;
+ }
+ this->updateTransponderMode(mode);
+ }
+
bool CSimulatorFsxCommon::simulatorReportedObjectAdded(DWORD objectId)
{
if (this->isShuttingDownOrDisconnected()) { return true; } // pretend everything is fine
@@ -1880,7 +1936,7 @@ namespace swift::simplugin::fsxcommon
HRESULT CSimulatorFsxCommon::initDataDefinitionsWhenConnected()
{
- return CSimConnectDefinitions::initDataDefinitionsWhenConnected(m_hSimConnect);
+ return CSimConnectDefinitions::initDataDefinitionsWhenConnected(m_hSimConnect, this->getSimulatorPluginInfo().getSimulatorInfo());
}
HRESULT CSimulatorFsxCommon::initWhenConnected()
diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h
index a223fe0aa..b49b84844 100644
--- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h
+++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h
@@ -478,6 +478,13 @@ namespace swift::simplugin::fsxcommon
//! \threadsafe
void updateOwnAircraftFromSimulator(const DataDefinitionClientAreaSb &sbDataArea);
+ //! Update transponder mode
+ //! \threadsafe
+ void updateTransponderMode(const misc::aviation::CTransponder::TransponderMode xpdrMode);
+
+ //! Update transponder mode from MSFS
+ void updateMSFSTransponderMode(const DataDefinitionMSFSTransponderMode transponderMode);
+
//! An AI aircraft was added in the simulator
bool simulatorReportedObjectAdded(DWORD objectId);
diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp b/src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp
index ab3f068e7..8ec92f361 100644
--- a/src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp
+++ b/src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp
@@ -254,6 +254,12 @@ namespace swift::simplugin::fsxcommon
simulatorFsxP3D->synchronizeTime(simEnv);
break;
}
+ case CSimConnectDefinitions::RequestMSFSTransponder:
+ {
+ const DataDefinitionMSFSTransponderMode *transponderMode = reinterpret_cast(&pObjData->dwData);
+ simulatorFsxP3D->updateMSFSTransponderMode(*transponderMode);
+ break;
+ }
default:
{
const DWORD objectId = pObjData->dwObjectID;
diff --git a/src/plugins/simulator/msfs/simulatormsfs.cpp b/src/plugins/simulator/msfs/simulatormsfs.cpp
index 0af17224d..e5f6d5577 100644
--- a/src/plugins/simulator/msfs/simulatormsfs.cpp
+++ b/src/plugins/simulator/msfs/simulatormsfs.cpp
@@ -31,19 +31,11 @@ namespace swift::simplugin::msfs
bool CSimulatorMsFs::connectTo()
{
-#ifdef Q_OS_WIN64
if (!loadAndResolveMSFSimConnect())
{
return false;
}
return CSimulatorFsxCommon::connectTo();
-#else
- if (!loadAndResolveFsxSimConnect(true))
- {
- return false;
- }
- return CSimulatorFsxCommon::connectTo();
-#endif
}
void CSimulatorMsFs::setTrueAltitude(CAircraftSituation &aircraftSituation, const DataDefinitionOwnAircraft &simulatorOwnAircraft)
@@ -54,19 +46,11 @@ namespace swift::simplugin::msfs
void CSimulatorMsFsListener::startImpl()
{
-#ifdef Q_OS_WIN64
if (!loadAndResolveMSFSimConnect())
{
return;
}
CSimulatorFsxCommonListener::startImpl();
-#else
- if (!loadAndResolveFsxSimConnect(true))
- {
- return;
- }
- CSimulatorFsxCommonListener::startImpl();
-#endif
}
} // ns
diff --git a/src/plugins/simulator/msfs/simulatormsfs.json b/src/plugins/simulator/msfs/simulatormsfs.json
index 56ed59434..2cf116d54 100644
--- a/src/plugins/simulator/msfs/simulatormsfs.json
+++ b/src/plugins/simulator/msfs/simulatormsfs.json
@@ -1,6 +1,7 @@
{
"identifier" : "org.swift-project.plugins.simulator.msfs",
"name" : "Flight Simulator 2020",
- "simulator" : "fsx",
- "description" : "Microsoft Flight Simulator 2020"
+ "simulator" : "msfs",
+ "description" : "Microsoft Flight Simulator 2020",
+ "config" : "org.swift-project.plugins.simulator.msfs.config"
}
diff --git a/src/plugins/simulator/msfsconfig/CMakeLists.txt b/src/plugins/simulator/msfsconfig/CMakeLists.txt
new file mode 100644
index 000000000..a416ab811
--- /dev/null
+++ b/src/plugins/simulator/msfsconfig/CMakeLists.txt
@@ -0,0 +1,27 @@
+# SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
+# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
+
+add_library(simulatormsfsconfig SHARED
+ simulatormsfsconfig.cpp
+ simulatormsfsconfig.h
+ simulatormsfsconfig.json
+)
+
+set_target_properties(simulatormsfsconfig PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/out/bin/plugins/simulator)
+set_target_properties(simulatormsfsconfig PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/out/bin/plugins/simulator)
+
+target_include_directories(simulatormsfsconfig PUBLIC ${PROJECT_SOURCE_DIR}/src)
+
+target_link_libraries(simulatormsfsconfig
+ PUBLIC
+ gui
+ misc
+ Qt::Core
+ PRIVATE
+ fsxcommon
+)
+
+install(TARGETS simulatormsfsconfig
+ LIBRARY DESTINATION bin/plugins/simulator
+ RUNTIME DESTINATION bin/plugins/simulator
+)
diff --git a/src/plugins/simulator/msfsconfig/simulatormsfsconfig.cpp b/src/plugins/simulator/msfsconfig/simulatormsfsconfig.cpp
new file mode 100644
index 000000000..e5e0a674f
--- /dev/null
+++ b/src/plugins/simulator/msfsconfig/simulatormsfsconfig.cpp
@@ -0,0 +1,18 @@
+// SPDX-FileCopyrightText: Copyright (C) 2017 swift Project Community / Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
+
+#include "simulatormsfsconfig.h"
+#include "../fsxcommon/simulatorfsxconfigwindow.h"
+
+namespace swift::simplugin::msfs
+{
+ CSimulatorMsfsConfig::CSimulatorMsfsConfig(QObject *parent) : QObject(parent)
+ {
+ // void
+ }
+
+ swift::gui::CPluginConfigWindow *CSimulatorMsfsConfig::createConfigWindow(QWidget *parent)
+ {
+ return new fsxcommon::CSimulatorFsxConfigWindow("MSFS", parent);
+ }
+}
diff --git a/src/plugins/simulator/msfsconfig/simulatormsfsconfig.h b/src/plugins/simulator/msfsconfig/simulatormsfsconfig.h
new file mode 100644
index 000000000..fa5ea819d
--- /dev/null
+++ b/src/plugins/simulator/msfsconfig/simulatormsfsconfig.h
@@ -0,0 +1,34 @@
+// SPDX-FileCopyrightText: Copyright (C) 2017 swift Project Community / Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
+
+//! \file
+
+#ifndef SWIFT_SIMPLUGIN_MSFS_SIMULATORMSFSCONFIG_H
+#define SWIFT_SIMPLUGIN_MSFS_SIMULATORMSFSCONFIG_H
+
+#include "gui/pluginconfig.h"
+
+namespace swift::simplugin::msfs
+{
+ /*!
+ * Window for setting up the MSFS plugin.
+ */
+ class CSimulatorMsfsConfig : public QObject, public swift::gui::IPluginConfig
+ {
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.swift-project.swiftgui.pluginconfiginterface" FILE "simulatormsfsconfig.json")
+ Q_INTERFACES(swift::gui::IPluginConfig)
+
+ public:
+ //! Ctor
+ CSimulatorMsfsConfig(QObject *parent = nullptr);
+
+ //! Dtor
+ virtual ~CSimulatorMsfsConfig() {}
+
+ //! \copydoc swift::gui::IPluginConfig::createConfigWindow()
+ swift::gui::CPluginConfigWindow *createConfigWindow(QWidget *parent) override;
+ };
+}
+
+#endif // guard
diff --git a/src/plugins/simulator/msfsconfig/simulatormsfsconfig.json b/src/plugins/simulator/msfsconfig/simulatormsfsconfig.json
new file mode 100644
index 000000000..9e2ce2e6e
--- /dev/null
+++ b/src/plugins/simulator/msfsconfig/simulatormsfsconfig.json
@@ -0,0 +1,3 @@
+{
+ "identifier" : "org.swift-project.plugins.simulator.msfs.config"
+}
diff --git a/src/plugins/simulator/msfsconfig/simulatormsfsconfig.json.license b/src/plugins/simulator/msfsconfig/simulatormsfsconfig.json.license
new file mode 100644
index 000000000..4eaf3369b
--- /dev/null
+++ b/src/plugins/simulator/msfsconfig/simulatormsfsconfig.json.license
@@ -0,0 +1,3 @@
+Copyright (C) swift Project Community / Contributors
+
+SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1