diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp index 85ad0f3669..200786fc01 100755 --- a/source/graphics/MapReader.cpp +++ b/source/graphics/MapReader.cpp @@ -1,7 +1,7 @@ #include "precompiled.h" -#include "lib/types.h" #include "MapReader.h" +#include "lib/types.h" #include "UnitManager.h" #include "Unit.h" #include "Game.h" @@ -21,8 +21,8 @@ #define LOG_CATEGORY "graphics" -// CMapReader constructor: nothing to do at the minute CMapReader::CMapReader() + : xml_reader(0) { } @@ -44,23 +44,23 @@ void CMapReader::LoadMap(const char* filename, CTerrain *pTerrain_, CUnitManager } // unpack the data - RegMemFun(this, &CMapReader::UnpackMap, L"CMapReader::UnpackMap", 691); + RegMemFun(this, &CMapReader::UnpackMap, L"CMapReader::UnpackMap", 1900); // apply data to the world - RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 415); + RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 20); if (unpacker.GetVersion()>=3) { // read the corresponding XML file filename_xml = filename; filename_xml = filename_xml.Left(filename_xml.Length()-4) + ".xml"; - RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 1320); + RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 1300); } - RegMemFun(this, &CMapReader::DelayLoadFinished, L"CMapReader::DelayLoadFinished", 3); + RegMemFun(this, &CMapReader::DelayLoadFinished, L"CMapReader::DelayLoadFinished", 5); } // UnpackMap: unpack the given data from the raw data stream into local variables -void CMapReader::UnpackMap() +int CMapReader::UnpackMap() { // now unpack everything into local data UnpackTerrain(); @@ -68,6 +68,8 @@ void CMapReader::UnpackMap() if (unpacker.GetVersion()>=2) { UnpackLightEnv(); } + + return 0; } // UnpackLightEnv: unpack lighting parameters from input stream @@ -138,7 +140,7 @@ void CMapReader::UnpackTerrain() } // ApplyData: take all the input data, and rebuild the scene from it -void CMapReader::ApplyData() +int CMapReader::ApplyData() { // initialise the terrain pTerrain->Initialize(m_MapSize,&m_Heightmap[0]); @@ -211,27 +213,74 @@ void CMapReader::ApplyData() // copy over the lighting parameters *pLightEnv=m_LightEnv; } + + return 0; } -void CMapReader::ReadXML() + + +class CXMLReader { +public: + CXMLReader(const CStr& xml_filename) + { + Init(xml_filename); + } + + // return semantics: see Loader.cpp!LoadFunc. + int ProgressiveRead(); + +private: + CXeromyces xmb_file; + + int el_scenario, el_entities, el_entity; + int el_template, el_player; + int el_position, el_orientation; + int el_nonentities, el_nonentity; + int el_actor; + int at_x, at_y, at_z; + int at_angle; + + XMBElement root; + XMBElementList nodes; // children of root + XMBElement node; // a child of nodes + XMBElementList entities, nonentities; // children of node + + // loop counters + int node_idx; + int entity_idx, nonentity_idx; + + // # entities+nonentities processed and total (for progress calc) + int completed_jobs, total_jobs; + + + void Init(const CStr& xml_filename); + int ReadEntities(XMBElement& parent, double end_time); + int ReadNonEntities(XMBElement& parent, double end_time); +}; + + +void CXMLReader::Init(const CStr& xml_filename) +{ + // must only assign once, so do it here + node_idx = entity_idx = nonentity_idx = 0; + #ifdef SCED // HACK: ScEd uses absolute filenames, not VFS paths. I can't be bothered // to make Xeromyces work with non-VFS, so just cheat: - CStr filename_vfs (filename_xml); - filename_vfs = filename_vfs.substr(filename_vfs.ReverseFind("\\mods\\official\\") + 15); - filename_vfs.Replace("\\", "/"); - filename_xml = filename_vfs; + CStr vfs_filename(xml_filename); + vfs_filename = vfs_filename.substr(vfs_filename.ReverseFind("\\mods\\official\\") + 15); + vfs_filename.Replace("\\", "/"); + xml_filename = vfs_filename; #endif - CXeromyces XeroFile; - if (XeroFile.Load(filename_xml) != PSRETURN_OK) + if (xmb_file.Load(xml_filename) != PSRETURN_OK) throw CFileUnpacker::CFileReadError(); - // Define all the elements and attributes used in the XML file -#define EL(x) int el_##x = XeroFile.getElementID(#x) -#define AT(x) int at_##x = XeroFile.getAttributeID(#x) + // define all the elements and attributes used in the XML file. +#define EL(x) el_##x = xmb_file.getElementID(#x) +#define AT(x) at_##x = xmb_file.getAttributeID(#x) EL(scenario); EL(entities); EL(entity); @@ -249,136 +298,220 @@ void CMapReader::ReadXML() #undef AT #undef EL - XMBElement root = XeroFile.getRoot(); + root = xmb_file.getRoot(); assert(root.getNodeName() == el_scenario); + nodes = root.getChildNodes(); - // - - XMBElementList children = root.getChildNodes(); - for (int i = 0; i < children.Count; ++i) + // find out total number of entities+nonentities + // (used when calculating progress) + completed_jobs = 0; + total_jobs = 0; + for (int i = 0; i < nodes.Count; i++) { - XMBElement child = children.item(i); - if (child.getNodeName() == el_entities) - { - // - - XMBElementList children = child.getChildNodes(); - for (int i = 0; i < children.Count; ++i) - { - XMBElement child = children.item(i); - assert(child.getNodeName() == el_entity); - - // - - CStrW TemplateName; - int PlayerID; - CVector3D Position; - float Orientation; - - XMBElementList children = child.getChildNodes(); - for (int i = 0; i < children.Count; ++i) - { - XMBElement child = children.item(i); - int element_name = child.getNodeName(); - - if (element_name == el_template) - { //