int main(int argc, const char **argv) { if(argc != 2) { printf("wrong arguments, there has to be one and only one and this is the mapfile to extract the images from.\n"); return -1; } IStorage *pStorage = CreateStorage("Teeworlds", argc, argv); CDataFileReader DataFile; if(!pStorage) { printf("Cannot get storage\n"); return -1; } if(!DataFile.Open(pStorage, argv[1], IStorage::TYPE_ALL)) { printf("Cannot read %s\n", argv[1]); return -1; } printf("Loading %s\n", argv[1]); png_init(0, 0); // load images int start, num; DataFile.GetType(MAPITEMTYPE_IMAGE, &start, &num); for(int i = 0; i < num; i++) { CMapItemImage *pImg = (CMapItemImage *)DataFile.GetItem(start+i, 0, 0); char *pName = (char *)DataFile.GetData(pImg->m_ImageName); if(pImg->m_External) { printf("skipping external %s\n", pName); } else { printf("writing %s.png\n", pName); void *pData = DataFile.GetData(pImg->m_ImageData); char buf[255]; #if defined(CONF_FAMILY_WINDOWS) _snprintf(buf, sizeof(buf), "%s.png", pName); #else snprintf(buf, sizeof(buf), "%s.png", pName); #endif png_t png; png_open_file_write(&png, buf); png_set_data(&png, pImg->m_Width, pImg->m_Height, 8, PNG_TRUECOLOR_ALPHA, (unsigned char*) pData); png_close_file(&png); DataFile.UnloadData(pImg->m_ImageData); } } DataFile.Close(); return 0; }
void Process(IStorage *pStorage, const char *pMapName, const char *pConfigName) { CDataFileReader Map; if(!Map.Open(pStorage, pMapName, IStorage::TYPE_ALL)) { dbg_msg("config_retrieve", "error opening map '%s'", pMapName); return; } bool ConfigFound = false; int Start, Num; Map.GetType(MAPITEMTYPE_INFO, &Start, &Num); for(int i = Start; i < Start + Num; i++) { int ItemID; CMapItemInfoSettings *pItem = (CMapItemInfoSettings *)Map.GetItem(i, 0, &ItemID); int ItemSize = Map.GetItemSize(i) - 8; if(!pItem || ItemID != 0) continue; if(ItemSize < (int)sizeof(CMapItemInfoSettings)) break; if(!(pItem->m_Settings > -1)) break; ConfigFound = true; IOHANDLE Config = pStorage->OpenFile(pConfigName, IOFLAG_WRITE, IStorage::TYPE_ALL); if(!Config) { dbg_msg("config_retrieve", "error opening config for writing '%s'", pConfigName); return; } int Size = Map.GetUncompressedDataSize(pItem->m_Settings); char *pSettings = (char *)Map.GetData(pItem->m_Settings); char *pNext = pSettings; while(pNext < pSettings + Size) { int StrSize = str_length(pNext) + 1; io_write(Config, pNext, StrSize - 1); io_write_newline(Config); pNext += StrSize; } Map.UnloadData(pItem->m_Settings); io_close(Config); break; } Map.Close(); if(!ConfigFound) { fs_remove(pConfigName); } }
virtual void GetType(int Type, int *pStart, int *pNum) { m_DataFile.GetType(Type, pStart, pNum); }
int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int StorageType) { CDataFileReader DataFile; //DATAFILE *df = datafile_load(filename); if(!DataFile.Open(pStorage, pFileName, StorageType)) return 0; Clean(); // check version CMapItemVersion *pItem = (CMapItemVersion *)DataFile.FindItem(MAPITEMTYPE_VERSION, 0); if(!pItem) { // import old map /*MAP old_mapstuff; editor->reset(); editor_load_old(df, this); */ } else if(pItem->m_Version == 1) { //editor.reset(false); // load images { int Start, Num; DataFile.GetType( MAPITEMTYPE_IMAGE, &Start, &Num); for(int i = 0; i < Num; i++) { CMapItemImage *pItem = (CMapItemImage *)DataFile.GetItem(Start+i, 0, 0); char *pName = (char *)DataFile.GetData(pItem->m_ImageName); // copy base info CEditorImage *pImg = new CEditorImage(m_pEditor); pImg->m_External = pItem->m_External; if(pItem->m_External) { char aBuf[256]; 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; pImg->m_TexID = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, 0); pImg->m_External = 1; } } else { pImg->m_Width = pItem->m_Width; pImg->m_Height = pItem->m_Height; pImg->m_Format = CImageInfo::FORMAT_RGBA; // copy image data void *pData = DataFile.GetData(pItem->m_ImageData); pImg->m_pData = mem_alloc(pImg->m_Width*pImg->m_Height*4, 1); mem_copy(pImg->m_pData, pData, pImg->m_Width*pImg->m_Height*4); pImg->m_TexID = m_pEditor->Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, pImg->m_Format, pImg->m_pData, CImageInfo::FORMAT_AUTO, 0); } // copy image name if(pName) str_copy(pImg->m_aName, pName, 128); m_lImages.add(pImg); // unload image DataFile.UnloadData(pItem->m_ImageData); DataFile.UnloadData(pItem->m_ImageName); } } // load groups { int LayersStart, LayersNum; DataFile.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersNum); int Start, Num; DataFile.GetType(MAPITEMTYPE_GROUP, &Start, &Num); for(int g = 0; g < Num; g++) { CMapItemGroup *pGItem = (CMapItemGroup *)DataFile.GetItem(Start+g, 0, 0); if(pGItem->m_Version < 1 || pGItem->m_Version > CMapItemGroup::CURRENT_VERSION) continue; CLayerGroup *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; } for(int l = 0; l < pGItem->m_NumLayers; l++) { CLayer *pLayer = 0; CMapItemLayer *pLayerItem = (CMapItemLayer *)DataFile.GetItem(LayersStart+pGItem->m_StartLayer+l, 0, 0); if(!pLayerItem) continue; if(pLayerItem->m_Type == LAYERTYPE_TILES) { CMapItemLayerTilemap *pTilemapItem = (CMapItemLayerTilemap *)pLayerItem; CLayerTiles *pTiles = 0; if(pTilemapItem->m_Flags&1) { pTiles = new CLayerGame(pTilemapItem->m_Width, pTilemapItem->m_Height); MakeGameLayer(pTiles); MakeGameGroup(pGroup); } else { pTiles = new CLayerTiles(pTilemapItem->m_Width, pTilemapItem->m_Height); pTiles->m_pEditor = m_pEditor; pTiles->m_Color.r = pTilemapItem->m_Color.r; pTiles->m_Color.g = pTilemapItem->m_Color.g; pTiles->m_Color.b = pTilemapItem->m_Color.b; pTiles->m_Color.a = pTilemapItem->m_Color.a; } pLayer = pTiles; pGroup->AddLayer(pTiles); void *pData = DataFile.GetData(pTilemapItem->m_Data); pTiles->m_Image = pTilemapItem->m_Image; pTiles->m_Game = pTilemapItem->m_Flags&1; mem_copy(pTiles->m_pTiles, pData, pTiles->m_Width*pTiles->m_Height*sizeof(CTile)); 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); } else if(pLayerItem->m_Type == LAYERTYPE_QUADS) { CMapItemLayerQuads *pQuadsItem = (CMapItemLayerQuads *)pLayerItem; CLayerQuads *pQuads = new CLayerQuads; pQuads->m_pEditor = m_pEditor; pLayer = pQuads; pQuads->m_Image = pQuadsItem->m_Image; if(pQuads->m_Image < -1 || pQuads->m_Image >= m_lImages.size()) pQuads->m_Image = -1; void *pData = DataFile.GetDataSwapped(pQuadsItem->m_Data); pGroup->AddLayer(pQuads); pQuads->m_lQuads.set_size(pQuadsItem->m_NumQuads); mem_copy(pQuads->m_lQuads.base_ptr(), pData, sizeof(CQuad)*pQuadsItem->m_NumQuads); DataFile.UnloadData(pQuadsItem->m_Data); } if(pLayer) pLayer->m_Flags = pLayerItem->m_Flags; } } } // load envelopes { CEnvPoint *pPoints = 0; { int Start, Num; DataFile.GetType(MAPITEMTYPE_ENVPOINTS, &Start, &Num); if(Num) pPoints = (CEnvPoint *)DataFile.GetItem(Start, 0, 0); } int Start, Num; DataFile.GetType(MAPITEMTYPE_ENVELOPE, &Start, &Num); for(int e = 0; e < Num; e++) { CMapItemEnvelope *pItem = (CMapItemEnvelope *)DataFile.GetItem(Start+e, 0, 0); CEnvelope *pEnv = new CEnvelope(pItem->m_Channels); pEnv->m_lPoints.set_size(pItem->m_NumPoints); mem_copy(pEnv->m_lPoints.base_ptr(), &pPoints[pItem->m_StartPoint], sizeof(CEnvPoint)*pItem->m_NumPoints); if(pItem->m_aName[0] != -1) // compatibility with old maps IntsToStr(pItem->m_aName, sizeof(pItem->m_aName)/sizeof(int), pEnv->m_aName); m_lEnvelopes.add(pEnv); } } } return 1; }
virtual bool Load(const char *pMapName, IStorage *pStorage) { if(!pStorage) pStorage = Kernel()->RequestInterface<IStorage>(); if(!pStorage) return false; if(!m_DataFile.Open(pStorage, pMapName, IStorage::TYPE_ALL)) return false; // check version CMapItemVersion *pItem = (CMapItemVersion *)m_DataFile.FindItem(MAPITEMTYPE_VERSION, 0); 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++) { CMapItemGroup *pGroup = static_cast<CMapItemGroup *>(m_DataFile.GetItem(GroupsStart + g, 0, 0)); for(int l = 0; l < pGroup->m_NumLayers; l++) { CMapItemLayer *pLayer = static_cast<CMapItemLayer *>(m_DataFile.GetItem(LayersStart + pGroup->m_StartLayer + l, 0, 0)); if(pLayer->m_Type == LAYERTYPE_TILES) { CMapItemLayerTilemap *pTilemap = reinterpret_cast<CMapItemLayerTilemap *>(pLayer); if(pTilemap->m_Version > 3) { const int TilemapCount = pTilemap->m_Width * pTilemap->m_Height; const int TilemapSize = TilemapCount * sizeof(CTile); if((TilemapCount / pTilemap->m_Width != pTilemap->m_Height) || (TilemapSize / (int)sizeof(CTile) != TilemapCount)) { dbg_msg("engine", "map layer too big (%d * %d * %u causes an integer overflow)", pTilemap->m_Width, pTilemap->m_Height, unsigned(sizeof(CTile))); return false; } CTile *pTiles = static_cast<CTile *>(mem_alloc(TilemapSize, 1)); if(!pTiles) return false; // extract original tile data int i = 0; CTile *pSavedTiles = static_cast<CTile *>(m_DataFile.GetData(pTilemap->m_Data)); while(i < TilemapCount) { for(unsigned Counter = 0; Counter <= pSavedTiles->m_Skip && i < TilemapCount; Counter++) { pTiles[i] = *pSavedTiles; pTiles[i++].m_Skip = 0; } pSavedTiles++; } m_DataFile.ReplaceData(pTilemap->m_Data, reinterpret_cast<char *>(pTiles)); } } } } return true; }