public Location(RawLocation rawLocation) { Crosstreet = rawLocation.CrossStreet; City = rawLocation.City; State = rawLocation.State; Postalcode = rawLocation.PostalCode; Country = rawLocation.Country; Lat = rawLocation.Lat; Lng = rawLocation.Lng; }
private byte[] bitmap_LoadData(int bitmapIndex, int lodIndex) { //Get source data byte[] sourceData = null; RawLocation rawLocation = (RawLocation)(bitmap.Bitmaps[bitmapIndex].RawOffsets[lodIndex] & 0xC0000000); if (rawLocation == RawLocation.Local) { sourceData = SelectedEntry.Raws[RawSection.Bitmap][(int)bitmap.Bitmaps[bitmapIndex].RawOffsets[lodIndex]].ToArray(); } else { string filelocation = string.Empty; int rawOffset = (int)(bitmap.Bitmaps[bitmapIndex].RawOffsets[lodIndex] & (uint)RawLocation.LocalMask); switch (rawLocation) { case RawLocation.Mainmenu: filelocation = HaloSettings.MainmenuPath; break; case RawLocation.Shared: filelocation = HaloSettings.SharedPath; break; case RawLocation.SinglePlayerShared: filelocation = HaloSettings.SingleplayerSharedPath; break; } //Check if (File.Exists(filelocation)) { using (FileStream fs = new FileStream(filelocation, FileMode.Open)) using (BinaryReader mapReader = new BinaryReader(fs)) { fs.Seek(rawOffset, SeekOrigin.Begin); sourceData = mapReader.ReadBytes(bitmap.Bitmaps[bitmapIndex].RawLengths[lodIndex]); } } } //Return return(sourceData); }
/// <summary> /// Initializes a new instance of the <see cref="HaloModel"/> class. /// </summary> /// <param name="entry">The model Halo 2 index entry.</param> public HaloModel(MapFile map, IndexEntry entry) { //Check if (map == null) { throw new ArgumentNullException(nameof(map)); } if (entry == null) { throw new ArgumentNullException(nameof(entry)); } else if (entry.Root != HaloTags.mode) { throw new ArgumentException("Index entry is not render model.", nameof(entry)); } //Setup this.map = map; this.entry = entry; tag = new ModelTag(entry); meshes = new Mesh[tag.Regions.Length][][]; //Setup property accessors compressionInfo = new CompressionInfoProperties(this); regions = new RegionProperties[tag.Regions.Length]; for (int i = 0; i < tag.Regions.Length; i++) { regions[i] = new RegionProperties(this, i); } permutations = new PermutationProperties[tag.Regions.Length][]; for (int i = 0; i < tag.Regions.Length; i++) { permutations[i] = new PermutationProperties[tag.Permutations[i].Length]; for (int j = 0; j < tag.Permutations[i].Length; j++) { permutations[i][j] = new PermutationProperties(this, i, j); } } sections = new SectionProperties[tag.Sections.Length]; for (int i = 0; i < tag.Sections.Length; i++) { sections[i] = new SectionProperties(this, i); } resources = new ResourceProperties[tag.Sections.Length][]; for (int i = 0; i < tag.Sections.Length; i++) { resources[i] = new ResourceProperties[tag.Resources[i].Length]; for (int j = 0; j < tag.Resources[i].Length; j++) { resources[i][j] = new ResourceProperties(this, i, j); } } //Loop through regions for (int r = 0; r < tag.Regions.Length; r++) { //Setup ModelTagGroup.Region region = tag.Regions[r]; meshes[r] = new Mesh[region.Permutations.Count][]; //Loop through permutations for (int p = 0; p < region.Permutations.Count; p++) { //Setup ModelTagGroup.Region.Permutation permutation = tag.Permutations[r][p]; meshes[r][p] = new Mesh[6]; //Loop through LODs byte[] sourceData = null; for (int l = 0; l < 6; l++) { //Get source data int sectionIndex = -1; switch (l) { case 0: sectionIndex = permutation.L1SectionIndex; break; case 1: sectionIndex = permutation.L2SectionIndex; break; case 2: sectionIndex = permutation.L3SectionIndex; break; case 3: sectionIndex = permutation.L4SectionIndex; break; case 4: sectionIndex = permutation.L5SectionIndex; break; case 5: sectionIndex = permutation.L6SectionIndex; break; } //Check if (sectionIndex >= 0 && sectionIndex < sections.Length) { //Get properties ModelTagGroup.Section section = tag.Sections[sectionIndex]; //Check if (section.RawOffset != uint.MaxValue) { RawLocation rawLocation = (RawLocation)(section.RawOffset & 0xC0000000); if (rawLocation == RawLocation.Local) { sourceData = entry.Raws[RawSection.Model][(int)section.RawOffset].ToArray(); } else { string fileLocation = string.Empty; int rawOffset = (int)(section.RawOffset & (uint)RawLocation.LocalMask); switch (rawLocation) { case RawLocation.Shared: fileLocation = HaloSettings.SharedPath; break; case RawLocation.Mainmenu: fileLocation = HaloSettings.MainmenuPath; break; case RawLocation.SinglePlayerShared: fileLocation = HaloSettings.SingleplayerSharedPath; break; } //Check if (File.Exists(fileLocation)) { using (FileStream fs = new FileStream(fileLocation, FileMode.Open)) using (BinaryReader mapReader = new BinaryReader(fs)) { fs.Seek(rawOffset, SeekOrigin.Begin); sourceData = mapReader.ReadBytes((int)section.RawSize); } } } } //Set if (sourceData.Length == 0) { continue; } //Dump try { using (FileStream fs = new FileStream(@"F:\model.bin", FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) fs.Write(sourceData, 0, sourceData.Length); } catch { } //Create Mesh meshes[r][p][l] = Mesh.Halo2Mesh(resources[sectionIndex], sourceData); } } } } }
/// <summary> /// Initializes a new <see cref="HaloBitmap"/> instance using the supplied object index entry. /// </summary> /// <param name="entry">The object index entry that contains the bitmap tag group data.</param> /// <exception cref="ArgumentNullException"><paramref name="entry"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="entry"/> is not a bitmap.</exception> public HaloBitmap(IndexEntry entry) { //Check if (entry == null) { throw new ArgumentNullException(nameof(entry)); } else if (entry.Root != HaloTags.bitm) { throw new ArgumentException("Index entry is not bitmap.", nameof(entry)); } //Setup this.entry = entry; tag = new BitmapTag(entry); maps = new Bitmap[tag.Bitmaps.Length][][]; //Setup Property Accessors bitmaps = new BitmapProperties[tag.Bitmaps.Length]; for (int i = 0; i < tag.Bitmaps.Length; i++) { bitmaps[i] = new BitmapProperties(this, i); } sequences = new SequenceProperties[tag.Sequences.Length]; for (int i = 0; i < tag.Sequences.Length; i++) { sequences[i] = new SequenceProperties(this, i); } //Check if (tag == null) { return; } else if (tag.Bitmaps.Length == 0) { return; } //Loop through bitmaps for (int k = 0; k < tag.Bitmaps.Length; k++) { //Setup BitmapTagGroup.Bitmap bitmap = tag.Bitmaps[k]; maps[k] = new Bitmap[6][]; //Loop through LODs byte[] sourceData = null; for (int l = 0; l < 6; l++) { //Get source data if (bitmap.rawOffsets[l] != uint.MaxValue) { RawLocation rawLocation = (RawLocation)(bitmap.rawOffsets[l] & 0xC0000000); if (rawLocation == RawLocation.Local) { sourceData = entry.Raws[RawSection.Bitmap][(int)bitmap.rawOffsets[l]].GetBuffer(); } else { string filelocation = string.Empty; int rawOffset = (int)(bitmap.rawOffsets[l] & (uint)RawLocation.LocalMask); switch (rawLocation) { case RawLocation.Mainmenu: filelocation = HaloSettings.MainmenuPath; break; case RawLocation.Shared: filelocation = HaloSettings.SharedPath; break; case RawLocation.SinglePlayerShared: filelocation = HaloSettings.SingleplayerSharedPath; break; } //Check if (File.Exists(filelocation)) { using (FileStream fs = new FileStream(filelocation, FileMode.Open)) using (BinaryReader mapReader = new BinaryReader(fs)) { fs.Seek(rawOffset, SeekOrigin.Begin); sourceData = mapReader.ReadBytes(bitmap.rawLengths[l]); } } } } //Set if (sourceData.Length == 0) { continue; } //Prepare BitmapFlags flags = (BitmapFlags)bitmap.flags; BitmapFormat format = (BitmapFormat)bitmap.format; PixelFormat bitmapFormat = PixelFormat.Format32bppArgb; int sourceBits = 32; switch (format) { case BitmapFormat.A8: case BitmapFormat.Y8: case BitmapFormat.P8Bump: case BitmapFormat.P8: case BitmapFormat.Ay8: sourceBits = 8; break; case BitmapFormat.A8y8: case BitmapFormat.A1r5g5b5: case BitmapFormat.A4r4g4b4: case BitmapFormat.V8u8: case BitmapFormat.G8b8: case BitmapFormat.R5g6b5: sourceBits = 16; break; case BitmapFormat.Dxt1: sourceBits = 4; break; case BitmapFormat.Dxt5: case BitmapFormat.Dxt3: sourceBits = 8; break; case BitmapFormat.Argbfp32: sourceBits = 128; break; } //Handle switch (format) { case BitmapFormat.R5g6b5: bitmapFormat = PixelFormat.Format16bppRgb565; break; case BitmapFormat.A1r5g5b5: bitmapFormat = PixelFormat.Format16bppArgb1555; break; case BitmapFormat.X8r8g8b8: bitmapFormat = PixelFormat.Format32bppRgb; break; case BitmapFormat.P8Bump: bitmapFormat = PixelFormat.Format8bppIndexed; break; case BitmapFormat.P8: bitmapFormat = PixelFormat.Format8bppIndexed; break; } //Prepare int width = bitmap.width, height = bitmap.height; if (flags.HasFlag(BitmapFlags.Linear)) { width = (int)Math.Ceiling(width / 16f) * 16; } //Loop LOD for (int i = 0; i < l; i++) { width /= 2; height /= 2; } //Prepare int mapWidth = width, mapHeight = height, location = 0; int mipmapCount = bitmap.mipmapCount; maps[k][l] = new Bitmap[mipmapCount + 1]; Size bitmapSize = Size.Empty; byte[] mapData = null; //Loop for (int i = 1; i <= mipmapCount + 1; i++) { //Prepare int mapIndex = i - 1; mapWidth = width; mapHeight = height; for (int j = 1; j < i; j++) { mapWidth /= 2; mapHeight /= 2; } //Get Size bitmapSize = new Size(mapWidth, mapHeight); //Check if (bitmapSize.Width == 0 || bitmapSize.Height == 0) { continue; } //Create Map int mapStride = mapWidth * sourceBits / 8; int mapSize = mapStride * mapHeight; //Ehh? switch (format) { case BitmapFormat.Dxt1: mapSize = Math.Max(mapSize, 8); break; case BitmapFormat.Dxt3: case BitmapFormat.Dxt5: mapSize = Math.Max(mapSize, 16); break; case BitmapFormat.P8: case BitmapFormat.P8Bump: mapSize = Math.Max(mapSize, 16); break; default: mapSize = Math.Max(mapSize, 1); break; } mapData = new byte[mapSize]; if (location + mapSize > sourceData.Length) { continue; } Array.Copy(sourceData, location, mapData, 0, mapSize); //Deswizzle? if ((flags & BitmapFlags.Swizzled) == BitmapFlags.Swizzled) { mapData = Swizzler.Swizzle(mapData, mapWidth, mapHeight, bitmap.depth, sourceBits, true); } if (mapData == null) { mapData = new byte[mapSize]; } using (Bitmap map = new Bitmap(mapWidth, mapHeight, bitmapFormat)) { unsafe { //Lock Bits BitmapData data = map.LockBits(new Rectangle(0, 0, mapWidth, mapHeight), ImageLockMode.ReadWrite, bitmapFormat); //Prepare Buffer byte[] bitmapData = new byte[data.Stride * data.Height]; int dataLength = Math.Min(bitmapData.Length, mapSize); //Handle Format... switch (format) { case BitmapFormat.A8: for (int x = 0; x < mapWidth * mapHeight; x++) { bitmapData[x * 4 + 0] = 255; bitmapData[x * 4 + 1] = 255; bitmapData[x * 4 + 2] = 255; bitmapData[x * 4 + 3] = mapData[x]; } break; case BitmapFormat.Y8: for (int x = 0; x < mapWidth * mapHeight; x++) { bitmapData[x * 4 + 0] = mapData[x]; bitmapData[x * 4 + 1] = mapData[x]; bitmapData[x * 4 + 2] = mapData[x]; bitmapData[x * 4 + 3] = 255; } break; case BitmapFormat.Ay8: for (int x = 0; x < mapWidth * mapHeight; x++) { bitmapData[x * 4 + 0] = mapData[x]; bitmapData[x * 4 + 1] = mapData[x]; bitmapData[x * 4 + 2] = mapData[x]; bitmapData[x * 4 + 3] = mapData[x]; } break; case BitmapFormat.A8y8: for (int x = 0; x < mapWidth * mapHeight; x++) { bitmapData[x * 4 + 0] = mapData[x * 2]; bitmapData[x * 4 + 1] = mapData[x * 2]; bitmapData[x * 4 + 2] = mapData[x * 2]; bitmapData[x * 4 + 3] = mapData[x * 2 + 1]; } break; case BitmapFormat.A4r4g4b4: for (int x = 0; x < mapWidth * mapHeight; x++) { bitmapData[x * 4 + 0] = (byte)(mapData[x * 2 + 0] & 0xF0); bitmapData[x * 4 + 1] = (byte)(mapData[x * 2 + 0] & 0x0F); bitmapData[x * 4 + 2] = (byte)(mapData[x * 2 + 1] & 0xF0); bitmapData[x * 4 + 3] = (byte)(mapData[x * 2 + 1] & 0x0F); } break; case BitmapFormat.P8Bump: case BitmapFormat.P8: Array.Copy(mapData, 0, bitmapData, 0, dataLength); break; case BitmapFormat.R5g6b5: Array.Copy(mapData, 0, bitmapData, 0, dataLength); break; case BitmapFormat.A1r5g5b5: Array.Copy(mapData, 0, bitmapData, 0, dataLength); break; case BitmapFormat.X8r8g8b8: Array.Copy(mapData, 0, bitmapData, 0, dataLength); break; case BitmapFormat.A8r8g8b8: Array.Copy(mapData, 0, bitmapData, 0, dataLength); break; case BitmapFormat.Dxt1: if (mapWidth >= 4 && mapHeight >= 4) { S3TC.DecompressDxt1(ref bitmapData, mapData, bitmapSize); } break; case BitmapFormat.Dxt3: if (mapWidth >= 4 && mapHeight >= 4) { S3TC.DecompressDxt3(ref bitmapData, mapData, bitmapSize); } break; case BitmapFormat.Dxt5: if (mapWidth >= 4 && mapHeight >= 4) { S3TC.DecompressDxt5(ref bitmapData, mapData, bitmapSize); } break; case BitmapFormat.Argbfp32: for (int x = 0; x < mapWidth * mapHeight; x++) { bitmapData[x * 4 + 0] = (byte)Math.Min((BitConverter.ToSingle(mapData, x * 16 + 8) * 255f), 255f); bitmapData[x * 4 + 1] = (byte)Math.Min((BitConverter.ToSingle(mapData, x * 16 + 4) * 255f), 255f); bitmapData[x * 4 + 2] = (byte)Math.Min((BitConverter.ToSingle(mapData, x * 16) * 255f), 255f); bitmapData[x * 4 + 3] = (byte)Math.Min((BitConverter.ToSingle(mapData, x * 16 + 12) * 255f), 255f); } break; case BitmapFormat.Rgbfp32: break; case BitmapFormat.Rgbfp16: break; case BitmapFormat.V8u8: for (int x = 0; x < mapWidth * mapHeight; x++) { bitmapData[x * 4 + 0] = 255; bitmapData[x * 4 + 1] = (byte)(127 + (sbyte)mapData[x * 2 + 1]); bitmapData[x * 4 + 2] = (byte)(127 + (sbyte)mapData[x * 2]); bitmapData[x * 4 + 3] = 255; } break; case BitmapFormat.G8b8: break; } //Copy Marshal.Copy(bitmapData, 0, data.Scan0, bitmapData.Length); map.UnlockBits(data); //Setup Palettes if (format == BitmapFormat.P8Bump) { map.SetNormalMapPalette(); } else if (format == BitmapFormat.P8) { map.SetGrayscalePalette(); } //Set location += mapSize; } //Draw into cropped image maps[k][l][mapIndex] = new Bitmap(bitmap.width, bitmap.height, bitmapFormat); using (Graphics g = Graphics.FromImage(maps[k][l][mapIndex])) g.DrawImage(map, Point.Empty); } } } } }