diff --git a/src/engine/shared/datafile.h b/src/engine/shared/datafile.h index c914fcc68..01ce8fa4b 100644 --- a/src/engine/shared/datafile.h +++ b/src/engine/shared/datafile.h @@ -30,6 +30,13 @@ public: m_pDataFile(nullptr) {} ~CDataFileReader() { Close(); } + CDataFileReader &operator=(CDataFileReader &&Other) + { + m_pDataFile = Other.m_pDataFile; + Other.m_pDataFile = nullptr; + return *this; + } + bool Open(class IStorage *pStorage, const char *pFilename, int StorageType); bool Close(); bool IsOpen() const { return m_pDataFile != nullptr; } diff --git a/src/engine/shared/map.cpp b/src/engine/shared/map.cpp index 26d95dcfa..0ac719cc2 100644 --- a/src/engine/shared/map.cpp +++ b/src/engine/shared/map.cpp @@ -2,6 +2,8 @@ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #include "map.h" +#include + #include #include @@ -63,23 +65,32 @@ bool CMap::Load(const char *pMapName) IStorage *pStorage = Kernel()->RequestInterface(); if(!pStorage) return false; - if(!m_DataFile.Open(pStorage, pMapName, IStorage::TYPE_ALL)) - return false; - // check version - const CMapItemVersion *pItem = (CMapItemVersion *)m_DataFile.FindItem(MAPITEMTYPE_VERSION, 0); - if(!pItem || pItem->m_Version != CMapItemVersion::CURRENT_VERSION) + + // Ensure current datafile is not left in an inconsistent state if loading fails, + // by loading the new datafile separately first. + CDataFileReader NewDataFile; + if(!NewDataFile.Open(pStorage, pMapName, IStorage::TYPE_ALL)) return false; - // replace compressed tile layers with uncompressed ones + // Check version + const CMapItemVersion *pItem = (CMapItemVersion *)NewDataFile.FindItem(MAPITEMTYPE_VERSION, 0); + if(pItem == nullptr || pItem->m_Version != CMapItemVersion::CURRENT_VERSION) + { + log_error("map/load", "Error: map version not supported."); + NewDataFile.Close(); + return false; + } + + // Replace compressed tile layers with uncompressed ones int GroupsStart, GroupsNum, LayersStart, LayersNum; - m_DataFile.GetType(MAPITEMTYPE_GROUP, &GroupsStart, &GroupsNum); - m_DataFile.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersNum); + NewDataFile.GetType(MAPITEMTYPE_GROUP, &GroupsStart, &GroupsNum); + NewDataFile.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersNum); for(int g = 0; g < GroupsNum; g++) { - const CMapItemGroup *pGroup = static_cast(m_DataFile.GetItem(GroupsStart + g)); + const CMapItemGroup *pGroup = static_cast(NewDataFile.GetItem(GroupsStart + g)); for(int l = 0; l < pGroup->m_NumLayers; l++) { - CMapItemLayer *pLayer = static_cast(m_DataFile.GetItem(LayersStart + pGroup->m_StartLayer + l)); + CMapItemLayer *pLayer = static_cast(NewDataFile.GetItem(LayersStart + pGroup->m_StartLayer + l)); if(pLayer->m_Type == LAYERTYPE_TILES) { CMapItemLayerTilemap *pTilemap = reinterpret_cast(pLayer); @@ -87,13 +98,16 @@ bool CMap::Load(const char *pMapName) { const size_t TilemapSize = (size_t)pTilemap->m_Width * pTilemap->m_Height * sizeof(CTile); CTile *pTiles = static_cast(malloc(TilemapSize)); - ExtractTiles(pTiles, (size_t)pTilemap->m_Width * pTilemap->m_Height, static_cast(m_DataFile.GetData(pTilemap->m_Data)), m_DataFile.GetDataSize(pTilemap->m_Data) / sizeof(CTile)); - m_DataFile.ReplaceData(pTilemap->m_Data, reinterpret_cast(pTiles), TilemapSize); + ExtractTiles(pTiles, (size_t)pTilemap->m_Width * pTilemap->m_Height, static_cast(NewDataFile.GetData(pTilemap->m_Data)), NewDataFile.GetDataSize(pTilemap->m_Data) / sizeof(CTile)); + NewDataFile.ReplaceData(pTilemap->m_Data, reinterpret_cast(pTiles), TilemapSize); } } } } + // Replace existing datafile with new datafile + m_DataFile.Close(); + m_DataFile = std::move(NewDataFile); return true; } diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index bfa967678..3c3188698 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -7907,7 +7907,6 @@ bool CEditor::Load(const char *pFileName, int StorageType) else { m_aFileName[0] = 0; - Reset(); } return Result; } diff --git a/src/game/editor/mapitems/map_io.cpp b/src/game/editor/mapitems/map_io.cpp index 42422bd38..7b8a0e0c1 100644 --- a/src/game/editor/mapitems/map_io.cpp +++ b/src/game/editor/mapitems/map_io.cpp @@ -427,546 +427,544 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio if(!DataFile.Open(m_pEditor->Storage(), pFileName, StorageType)) return false; + // check version + const CMapItemVersion *pItemVersion = static_cast(DataFile.FindItem(MAPITEMTYPE_VERSION, 0)); + if(pItemVersion == nullptr || pItemVersion->m_Version != CMapItemVersion::CURRENT_VERSION) + { + ErrorHandler("Error: The map has an unsupported version."); + return false; + } + Clean(); - // check version - CMapItemVersion *pItemVersion = (CMapItemVersion *)DataFile.FindItem(MAPITEMTYPE_VERSION, 0); - if(!pItemVersion) + // load map info { - return false; + int Start, Num; + DataFile.GetType(MAPITEMTYPE_INFO, &Start, &Num); + for(int i = Start; i < Start + Num; i++) + { + int ItemSize = DataFile.GetItemSize(Start); + int ItemID; + CMapItemInfoSettings *pItem = (CMapItemInfoSettings *)DataFile.GetItem(i, nullptr, &ItemID); + if(!pItem || ItemID != 0) + continue; + + if(pItem->m_Author > -1) + str_copy(m_MapInfo.m_aAuthor, (char *)DataFile.GetData(pItem->m_Author)); + if(pItem->m_MapVersion > -1) + str_copy(m_MapInfo.m_aVersion, (char *)DataFile.GetData(pItem->m_MapVersion)); + if(pItem->m_Credits > -1) + str_copy(m_MapInfo.m_aCredits, (char *)DataFile.GetData(pItem->m_Credits)); + if(pItem->m_License > -1) + str_copy(m_MapInfo.m_aLicense, (char *)DataFile.GetData(pItem->m_License)); + + if(pItem->m_Version != 1 || ItemSize < (int)sizeof(CMapItemInfoSettings)) + break; + + if(!(pItem->m_Settings > -1)) + break; + + const unsigned Size = DataFile.GetDataSize(pItem->m_Settings); + char *pSettings = (char *)DataFile.GetData(pItem->m_Settings); + char *pNext = pSettings; + while(pNext < pSettings + Size) + { + int StrSize = str_length(pNext) + 1; + m_vSettings.emplace_back(pNext); + pNext += StrSize; + } + } } - else if(pItemVersion->m_Version == CMapItemVersion::CURRENT_VERSION) + + // load images { - // load map info + int Start, Num; + DataFile.GetType(MAPITEMTYPE_IMAGE, &Start, &Num); + for(int i = 0; i < Num; i++) { - int Start, Num; - DataFile.GetType(MAPITEMTYPE_INFO, &Start, &Num); - for(int i = Start; i < Start + Num; i++) + CMapItemImage_v2 *pItem = (CMapItemImage_v2 *)DataFile.GetItem(Start + i); + char *pName = (char *)DataFile.GetData(pItem->m_ImageName); + + // copy base info + std::shared_ptr pImg = std::make_shared(m_pEditor); + pImg->m_External = pItem->m_External; + + const CImageInfo::EImageFormat Format = pItem->m_Version < CMapItemImage_v2::CURRENT_VERSION ? CImageInfo::FORMAT_RGBA : CImageInfo::ImageFormatFromInt(pItem->m_Format); + if(pImg->m_External || (Format != CImageInfo::FORMAT_RGB && Format != CImageInfo::FORMAT_RGBA)) { - int ItemSize = DataFile.GetItemSize(Start); - int ItemID; - CMapItemInfoSettings *pItem = (CMapItemInfoSettings *)DataFile.GetItem(i, nullptr, &ItemID); - if(!pItem || ItemID != 0) - continue; + char aBuf[IO_MAX_PATH_LENGTH]; + str_format(aBuf, sizeof(aBuf), "mapres/%s.png", pName); - if(pItem->m_Author > -1) - str_copy(m_MapInfo.m_aAuthor, (char *)DataFile.GetData(pItem->m_Author)); - if(pItem->m_MapVersion > -1) - str_copy(m_MapInfo.m_aVersion, (char *)DataFile.GetData(pItem->m_MapVersion)); - if(pItem->m_Credits > -1) - str_copy(m_MapInfo.m_aCredits, (char *)DataFile.GetData(pItem->m_Credits)); - if(pItem->m_License > -1) - str_copy(m_MapInfo.m_aLicense, (char *)DataFile.GetData(pItem->m_License)); - - if(pItem->m_Version != 1 || ItemSize < (int)sizeof(CMapItemInfoSettings)) - break; - - if(!(pItem->m_Settings > -1)) - break; - - const unsigned Size = DataFile.GetDataSize(pItem->m_Settings); - char *pSettings = (char *)DataFile.GetData(pItem->m_Settings); - char *pNext = pSettings; - while(pNext < pSettings + Size) + // load external + CEditorImage ImgInfo(m_pEditor); + if(m_pEditor->Graphics()->LoadPNG(&ImgInfo, aBuf, IStorage::TYPE_ALL)) { - int StrSize = str_length(pNext) + 1; - m_vSettings.emplace_back(pNext); - pNext += StrSize; - } - } - } - - // load images - { - int Start, Num; - DataFile.GetType(MAPITEMTYPE_IMAGE, &Start, &Num); - for(int i = 0; i < Num; i++) - { - CMapItemImage_v2 *pItem = (CMapItemImage_v2 *)DataFile.GetItem(Start + i); - char *pName = (char *)DataFile.GetData(pItem->m_ImageName); - - // copy base info - std::shared_ptr pImg = std::make_shared(m_pEditor); - pImg->m_External = pItem->m_External; - - const CImageInfo::EImageFormat Format = pItem->m_Version < CMapItemImage_v2::CURRENT_VERSION ? CImageInfo::FORMAT_RGBA : CImageInfo::ImageFormatFromInt(pItem->m_Format); - if(pImg->m_External || (Format != CImageInfo::FORMAT_RGB && Format != CImageInfo::FORMAT_RGBA)) - { - char aBuf[IO_MAX_PATH_LENGTH]; - str_format(aBuf, sizeof(aBuf), "mapres/%s.png", pName); - - // load external - CEditorImage ImgInfo(m_pEditor); - if(m_pEditor->Graphics()->LoadPNG(&ImgInfo, aBuf, IStorage::TYPE_ALL)) - { - *pImg = ImgInfo; - int TextureLoadFlag = m_pEditor->Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; - if(ImgInfo.m_Width % 16 != 0 || ImgInfo.m_Height % 16 != 0) - TextureLoadFlag = 0; - pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, TextureLoadFlag, aBuf); - ImgInfo.m_pData = nullptr; - pImg->m_External = 1; - } - } - else - { - pImg->m_Width = pItem->m_Width; - pImg->m_Height = pItem->m_Height; - pImg->m_Format = Format; - - // copy image data - void *pData = DataFile.GetData(pItem->m_ImageData); - const size_t DataSize = (size_t)pImg->m_Width * pImg->m_Height * CImageInfo::PixelSize(Format); - pImg->m_pData = malloc(DataSize); - mem_copy(pImg->m_pData, pData, DataSize); + *pImg = ImgInfo; int TextureLoadFlag = m_pEditor->Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; - if(pImg->m_Width % 16 != 0 || pImg->m_Height % 16 != 0) + if(ImgInfo.m_Width % 16 != 0 || ImgInfo.m_Height % 16 != 0) TextureLoadFlag = 0; - pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, pImg->m_Format, pImg->m_pData, TextureLoadFlag); + pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, TextureLoadFlag, aBuf); + ImgInfo.m_pData = nullptr; + pImg->m_External = 1; } - - // copy image name - if(pName) - str_copy(pImg->m_aName, pName); - - // load auto mapper file - pImg->m_AutoMapper.Load(pImg->m_aName); - - m_vpImages.push_back(pImg); - - // unload image - DataFile.UnloadData(pItem->m_ImageData); - DataFile.UnloadData(pItem->m_ImageName); } - } - - // load sounds - { - int Start, Num; - DataFile.GetType(MAPITEMTYPE_SOUND, &Start, &Num); - for(int i = 0; i < Num; i++) + else { - CMapItemSound *pItem = (CMapItemSound *)DataFile.GetItem(Start + i); - char *pName = (char *)DataFile.GetData(pItem->m_SoundName); + pImg->m_Width = pItem->m_Width; + pImg->m_Height = pItem->m_Height; + pImg->m_Format = Format; - // copy base info - std::shared_ptr pSound = std::make_shared(m_pEditor); - if(pItem->m_External) + // copy image data + void *pData = DataFile.GetData(pItem->m_ImageData); + const size_t DataSize = (size_t)pImg->m_Width * pImg->m_Height * CImageInfo::PixelSize(Format); + pImg->m_pData = malloc(DataSize); + mem_copy(pImg->m_pData, pData, DataSize); + int TextureLoadFlag = m_pEditor->Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; + if(pImg->m_Width % 16 != 0 || pImg->m_Height % 16 != 0) + TextureLoadFlag = 0; + pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, pImg->m_Format, pImg->m_pData, TextureLoadFlag); + } + + // copy image name + if(pName) + str_copy(pImg->m_aName, pName); + + // load auto mapper file + pImg->m_AutoMapper.Load(pImg->m_aName); + + m_vpImages.push_back(pImg); + + // unload image + DataFile.UnloadData(pItem->m_ImageData); + DataFile.UnloadData(pItem->m_ImageName); + } + } + + // load sounds + { + int Start, Num; + DataFile.GetType(MAPITEMTYPE_SOUND, &Start, &Num); + for(int i = 0; i < Num; i++) + { + CMapItemSound *pItem = (CMapItemSound *)DataFile.GetItem(Start + i); + char *pName = (char *)DataFile.GetData(pItem->m_SoundName); + + // copy base info + std::shared_ptr pSound = std::make_shared(m_pEditor); + if(pItem->m_External) + { + char aBuf[IO_MAX_PATH_LENGTH]; + str_format(aBuf, sizeof(aBuf), "mapres/%s.opus", pName); + + // load external + if(m_pEditor->Storage()->ReadFile(pName, IStorage::TYPE_ALL, &pSound->m_pData, &pSound->m_DataSize)) { - char aBuf[IO_MAX_PATH_LENGTH]; - str_format(aBuf, sizeof(aBuf), "mapres/%s.opus", pName); - - // load external - if(m_pEditor->Storage()->ReadFile(pName, IStorage::TYPE_ALL, &pSound->m_pData, &pSound->m_DataSize)) - { - pSound->m_SoundID = m_pEditor->Sound()->LoadOpusFromMem(pSound->m_pData, pSound->m_DataSize, true); - } - } - else - { - pSound->m_DataSize = pItem->m_SoundDataSize; - - // copy sample data - void *pData = DataFile.GetData(pItem->m_SoundData); - pSound->m_pData = malloc(pSound->m_DataSize); - mem_copy(pSound->m_pData, pData, pSound->m_DataSize); pSound->m_SoundID = m_pEditor->Sound()->LoadOpusFromMem(pSound->m_pData, pSound->m_DataSize, true); } - - // copy image name - if(pName) - str_copy(pSound->m_aName, pName); - - m_vpSounds.push_back(pSound); - - // unload image - DataFile.UnloadData(pItem->m_SoundData); - DataFile.UnloadData(pItem->m_SoundName); } - } - - // load groups - { - int LayersStart, LayersNum; - DataFile.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersNum); - - int Start, Num; - DataFile.GetType(MAPITEMTYPE_GROUP, &Start, &Num); - - int StartEx, NumEx; - DataFile.GetType(MAPITEMTYPE_GROUP_EX, &StartEx, &NumEx); - for(int g = 0; g < Num; g++) + else { - CMapItemGroup *pGItem = (CMapItemGroup *)DataFile.GetItem(Start + g); - CMapItemGroupEx *pGItemEx = nullptr; - if(NumEx) - pGItemEx = (CMapItemGroupEx *)DataFile.GetItem(StartEx + g); + pSound->m_DataSize = pItem->m_SoundDataSize; - if(pGItem->m_Version < 1 || pGItem->m_Version > CMapItemGroup::CURRENT_VERSION) + // copy sample data + void *pData = DataFile.GetData(pItem->m_SoundData); + pSound->m_pData = malloc(pSound->m_DataSize); + mem_copy(pSound->m_pData, pData, pSound->m_DataSize); + pSound->m_SoundID = m_pEditor->Sound()->LoadOpusFromMem(pSound->m_pData, pSound->m_DataSize, true); + } + + // copy image name + if(pName) + str_copy(pSound->m_aName, pName); + + m_vpSounds.push_back(pSound); + + // unload image + DataFile.UnloadData(pItem->m_SoundData); + DataFile.UnloadData(pItem->m_SoundName); + } + } + + // load groups + { + int LayersStart, LayersNum; + DataFile.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersNum); + + int Start, Num; + DataFile.GetType(MAPITEMTYPE_GROUP, &Start, &Num); + + int StartEx, NumEx; + DataFile.GetType(MAPITEMTYPE_GROUP_EX, &StartEx, &NumEx); + for(int g = 0; g < Num; g++) + { + CMapItemGroup *pGItem = (CMapItemGroup *)DataFile.GetItem(Start + g); + CMapItemGroupEx *pGItemEx = nullptr; + if(NumEx) + pGItemEx = (CMapItemGroupEx *)DataFile.GetItem(StartEx + g); + + if(pGItem->m_Version < 1 || pGItem->m_Version > CMapItemGroup::CURRENT_VERSION) + continue; + + std::shared_ptr pGroup = NewGroup(); + pGroup->m_ParallaxX = pGItem->m_ParallaxX; + pGroup->m_ParallaxY = pGItem->m_ParallaxY; + pGroup->m_OffsetX = pGItem->m_OffsetX; + pGroup->m_OffsetY = pGItem->m_OffsetY; + + if(pGItem->m_Version >= 2) + { + pGroup->m_UseClipping = pGItem->m_UseClipping; + pGroup->m_ClipX = pGItem->m_ClipX; + pGroup->m_ClipY = pGItem->m_ClipY; + pGroup->m_ClipW = pGItem->m_ClipW; + pGroup->m_ClipH = pGItem->m_ClipH; + } + + // load group name + if(pGItem->m_Version >= 3) + IntsToStr(pGItem->m_aName, sizeof(pGroup->m_aName) / sizeof(int), pGroup->m_aName); + + pGroup->m_ParallaxZoom = GetParallaxZoom(pGItem, pGItemEx); + pGroup->m_CustomParallaxZoom = pGroup->m_ParallaxZoom != GetParallaxZoomDefault(pGroup->m_ParallaxX, pGroup->m_ParallaxY); + + for(int l = 0; l < pGItem->m_NumLayers; l++) + { + CMapItemLayer *pLayerItem = (CMapItemLayer *)DataFile.GetItem(LayersStart + pGItem->m_StartLayer + l); + if(!pLayerItem) continue; - std::shared_ptr pGroup = NewGroup(); - pGroup->m_ParallaxX = pGItem->m_ParallaxX; - pGroup->m_ParallaxY = pGItem->m_ParallaxY; - pGroup->m_OffsetX = pGItem->m_OffsetX; - pGroup->m_OffsetY = pGItem->m_OffsetY; - - if(pGItem->m_Version >= 2) + if(pLayerItem->m_Type == LAYERTYPE_TILES) { - pGroup->m_UseClipping = pGItem->m_UseClipping; - pGroup->m_ClipX = pGItem->m_ClipX; - pGroup->m_ClipY = pGItem->m_ClipY; - pGroup->m_ClipW = pGItem->m_ClipW; - pGroup->m_ClipH = pGItem->m_ClipH; + CMapItemLayerTilemap *pTilemapItem = (CMapItemLayerTilemap *)pLayerItem; + + std::shared_ptr pTiles; + if(pTilemapItem->m_Flags & TILESLAYERFLAG_GAME) + { + pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); + MakeGameLayer(pTiles); + MakeGameGroup(pGroup); + } + else if(pTilemapItem->m_Flags & TILESLAYERFLAG_TELE) + { + if(pTilemapItem->m_Version <= 2) + pTilemapItem->m_Tele = *((const int *)(pTilemapItem) + 15); + + pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); + MakeTeleLayer(pTiles); + } + else if(pTilemapItem->m_Flags & TILESLAYERFLAG_SPEEDUP) + { + if(pTilemapItem->m_Version <= 2) + pTilemapItem->m_Speedup = *((const int *)(pTilemapItem) + 16); + + pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); + MakeSpeedupLayer(pTiles); + } + else if(pTilemapItem->m_Flags & TILESLAYERFLAG_FRONT) + { + if(pTilemapItem->m_Version <= 2) + pTilemapItem->m_Front = *((const int *)(pTilemapItem) + 17); + + pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); + MakeFrontLayer(pTiles); + } + else if(pTilemapItem->m_Flags & TILESLAYERFLAG_SWITCH) + { + if(pTilemapItem->m_Version <= 2) + pTilemapItem->m_Switch = *((const int *)(pTilemapItem) + 18); + + pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); + MakeSwitchLayer(pTiles); + } + else if(pTilemapItem->m_Flags & TILESLAYERFLAG_TUNE) + { + if(pTilemapItem->m_Version <= 2) + pTilemapItem->m_Tune = *((const int *)(pTilemapItem) + 19); + + pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); + MakeTuneLayer(pTiles); + } + else + { + pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); + pTiles->m_pEditor = m_pEditor; + pTiles->m_Color = pTilemapItem->m_Color; + pTiles->m_ColorEnv = pTilemapItem->m_ColorEnv; + pTiles->m_ColorEnvOffset = pTilemapItem->m_ColorEnvOffset; + } + + pTiles->m_Flags = pLayerItem->m_Flags; + + pGroup->AddLayer(pTiles); + pTiles->m_Image = pTilemapItem->m_Image; + pTiles->m_Game = pTilemapItem->m_Flags & TILESLAYERFLAG_GAME; + + // load layer name + if(pTilemapItem->m_Version >= 3) + IntsToStr(pTilemapItem->m_aName, sizeof(pTiles->m_aName) / sizeof(int), pTiles->m_aName); + + if(pTiles->m_Tele) + { + void *pTeleData = DataFile.GetData(pTilemapItem->m_Tele); + unsigned int Size = DataFile.GetDataSize(pTilemapItem->m_Tele); + if(Size >= (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CTeleTile)) + { + CTeleTile *pLayerTeleTiles = std::static_pointer_cast(pTiles)->m_pTeleTile; + mem_copy(pLayerTeleTiles, pTeleData, (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CTeleTile)); + + for(int i = 0; i < pTiles->m_Width * pTiles->m_Height; i++) + { + if(IsValidTeleTile(pLayerTeleTiles[i].m_Type)) + pTiles->m_pTiles[i].m_Index = pLayerTeleTiles[i].m_Type; + else + pTiles->m_pTiles[i].m_Index = 0; + } + } + DataFile.UnloadData(pTilemapItem->m_Tele); + } + else if(pTiles->m_Speedup) + { + void *pSpeedupData = DataFile.GetData(pTilemapItem->m_Speedup); + unsigned int Size = DataFile.GetDataSize(pTilemapItem->m_Speedup); + + if(Size >= (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CSpeedupTile)) + { + CSpeedupTile *pLayerSpeedupTiles = std::static_pointer_cast(pTiles)->m_pSpeedupTile; + mem_copy(pLayerSpeedupTiles, pSpeedupData, (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CSpeedupTile)); + + for(int i = 0; i < pTiles->m_Width * pTiles->m_Height; i++) + { + if(IsValidSpeedupTile(pLayerSpeedupTiles[i].m_Type) && pLayerSpeedupTiles[i].m_Force > 0) + pTiles->m_pTiles[i].m_Index = pLayerSpeedupTiles[i].m_Type; + else + pTiles->m_pTiles[i].m_Index = 0; + } + } + + DataFile.UnloadData(pTilemapItem->m_Speedup); + } + else if(pTiles->m_Front) + { + void *pFrontData = DataFile.GetData(pTilemapItem->m_Front); + unsigned int Size = DataFile.GetDataSize(pTilemapItem->m_Front); + pTiles->ExtractTiles(pTilemapItem->m_Version, (CTile *)pFrontData, Size); + DataFile.UnloadData(pTilemapItem->m_Front); + } + else if(pTiles->m_Switch) + { + void *pSwitchData = DataFile.GetData(pTilemapItem->m_Switch); + unsigned int Size = DataFile.GetDataSize(pTilemapItem->m_Switch); + if(Size >= (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CSwitchTile)) + { + CSwitchTile *pLayerSwitchTiles = std::static_pointer_cast(pTiles)->m_pSwitchTile; + mem_copy(pLayerSwitchTiles, pSwitchData, (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CSwitchTile)); + + for(int i = 0; i < pTiles->m_Width * pTiles->m_Height; i++) + { + if(((pLayerSwitchTiles[i].m_Type > (ENTITY_CRAZY_SHOTGUN + ENTITY_OFFSET) && pLayerSwitchTiles[i].m_Type < (ENTITY_DRAGGER_WEAK + ENTITY_OFFSET)) || pLayerSwitchTiles[i].m_Type == (ENTITY_LASER_O_FAST + 1 + ENTITY_OFFSET))) + continue; + else if(pLayerSwitchTiles[i].m_Type >= (ENTITY_ARMOR_1 + ENTITY_OFFSET) && pLayerSwitchTiles[i].m_Type <= (ENTITY_DOOR + ENTITY_OFFSET)) + { + pTiles->m_pTiles[i].m_Index = pLayerSwitchTiles[i].m_Type; + pTiles->m_pTiles[i].m_Flags = pLayerSwitchTiles[i].m_Flags; + continue; + } + + if(IsValidSwitchTile(pLayerSwitchTiles[i].m_Type)) + { + pTiles->m_pTiles[i].m_Index = pLayerSwitchTiles[i].m_Type; + pTiles->m_pTiles[i].m_Flags = pLayerSwitchTiles[i].m_Flags; + } + } + } + DataFile.UnloadData(pTilemapItem->m_Switch); + } + else if(pTiles->m_Tune) + { + void *pTuneData = DataFile.GetData(pTilemapItem->m_Tune); + unsigned int Size = DataFile.GetDataSize(pTilemapItem->m_Tune); + if(Size >= (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CTuneTile)) + { + CTuneTile *pLayerTuneTiles = std::static_pointer_cast(pTiles)->m_pTuneTile; + mem_copy(pLayerTuneTiles, pTuneData, (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CTuneTile)); + + for(int i = 0; i < pTiles->m_Width * pTiles->m_Height; i++) + { + if(IsValidTuneTile(pLayerTuneTiles[i].m_Type)) + pTiles->m_pTiles[i].m_Index = pLayerTuneTiles[i].m_Type; + else + pTiles->m_pTiles[i].m_Index = 0; + } + } + DataFile.UnloadData(pTilemapItem->m_Tune); + } + else // regular tile layer or game layer + { + void *pData = DataFile.GetData(pTilemapItem->m_Data); + unsigned int Size = DataFile.GetDataSize(pTilemapItem->m_Data); + pTiles->ExtractTiles(pTilemapItem->m_Version, (CTile *)pData, Size); + + if(pTiles->m_Game && pTilemapItem->m_Version == MakeVersion(1, *pTilemapItem)) + { + for(int i = 0; i < pTiles->m_Width * pTiles->m_Height; i++) + { + if(pTiles->m_pTiles[i].m_Index) + pTiles->m_pTiles[i].m_Index += ENTITY_OFFSET; + } + } + DataFile.UnloadData(pTilemapItem->m_Data); + } } - - // load group name - if(pGItem->m_Version >= 3) - IntsToStr(pGItem->m_aName, sizeof(pGroup->m_aName) / sizeof(int), pGroup->m_aName); - - pGroup->m_ParallaxZoom = GetParallaxZoom(pGItem, pGItemEx); - pGroup->m_CustomParallaxZoom = pGroup->m_ParallaxZoom != GetParallaxZoomDefault(pGroup->m_ParallaxX, pGroup->m_ParallaxY); - - for(int l = 0; l < pGItem->m_NumLayers; l++) + else if(pLayerItem->m_Type == LAYERTYPE_QUADS) { - CMapItemLayer *pLayerItem = (CMapItemLayer *)DataFile.GetItem(LayersStart + pGItem->m_StartLayer + l); - if(!pLayerItem) + const CMapItemLayerQuads *pQuadsItem = (CMapItemLayerQuads *)pLayerItem; + + std::shared_ptr pQuads = std::make_shared(m_pEditor); + pQuads->m_Flags = pLayerItem->m_Flags; + pQuads->m_Image = pQuadsItem->m_Image; + if(pQuads->m_Image < -1 || pQuads->m_Image >= (int)m_vpImages.size()) + pQuads->m_Image = -1; + + // load layer name + if(pQuadsItem->m_Version >= 2) + IntsToStr(pQuadsItem->m_aName, sizeof(pQuads->m_aName) / sizeof(int), pQuads->m_aName); + + void *pData = DataFile.GetDataSwapped(pQuadsItem->m_Data); + pGroup->AddLayer(pQuads); + pQuads->m_vQuads.resize(pQuadsItem->m_NumQuads); + mem_copy(pQuads->m_vQuads.data(), pData, sizeof(CQuad) * pQuadsItem->m_NumQuads); + DataFile.UnloadData(pQuadsItem->m_Data); + } + else if(pLayerItem->m_Type == LAYERTYPE_SOUNDS) + { + const CMapItemLayerSounds *pSoundsItem = (CMapItemLayerSounds *)pLayerItem; + if(pSoundsItem->m_Version < 1 || pSoundsItem->m_Version > CMapItemLayerSounds::CURRENT_VERSION) continue; - if(pLayerItem->m_Type == LAYERTYPE_TILES) + std::shared_ptr pSounds = std::make_shared(m_pEditor); + pSounds->m_Flags = pLayerItem->m_Flags; + pSounds->m_Sound = pSoundsItem->m_Sound; + + // validate m_Sound + if(pSounds->m_Sound < -1 || pSounds->m_Sound >= (int)m_vpSounds.size()) + pSounds->m_Sound = -1; + + // load layer name + IntsToStr(pSoundsItem->m_aName, sizeof(pSounds->m_aName) / sizeof(int), pSounds->m_aName); + + // load data + void *pData = DataFile.GetDataSwapped(pSoundsItem->m_Data); + pGroup->AddLayer(pSounds); + pSounds->m_vSources.resize(pSoundsItem->m_NumSources); + mem_copy(pSounds->m_vSources.data(), pData, sizeof(CSoundSource) * pSoundsItem->m_NumSources); + DataFile.UnloadData(pSoundsItem->m_Data); + } + else if(pLayerItem->m_Type == LAYERTYPE_SOUNDS_DEPRECATED) + { + // compatibility with old sound layers + const CMapItemLayerSounds *pSoundsItem = (CMapItemLayerSounds *)pLayerItem; + if(pSoundsItem->m_Version < 1 || pSoundsItem->m_Version > CMapItemLayerSounds::CURRENT_VERSION) + continue; + + std::shared_ptr pSounds = std::make_shared(m_pEditor); + pSounds->m_Flags = pLayerItem->m_Flags; + pSounds->m_Sound = pSoundsItem->m_Sound; + + // validate m_Sound + if(pSounds->m_Sound < -1 || pSounds->m_Sound >= (int)m_vpSounds.size()) + pSounds->m_Sound = -1; + + // load layer name + IntsToStr(pSoundsItem->m_aName, sizeof(pSounds->m_aName) / sizeof(int), pSounds->m_aName); + + // load data + CSoundSource_DEPRECATED *pData = (CSoundSource_DEPRECATED *)DataFile.GetDataSwapped(pSoundsItem->m_Data); + pGroup->AddLayer(pSounds); + pSounds->m_vSources.resize(pSoundsItem->m_NumSources); + + for(int i = 0; i < pSoundsItem->m_NumSources; i++) { - CMapItemLayerTilemap *pTilemapItem = (CMapItemLayerTilemap *)pLayerItem; + CSoundSource_DEPRECATED *pOldSource = &pData[i]; - std::shared_ptr pTiles; - if(pTilemapItem->m_Flags & TILESLAYERFLAG_GAME) - { - pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); - MakeGameLayer(pTiles); - MakeGameGroup(pGroup); - } - else if(pTilemapItem->m_Flags & TILESLAYERFLAG_TELE) - { - if(pTilemapItem->m_Version <= 2) - pTilemapItem->m_Tele = *((const int *)(pTilemapItem) + 15); + CSoundSource &Source = pSounds->m_vSources[i]; + Source.m_Position = pOldSource->m_Position; + Source.m_Loop = pOldSource->m_Loop; + Source.m_Pan = true; + Source.m_TimeDelay = pOldSource->m_TimeDelay; + Source.m_Falloff = 0; - pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); - MakeTeleLayer(pTiles); - } - else if(pTilemapItem->m_Flags & TILESLAYERFLAG_SPEEDUP) - { - if(pTilemapItem->m_Version <= 2) - pTilemapItem->m_Speedup = *((const int *)(pTilemapItem) + 16); + Source.m_PosEnv = pOldSource->m_PosEnv; + Source.m_PosEnvOffset = pOldSource->m_PosEnvOffset; + Source.m_SoundEnv = pOldSource->m_SoundEnv; + Source.m_SoundEnvOffset = pOldSource->m_SoundEnvOffset; - pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); - MakeSpeedupLayer(pTiles); - } - else if(pTilemapItem->m_Flags & TILESLAYERFLAG_FRONT) - { - if(pTilemapItem->m_Version <= 2) - pTilemapItem->m_Front = *((const int *)(pTilemapItem) + 17); - - pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); - MakeFrontLayer(pTiles); - } - else if(pTilemapItem->m_Flags & TILESLAYERFLAG_SWITCH) - { - if(pTilemapItem->m_Version <= 2) - pTilemapItem->m_Switch = *((const int *)(pTilemapItem) + 18); - - pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); - MakeSwitchLayer(pTiles); - } - else if(pTilemapItem->m_Flags & TILESLAYERFLAG_TUNE) - { - if(pTilemapItem->m_Version <= 2) - pTilemapItem->m_Tune = *((const int *)(pTilemapItem) + 19); - - pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); - MakeTuneLayer(pTiles); - } - else - { - pTiles = std::make_shared(m_pEditor, pTilemapItem->m_Width, pTilemapItem->m_Height); - pTiles->m_pEditor = m_pEditor; - pTiles->m_Color = pTilemapItem->m_Color; - pTiles->m_ColorEnv = pTilemapItem->m_ColorEnv; - pTiles->m_ColorEnvOffset = pTilemapItem->m_ColorEnvOffset; - } - - pTiles->m_Flags = pLayerItem->m_Flags; - - pGroup->AddLayer(pTiles); - pTiles->m_Image = pTilemapItem->m_Image; - pTiles->m_Game = pTilemapItem->m_Flags & TILESLAYERFLAG_GAME; - - // load layer name - if(pTilemapItem->m_Version >= 3) - IntsToStr(pTilemapItem->m_aName, sizeof(pTiles->m_aName) / sizeof(int), pTiles->m_aName); - - if(pTiles->m_Tele) - { - void *pTeleData = DataFile.GetData(pTilemapItem->m_Tele); - unsigned int Size = DataFile.GetDataSize(pTilemapItem->m_Tele); - if(Size >= (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CTeleTile)) - { - CTeleTile *pLayerTeleTiles = std::static_pointer_cast(pTiles)->m_pTeleTile; - mem_copy(pLayerTeleTiles, pTeleData, (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CTeleTile)); - - for(int i = 0; i < pTiles->m_Width * pTiles->m_Height; i++) - { - if(IsValidTeleTile(pLayerTeleTiles[i].m_Type)) - pTiles->m_pTiles[i].m_Index = pLayerTeleTiles[i].m_Type; - else - pTiles->m_pTiles[i].m_Index = 0; - } - } - DataFile.UnloadData(pTilemapItem->m_Tele); - } - else if(pTiles->m_Speedup) - { - void *pSpeedupData = DataFile.GetData(pTilemapItem->m_Speedup); - unsigned int Size = DataFile.GetDataSize(pTilemapItem->m_Speedup); - - if(Size >= (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CSpeedupTile)) - { - CSpeedupTile *pLayerSpeedupTiles = std::static_pointer_cast(pTiles)->m_pSpeedupTile; - mem_copy(pLayerSpeedupTiles, pSpeedupData, (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CSpeedupTile)); - - for(int i = 0; i < pTiles->m_Width * pTiles->m_Height; i++) - { - if(IsValidSpeedupTile(pLayerSpeedupTiles[i].m_Type) && pLayerSpeedupTiles[i].m_Force > 0) - pTiles->m_pTiles[i].m_Index = pLayerSpeedupTiles[i].m_Type; - else - pTiles->m_pTiles[i].m_Index = 0; - } - } - - DataFile.UnloadData(pTilemapItem->m_Speedup); - } - else if(pTiles->m_Front) - { - void *pFrontData = DataFile.GetData(pTilemapItem->m_Front); - unsigned int Size = DataFile.GetDataSize(pTilemapItem->m_Front); - pTiles->ExtractTiles(pTilemapItem->m_Version, (CTile *)pFrontData, Size); - DataFile.UnloadData(pTilemapItem->m_Front); - } - else if(pTiles->m_Switch) - { - void *pSwitchData = DataFile.GetData(pTilemapItem->m_Switch); - unsigned int Size = DataFile.GetDataSize(pTilemapItem->m_Switch); - if(Size >= (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CSwitchTile)) - { - CSwitchTile *pLayerSwitchTiles = std::static_pointer_cast(pTiles)->m_pSwitchTile; - mem_copy(pLayerSwitchTiles, pSwitchData, (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CSwitchTile)); - - for(int i = 0; i < pTiles->m_Width * pTiles->m_Height; i++) - { - if(((pLayerSwitchTiles[i].m_Type > (ENTITY_CRAZY_SHOTGUN + ENTITY_OFFSET) && pLayerSwitchTiles[i].m_Type < (ENTITY_DRAGGER_WEAK + ENTITY_OFFSET)) || pLayerSwitchTiles[i].m_Type == (ENTITY_LASER_O_FAST + 1 + ENTITY_OFFSET))) - continue; - else if(pLayerSwitchTiles[i].m_Type >= (ENTITY_ARMOR_1 + ENTITY_OFFSET) && pLayerSwitchTiles[i].m_Type <= (ENTITY_DOOR + ENTITY_OFFSET)) - { - pTiles->m_pTiles[i].m_Index = pLayerSwitchTiles[i].m_Type; - pTiles->m_pTiles[i].m_Flags = pLayerSwitchTiles[i].m_Flags; - continue; - } - - if(IsValidSwitchTile(pLayerSwitchTiles[i].m_Type)) - { - pTiles->m_pTiles[i].m_Index = pLayerSwitchTiles[i].m_Type; - pTiles->m_pTiles[i].m_Flags = pLayerSwitchTiles[i].m_Flags; - } - } - } - DataFile.UnloadData(pTilemapItem->m_Switch); - } - else if(pTiles->m_Tune) - { - void *pTuneData = DataFile.GetData(pTilemapItem->m_Tune); - unsigned int Size = DataFile.GetDataSize(pTilemapItem->m_Tune); - if(Size >= (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CTuneTile)) - { - CTuneTile *pLayerTuneTiles = std::static_pointer_cast(pTiles)->m_pTuneTile; - mem_copy(pLayerTuneTiles, pTuneData, (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CTuneTile)); - - for(int i = 0; i < pTiles->m_Width * pTiles->m_Height; i++) - { - if(IsValidTuneTile(pLayerTuneTiles[i].m_Type)) - pTiles->m_pTiles[i].m_Index = pLayerTuneTiles[i].m_Type; - else - pTiles->m_pTiles[i].m_Index = 0; - } - } - DataFile.UnloadData(pTilemapItem->m_Tune); - } - else // regular tile layer or game layer - { - void *pData = DataFile.GetData(pTilemapItem->m_Data); - unsigned int Size = DataFile.GetDataSize(pTilemapItem->m_Data); - pTiles->ExtractTiles(pTilemapItem->m_Version, (CTile *)pData, Size); - - if(pTiles->m_Game && pTilemapItem->m_Version == MakeVersion(1, *pTilemapItem)) - { - for(int i = 0; i < pTiles->m_Width * pTiles->m_Height; i++) - { - if(pTiles->m_pTiles[i].m_Index) - pTiles->m_pTiles[i].m_Index += ENTITY_OFFSET; - } - } - DataFile.UnloadData(pTilemapItem->m_Data); - } + Source.m_Shape.m_Type = CSoundShape::SHAPE_CIRCLE; + Source.m_Shape.m_Circle.m_Radius = pOldSource->m_FalloffDistance; } - else if(pLayerItem->m_Type == LAYERTYPE_QUADS) - { - const CMapItemLayerQuads *pQuadsItem = (CMapItemLayerQuads *)pLayerItem; - std::shared_ptr pQuads = std::make_shared(m_pEditor); - pQuads->m_Flags = pLayerItem->m_Flags; - pQuads->m_Image = pQuadsItem->m_Image; - if(pQuads->m_Image < -1 || pQuads->m_Image >= (int)m_vpImages.size()) - pQuads->m_Image = -1; - - // load layer name - if(pQuadsItem->m_Version >= 2) - IntsToStr(pQuadsItem->m_aName, sizeof(pQuads->m_aName) / sizeof(int), pQuads->m_aName); - - void *pData = DataFile.GetDataSwapped(pQuadsItem->m_Data); - pGroup->AddLayer(pQuads); - pQuads->m_vQuads.resize(pQuadsItem->m_NumQuads); - mem_copy(pQuads->m_vQuads.data(), pData, sizeof(CQuad) * pQuadsItem->m_NumQuads); - DataFile.UnloadData(pQuadsItem->m_Data); - } - else if(pLayerItem->m_Type == LAYERTYPE_SOUNDS) - { - const CMapItemLayerSounds *pSoundsItem = (CMapItemLayerSounds *)pLayerItem; - if(pSoundsItem->m_Version < 1 || pSoundsItem->m_Version > CMapItemLayerSounds::CURRENT_VERSION) - continue; - - std::shared_ptr pSounds = std::make_shared(m_pEditor); - pSounds->m_Flags = pLayerItem->m_Flags; - pSounds->m_Sound = pSoundsItem->m_Sound; - - // validate m_Sound - if(pSounds->m_Sound < -1 || pSounds->m_Sound >= (int)m_vpSounds.size()) - pSounds->m_Sound = -1; - - // load layer name - IntsToStr(pSoundsItem->m_aName, sizeof(pSounds->m_aName) / sizeof(int), pSounds->m_aName); - - // load data - void *pData = DataFile.GetDataSwapped(pSoundsItem->m_Data); - pGroup->AddLayer(pSounds); - pSounds->m_vSources.resize(pSoundsItem->m_NumSources); - mem_copy(pSounds->m_vSources.data(), pData, sizeof(CSoundSource) * pSoundsItem->m_NumSources); - DataFile.UnloadData(pSoundsItem->m_Data); - } - else if(pLayerItem->m_Type == LAYERTYPE_SOUNDS_DEPRECATED) - { - // compatibility with old sound layers - const CMapItemLayerSounds *pSoundsItem = (CMapItemLayerSounds *)pLayerItem; - if(pSoundsItem->m_Version < 1 || pSoundsItem->m_Version > CMapItemLayerSounds::CURRENT_VERSION) - continue; - - std::shared_ptr pSounds = std::make_shared(m_pEditor); - pSounds->m_Flags = pLayerItem->m_Flags; - pSounds->m_Sound = pSoundsItem->m_Sound; - - // validate m_Sound - if(pSounds->m_Sound < -1 || pSounds->m_Sound >= (int)m_vpSounds.size()) - pSounds->m_Sound = -1; - - // load layer name - IntsToStr(pSoundsItem->m_aName, sizeof(pSounds->m_aName) / sizeof(int), pSounds->m_aName); - - // load data - CSoundSource_DEPRECATED *pData = (CSoundSource_DEPRECATED *)DataFile.GetDataSwapped(pSoundsItem->m_Data); - pGroup->AddLayer(pSounds); - pSounds->m_vSources.resize(pSoundsItem->m_NumSources); - - for(int i = 0; i < pSoundsItem->m_NumSources; i++) - { - CSoundSource_DEPRECATED *pOldSource = &pData[i]; - - CSoundSource &Source = pSounds->m_vSources[i]; - Source.m_Position = pOldSource->m_Position; - Source.m_Loop = pOldSource->m_Loop; - Source.m_Pan = true; - Source.m_TimeDelay = pOldSource->m_TimeDelay; - Source.m_Falloff = 0; - - Source.m_PosEnv = pOldSource->m_PosEnv; - Source.m_PosEnvOffset = pOldSource->m_PosEnvOffset; - Source.m_SoundEnv = pOldSource->m_SoundEnv; - Source.m_SoundEnvOffset = pOldSource->m_SoundEnvOffset; - - Source.m_Shape.m_Type = CSoundShape::SHAPE_CIRCLE; - Source.m_Shape.m_Circle.m_Radius = pOldSource->m_FalloffDistance; - } - - DataFile.UnloadData(pSoundsItem->m_Data); - } + DataFile.UnloadData(pSoundsItem->m_Data); } } } + } - // load envelopes + // load envelopes + { + const CMapBasedEnvelopePointAccess EnvelopePoints(&DataFile); + + int EnvStart, EnvNum; + DataFile.GetType(MAPITEMTYPE_ENVELOPE, &EnvStart, &EnvNum); + for(int e = 0; e < EnvNum; e++) { - const CMapBasedEnvelopePointAccess EnvelopePoints(&DataFile); - - int EnvStart, EnvNum; - DataFile.GetType(MAPITEMTYPE_ENVELOPE, &EnvStart, &EnvNum); - for(int e = 0; e < EnvNum; e++) + CMapItemEnvelope *pItem = (CMapItemEnvelope *)DataFile.GetItem(EnvStart + e); + std::shared_ptr pEnv = std::make_shared(pItem->m_Channels); + pEnv->m_vPoints.resize(pItem->m_NumPoints); + for(int p = 0; p < pItem->m_NumPoints; p++) { - CMapItemEnvelope *pItem = (CMapItemEnvelope *)DataFile.GetItem(EnvStart + e); - std::shared_ptr pEnv = std::make_shared(pItem->m_Channels); - pEnv->m_vPoints.resize(pItem->m_NumPoints); - for(int p = 0; p < pItem->m_NumPoints; p++) - { - const CEnvPoint *pPoint = EnvelopePoints.GetPoint(pItem->m_StartPoint + p); - if(pPoint != nullptr) - mem_copy(&pEnv->m_vPoints[p], pPoint, sizeof(CEnvPoint)); - const CEnvPointBezier *pPointBezier = EnvelopePoints.GetBezier(pItem->m_StartPoint + p); - if(pPointBezier != nullptr) - mem_copy(&pEnv->m_vPoints[p].m_Bezier, pPointBezier, sizeof(CEnvPointBezier)); - } - if(pItem->m_aName[0] != -1) // compatibility with old maps - IntsToStr(pItem->m_aName, sizeof(pItem->m_aName) / sizeof(int), pEnv->m_aName); - m_vpEnvelopes.push_back(pEnv); - if(pItem->m_Version >= CMapItemEnvelope_v2::CURRENT_VERSION) - pEnv->m_Synchronized = pItem->m_Synchronized; + const CEnvPoint *pPoint = EnvelopePoints.GetPoint(pItem->m_StartPoint + p); + if(pPoint != nullptr) + mem_copy(&pEnv->m_vPoints[p], pPoint, sizeof(CEnvPoint)); + const CEnvPointBezier *pPointBezier = EnvelopePoints.GetBezier(pItem->m_StartPoint + p); + if(pPointBezier != nullptr) + mem_copy(&pEnv->m_vPoints[p].m_Bezier, pPointBezier, sizeof(CEnvPointBezier)); } + if(pItem->m_aName[0] != -1) // compatibility with old maps + IntsToStr(pItem->m_aName, sizeof(pItem->m_aName) / sizeof(int), pEnv->m_aName); + m_vpEnvelopes.push_back(pEnv); + if(pItem->m_Version >= CMapItemEnvelope_v2::CURRENT_VERSION) + pEnv->m_Synchronized = pItem->m_Synchronized; } + } + // load automapper configurations + { + int AutomapperConfigStart, AutomapperConfigNum; + DataFile.GetType(MAPITEMTYPE_AUTOMAPPER_CONFIG, &AutomapperConfigStart, &AutomapperConfigNum); + for(int i = 0; i < AutomapperConfigNum; i++) { - int AutomapperConfigStart, AutomapperConfigNum; - DataFile.GetType(MAPITEMTYPE_AUTOMAPPER_CONFIG, &AutomapperConfigStart, &AutomapperConfigNum); - for(int i = 0; i < AutomapperConfigNum; i++) + CMapItemAutoMapperConfig *pItem = (CMapItemAutoMapperConfig *)DataFile.GetItem(AutomapperConfigStart + i); + if(pItem->m_Version == CMapItemAutoMapperConfig::CURRENT_VERSION) { - CMapItemAutoMapperConfig *pItem = (CMapItemAutoMapperConfig *)DataFile.GetItem(AutomapperConfigStart + i); - if(pItem->m_Version == CMapItemAutoMapperConfig::CURRENT_VERSION) + if(pItem->m_GroupId >= 0 && (size_t)pItem->m_GroupId < m_vpGroups.size() && + pItem->m_LayerId >= 0 && (size_t)pItem->m_LayerId < m_vpGroups[pItem->m_GroupId]->m_vpLayers.size()) { - if(pItem->m_GroupId >= 0 && (size_t)pItem->m_GroupId < m_vpGroups.size() && - pItem->m_LayerId >= 0 && (size_t)pItem->m_LayerId < m_vpGroups[pItem->m_GroupId]->m_vpLayers.size()) + std::shared_ptr pLayer = m_vpGroups[pItem->m_GroupId]->m_vpLayers[pItem->m_LayerId]; + if(pLayer->m_Type == LAYERTYPE_TILES) { - std::shared_ptr pLayer = m_vpGroups[pItem->m_GroupId]->m_vpLayers[pItem->m_LayerId]; - if(pLayer->m_Type == LAYERTYPE_TILES) + std::shared_ptr pTiles = std::static_pointer_cast(m_vpGroups[pItem->m_GroupId]->m_vpLayers[pItem->m_LayerId]); + // only load auto mappers for tile layers (not physics layers) + if(!(pTiles->m_Game || pTiles->m_Tele || pTiles->m_Speedup || + pTiles->m_Front || pTiles->m_Switch || pTiles->m_Tune)) { - std::shared_ptr pTiles = std::static_pointer_cast(m_vpGroups[pItem->m_GroupId]->m_vpLayers[pItem->m_LayerId]); - // only load auto mappers for tile layers (not physics layers) - if(!(pTiles->m_Game || pTiles->m_Tele || pTiles->m_Speedup || - pTiles->m_Front || pTiles->m_Switch || pTiles->m_Tune)) - { - pTiles->m_AutoMapperConfig = pItem->m_AutomapperConfig; - pTiles->m_Seed = pItem->m_AutomapperSeed; - pTiles->m_AutoAutoMap = !!(pItem->m_Flags & CMapItemAutoMapperConfig::FLAG_AUTOMATIC); - } + pTiles->m_AutoMapperConfig = pItem->m_AutomapperConfig; + pTiles->m_Seed = pItem->m_AutomapperSeed; + pTiles->m_AutoAutoMap = !!(pItem->m_Flags & CMapItemAutoMapperConfig::FLAG_AUTOMATIC); } } } } } } - else - return false; PerformSanityChecks(ErrorHandler);