diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e688969ce..4093e33877 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ set(BSA bsa/bsa_archive.cpp bsa/bsa_file.cpp) set(NIF nif/nif_file.cpp nifogre/ogre_nif_loader.cpp) set(TOOLS tools/stringops.cpp) set(MANGLE_VFS mangle/vfs/servers/ogre_vfs.cpp) -set(GAME game/main.cpp) +set(GAME game/main.cpp game/esm_store.cpp) # Platform specific if (WIN32) diff --git a/esm/esm_reader.hpp b/esm/esm_reader.hpp index 440e4abd80..4e9d6c85dc 100644 --- a/esm/esm_reader.hpp +++ b/esm/esm_reader.hpp @@ -222,8 +222,8 @@ public: else spf = SF_Other; } - /// Load ES file from a new stream, parses the header. Calls close() - /// automatically. + /// Load ES file from a new stream, parses the header. Closes the + /// currently open file first, if any. void open(Mangle::Stream::StreamPtr _esm, const std::string &name) { openRaw(_esm, name); diff --git a/game/esm_store.cpp b/game/esm_store.cpp new file mode 100644 index 0000000000..1544719dec --- /dev/null +++ b/game/esm_store.cpp @@ -0,0 +1,184 @@ +#include +#include +#include "esm_store.hpp" + +using namespace ESM; +using namespace std; + +struct RecList +{ + virtual void load(ESMReader &esm) = 0; + virtual int getSize() = 0; + virtual const string& getName() = 0; +}; + +/* Lists all the list types. Mostly used for quick lookup on + loading. The index is the record name (4 chars) parsed as a 32 bit + int. Eg. REC_ACTI, REC_BOOK etc. See esm/records.hpp for the + complete list. + */ +typedef map RecListList; +RecListList recLists; + +template +struct RecListIDT : RecList +{ + // Store ourselves in the list of all lists + RecListIDT() { recLists[RecID] = this; } +}; + +template +struct RecListT : RecListIDT +{ + typedef map MapType; + + MapType list; + string listName; + + RecListT(const string &name) : listName(name) {} + + void load(ESMReader &esm) + { + string id = esm.getHNString("NAME"); + + X &ref = list[id]; + ref.load(esm); + } + + int getSize() { return list.size(); } + + const string& getName() { return listName; } +}; + +// The only difference to the above is a slight change to the load() +// function. We might merge these together later, and store the id in +// all the structs. +template +struct RecIDListT : RecListIDT +{ + typedef map MapType; + + MapType list; + string listName; + + RecIDListT(const string &name) : listName(name) {} + + void load(ESMReader &esm) + { + string id = esm.getHNString("NAME"); + + X &ref = list[id]; + ref.id = id; + ref.load(esm); + } + + int getSize() { return list.size(); } + + const string& getName() { return listName; } +}; + +// Cells aren't simply indexed by name. Exterior cells are treated +// separately. +struct CellList : RecListIDT +{ + // Just count them for now + int count; + string listName; + + CellList() { listName = "Cells"; } + + void load(ESMReader &esm) + { + count++; + esm.skipRecord(); + } + + int getSize() { return count; } + + const string& getName() { return listName; } +}; + +/* We need special lists for: + + Cells (partially done) + Magic effects + Skills + Dialog / Info combo + Scripts + Land + Path grids + Land textures + */ + +RecListT activators ("Activators"); +RecListT potions ("Potions"); +RecListT appas ("Apparatuses"); +RecListT armors ("Armors"); +RecListT bodyParts ("Body parts"); +RecListT books ("Books"); +RecListT birthSigns ("Birth signs"); +CellList cells; +RecListT classes ("Classes"); +RecListT clothes ("Clothes"); +RecListT contChange ("Container changes"); +RecListT containers ("Containers"); +RecListT creatures ("Creatures"); +RecListT creaChange ("Creature changes"); +RecListT dialogs ("Dialogues"); +RecListT doors ("Doors"); +RecListT enchants ("Enchantments"); +RecListT factions ("Factions"); +RecListT globals ("Globals"); +RecIDListTgameSettings ("Game settings"); +//RecListT dialInfos ("Dialog entries"); +RecListT ingreds ("Ingredients"); +//RecListT lands ("Land data"); +RecListT creatureLists("Creature leveled lists"); +RecListT itemLists ("Item leveled lists"); +RecListT lights ("Lights"); +RecListT lockpicks ("Lockpicks"); +//RecListT landTexts ("Land textures"); +//RecListT magicEffects ("Magic effects"); +RecListT miscItems ("Misc items"); +RecListT npcs ("NPCs"); +RecListT npcChange ("NPC changes"); +//RecListT pathgrids ("Path grids"); +RecListT probes ("Probes"); +RecListT races ("Races"); +RecListT regions ("Regions"); +RecListT repairs ("Repair items"); +//RecListT scripts ("Scripts"); +//RecListT skills ("Skills"); +RecListT soundGens ("Sound generators"); +RecListT sounds ("Sounds"); +RecListT spells ("Spells"); +RecListT startScripts ("Start scripts"); +RecListT statics ("Statics"); +RecListT weapons ("Weapons"); + +void storeESM(ESMReader &esm) +{ + // Loop through all records + while(esm.hasMoreRecs()) + { + NAME n = esm.getRecName(); + esm.getRecHeader(); + + // Look up the record type. + RecListList::iterator it = recLists.find(n.val); + + if(it == recLists.end()) + { + // Not found (this would be an error later) + esm.skipRecord(); + continue; + } + + // Load it + it->second->load(esm); + } + + cout << "\n" << recLists.size() << " record types:\n"; + for(RecListList::iterator it = recLists.begin(); it != recLists.end(); it++) + cout << " " << it->second->getName() << ": " << it->second->getSize() << endl; +} diff --git a/game/esm_store.hpp b/game/esm_store.hpp new file mode 100644 index 0000000000..a074c90b7b --- /dev/null +++ b/game/esm_store.hpp @@ -0,0 +1,8 @@ +#ifndef _GAME_ESM_STORE_H +#define _GAME_ESM_STORE_H + +#include "esm/records.hpp" + +void storeESM(ESM::ESMReader &esm); + +#endif diff --git a/game/main.cpp b/game/main.cpp index fd013dd4e0..677b0ca37d 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -1,7 +1,7 @@ #include #include "bsa/bsa_archive.h" -#include "esm/records.hpp" +#include "esm_store.hpp" #include "Ogre.h" @@ -34,9 +34,11 @@ void maintest() cout << "Adding " << bsaFile << endl; addBSA(bsaFile); - cout << "Loading ESM " << esmFile << " (header only)\n"; + cout << "Loading ESM " << esmFile << "\n"; ESM::ESMReader esm; esm.open(esmFile); + storeESM(esm); + esm.close(); cout << "\nThat's all for now!\n"; } diff --git a/nifogre/tests/ogre_skeleton_test.cpp b/nifogre/tests/ogre_skeleton_test.cpp index 5fd0c8d589..df9139b95b 100644 --- a/nifogre/tests/ogre_skeleton_test.cpp +++ b/nifogre/tests/ogre_skeleton_test.cpp @@ -1,7 +1,13 @@ -#include "ogre_mesh_common.cpp" +#include "ogre_common.cpp" void C::doTest() { + SkeletonManager &skm = SkeletonManager::getSingleton(); + + SkeletonPtr skp = skm.create("MySkel", "General"); + + cout << "hello\n"; + /* MeshPtr msh = makeMesh("mesh1"); // Display the mesh @@ -11,4 +17,5 @@ void C::doTest() node->attachObject(ent); node->setPosition(0,0,4); } + */ }