private void Read(BinaryReader br) { Header = new Header { Version = (Version)br.ReadUInt32(), NumLumps = br.ReadInt32(), LumpOffest = br.ReadInt32() }; if (Header.Version != Version.Wad2 && Header.Version != Version.Wad3) { throw new NotSupportedException("Only Goldsource (WAD2 & WAD3) WAD files are supported."); } br.BaseStream.Seek(Header.LumpOffest, SeekOrigin.Begin); for (var i = 0; i < Header.NumLumps; i++) { var lump = new Lump { Offset = br.ReadInt32(), CompressedSize = br.ReadInt32(), UncompressedSize = br.ReadInt32(), Type = (LumpType)br.ReadByte(), Compression = br.ReadByte() }; br.ReadBytes(2); var name = br.ReadChars(Lump.NameLength); var len = Array.IndexOf(name, '\0'); lump.Name = new string(name, 0, len < 0 ? name.Length : len); Lumps.Add(lump); } foreach (var lump in Lumps) { br.BaseStream.Seek(lump.Offset, SeekOrigin.Begin); Texture texture; switch (lump.Type) { case LumpType.Image: texture = new Texture { Name = lump.Name, Width = br.ReadUInt32(), Height = br.ReadUInt32(), NumMips = 1 }; var size = (int)(texture.Width * texture.Height); texture.MipData = new[] { br.ReadBytes(size) }; var paletteSize = br.ReadUInt16(); texture.Palette = br.ReadBytes(paletteSize * 3); break; case LumpType.Texture: texture = ReadMipTexture(br); break; default: continue; } Textures[texture.Name] = texture; } }
/// <summary> /// Reads the data of a HOG file from a stream. /// </summary> /// <param name="stream">The stream to read the HOG file from. The stream must be seekable</param> public void Read(Stream stream) { lock (hogFileLock) { if (!stream.CanSeek) { throw new ArgumentException("HOGFIle:Read: Passed stream must be seekable."); } BinaryReader br = new BinaryReader(stream); fileStream = br; Lumps.Clear(); char[] header = new char[3]; header[0] = (char)br.ReadByte(); header[1] = (char)br.ReadByte(); header[2] = (char)br.ReadByte(); var headerString = new string(header); switch (headerString) { case "DHF": Format = HOGFormat.Standard; break; case "D2X": Format = HOGFormat.D2X_XL; break; default: throw new InvalidDataException($"Unrecognized HOG header \"{headerString}\""); } try { while (true) { char[] filenamedata = new char[13]; bool hashitnull = false; for (int x = 0; x < 13; x++) { char c = (char)br.ReadByte(); if (c == 0) { hashitnull = true; } if (!hashitnull) { filenamedata[x] = c; } } string filename = new string(filenamedata); filename = filename.Trim(' ', '\0'); int filesize = br.ReadInt32(); if (Format == HOGFormat.D2X_XL && filesize < 0) { // D2X-XL format encodes "extended" lump headers with negative file sizes filesize = -filesize; string longFilename = Encoding.ASCII.GetString(br.ReadBytes(256)); if (longFilename.Contains("\0")) { longFilename = longFilename.Remove(longFilename.IndexOf('\0')); } longFilename = longFilename.Trim(' '); // No real reason to use short filename in this instance; just replace it filename = longFilename; } int offset = (int)br.BaseStream.Position; br.BaseStream.Seek(filesize, SeekOrigin.Current); //I hate hog files. Wads are cooler.. HOGLump lump = new HOGLump(filename, filesize, offset); Lumps.Add(lump); } } catch (EndOfStreamException) { //we got all the files //heh //i love hog //classification now lives in EditorHOGFile since only editors care about it } } }