- Add some updated files missing from last commit.

- Move plugin dependency test from esmreader.cpp to esmstpre.cpp; fixes crash in omwlauncher.
pull/16/head
Mark Siewert 12 years ago
parent 8ea9f00e6f
commit 896ab44d1e

@ -34,7 +34,7 @@ add_openmw_dir (mwgui
)
add_openmw_dir (mwdialogue
dialoguemanagerimp journalimp journalentry quest topic
dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper
)
add_openmw_dir (mwscript
@ -50,9 +50,10 @@ add_openmw_dir (mwsound
add_openmw_dir (mwworld
refdata worldimp physicssystem scene globals class action nullaction actionteleport
containerstore actiontalk actiontake manualref player cellfunctors
containerstore actiontalk actiontake manualref player cellfunctors failedaction
cells localscripts customdata weather inventorystore ptr actionopen actionread
actionequip timestamp actionalchemy cellstore actionapply actioneat
esmstore store recordcmp
)
add_openmw_dir (mwclass
@ -62,7 +63,7 @@ add_openmw_dir (mwclass
add_openmw_dir (mwmechanics
mechanicsmanagerimp stat creaturestats magiceffects movement actors drawstate spells
activespells npcstats aipackage aisequence alchemy
activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow aiescort aiactivate
)
add_openmw_dir (mwbase

@ -221,7 +221,7 @@ namespace MWRender
//
//If we don't sort the ltex indexes, the splatting order may differ between
//cells which may lead to inconsistent results when shading between cells
int num = MWBase::Environment::get().getWorld()->getStore().landTexts.getSizePlugin(plugin);
int num = MWBase::Environment::get().getWorld()->getStore().get<ESM::LandTexture>().getSize(plugin);
std::set<uint16_t> ltexIndexes;
for ( int y = fromY - 1; y < fromY + size + 1; y++ )
{

@ -49,10 +49,10 @@ namespace MWWorld
return; // this is a dynamically generated cell -> skipping.
// Load references from all plugins that do something with this cell.
for (size_t i = 0; i < cell->mContextList.size(); i++)
for (size_t i = 0; i < mCell->mContextList.size(); i++)
{
// Reopen the ESM reader and seek to the right position.
int index = cell->mContextList.at(i).index;
int index = mCell->mContextList.at(i).index;
mCell->restore (esm[index], i);
ESM::CellRef ref;
@ -81,10 +81,10 @@ namespace MWWorld
return; // this is a dynamically generated cell -> skipping.
// Load references from all plugins that do something with this cell.
for (size_t i = 0; i < cell->mContextList.size(); i++)
for (size_t i = 0; i < mCell->mContextList.size(); i++)
{
// Reopen the ESM reader and seek to the right position.
int index = cell->mContextList.at(i).index;
int index = mCell->mContextList.at(i).index;
mCell->restore (esm[index], i);
ESM::CellRef ref;

@ -49,26 +49,32 @@ namespace MWWorld
{
typedef LiveCellRef<X> LiveRef;
typedef std::map<int,LiveRef> List;
List list;
List mList;
// Search for the given reference in the given reclist from
// ESMStore. Insert the reference into the list if a match is
// found. If not, throw an exception.
template <typename Y>
void find(ESM::CellRef &ref, const Y& recList)
/// Searches for reference of appropriate type in given ESMStore.
/// If reference exists, loads it into container, throws an exception
/// on miss
void load(ESM::CellRef &ref, const MWWorld::ESMStore &esmStore)
{
const X* obj = recList.find(ref.mRefID);
if(obj == NULL)
throw std::runtime_error("Error resolving cell reference " + ref.mRefID);
// for throwing exception on unhandled record type
const MWWorld::Store<X> &store = esmStore.get<X>();
const X *ptr = store.find(ref.mRefID);
list[ref.mRefnum] = LiveRef(ref, obj);
/// \note redundant because Store<X>::find() throws exception on miss
if (ptr == NULL) {
throw std::runtime_error("Error resolving cell reference " + ref.mRefID);
}
mList[ref.mRefnum] = LiveRef(ref, ptr);
}
LiveRef *find (const std::string& name)
{
for (typename std::map<int,LiveRef>::iterator iter (list.begin()); iter!=list.end(); ++iter)
for (typename std::map<int,LiveRef>::iterator iter (mList.begin()); iter!=mList.end(); ++iter)
{
if (iter->second.mData.getCount() > 0 && iter->second.ref.mRefID == name)
if (iter->second.mData.getCount() > 0 && iter->second.mRef.mRefID == name)
return &iter->second;
}
@ -76,8 +82,8 @@ namespace MWWorld
}
LiveRef &insert(const LiveRef &item) {
list[item.ref.mRefnum] = item;
return list[item.ref.mRefnum];
mList[item.mRef.mRefnum] = item;
return mList[item.mRef.mRefnum];
}
};

@ -3,6 +3,8 @@
#include <set>
#include <iostream>
#include <boost/filesystem/v3/operations.hpp>
namespace MWWorld
{
@ -25,6 +27,33 @@ void ESMStore::load(ESM::ESMReader &esm)
ESM::Dialogue *dialogue = 0;
// Cache parent esX files by tracking their indices in the global list of
// all files/readers used by the engine. This will greaty help to accelerate
// parsing of reference IDs.
size_t index = ~0;
const ESM::ESMReader::MasterList &masters = esm.getMasters();
std::vector<ESM::ESMReader> *allPlugins = esm.getGlobalReaderList();
for (size_t j = 0; j < masters.size(); j++) {
ESM::MasterData &mast = const_cast<ESM::MasterData&>(masters[j]);
std::string fname = mast.name;
for (size_t i = 0; i < esm.getIndex(); i++) {
const std::string &candidate = allPlugins->at(i).getContext().filename;
std::string fnamecandidate = boost::filesystem::path(candidate).filename().string();
if (fname == fnamecandidate) {
index = i;
break;
}
}
if (index == (size_t)~0) {
// Tried to load a parent file that has not been loaded yet. This is bad,
// the launcher should have taken care of this.
std::string fstring = "File " + fname + " asks for parent file " + masters[j].name
+ ", but it has not been loaded yet. Please check your load order.";
esm.fail(fstring);
}
mast.index = index;
}
// Loop through all records
while(esm.hasMoreRecs())
{

@ -219,24 +219,31 @@ namespace MWWorld
template <>
class Store<ESM::LandTexture> : public StoreBase
{
std::vector<ESM::LandTexture> mStatic;
// For multiple ESM/ESP files we need one list per file.
typedef std::vector<ESM::LandTexture> LandTextureList;
std::vector<LandTextureList> mStatic;
public:
Store<ESM::LandTexture>() {
mStatic.reserve(128);
mStatic.push_back(LandTextureList());
LandTextureList &ltexl = mStatic[0];
// More than enough to hold Morrowind.esm. Extra lists for plugins will we
// added on-the-fly in a different method.
ltexl.reserve(128);
}
typedef std::vector<ESM::LandTexture>::const_iterator iterator;
const ESM::LandTexture *search(size_t index) const {
if (index < mStatic.size()) {
return &mStatic.at(index);
}
return 0;
const ESM::LandTexture *search(size_t index, size_t plugin) const {
assert(plugin < mStatic.size());
const LandTextureList &ltexl = mStatic[plugin];
assert(index < ltexl.size());
return &ltexl.at(index);
}
const ESM::LandTexture *find(size_t index) const {
const ESM::LandTexture *ptr = search(index);
const ESM::LandTexture *find(size_t index, size_t plugin) const {
const ESM::LandTexture *ptr = search(index, plugin);
if (ptr == 0) {
std::ostringstream msg;
msg << "Land texture with index " << index << " not found";
@ -249,23 +256,40 @@ namespace MWWorld
return mStatic.size();
}
void load(ESM::ESMReader &esm, const std::string &id) {
ESM::LandTexture ltex;
ltex.load(esm);
int getSize(size_t plugin) const {
assert(plugin < mStatic.size());
return mStatic[plugin].size();
}
void load(ESM::ESMReader &esm, const std::string &id, size_t plugin) {
ESM::LandTexture lt;
lt.load(esm);
lt.mId = id;
if (ltex.mIndex >= (int) mStatic.size()) {
mStatic.resize(ltex.mIndex + 1);
// Make sure we have room for the structure
if (plugin >= mStatic.size()) {
mStatic.resize(plugin+1);
}
mStatic[ltex.mIndex] = ltex;
mStatic[ltex.mIndex].mId = id;
LandTextureList &ltexl = mStatic[plugin];
if(lt.mIndex + 1 > (int)ltexl.size())
ltexl.resize(lt.mIndex+1);
// Store it
ltexl[lt.mIndex] = lt;
}
iterator begin() const {
return mStatic.begin();
void load(ESM::ESMReader &esm, const std::string &id) {
load(esm, id, esm.getIndex());
}
iterator end() const {
return mStatic.end();
iterator begin(size_t plugin) const {
assert(plugin < mStatic.size());
return mStatic[plugin].begin();
}
iterator end(size_t plugin) const {
assert(plugin < mStatic.size());
return mStatic[plugin].end();
}
};

@ -1081,8 +1081,8 @@ namespace MWWorld
std::vector<World::DoorMarker> result;
MWWorld::CellRefList<ESM::Door>& doors = cell->mDoors;
std::map< MWWorld::LiveCellRef<ESM::Door> >& refList = doors.mList;
for (std::map<int, MWWorld::LiveCellRef<ESM::Door> >::iterator it = refList.begin(); it != refList.end(); ++it)
CellRefList<ESM::Door>::List& refList = doors.mList;
for (CellRefList<ESM::Door>::List::iterator it = refList.begin(); it != refList.end(); ++it)
{
MWWorld::LiveCellRef<ESM::Door>& ref = it->second;

@ -1,6 +1,5 @@
#include "esmreader.hpp"
#include <stdexcept>
#include <boost/filesystem/v3/operations.hpp>
namespace ESM
{
@ -62,7 +61,6 @@ void ESMReader::openRaw(Ogre::DataStreamPtr _esm, const std::string &name)
void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name)
{
openRaw(_esm, name);
std::string fname = boost::filesystem::path(name).filename().string();
if (getRecName() != "TES3")
fail("Not a valid Morrowind file");
@ -80,29 +78,6 @@ void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name)
MasterData m;
m.name = getHString();
m.size = getHNLong("DATA");
// Cache parent esX files by tracking their indices in the global list of
// all files/readers used by the engine. This will greaty help to accelerate
// parsing of reference IDs.
size_t index = ~0;
// TODO: check for case mismatch, it might be required on Windows.
size_t i = 0;
// FIXME: This is ugly! Make it nicer!
for (; i < idx; i++) {
const std::string &candidate = mGlobalReaderList->at(i).getContext().filename;
std::string fnamecandidate = boost::filesystem::path(candidate).filename().string();
if (m.name == fnamecandidate) {
index = i;
break;
}
}
if (index == (size_t)~0) {
// Tried to load a parent file that has not been loaded yet. This is bad,
// the launcher should have taken care of this.
std::string fstring = "File " + fname + " asks for parent file " + m.name
+ ", but it has not been loaded yet. Please check your load order.";
fail(fstring);
}
m.index = index;
mMasters.push_back(m);
}

@ -85,6 +85,7 @@ public:
const int getIndex() {return idx;}
void setGlobalReaderList(std::vector<ESMReader> *list) {mGlobalReaderList = list;}
std::vector<ESMReader> *getGlobalReaderList() {return mGlobalReaderList;}
/*************************************************************************
*

Loading…
Cancel
Save