]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/options.cxx
One more Mac helper moved into CocoaHelpers.mm
[flightgear.git] / src / Main / options.cxx
index 261343b13e96bb8cfcf4dd52f60fb6eea1694ffb..691e7be2405623058820e71de5dd7e1209c3f3da 100644 (file)
 #include <simgear/sound/soundmgr_openal.hxx>
 #include <simgear/misc/strutils.hxx>
 #include <Autopilot/route_mgr.hxx>
+
 #include <GUI/gui.h>
+#include <GUI/MessageBox.hxx>
 
+#include <Main/locale.hxx>
 #include "globals.hxx"
 #include "fg_init.hxx"
 #include "fg_props.hxx"
@@ -62,6 +65,7 @@
 #include <Viewer/viewer.hxx>
 #include <Viewer/viewmgr.hxx>
 #include <Environment/presets.hxx>
+#include "AircraftDirVisitorBase.hxx"
 
 #include <osg/Version>
 
 #  include <Include/no_version.h>
 #endif
 
-#ifdef __APPLE__
-#  include <CoreFoundation/CoreFoundation.h>
-#endif
-
 using std::string;
 using std::sort;
 using std::cout;
@@ -111,8 +111,7 @@ static int fgSetupProxy( const char *arg );
  * in case, we provide some initial sane values here. This method
  * should be invoked *before* reading any init files.
  */
-static void
-fgSetDefaults ()
+void fgSetDefaults ()
 {
 
                                // Position (deliberately out of range)
@@ -158,9 +157,7 @@ fgSetDefaults ()
     fgSetBool("/sim/presets/trim", false);
 
                                // Miscellaneous
-    fgSetBool("/sim/startup/game-mode", false);
     fgSetBool("/sim/startup/splash-screen", true);
-    fgSetBool("/sim/startup/intro-music", true);
     // we want mouse-pointer to have an undefined value if nothing is
     // specified so we can do the right thing for voodoo-1/2 cards.
     // fgSetString("/sim/startup/mouse-pointer", "disabled");
@@ -198,9 +195,9 @@ fgSetDefaults ()
     fgSetBool("/sim/rendering/distance-attenuation", false);
     fgSetBool("/sim/rendering/specular-highlight", true);
     fgSetString("/sim/rendering/materials-file", "materials.xml");
-    fgSetInt("/sim/startup/xsize", 800);
-    fgSetInt("/sim/startup/ysize", 600);
-    fgSetInt("/sim/rendering/bits-per-pixel", 16);
+    fgSetInt("/sim/startup/xsize", 1024);
+    fgSetInt("/sim/startup/ysize", 768);
+    fgSetInt("/sim/rendering/bits-per-pixel", 32);
     fgSetString("/sim/view-mode", "pilot");
     fgSetDouble("/sim/current-view/heading-offset-deg", 0);
 
@@ -225,23 +222,145 @@ fgSetDefaults ()
     fgSetInt("/sim/multiplay/rxport", 0);
     fgSetInt("/sim/multiplay/txport", 0);
     
-    fgSetString("/sim/version/flightgear", FLIGHTGEAR_VERSION);
-    fgSetString("/sim/version/simgear", SG_STRINGIZE(SIMGEAR_VERSION));
-    fgSetString("/sim/version/openscenegraph", osgGetVersion());
-    fgSetString("/sim/version/revision", REVISION);
-    fgSetInt("/sim/version/build-number", HUDSON_BUILD_NUMBER);
-    fgSetString("/sim/version/build-id", HUDSON_BUILD_ID);
-#ifdef FG_HAVE_HLA     // -DENABLE_RTI=ON
-    fgSetBool("/sim/version/hla-support", true);
-#else                  // -DENABLE_RTI=OFF
-    fgSetBool("/sim/version/hla-support", false);
-#endif
-
-  char* envp = ::getenv( "http_proxy" );
+    SGPropertyNode* v = globals->get_props()->getNode("/sim/version", true);
+    v->setValueReadOnly("flightgear", FLIGHTGEAR_VERSION);
+    v->setValueReadOnly("simgear", SG_STRINGIZE(SIMGEAR_VERSION));
+    v->setValueReadOnly("openscenegraph", osgGetVersion());
+    v->setValueReadOnly("openscenegraph-thread-safe-reference-counting",
+                         osg::Referenced::getThreadSafeReferenceCounting());
+    v->setValueReadOnly("revision", REVISION);
+    v->setValueReadOnly("build-number", HUDSON_BUILD_NUMBER);
+    v->setValueReadOnly("build-id", HUDSON_BUILD_ID);
+    v->setValueReadOnly("hla-support", bool(FG_HAVE_HLA));
+
+    char* envp = ::getenv( "http_proxy" );
     if( envp != NULL )
       fgSetupProxy( envp );
 }
 
+///////////////////////////////////////////////////////////////////////////////
+// helper object to implement the --show-aircraft command.
+// resides here so we can share the fgFindAircraftInDir template above,
+// and hence ensure this command lists exectly the same aircraft as the normal
+// loading path.
+class ShowAircraft : public AircraftDirVistorBase
+{
+public:
+    ShowAircraft()
+    {
+        _minStatus = getNumMaturity(fgGetString("/sim/aircraft-min-status", "all"));
+    }
+    
+    
+    void show(const SGPath& path)
+    {
+        visitDir(path, 0);
+        
+        simgear::requestConsole(); // ensure console is shown on Windows
+        
+        std::sort(_aircraft.begin(), _aircraft.end(), ciLessLibC());
+        cout << "Available aircraft:" << endl;
+        for ( unsigned int i = 0; i < _aircraft.size(); i++ ) {
+            cout << _aircraft[i] << endl;
+        }
+    }
+    
+private:
+    virtual VisitResult visit(const SGPath& path)
+    {
+        SGPropertyNode root;
+        try {
+            readProperties(path.str(), &root);
+        } catch (sg_exception& ) {
+            return VISIT_CONTINUE;
+        }
+        
+        int maturity = 0;
+        string descStr("   ");
+        descStr += path.file();
+        // trim common suffix from file names
+        int nPos = descStr.rfind("-set.xml");
+        if (nPos == (int)(descStr.size() - 8)) {
+            descStr.resize(nPos);
+        }
+        
+        SGPropertyNode *node = root.getNode("sim");
+        if (node) {
+            SGPropertyNode* desc = node->getNode("description");
+            // if a status tag is found, read it in
+            if (node->hasValue("status")) {
+                maturity = getNumMaturity(node->getStringValue("status"));
+            }
+            
+            if (desc) {
+                if (descStr.size() <= 27+3) {
+                    descStr.append(29+3-descStr.size(), ' ');
+                } else {
+                    descStr += '\n';
+                    descStr.append( 32, ' ');
+                }
+                descStr += desc->getStringValue();
+            }
+        } // of have 'sim' node
+        
+        if (maturity >= _minStatus) {
+            _aircraft.push_back(descStr);
+        }
+        
+        return VISIT_CONTINUE;
+    }
+    
+    
+    int getNumMaturity(const char * str)
+    {
+        // changes should also be reflected in $FG_ROOT/data/options.xml &
+        // $FG_ROOT/data/Translations/string-default.xml
+        const char* levels[] = {"alpha","beta","early-production","production"};
+        
+        if (!strcmp(str, "all")) {
+            return 0;
+        }
+        
+        for (size_t i=0; i<(sizeof(levels)/sizeof(levels[0]));i++)
+            if (strcmp(str,levels[i])==0)
+                return i;
+        
+        return 0;
+    }
+    
+    // recommended in Meyers, Effective STL when internationalization and embedded
+    // NULLs aren't an issue.  Much faster than the STL or Boost lex versions.
+    struct ciLessLibC : public std::binary_function<string, string, bool>
+    {
+        bool operator()(const std::string &lhs, const std::string &rhs) const
+        {
+            return strcasecmp(lhs.c_str(), rhs.c_str()) < 0 ? 1 : 0;
+        }
+    };
+    
+    int _minStatus;
+    string_list _aircraft;
+};
+
+/*
+ * Search in the current directory, and in on directory deeper
+ * for <aircraft>-set.xml configuration files and show the aircaft name
+ * and the contents of the<description> tag in a sorted manner.
+ *
+ * @parampath the directory to search for configuration files
+ */
+void fgShowAircraft(const SGPath &path)
+{
+    ShowAircraft s;
+    s.show(path);
+    
+#ifdef _MSC_VER
+    cout << "Hit a key to continue..." << endl;
+    std::cin.get();
+#endif
+}
+
+
 static bool
 parse_wind (const string &wind, double * min_hdg, double * max_hdg,
            double * speed, double * gust)
@@ -1207,6 +1326,14 @@ fgOptCallSign(const char * arg)
     return FG_OPTIONS_OK;
 }
 
+static int
+fgOptIgnoreAutosave(const char* arg)
+{
+    fgSetBool("/sim/startup/ignore-autosave", true);
+    // don't overwrite autosave on exit
+    fgSetBool("/sim/startup/save-on-exit", false);
+    return FG_OPTIONS_OK;
+}
 
 // Set a property for the --prop: option. Syntax: --prop:[<type>:]<name>=<value>
 // <type> can be "double" etc. but also only the first letter "d".
@@ -1298,15 +1425,12 @@ struct OptionDesc {
     } fgOptionArray[] = {
 
     {"language",                     true,  OPTION_IGNORE, "", false, "", 0 },
+       {"console",                      false, OPTION_IGNORE,   "", false, "", 0 },
     {"disable-rembrandt",            false, OPTION_BOOL,   "/sim/rendering/rembrandt/enabled", false, "", 0 },
     {"enable-rembrandt",             false, OPTION_BOOL,   "/sim/rendering/rembrandt/enabled", true, "", 0 },
     {"renderer",                     true,  OPTION_STRING, "/sim/rendering/rembrandt/renderer", false, "", 0 },
-    {"disable-game-mode",            false, OPTION_BOOL,   "/sim/startup/game-mode", false, "", 0 },
-    {"enable-game-mode",             false, OPTION_BOOL,   "/sim/startup/game-mode", true, "", 0 },
     {"disable-splash-screen",        false, OPTION_BOOL,   "/sim/startup/splash-screen", false, "", 0 },
     {"enable-splash-screen",         false, OPTION_BOOL,   "/sim/startup/splash-screen", true, "", 0 },
-    {"disable-intro-music",          false, OPTION_BOOL,   "/sim/startup/intro-music", false, "", 0 },
-    {"enable-intro-music",           false, OPTION_BOOL,   "/sim/startup/intro-music", true, "", 0 },
     {"disable-mouse-pointer",        false, OPTION_STRING, "/sim/startup/mouse-pointer", false, "disabled", 0 },
     {"enable-mouse-pointer",         false, OPTION_STRING, "/sim/startup/mouse-pointer", false, "enabled", 0 },
     {"disable-random-objects",       false, OPTION_BOOL,   "/sim/rendering/random-objects", false, "", 0 },
@@ -1404,6 +1528,8 @@ struct OptionDesc {
     {"enable-fullscreen",            false, OPTION_BOOL,   "/sim/startup/fullscreen", true, "", 0 },
     {"disable-save-on-exit",         false, OPTION_BOOL,   "/sim/startup/save-on-exit", false, "", 0 },
     {"enable-save-on-exit",          false, OPTION_BOOL,   "/sim/startup/save-on-exit", true, "", 0 },
+    {"read-only",                    false, OPTION_BOOL,   "/sim/fghome-readonly", true, "", 0 },
+    {"ignore-autosave",              false, OPTION_FUNC,   "", false, "", fgOptIgnoreAutosave },
     {"restore-defaults",             false, OPTION_BOOL,   "/sim/startup/restore-defaults", true, "", 0 },
     {"shading-flat",                 false, OPTION_BOOL,   "/sim/rendering/shading", false, "", 0 },
     {"shading-smooth",               false, OPTION_BOOL,   "/sim/rendering/shading", true, "", 0 },
@@ -1461,7 +1587,7 @@ struct OptionDesc {
     {"proxy",                        true,  OPTION_FUNC,    "", false, "", fgSetupProxy },
     {"callsign",                     true,  OPTION_FUNC,    "", false, "", fgOptCallSign},
     {"multiplay",                    true,  OPTION_CHANNEL | OPTION_MULTI, "", false, "", 0 },
-#ifdef FG_HAVE_HLA
+#if FG_HAVE_HLA
     {"hla",                          true,  OPTION_CHANNEL, "", false, "", 0 },
     {"hla-local",                    true,  OPTION_CHANNEL, "", false, "", 0 },
 #endif
@@ -1697,8 +1823,6 @@ Options::~Options()
   
 void Options::init(int argc, char **argv, const SGPath& appDataPath)
 {
-  fgSetDefaults();
-  
 // first, process the command line
   bool inOptions = true;
   for (int i=1; i<argc; ++i) {
@@ -1888,6 +2012,9 @@ int Options::parseOption(const string& s)
   } else if ( (s == "--verbose") || (s == "-v") ) {
     // verbose help/usage request
     return FG_OPTIONS_VERBOSE_HELP;
+  } else if ((s == "--console") || (s == "-c")) {
+         simgear::requestConsole();
+         return FG_OPTIONS_OK;
   } else if (s.find("-psn") == 0) {
     // on Mac, when launched from the GUI, we are passed the ProcessSerialNumber
     // as an argument (and no others). Silently ignore the argument here.
@@ -2088,7 +2215,7 @@ void Options::showUsage() const
   FGLocale *locale = globals->get_locale();
   SGPropertyNode options_root;
   
-  SG_LOG( SG_GENERAL, SG_ALERT, "" ); // To popup the console on Windows
+  simgear::requestConsole(); // ensure console is shown on Windows
   cout << endl;
 
   try {
@@ -2225,30 +2352,7 @@ string Options::platformDefaultRoot() const
   return "..\\data";
 }
 #elif defined(__APPLE__)
-string Options::platformDefaultRoot() const
-{
-  /*
-   The following code looks for the base package inside the application 
-   bundle, in the standard Contents/Resources location. 
-   */
-  CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
-  
-  // look for a 'data' subdir
-  CFURLRef dataDir = CFURLCreateCopyAppendingPathComponent(NULL, resourcesUrl, CFSTR("data"), true);
-  
-  CFURLRef absoluteDataUrl = CFURLCopyAbsoluteURL(dataDir);
-  
-  // now convert down to a path, and the a c-string
-  CFStringRef path = CFURLCopyFileSystemPath(absoluteDataUrl, kCFURLPOSIXPathStyle);  
-  string root = CFStringGetCStringPtr(path, CFStringGetSystemEncoding());
-  
-  CFRelease(absoluteDataUrl);
-  CFRelease(resourcesUrl);
-  CFRelease(dataDir);
-  CFRelease(path);
-  
-  return root;
-}
+// platformDefaultRoot defined in CocoaHelpers.mm
 #else
 string Options::platformDefaultRoot() const
 {
@@ -2277,20 +2381,23 @@ void Options::setupRoot()
 // validate it
   static char required_version[] = FLIGHTGEAR_VERSION;
   string base_version = fgBasePackageVersion();
-  if ( !(base_version == required_version) ) {
-    // tell the operator how to use this application
+    if (base_version.empty()) {
+        flightgear::fatalMessageBox("Base package not found",
+                                    "Required data files not found, check your installation.",
+                                    "Looking for base-package files at: '" + root + "'");
+
+        exit(-1);
+    }
     
-    SG_LOG( SG_GENERAL, SG_ALERT, "" ); // To popup the console on windows
-    cerr << endl << "Base package check failed:" << endl \
-    << "  Version " << base_version << " found at: " \
-    << globals->get_fg_root() << endl \
-    << "  Version " << required_version << " is required." << endl \
-    << "Please upgrade/downgrade base package and set the path to your fgdata" << endl \
-    << "with --fg-root=path_to_your_fgdata" << endl;
-#ifdef _MSC_VER
-    cerr << "Hit a key to continue..." << endl;
-    cin.get();
-#endif
+ if (base_version != required_version) {
+    // tell the operator how to use this application
+   
+      flightgear::fatalMessageBox("Base package version mismatch",
+                                  "Version check failed: please check your installation.",
+                                  "Found data files for version '" + base_version +
+                                  "' at '" + globals->get_fg_root() + "', version '"
+                                  + required_version + "' is required.");
+
     exit(-1);
   }
 }