Index: ps/trunk/source/graphics/MapReader.cpp =================================================================== --- ps/trunk/source/graphics/MapReader.cpp (revision 2037) +++ ps/trunk/source/graphics/MapReader.cpp (revision 2038) @@ -1,309 +1,315 @@ #include "precompiled.h" #include "lib/types.h" #include "MapReader.h" #include "UnitManager.h" #include "Unit.h" #include "Game.h" #include "ObjectManager.h" #include "BaseEntity.h" #include "BaseEntityCollection.h" #include "EntityManager.h" #include "Model.h" #include "Terrain.h" #include "TextureManager.h" #include "timer.h" +#include "Loader.h" +#include "LoaderThunks.h" // CMapReader constructor: nothing to do at the minute CMapReader::CMapReader() { } + // LoadMap: try to load the map from given file; reinitialise the scene to new data if successful -void CMapReader::LoadMap(const char* filename, CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv) +void CMapReader::LoadMap(const char* filename, CTerrain *pTerrain_, CUnitManager *pUnitMan_, CLightEnv *pLightEnv_) { - TIMER(__CMapReader__LoadMap); + // latch parameters (held until DelayedLoadFinished) + pTerrain = pTerrain_; + pUnitMan = pUnitMan_; + pLightEnv = pLightEnv_; - CFileUnpacker unpacker; - { - TIMER(____CMapReader__LoadMap__read); - unpacker.Read(filename,"PSMP"); - } + // [25ms] + unpacker.Read(filename,"PSMP"); // check version if (unpacker.GetVersion()=3) { // read the corresponding XML file - CStr filename_xml (filename); + filename_xml = filename; filename_xml = filename_xml.Left(filename_xml.Length()-4) + ".xml"; - ReadXML(filename_xml); + RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 1320); } + + RegMemFun(this, &CMapReader::DelayLoadFinished, L"CMapReader::DelayLoadFinished", 3); } // UnpackMap: unpack the given data from the raw data stream into local variables -void CMapReader::UnpackMap(CFileUnpacker& unpacker) +void CMapReader::UnpackMap() { -TIMER(____CMapReader__UnpackMap); - // now unpack everything into local data - UnpackTerrain(unpacker); - UnpackObjects(unpacker); + UnpackTerrain(); + UnpackObjects(); if (unpacker.GetVersion()>=2) { - UnpackLightEnv(unpacker); + UnpackLightEnv(); } } // UnpackLightEnv: unpack lighting parameters from input stream -void CMapReader::UnpackLightEnv(CFileUnpacker& unpacker) +void CMapReader::UnpackLightEnv() { unpacker.UnpackRaw(&m_LightEnv.m_SunColor,sizeof(m_LightEnv.m_SunColor)); unpacker.UnpackRaw(&m_LightEnv.m_Elevation,sizeof(m_LightEnv.m_Elevation)); unpacker.UnpackRaw(&m_LightEnv.m_Rotation,sizeof(m_LightEnv.m_Rotation)); unpacker.UnpackRaw(&m_LightEnv.m_TerrainAmbientColor,sizeof(m_LightEnv.m_TerrainAmbientColor)); unpacker.UnpackRaw(&m_LightEnv.m_UnitsAmbientColor,sizeof(m_LightEnv.m_UnitsAmbientColor)); m_LightEnv.CalculateSunDirection(); } // UnpackObjects: unpack world objects from input stream -void CMapReader::UnpackObjects(CFileUnpacker& unpacker) +void CMapReader::UnpackObjects() { // unpack object types u32 numObjTypes; unpacker.UnpackRaw(&numObjTypes,sizeof(numObjTypes)); m_ObjectTypes.resize(numObjTypes); for (uint i=0;iGetHandle(); } m_TerrainTextures.push_back(handle); } // unpack tile data u32 tilesPerSide=m_MapSize*PATCH_SIZE; m_Tiles.resize(SQR(tilesPerSide)); unpacker.UnpackRaw(&m_Tiles[0],(u32)(sizeof(STileDesc)*m_Tiles.size())); } // ApplyData: take all the input data, and rebuild the scene from it -void CMapReader::ApplyData(CFileUnpacker& unpacker, CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv) +void CMapReader::ApplyData() { -TIMER(____CMapReader__ApplyData); - // initialise the terrain pTerrain->Initialize(m_MapSize,&m_Heightmap[0]); // setup the textures on the minipatches STileDesc* tileptr=&m_Tiles[0]; for (u32 j=0;jGetPatch(i,j)->m_MiniPatches[m][k]; mp.Tex1=m_TerrainTextures[tileptr->m_Tex1Index]; mp.Tex1Priority=tileptr->m_Priority; tileptr++; } } } } // remove all existing entities (by recreating the entity manager) delete &g_EntityManager; new CEntityManager(); // delete all remaining non-entity units pUnitMan->DeleteAll(); // add new objects for (u32 i=0;iGetIn(); CVector3D position = ((CMatrix3D*)m_Objects[i].m_Transform)->GetTranslation(); g_EntityManager.create(templateObject, position, atan2(-orient.X, -orient.Z)); continue; } } CUnit* unit = g_UnitMan.CreateUnit(m_ObjectTypes.at(m_Objects[i].m_ObjectIndex), NULL); if (unit) { CMatrix3D transform; memcpy(&transform._11,m_Objects[i].m_Transform,sizeof(float)*16); unit->GetModel()->SetTransform(transform); } } if (unpacker.GetVersion()>=2) { // copy over the lighting parameters *pLightEnv=m_LightEnv; } } -void CMapReader::ReadXML(const char* filename) +void CMapReader::ReadXML() { - TIMER(____CMapReader__ReadXML); - #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); + CStr filename_vfs (filename_xml); filename_vfs = filename_vfs.substr(filename_vfs.ReverseFind("\\mods\\official\\") + 15); filename_vfs.Replace("\\", "/"); - filename = filename_vfs; + filename_xml = filename_vfs; #endif CXeromyces XeroFile; - if (XeroFile.Load(filename) != PSRETURN_OK) + if (XeroFile.Load(filename_xml) != 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) EL(scenario); EL(entities); EL(entity); EL(template); EL(player); EL(position); EL(orientation); AT(x); AT(y); AT(z); AT(angle); #undef AT #undef EL XMBElement root = XeroFile.getRoot(); assert(root.getNodeName() == el_scenario); // XMBElementList children = root.getChildNodes(); for (int i = 0; i < children.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) { //