Exemple #1
0
char *
br_build_path (const char *dir, const char *file)
{
	char *dir2, *result;
	size_t len;
	int must_free = 0;

	len = strlen (dir);
	if (len > 0 && dir[len - 1] != '/') {
		dir2 = br_strcat (dir, "/");
		must_free = 1;
	} else
		dir2 = (char *) dir;

	result = br_strcat (dir2, file);
	if (must_free)
		free (dir2);
	return result;
}
Exemple #2
0
/**
 * br_prepend_prefix:
 * symbol: A symbol that belongs to the app/library you want to locate.
 * path: The path that you want to prepend the prefix to.
 * Returns: The new path, or NULL on error. This string should be freed when no
 *	    longer needed.
 *
 * Gets the prefix of the app/library that symbol belongs to. Prepend that prefix to path.
 * Note that symbol cannot be a pointer to a function. That will not work.
 *
 * Example:
 * --> The application is /usr/bin/foo
 * br_prepend_prefix (&argc, "/share/foo/data.png");   --> Returns "/usr/share/foo/data.png"
 */
char *
br_prepend_prefix (void *symbol, const char *path)
{
	char *tmp, *newpath;

	br_return_val_if_fail (symbol != NULL, NULL);
	br_return_val_if_fail (path != NULL, NULL);

	tmp = br_locate_prefix (symbol);
	if (!tmp) return NULL;

	if (strcmp (tmp, "/") == 0)
		newpath = strdup (path);
	else
		newpath = br_strcat (tmp, path);

	/* Get rid of compiler warning ("br_prepend_prefix never used") */
	if (0) br_prepend_prefix (NULL, NULL);

	free (tmp);
	return newpath;
}
static void init_physfs(const char* argv0)
{
  if(!PHYSFS_init(argv0)) {
    std::stringstream msg;
    msg << "Couldn't initialize physfs: " << PHYSFS_getLastError();
    throw std::runtime_error(msg.str());
  }

  // Initialize physfs (this is a slightly modified version of
  // PHYSFS_setSaneConfig
  const char* application = PACKAGE_NAME;
  const char* userdir = PHYSFS_getUserDir();
  const char* dirsep = PHYSFS_getDirSeparator();
  char* writedir = new char[strlen(userdir) + strlen(application) + 2];

  // Set configuration directory
  sprintf(writedir, "%s.%s", userdir, application);
  if(!PHYSFS_setWriteDir(writedir)) {
    // try to create the directory
    char* mkdir = new char[strlen(application) + 2];
    sprintf(mkdir, ".%s", application);
    if(!PHYSFS_setWriteDir(userdir) || !PHYSFS_mkdir(mkdir)) {
      std::ostringstream msg;
      msg << "Failed creating configuration directory '" 
          << writedir << "': " << PHYSFS_getLastError();
      delete[] writedir;
      delete[] mkdir;
      throw std::runtime_error(msg.str());
    }
    delete[] mkdir;
    
    if(!PHYSFS_setWriteDir(writedir)) {
      std::ostringstream msg;
      msg << "Failed to use configuration directory '" 
          <<  writedir << "': " << PHYSFS_getLastError();
      delete[] writedir;
      throw std::runtime_error(msg.str());
    }
  }
  PHYSFS_addToSearchPath(writedir, 0);
  delete[] writedir;

  // Search for archives and add them to the search path
  const char* archiveExt = "zip";
  char** rc = PHYSFS_enumerateFiles("/");
  size_t extlen = strlen(archiveExt);

  for(char** i = rc; *i != 0; ++i) {
    size_t l = strlen(*i);
    if((l > extlen) && ((*i)[l - extlen - 1] == '.')) {
      const char* ext = (*i) + (l - extlen);
      if(strcasecmp(ext, archiveExt) == 0) {
        const char* d = PHYSFS_getRealDir(*i);
        char* str = new char[strlen(d) + strlen(dirsep) + l + 1];
        sprintf(str, "%s%s%s", d, dirsep, *i);
        PHYSFS_addToSearchPath(str, 1);
        delete[] str;
      }
    }
  }
  
  PHYSFS_freeList(rc);

  // when started from source dir...
  std::string dir = PHYSFS_getBaseDir();
  dir += "/data";
  std::string testfname = dir;
  testfname += "/credits.txt";
  bool sourcedir = false;
  FILE* f = fopen(testfname.c_str(), "r");
  if(f) {
    fclose(f);
    if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) {
      log_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
    } else {
      sourcedir = true;
    }
  }

#ifdef MACOSX
  // when started from Application file on Mac OS X...
  dir = PHYSFS_getBaseDir();
  dir += "SuperTux.app/Contents/Resources/data";
  testfname = dir + "/credits.txt";
  sourcedir = false;
  f = fopen(testfname.c_str(), "r");
  if(f) {
    fclose(f);
    if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) {
      msg_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
    } else {
      sourcedir = true;
    }
  }
#endif

  if(!sourcedir) {
#if defined(APPDATADIR) || defined(ENABLE_BINRELOC)
    std::string datadir;
#ifdef ENABLE_BINRELOC
    char* brdatadir = br_strcat(DATADIR, "/" PACKAGE_NAME);
    datadir = brdatadir;
    free(brdatadir);
#else
    datadir = APPDATADIR;
#endif
    if(!PHYSFS_addToSearchPath(datadir.c_str(), 1)) {
      log_warning << "Couldn't add '" << datadir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
    }
#endif
  }

  // allow symbolic links
  PHYSFS_permitSymbolicLinks(1);

  //show search Path
  for(char** i = PHYSFS_getSearchPath(); *i != NULL; i++)
    log_info << "[" << *i << "] is in the search path" << std::endl;
}
Exemple #4
0
Ogre::Root* OgreSetup::createOgreSystem()
{
	ConfigService& configSrv(EmberServices::getSingleton().getConfigService());

	if (configSrv.getPrefix() != "") {
		//We need to set the current directory to the prefix before trying to load Ogre.
		//The reason for this is that Ogre loads a lot of dynamic modules, and in some build configuration
		//(like AppImage) the lookup path for some of these are based on the installation directory of Ember.
		if (chdir(configSrv.getPrefix().c_str())) {
			S_LOG_WARNING("Failed to change to the prefix directory '" << configSrv.getPrefix() << "'. Ogre loading might fail.");
		}
	}

	std::string pluginExtension = ".so";
	mRoot = new Ogre::Root("", "ogre.cfg", "");

	//we will try to load the plugins from series of different location, with the hope of getting at least one right
	std::vector<std::string> pluginLocations;

	if (configSrv.itemExists("ogre", "plugins")) {
		std::string plugins(configSrv.getValue("ogre", "plugins"));
		//if it's defined in the config, use that location first
		if (configSrv.itemExists("ogre", "plugindir")) {
			std::string pluginDir(configSrv.getValue("ogre", "plugindir"));
			pluginLocations.push_back(pluginDir);
		}
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
		pluginExtension = ".dll";
		pluginLocations.push_back("."); //on windows we'll bundle the dll files in the same directory as the executable
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
		pluginExtension = ".so";
		std::string pluginDir = configSrv.getPrefix();
		pluginDir += "/lib/OGRE";
		pluginLocations.push_back(pluginDir);

#ifdef ENABLE_BINRELOC
		//binreloc might be used
		char* br_libdir = br_find_lib_dir(br_strcat(PREFIX, "/lib"));
		std::string libDir(br_libdir);
		free(br_libdir);
		pluginLocations.push_back(libDir + "/OGRE");
#endif
#ifdef OGRE_PLUGINDIR
		//also try with the plugindir defined for Ogre
		pluginLocations.push_back(OGRE_PLUGINDIR);
#endif
		//enter the usual locations if Ogre is installed system wide, with local installations taking precedence
		pluginLocations.push_back("/usr/local/lib/OGRE");
		pluginLocations.push_back("/usr/lib/OGRE");
#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE
		// On Mac, plugins are found in Resources in the Main (Application) bundle, then in the Ogre framework bundle
		pluginExtension = "";
		std::string pluginDir = configSrv.getSharedDataDirectory();
		pluginLocations.push_back(pluginDir);
		pluginDir += "/../Plugins";
		pluginLocations.push_back(pluginDir);
		pluginLocations.push_back("");
#endif
		Tokeniser tokeniser(plugins, ",");
		std::string token = tokeniser.nextToken();
		while (token != "") {
			std::string pluginPath;
			bool pluginLoaded = false;
			for (std::vector<std::string>::iterator I = pluginLocations.begin(); I != pluginLocations.end(); ++I) {
				pluginPath = (*I) + "/" + token + pluginExtension;
				S_LOG_INFO("Trying to load the plugin '" << pluginPath << "'.");
				try {
					mRoot->loadPlugin(pluginPath);
					pluginLoaded = true;
					break;
				} catch (...) {
					pluginPath = (*I) + "/" + token + "_d" + pluginExtension;
					S_LOG_INFO("Trying to load the plugin '" << pluginPath << "'.");
					try {
						mRoot->loadPlugin(pluginPath);
						pluginLoaded = true;
						break;
					} catch (...) {
					}
				}
			}
			if (pluginLoaded) {
				S_LOG_INFO("Successfully loaded the plugin '" << token << "' from '" << pluginPath << "'.");
			} else {
				S_LOG_FAILURE("Failed to load the plugin '" << token << "'!");
			}
			token = tokeniser.nextToken();
		}
	}

	if (chdir(configSrv.getEmberDataDirectory().c_str())) {
		S_LOG_WARNING("Failed to change to the data directory '" << configSrv.getEmberDataDirectory() << "'.");
	}

	return mRoot;
}