diff --git a/source/graphics/Decal.h b/source/graphics/Decal.h index af2516b3fe..28411019c6 100644 --- a/source/graphics/Decal.h +++ b/source/graphics/Decal.h @@ -53,6 +53,7 @@ public: CModelDecal(CTerrain* terrain, const SDecal& decal) : m_Terrain(terrain), m_Decal(decal) { + ENSURE(terrain != NULL); } /// Dynamic cast diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp index 06a90986f1..1b59ecf452 100644 --- a/source/graphics/MapReader.cpp +++ b/source/graphics/MapReader.cpp @@ -131,9 +131,15 @@ void CMapReader::LoadMap(const VfsPath& pathname, const CScriptValRooted& setti RegMemFun(this, &CMapReader::UnpackMap, L"CMapReader::UnpackMap", 1200); // read the corresponding XML file - RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 5800); + RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 50); - // apply data to the world + // apply terrain data to the world + RegMemFun(this, &CMapReader::ApplyTerrainData, L"CMapReader::ApplyTerrainData", 5); + + // read entities + RegMemFun(this, &CMapReader::ReadXMLEntities, L"CMapReader::ReadXMLEntities", 5800); + + // apply misc data to the world RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 5); // load map settings script (must be done after reading map) @@ -189,10 +195,13 @@ void CMapReader::LoadRandomMap(const CStrW& scriptFile, const CScriptValRooted& // parse RMS results into camera settings RegMemFun(this, &CMapReader::ParseCamera, L"CMapReader::ParseCamera", 5); + // apply terrain data to the world + RegMemFun(this, &CMapReader::ApplyTerrainData, L"CMapReader::ApplyTerrainData", 5); + // parse RMS results into entities RegMemFun(this, &CMapReader::ParseEntities, L"CMapReader::ParseEntities", 1000); - // apply data to the world + // apply misc data to the world RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 5); // load map settings script (must be done after reading map) @@ -264,8 +273,7 @@ int CMapReader::UnpackTerrain() return 0; } -// ApplyData: take all the input data, and rebuild the scene from it -int CMapReader::ApplyData() +int CMapReader::ApplyTerrainData() { if (m_PatchesPerSide == 0) { @@ -296,6 +304,16 @@ int CMapReader::ApplyData() } } + CmpPtr cmpTerrain(*pSimContext, SYSTEM_ENTITY); + if (cmpTerrain) + cmpTerrain->ReloadTerrain(); + + return 0; +} + +// ApplyData: take all the input data, and rebuild the scene from it +int CMapReader::ApplyData() +{ // copy over the lighting parameters if (pLightEnv) *pLightEnv = m_LightEnv; @@ -327,10 +345,6 @@ int CMapReader::ApplyData() } } - CmpPtr cmpTerrain(*pSimContext, SYSTEM_ENTITY); - if (cmpTerrain) - cmpTerrain->ReloadTerrain(); - return 0; } @@ -398,8 +412,11 @@ public: CStr ReadScriptSettings(); + // read everything except for entities + void ReadXML(); + // return semantics: see Loader.cpp!LoadFunc. - int ProgressiveRead(); + int ProgressiveReadEntities(); private: CXeromyces xmb_file; @@ -1074,17 +1091,11 @@ int CXMLReader::ReadEntities(XMBElement parent, double end_time) return 0; } -int CXMLReader::ProgressiveRead() +void CXMLReader::ReadXML() { - // yield after this time is reached. balances increased progress bar - // smoothness vs. slowing down loading. - const double end_time = timer_Time() + 200e-3; - - int ret; - - while (node_idx < nodes.Count) + for (int i = 0; i < nodes.Count; ++i) { - XMBElement node = nodes.Item(node_idx); + XMBElement node = nodes.Item(i); CStr name = xmb_file.GetElementString(node.GetNodeName()); if (name == "Terrain") { @@ -1100,16 +1111,11 @@ int CXMLReader::ProgressiveRead() } else if (name == "ScriptSettings") { - //Already loaded - this is to prevent an assertion + // Already loaded - this is to prevent an assertion } else if (name == "Entities") { - if (!m_MapReader.m_SkipEntities) - { - ret = ReadEntities(node, end_time); - if (ret != 0) // error or timed out - return ret; - } + // Handled by ProgressiveReadEntities instead } else if (name == "Paths") { @@ -1129,6 +1135,30 @@ int CXMLReader::ProgressiveRead() debug_printf(L"Invalid XML element in map file: %hs\n", name.c_str()); debug_warn(L"Invalid map XML data"); } + } +} + +int CXMLReader::ProgressiveReadEntities() +{ + // yield after this time is reached. balances increased progress bar + // smoothness vs. slowing down loading. + const double end_time = timer_Time() + 200e-3; + + int ret; + + while (node_idx < nodes.Count) + { + XMBElement node = nodes.Item(node_idx); + CStr name = xmb_file.GetElementString(node.GetNodeName()); + if (name == "Entities") + { + if (!m_MapReader.m_SkipEntities) + { + ret = ReadEntities(node, end_time); + if (ret != 0) // error or timed out + return ret; + } + } node_idx++; } @@ -1170,13 +1200,23 @@ int CMapReader::LoadMapSettings() return 0; } -// progressive int CMapReader::ReadXML() { if (!xml_reader) xml_reader = new CXMLReader(filename_xml, *this); - int ret = xml_reader->ProgressiveRead(); + xml_reader->ReadXML(); + + return 0; +} + +// progressive +int CMapReader::ReadXMLEntities() +{ + if (!xml_reader) + xml_reader = new CXMLReader(filename_xml, *this); + + int ret = xml_reader->ProgressiveReadEntities(); // finished or failed if (ret <= 0) { diff --git a/source/graphics/MapReader.h b/source/graphics/MapReader.h index 3d61fc042f..e224162e1d 100644 --- a/source/graphics/MapReader.h +++ b/source/graphics/MapReader.h @@ -79,10 +79,14 @@ private: // ApplyData: take all the input data, and rebuild the scene from it int ApplyData(); + int ApplyTerrainData(); - // ReadXML: read some other data (entities, etc) in XML format + // read some misc data from the XML file int ReadXML(); + // read entity data from the XML file + int ReadXMLEntities(); + // clean up everything used during delayed load int DelayLoadFinished();