/// <summary> /// Returns an SM2 map texuture /// </summary> public BitmapSource GetTexture(Map map, int detail, UnitSync unitSync) { UnitSync.NativeMethods.RemoveAllArchives(); UnitSync.NativeMethods.AddAllArchives(map.ArchiveName); ProgressChanged(this, new ProgressChangedEventArgs(0, "Extracting map")); var mapDir = UnitSync.NativeMethods.GetMapFileName(UnitSync.NativeMethods.GetMapIndex(map.Name)); var smfFileData = unitSync.ReadVfsFile(mapDir); BinaryReader reader; try { reader = new BinaryReader(new MemoryStream(smfFileData)); } catch (System.ArgumentNullException nullEx) { throw new System.ArgumentNullException("smfFileData", "Unable to read SMF: " + mapDir); } var smfHeader = reader.ReadStruct <SMFHeader>(); smfHeader.SelfCheck(); var mapWidth = smfHeader.mapx; var mapHeight = smfHeader.mapy; reader.BaseStream.Position = smfHeader.tilesPtr; var mapTileHeader = reader.ReadStruct <MapTileHeader>(); // get the tile files and the number of tiles they contain var tileFiles = new Dictionary <byte[], int>(); for (var i = 0; i < mapTileHeader.numTileFiles; i++) { var numTiles = reader.ReadInt32(); var tileFileData = unitSync.ReadVfsFile("maps\\" + reader.ReadCString()); tileFiles.Add(tileFileData, numTiles); } // get the position of the tiles var mapUnitInTiles = Tiles.TileMipLevel1Size / smfHeader.texelPerSquare; var tilesX = smfHeader.mapx / mapUnitInTiles; var tilesY = smfHeader.mapy / mapUnitInTiles; var tileIndices = new int[tilesX * tilesY]; for (var i = 0; i < tileIndices.Length; i++) { tileIndices[i] = reader.ReadInt32(); } Tiles.ProgressChanged += (s, e) => ProgressChanged(this, e); UnitSync.NativeMethods.RemoveAllArchives(); // load the tiles WriteableBitmap ret; try { ret = (WriteableBitmap)Tiles.LoadTiles(tileFiles, tileIndices, tilesX, tilesY, detail); } catch (System.Exception ex) { // some maps (e.g. Glacies) fail to load the tiles properly; use minimap as a fallback //if (map.Texture == null) throw new System.Exception("Unable to load map texture"); //var newBitmap = new Bitmap(GetBitmap(map.Texture), new Size(map.Texture.PixelWidth / 8, map.Texture.PixelHeight / 8)); map.Minimap = unitSync.GetMinimap(map); ret = new WriteableBitmap(ConvertBitmap(map.Minimap)); ret.Freeze(); //ret.Unlock(); } return(ret); }