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

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

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

@ -68,8 +68,7 @@ namespace OMW
boost::filesystem::path mResDir; boost::filesystem::path mResDir;
OEngine::Render::OgreRenderer *mOgre; OEngine::Render::OgreRenderer *mOgre;
std::string mCellName; std::string mCellName;
std::vector<std::string> mMaster; std::vector<std::string> mContentFiles;
std::vector<std::string> mPlugins;
int mFpsLevel; int mFpsLevel;
bool mVerboseScripts; bool mVerboseScripts;
bool mNewGame; bool mNewGame;
@ -135,13 +134,11 @@ namespace OMW
/// Set start cell name (only interiors for now) /// Set start cell name (only interiors for now)
void setCell(const std::string& cellName); void setCell(const std::string& cellName);
/// Set master file (esm) /**
/// - If the given name does not have an extension, ".esm" is added automatically * @brief addContentFile - Adds content file (ie. esm/esp, or omwgame/omwaddon) to the content files container.
void addMaster(const std::string& master); * @param file - filename (extension is required)
*/
/// Same as "addMaster", but for plugin files (esp) void addContentFile(const std::string& file);
/// - If the given name does not have an extension, ".esp" is added automatically
void addPlugin(const std::string& plugin);
/// Enable fps counter /// Enable fps counter
void showFPS(int level); 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"), ("start", bpo::value<std::string>()->default_value("Beshara"),
"set initial cell") "set initial cell")
("master", bpo::value<StringsVector>()->default_value(StringsVector(), "") ("content", bpo::value<StringsVector>()->default_value(StringsVector(), "")
->multitoken(), "master file(s)") ->multitoken(), "content file(s): esm/esp, or omwgame/omwaddon")
("plugin", bpo::value<StringsVector>()->default_value(StringsVector(), "")
->multitoken(), "plugin file(s)")
("anim-verbose", bpo::value<bool>()->implicit_value(true) ("anim-verbose", bpo::value<bool>()->implicit_value(true)
->default_value(false), "output animation indices files") ->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"); ("activate-dist", bpo::value <int> ()->default_value (-1), "activation distance override");
;
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv) bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv)
.options(desc).allow_unregistered().run(); .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>()); engine.setResourceDir(variables["resources"].as<std::string>());
// master and plugin StringsVector content = variables["content"].as<StringsVector>();
StringsVector master = variables["master"].as<StringsVector>(); if (content.empty())
if (master.empty())
{ {
std::cout << "No master file given. Aborting...\n"; std::cout << "No content file given (esm/esp, nor omwgame/omwaddon). Aborting..." << std::endl;
return false; return false;
} }
StringsVector plugin = variables["plugin"].as<StringsVector>(); StringsVector::const_iterator it(content.begin());
// Removed check for 255 files, which would be the hard-coded limit in Morrowind. StringsVector::const_iterator end(content.end());
// I'll keep the following variable in, maybe we can use it for something different. for (; it != end; ++it)
// 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++)
{ {
engine.addPlugin(plugin[i]); engine.addContentFile(*it);
} }
// startup-settings // 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" #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> #include <OgreSceneNode.h>
@ -31,6 +38,10 @@
#include "containerstore.hpp" #include "containerstore.hpp"
#include "inventorystore.hpp" #include "inventorystore.hpp"
#include "contentloader.hpp"
#include "esmloader.hpp"
#include "omwloader.hpp"
using namespace Ogre; using namespace Ogre;
namespace namespace
@ -80,6 +91,38 @@ namespace
namespace MWWorld 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) Ptr World::getPtrViaHandle (const std::string& handle, Ptr::CellStore& cell)
{ {
if (MWWorld::LiveCellRef<ESM::Activator> *ref = if (MWWorld::LiveCellRef<ESM::Activator> *ref =
@ -163,7 +206,7 @@ namespace MWWorld
World::World (OEngine::Render::OgreRenderer& renderer, World::World (OEngine::Render::OgreRenderer& renderer,
const Files::Collections& fileCollections, 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, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir,
ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap, int mActivationDistanceOverride) ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap, int mActivationDistanceOverride)
: mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0), : mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0),
@ -181,44 +224,22 @@ namespace MWWorld
mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback); mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback);
int idx = 0;
// NOTE: We might need to reserve one more for the running game / save. // 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(); Loading::Listener* listener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
listener->loadingOn(); 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"; GameContentLoader gameContentLoader(*listener);
listener->setLabel(masterPath.filename().string()); EsmLoader esmLoader(mStore, mEsm, encoder, *listener);
OmwLoader omwLoader(*listener);
// This parses the ESM file gameContentLoader.addLoader(".esm", &esmLoader);
ESM::ESMReader lEsm; gameContentLoader.addLoader(".esp", &esmLoader);
lEsm.setEncoder(encoder); gameContentLoader.addLoader(".omwgame", &omwLoader);
lEsm.setIndex(idx); gameContentLoader.addLoader(".omwaddon", &omwLoader);
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]));
std::cout << "Loading ESP " << pluginPath.string() << "\n"; loadContentFiles(fileCollections, contentFiles, gameContentLoader);
listener->setLabel(pluginPath.filename().string());
// 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(); listener->loadingOff();
// insert records that may not be present in all versions of MW // insert records that may not be present in all versions of MW
@ -1960,4 +1981,19 @@ namespace MWWorld
return mGodMode; 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 "../mwbase/world.hpp"
#include "contentloader.hpp"
namespace Ogre namespace Ogre
{ {
class Vector3; class Vector3;
@ -41,6 +43,8 @@ namespace MWRender
class Animation; class Animation;
} }
struct ContentLoader;
namespace MWWorld namespace MWWorld
{ {
class WeatherManager; class WeatherManager;
@ -113,6 +117,15 @@ namespace MWWorld
void ensureNeededRecords(); 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; int mPlayIntro;
bool mTeleportEnabled; bool mTeleportEnabled;
@ -121,7 +134,7 @@ namespace MWWorld
World (OEngine::Render::OgreRenderer& renderer, World (OEngine::Render::OgreRenderer& renderer,
const Files::Collections& fileCollections, 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, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir,
ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap, int mActivationDistanceOverride); ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap, int mActivationDistanceOverride);

Loading…
Cancel
Save