Issue #913: Merge --master and --plugin switches

Merged master/plugin switches into content in openmw
and mwiniimporter.

Extension in content files is now required.

Signed-off-by: Lukasz Gromanowski <lgromanowski@gmail.com>
pull/51/head
Lukasz Gromanowski 11 years ago
parent 6143ec33e0
commit 9c2145eda1

@ -813,8 +813,7 @@ void MwIniImporter::importArchives(multistrmap &cfg, const multistrmap &ini) con
}
void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini) const {
std::vector<std::string> esmFiles;
std::vector<std::string> espFiles;
std::vector<std::string> contentFiles;
std::string baseGameFile("Game Files:GameFile");
std::string gameFile("");
@ -832,29 +831,19 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini) co
std::string filetype(entry->substr(entry->length()-3));
Misc::StringUtils::toLower(filetype);
if(filetype.compare("esm") == 0) {
esmFiles.push_back(*entry);
}
else if(filetype.compare("esp") == 0) {
espFiles.push_back(*entry);
if(filetype.compare("esm") == 0 || filetype.compare("esp") == 0) {
contentFiles.push_back(*entry);
}
}
gameFile = "";
}
cfg.erase("master");
cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("master", std::vector<std::string>() ) );
for(std::vector<std::string>::const_iterator it=esmFiles.begin(); it!=esmFiles.end(); ++it) {
cfg["master"].push_back(*it);
}
cfg.erase("plugin");
cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("plugin", std::vector<std::string>() ) );
cfg.erase("content");
cfg.insert( std::make_pair("content", std::vector<std::string>() ) );
for(std::vector<std::string>::const_iterator it=espFiles.begin(); it!=espFiles.end(); ++it) {
cfg["plugin"].push_back(*it);
for(std::vector<std::string>::const_iterator it=contentFiles.begin(); it!=contentFiles.end(); ++it) {
cfg["content"].push_back(*it);
}
}

@ -58,6 +58,7 @@ add_openmw_dir (mwworld
cells localscripts customdata weather inventorystore ptr actionopen actionread
actionequip timestamp actionalchemy cellstore actionapply actioneat
esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor
contentloader esmloader omwloader
)
add_openmw_dir (mwclass

@ -261,34 +261,14 @@ void OMW::Engine::setCell (const std::string& cellName)
mCellName = cellName;
}
// Set master file (esm)
// - If the given name does not have an extension, ".esm" is added automatically
void OMW::Engine::addMaster (const std::string& master)
void OMW::Engine::addContentFile(const std::string& file)
{
mMaster.push_back(master);
std::string &str = mMaster.back();
// Append .esm if not already there
std::string::size_type sep = str.find_last_of (".");
if (sep == std::string::npos)
{
str += ".esm";
}
}
if (file.find_last_of(".") == std::string::npos)
{
throw std::runtime_error("Missing extension in content file!");
}
// Add plugin file (esp)
void OMW::Engine::addPlugin (const std::string& plugin)
{
mPlugins.push_back(plugin);
std::string &str = mPlugins.back();
// Append .esp if not already there
std::string::size_type sep = str.find_last_of (".");
if (sep == std::string::npos)
{
str += ".esp";
}
mContentFiles.push_back(file);
}
void OMW::Engine::setScriptsVerbosity(bool scriptsVerbosity)
@ -403,7 +383,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
mEnvironment.getWindowManager()->setNewGame(true);
// Create the world
mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mMaster, mPlugins,
mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mContentFiles,
mResDir, mCfgMgr.getCachePath(), mEncoder, mFallbackMap,
mActivationDistanceOverride));
MWBase::Environment::get().getWorld()->setupPlayer();
@ -414,8 +394,8 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
//Load translation data
mTranslationDataStorage.setEncoder(mEncoder);
for (size_t i = 0; i < mMaster.size(); i++)
mTranslationDataStorage.loadTranslationData(mFileCollections, mMaster[i]);
for (size_t i = 0; i < mContentFiles.size(); i++)
mTranslationDataStorage.loadTranslationData(mFileCollections, mContentFiles[i]);
Compiler::registerExtensions (mExtensions);
@ -480,7 +460,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
void OMW::Engine::go()
{
assert (!mCellName.empty());
assert (!mMaster.empty());
assert (!mContentFiles.empty());
assert (!mOgre);
Settings::Manager settings;

@ -68,8 +68,7 @@ namespace OMW
boost::filesystem::path mResDir;
OEngine::Render::OgreRenderer *mOgre;
std::string mCellName;
std::vector<std::string> mMaster;
std::vector<std::string> mPlugins;
std::vector<std::string> mContentFiles;
int mFpsLevel;
bool mVerboseScripts;
bool mNewGame;
@ -135,13 +134,11 @@ namespace OMW
/// Set start cell name (only interiors for now)
void setCell(const std::string& cellName);
/// Set master file (esm)
/// - If the given name does not have an extension, ".esm" is added automatically
void addMaster(const std::string& master);
/// Same as "addMaster", but for plugin files (esp)
/// - If the given name does not have an extension, ".esp" is added automatically
void addPlugin(const std::string& plugin);
/**
* @brief addContentFile - Adds content file (ie. esm/esp, or omwgame/omwaddon) to the content files container.
* @param file - filename (extension is required)
*/
void addContentFile(const std::string& file);
/// Enable fps counter
void showFPS(int level);

@ -110,11 +110,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
("start", bpo::value<std::string>()->default_value("Beshara"),
"set initial cell")
("master", bpo::value<StringsVector>()->default_value(StringsVector(), "")
->multitoken(), "master file(s)")
("plugin", bpo::value<StringsVector>()->default_value(StringsVector(), "")
->multitoken(), "plugin file(s)")
("content", bpo::value<StringsVector>()->default_value(StringsVector(), "")
->multitoken(), "content file(s): esm/esp, or omwgame/omwaddon")
("anim-verbose", bpo::value<bool>()->implicit_value(true)
->default_value(false), "output animation indices files")
@ -152,8 +149,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
("activate-dist", bpo::value <int> ()->default_value (-1), "activation distance override");
;
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv)
.options(desc).allow_unregistered().run();
@ -211,29 +206,18 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
engine.setResourceDir(variables["resources"].as<std::string>());
// master and plugin
StringsVector master = variables["master"].as<StringsVector>();
if (master.empty())
StringsVector content = variables["content"].as<StringsVector>();
if (content.empty())
{
std::cout << "No master file given. Aborting...\n";
return false;
std::cout << "No content file given (esm/esp, nor omwgame/omwaddon). Aborting..." << std::endl;
return false;
}
StringsVector plugin = variables["plugin"].as<StringsVector>();
// Removed check for 255 files, which would be the hard-coded limit in Morrowind.
// I'll keep the following variable in, maybe we can use it for something different.
// Say, a feedback like "loading file x/cnt".
// Commenting this out for now to silence compiler warning.
//int cnt = master.size() + plugin.size();
// Prepare loading master/plugin files (i.e. send filenames to engine)
for (std::vector<std::string>::size_type i = 0; i < master.size(); i++)
{
engine.addMaster(master[i]);
}
for (std::vector<std::string>::size_type i = 0; i < plugin.size(); i++)
StringsVector::const_iterator it(content.begin());
StringsVector::const_iterator end(content.end());
for (; it != end; ++it)
{
engine.addPlugin(plugin[i]);
engine.addContentFile(*it);
}
// startup-settings

@ -0,0 +1,35 @@
#ifndef CONTENTLOADER_HPP
#define CONTENTLOADER_HPP
#include <iosfwd>
#include <boost/filesystem/path.hpp>
#include "components/loadinglistener/loadinglistener.hpp"
namespace MWWorld
{
struct ContentLoader
{
ContentLoader(Loading::Listener& listener)
: mListener(listener)
{
}
virtual ~ContentLoader()
{
}
virtual void load(const boost::filesystem::path& filepath, int& index)
{
std::cout << "Loading content file " << filepath.string() << std::endl;
mListener.setLabel(filepath.string());
}
protected:
Loading::Listener& mListener;
};
} /* namespace MWWorld */
#endif /* CONTENTLOADER_HPP */

@ -0,0 +1,31 @@
#include "esmloader.hpp"
#include "esmstore.hpp"
#include "components/to_utf8/to_utf8.hpp"
namespace MWWorld
{
EsmLoader::EsmLoader(MWWorld::ESMStore& store, std::vector<ESM::ESMReader>& readers,
ToUTF8::Utf8Encoder* encoder, Loading::Listener& listener)
: ContentLoader(listener)
, mStore(store)
, mEsm(readers)
, mEncoder(encoder)
{
}
void EsmLoader::load(const boost::filesystem::path& filepath, int& index)
{
ContentLoader::load(filepath.filename(), index);
ESM::ESMReader lEsm;
lEsm.setEncoder(mEncoder);
lEsm.setIndex(index);
lEsm.setGlobalReaderList(&mEsm);
lEsm.open(filepath.string());
mEsm[index] = lEsm;
mStore.load(mEsm[index], &mListener);
}
} /* namespace MWWorld */

@ -0,0 +1,34 @@
#ifndef ESMLOADER_HPP
#define ESMLOADER_HPP
#include <vector>
#include "contentloader.hpp"
#include "components/esm/esmreader.hpp"
namespace ToUTF8
{
class Utf8Encoder;
}
namespace MWWorld
{
class ESMStore;
struct EsmLoader : public ContentLoader
{
EsmLoader(MWWorld::ESMStore& store, std::vector<ESM::ESMReader>& readers,
ToUTF8::Utf8Encoder* encoder, Loading::Listener& listener);
void load(const boost::filesystem::path& filepath, int& index);
private:
std::vector<ESM::ESMReader>& mEsm;
MWWorld::ESMStore& mStore;
ToUTF8::Utf8Encoder* mEncoder;
};
} /* namespace MWWorld */
#endif // ESMLOADER_HPP

@ -0,0 +1,17 @@
#include "omwloader.hpp"
namespace MWWorld
{
OmwLoader::OmwLoader(Loading::Listener& listener)
: ContentLoader(listener)
{
}
void OmwLoader::load(const boost::filesystem::path& filepath, int& index)
{
ContentLoader::load(filepath.filename(), index);
}
} /* namespace MWWorld */

@ -0,0 +1,21 @@
#ifndef OMWLOADER_HPP
#define OMWLOADER_HPP
#include "contentloader.hpp"
namespace MWWorld
{
/**
* @brief Placeholder for real OpenMW content loader
*/
struct OmwLoader : public ContentLoader
{
OmwLoader(Loading::Listener& listener);
void load(const boost::filesystem::path& filepath, int& index);
};
} /* namespace MWWorld */
#endif /* OMWLOADER_HPP */

@ -1,4 +1,11 @@
#include "worldimp.hpp"
#ifdef _WIN32
#include <boost/tr1/tr1/unordered_map>
#elif defined HAVE_UNORDERED_MAP
#include <unordered_map>
#else
#include <tr1/unordered_map>
#endif
#include <OgreSceneNode.h>
@ -31,6 +38,10 @@
#include "containerstore.hpp"
#include "inventorystore.hpp"
#include "contentloader.hpp"
#include "esmloader.hpp"
#include "omwloader.hpp"
using namespace Ogre;
namespace
@ -80,6 +91,38 @@ namespace
namespace MWWorld
{
struct GameContentLoader : public ContentLoader
{
GameContentLoader(Loading::Listener& listener)
: ContentLoader(listener)
{
}
bool addLoader(const std::string& extension, ContentLoader* loader)
{
return mLoaders.insert(std::make_pair(extension, loader)).second;
}
void load(const boost::filesystem::path& filepath, int& index)
{
LoadersContainer::iterator it(mLoaders.find(filepath.extension().string()));
if (it != mLoaders.end())
{
it->second->load(filepath, index);
}
else
{
std::string msg("Cannot load file: ");
msg += filepath.string();
throw std::runtime_error(msg.c_str());
}
}
private:
typedef std::tr1::unordered_map<std::string, ContentLoader*> LoadersContainer;
LoadersContainer mLoaders;
};
Ptr World::getPtrViaHandle (const std::string& handle, Ptr::CellStore& cell)
{
if (MWWorld::LiveCellRef<ESM::Activator> *ref =
@ -163,7 +206,7 @@ namespace MWWorld
World::World (OEngine::Render::OgreRenderer& renderer,
const Files::Collections& fileCollections,
const std::vector<std::string>& master, const std::vector<std::string>& plugins,
const std::vector<std::string>& contentFiles,
const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir,
ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap, int mActivationDistanceOverride)
: mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0),
@ -181,44 +224,22 @@ namespace MWWorld
mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback);
int idx = 0;
// NOTE: We might need to reserve one more for the running game / save.
mEsm.resize(master.size() + plugins.size());
mEsm.resize(contentFiles.size());
Loading::Listener* listener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
listener->loadingOn();
for (std::vector<std::string>::size_type i = 0; i < master.size(); i++, idx++)
{
boost::filesystem::path masterPath (fileCollections.getCollection (".esm").getPath (master[i]));
std::cout << "Loading ESM " << masterPath.string() << "\n";
listener->setLabel(masterPath.filename().string());
GameContentLoader gameContentLoader(*listener);
EsmLoader esmLoader(mStore, mEsm, encoder, *listener);
OmwLoader omwLoader(*listener);
// This parses the ESM file
ESM::ESMReader lEsm;
lEsm.setEncoder(encoder);
lEsm.setIndex(idx);
lEsm.setGlobalReaderList(&mEsm);
lEsm.open (masterPath.string());
mEsm[idx] = lEsm;
mStore.load (mEsm[idx], listener);
}
for (std::vector<std::string>::size_type i = 0; i < plugins.size(); i++, idx++)
{
boost::filesystem::path pluginPath (fileCollections.getCollection (".esp").getPath (plugins[i]));
gameContentLoader.addLoader(".esm", &esmLoader);
gameContentLoader.addLoader(".esp", &esmLoader);
gameContentLoader.addLoader(".omwgame", &omwLoader);
gameContentLoader.addLoader(".omwaddon", &omwLoader);
std::cout << "Loading ESP " << pluginPath.string() << "\n";
listener->setLabel(pluginPath.filename().string());
loadContentFiles(fileCollections, contentFiles, gameContentLoader);
// This parses the ESP file
ESM::ESMReader lEsm;
lEsm.setEncoder(encoder);
lEsm.setIndex(idx);
lEsm.setGlobalReaderList(&mEsm);
lEsm.open (pluginPath.string());
mEsm[idx] = lEsm;
mStore.load (mEsm[idx], listener);
}
listener->loadingOff();
// insert records that may not be present in all versions of MW
@ -1960,4 +1981,19 @@ namespace MWWorld
return mGodMode;
}
void World::loadContentFiles(const Files::Collections& fileCollections,
const std::vector<std::string>& content, ContentLoader& contentLoader)
{
std::vector<std::string>::const_iterator it(content.begin());
std::vector<std::string>::const_iterator end(content.end());
for (int idx = 0; it != end; ++it, ++idx)
{
boost::filesystem::path filename(*it);
const Files::MultiDirCollection& col = fileCollections.getCollection(filename.extension().string());
if (col.doesExist(*it))
{
contentLoader.load(col.getPath(*it), idx);
}
}
}
}

@ -14,6 +14,8 @@
#include "../mwbase/world.hpp"
#include "contentloader.hpp"
namespace Ogre
{
class Vector3;
@ -41,6 +43,8 @@ namespace MWRender
class Animation;
}
struct ContentLoader;
namespace MWWorld
{
class WeatherManager;
@ -113,6 +117,15 @@ namespace MWWorld
void ensureNeededRecords();
/**
* @brief loadContentFiles - Loads content files (esm,esp,omwgame,omwaddon)
* @param fileCollections- Container which holds content file names and their paths
* @param content - Container which holds content file names
* @param contentLoader -
*/
void loadContentFiles(const Files::Collections& fileCollections,
const std::vector<std::string>& content, ContentLoader& contentLoader);
int mPlayIntro;
bool mTeleportEnabled;
@ -121,7 +134,7 @@ namespace MWWorld
World (OEngine::Render::OgreRenderer& renderer,
const Files::Collections& fileCollections,
const std::vector<std::string>& master, const std::vector<std::string>& plugins,
const std::vector<std::string>& contentFiles,
const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir,
ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap, int mActivationDistanceOverride);

Loading…
Cancel
Save