diff --git a/src/engine/shared/datafile.cpp b/src/engine/shared/datafile.cpp index c0c08c5dc..47238892f 100644 --- a/src/engine/shared/datafile.cpp +++ b/src/engine/shared/datafile.cpp @@ -346,6 +346,15 @@ void *CDataFileReader::GetDataSwapped(int Index) return GetDataImpl(Index, 1); } +void CDataFileReader::ReplaceData(int Index, char *pData) +{ + // make sure the data has been loaded + GetDataImpl(Index, 0); + + UnloadData(Index); + m_pDataFile->m_ppDataPtrs[Index] = pData; +} + void CDataFileReader::UnloadData(int Index) { if(Index < 0 || Index >= m_pDataFile->m_Header.m_NumRawData) diff --git a/src/engine/shared/datafile.h b/src/engine/shared/datafile.h index c55f1fccf..3a45a823a 100644 --- a/src/engine/shared/datafile.h +++ b/src/engine/shared/datafile.h @@ -38,6 +38,7 @@ public: void *GetData(int Index); void *GetDataSwapped(int Index); // makes sure that the data is 32bit LE ints when saved int GetDataSize(int Index) const; + void ReplaceData(int Index, char *pData); void UnloadData(int Index); int NumData() const; diff --git a/src/engine/shared/map.cpp b/src/engine/shared/map.cpp index 24fc1ec12..d14941e97 100644 --- a/src/engine/shared/map.cpp +++ b/src/engine/shared/map.cpp @@ -70,6 +70,43 @@ bool CMap::Load(const char *pMapName) if(!pItem || pItem->m_Version != CMapItemVersion::CURRENT_VERSION) 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); + for(int g = 0; g < GroupsNum; g++) + { + const CMapItemGroup *pGroup = static_cast(m_DataFile.GetItem(GroupsStart + g)); + for(int l = 0; l < pGroup->m_NumLayers; l++) + { + CMapItemLayer *pLayer = static_cast(m_DataFile.GetItem(LayersStart + pGroup->m_StartLayer + l)); + if(pLayer->m_Type == LAYERTYPE_TILES) + { + CMapItemLayerTilemap *pTilemap = reinterpret_cast(pLayer); + if(pTilemap->m_Version > 3) + { + CTile *pTiles = static_cast(malloc(pTilemap->m_Width * pTilemap->m_Height * sizeof(CTile))); + + // extract original tile data + int i = 0; + CTile *pSavedTiles = static_cast(m_DataFile.GetData(pTilemap->m_Data)); + while(i < pTilemap->m_Width * pTilemap->m_Height) + { + for(unsigned Counter = 0; Counter <= pSavedTiles->m_Skip && i < pTilemap->m_Width * pTilemap->m_Height; Counter++) + { + pTiles[i] = *pSavedTiles; + pTiles[i++].m_Skip = 0; + } + + pSavedTiles++; + } + + m_DataFile.ReplaceData(pTilemap->m_Data, reinterpret_cast(pTiles)); + } + } + } + } + return true; } diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index 49b3a639e..2f2d835e4 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -624,6 +624,7 @@ public: void ModifyEnvelopeIndex(INDEX_MODIFY_FUNC pfnFunc) override; void PrepareForSave(); + void ExtractTiles(CTile *pSavedTiles); void GetSize(float *pWidth, float *pHeight) override { diff --git a/src/game/editor/io.cpp b/src/game/editor/io.cpp index d6b818138..6b1349b78 100644 --- a/src/game/editor/io.cpp +++ b/src/game/editor/io.cpp @@ -793,17 +793,17 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio { void *pData = DataFile.GetData(pTilemapItem->m_Data); unsigned int Size = DataFile.GetDataSize(pTilemapItem->m_Data); - if(Size >= (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CTile)) - { + if(pTilemapItem->m_Version > 3) + pTiles->ExtractTiles((CTile *)pData); + else if(Size >= (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CTile)) mem_copy(pTiles->m_pTiles, pData, (size_t)pTiles->m_Width * pTiles->m_Height * sizeof(CTile)); - if(pTiles->m_Game && pTilemapItem->m_Version == MakeVersion(1, *pTilemapItem)) + if(pTiles->m_Game && pTilemapItem->m_Version == MakeVersion(1, *pTilemapItem)) + { + for(int i = 0; i < pTiles->m_Width * pTiles->m_Height; i++) { - 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; - } + if(pTiles->m_pTiles[i].m_Index) + pTiles->m_pTiles[i].m_Index += ENTITY_OFFSET; } } DataFile.UnloadData(pTilemapItem->m_Data); diff --git a/src/game/editor/layer_tiles.cpp b/src/game/editor/layer_tiles.cpp index 0910c315a..9ce36da92 100644 --- a/src/game/editor/layer_tiles.cpp +++ b/src/game/editor/layer_tiles.cpp @@ -97,6 +97,21 @@ void CLayerTiles::PrepareForSave() } } +void CLayerTiles::ExtractTiles(CTile *pSavedTiles) +{ + int i = 0; + while(i < m_Width * m_Height) + { + for(unsigned Counter = 0; Counter <= pSavedTiles->m_Skip && i < m_Width * m_Height; Counter++) + { + m_pTiles[i] = *pSavedTiles; + m_pTiles[i++].m_Skip = 0; + } + + pSavedTiles++; + } +} + void CLayerTiles::MakePalette() { for(int y = 0; y < m_Height; y++) diff --git a/src/game/mapitems.h b/src/game/mapitems.h index eeba9fa3a..73ed01105 100644 --- a/src/game/mapitems.h +++ b/src/game/mapitems.h @@ -298,6 +298,11 @@ struct CMapItemLayer struct CMapItemLayerTilemap { + enum + { + CURRENT_VERSION = 4 + }; + CMapItemLayer m_Layer; int m_Version;