public void AddFile(string path, string entryPath, WadEntry entry) { char pathSeparator = Pathing.GetPathSeparator(path); string[] folders = path.Split(pathSeparator); //If folders length is 1 then we can add the file to this directory //if not, then we pass it down the hierarchy if (folders.Length == 1) { this.Items.Add(new WadFileViewModel(this._wadViewModel, this, entryPath, folders[0], entry)); } else { //If the folder exists we pass the file to it //if it doesn't then we create it before passing the file if (this.Items.FirstOrDefault(x => x.Name == folders[0]) is WadFolderViewModel folder) { folder.AddFile(path.Substring(path.IndexOf(pathSeparator) + 1), entryPath, entry); } else { string newFolderPath = string.Format("{0}/{1}", this.Path, folders[0]); WadFolderViewModel newFolder = new WadFolderViewModel(this._wadViewModel, this, newFolderPath); newFolder.AddFile(path.Substring(path.IndexOf(pathSeparator) + 1), entryPath, entry); this.Items.Add(newFolder); } } }
public WadFileViewModel(WadViewModel wadViewModel, WadItemViewModel parent, string path, string name, WadEntry entry) : base(wadViewModel, parent, WadItemType.File) { this.Path = path; this.Name = name; this.Entry = entry; }
public static void Save(WadFile wad, Stream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } var writer = new BinaryWriter(stream); var startOffset = stream.Position; // Version writer.Write(Version); writer.Flush(); // Header // Valid texture count (number of entries) writer.Write((int)wad.Textures.Count(t => t is TextureByteIndexPaletteWithMipmaps || t is TextureByteIndexPalette)); // TextureLumpInfo offset position // Will be changed later var global_textureLumpInfo_offset_position = stream.Position; writer.Write((int)0); writer.Flush(); List <int> positions = new List <int>(); List <char[]> names = new List <char[]>(); List <int> sizes = new List <int>(); for (int i = 0; i < wad.Textures.Count; i++) { long position = stream.Position - startOffset; positions.Add((int)position); //TODO Save entry throw new NotImplementedException("Saving entry is not implemented yet."); long length = stream.Position - position - startOffset; sizes.Add((int)length); } var global_wadEntry_position = stream.Position; stream.Position = global_textureLumpInfo_offset_position; writer.Write((int)(global_wadEntry_position - startOffset)); writer.Flush(); stream.Position = global_wadEntry_position; for (int i = 0; i < positions.Count; i++) { var position = positions[i]; var name = names[i]; var size = sizes[i]; var entry = new WadEntry((int)(position - startOffset), size, WadEntry.TextureType, name); entry.Write(writer); } }
public WadImageStream(WadEntry entry, Stream stream) { _entry = entry; using (var br = new BinaryReader(stream)) { PrepareData(br); } }
private static void ConvertSimpleSkinToGltf(FileConversionParameter parameter) { WadEntry simpleSkinWadEntry = parameter.Parameter; SimpleSkin simpleSkin = new SimpleSkin(simpleSkinWadEntry.GetDataHandle().GetDecompressedStream()); ModelRoot gltf = simpleSkin.ToGltf(); gltf.SaveGLB(Path.ChangeExtension(parameter.OutputPath, "glb")); }
private static void ConvertScbToGltf(FileConversionParameter parameter) { WadEntry staticObjectWadEntry = parameter.Parameter; StaticObject staticObject = StaticObject.ReadSCB(staticObjectWadEntry.GetDataHandle().GetDecompressedStream()); ModelRoot gltf = staticObject.ToGltf(); gltf.SaveGLB(Path.ChangeExtension(parameter.OutputPath, "glb")); }
private static void ConvertMapGeometryToGltf(FileConversionParameter parameter) { WadEntry mapGeometryWadEntry = parameter.Parameter; MapGeometry mapGeometry = new MapGeometry(mapGeometryWadEntry.GetDataHandle().GetDecompressedStream()); ModelRoot gltf = mapGeometry.ToGLTF(); gltf.SaveGLB(Path.ChangeExtension(parameter.OutputPath, "glb")); }
public WadImageStream(WadEntry entry, WadPackage package) { _entry = entry; using (var br = new BinaryReader(package.OpenFile(package.PackageFile))) { br.BaseStream.Position = entry.Offset; PrepareData(br); } }
public static string[] GetTextureList(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } var reader = new BinaryReader(stream); var startOffset = stream.Position; // Validate version uint version = reader.ReadUInt32(); if (version != Version) { throw new BspLib.Wad.Exceptions.WadVersionNotSupportedException(version); } int num = reader.ReadInt32(); int offset = reader.ReadInt32(); List <string> names = new List <string>(num); stream.Position = offset + startOffset; for (int i = 0; i < num; i++) { var entry = WadEntry.Read(reader); // Is a texture if (entry.Type == WadEntry.TextureType) { // Compressed if (entry.Compressed) { // Could not find how it works (no documentation). // In official github ( https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/utils/common/wadlib.c on line 301 ): // // F I X M E: do compression Console.Error.WriteLine("WadEntry ID={0}, Name='{1}' is compressed texture which is not supported. Skipping.", i, entry.Name_s); } // Not Compressed else { names.Add(entry.Name_s); } } // Not a texture else { Console.Error.WriteLine("WadEntry ID={0}, Name='{1}' has unknown / unsupported type 0x{2:X2}.", i, entry.Name_s, entry.Type); } } return(names.ToArray()); }
private static void ConvertSimpleSkinWithSkeletonToGltf(FileConversionParameter parameter) { WadEntry simpleSkinWadEntry = parameter.Parameter; WadEntry skeletonWadEntry = parameter.AdditionalParameters.FirstOrDefault(x => x.Item1 == FileConversionAdditionalParameterType.Skeleton).Item2; SimpleSkin simpleSkin = new SimpleSkin(simpleSkinWadEntry.GetDataHandle().GetDecompressedStream()); Skeleton skeleton = new Skeleton(skeletonWadEntry.GetDataHandle().GetDecompressedStream()); ModelRoot gltf = simpleSkin.ToGltf(skeleton); gltf.SaveGLB(Path.ChangeExtension(parameter.OutputPath, "glb")); }
private static IEnumerable <string> ProcessLegacyDirList(WadEntry entry) { using Stream entryStream = entry.GetDataHandle().GetDecompressedStream(); using (BinaryReader br = new BinaryReader(entryStream)) { uint pathCount = br.ReadUInt32(); for (int i = 0; i < pathCount; i++) { yield return(Encoding.ASCII.GetString(br.ReadBytes(br.ReadInt32()))); } } }
public static string Get(WadEntry entry) { if (_hashtable.ContainsKey(entry.XXHash)) { return(_hashtable[entry.XXHash]); } else { Stream decompressedStream = entry.GetDataHandle().GetDecompressedStream(); string extension = LeagueUtilities.GetExtension(LeagueUtilities.GetExtensionType(decompressedStream)); return(string.Format("{0}.{1}", entry.XXHash.ToString("x16"), extension)); } }
private static void ConvertScbToObj(FileConversionParameter parameter) { WadEntry staticObjectWadEntry = parameter.Parameter; StaticObject staticObject = StaticObject.ReadSCB(staticObjectWadEntry.GetDataHandle().GetDecompressedStream()); var objs = staticObject.ToObj(); string baseName = Path.GetFileNameWithoutExtension(parameter.OutputPath); foreach ((string material, OBJFile obj) in objs) { string objPath = parameter.OutputPath.Replace(baseName, baseName + '_' + material); obj.Write(objPath); } }
private static FileConversionParameter ConstructSimpleSkinWithSkeletonParameter(string outputPath, WadFileViewModel parameter, WadViewModel wad) { // We need to find a skeleton file with the same filename as the Simple Skin string skeletonPath = Path.ChangeExtension(parameter.Path, "skl"); WadEntry skeletonWadEntry = wad.GetAllFiles().FirstOrDefault(x => x.Path == skeletonPath).Entry; if (skeletonWadEntry is null) { throw new Exception(Localization.Get("ConversionSimpleSkinWithSkeletonSkeletonNotFound")); } else { return(new FileConversionParameter(outputPath, parameter.Entry, new List <(FileConversionAdditionalParameterType, WadEntry)>() { (FileConversionAdditionalParameterType.Skeleton, skeletonWadEntry) })); } }
private TextureFlags GetFlags(WadEntry entry) { return(_file.NameWithoutExtension.IndexOf("decal", StringComparison.CurrentCultureIgnoreCase) >= 0 && entry.Name.StartsWith("{") ? TextureFlags.Transparent : TextureFlags.None); }
public static void Save(WadFile wad, Stream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } var writer = new BinaryWriter(stream); var startOffset = stream.Position; // Version writer.Write(Version); writer.Flush(); // Header // Valid texture count (number of entries) writer.Write((int)wad.Textures.Count(t => t is Texture)); // TextureLumpInfo offset position // Will be changed later var global_textureLumpInfo_offset_position = stream.Position; writer.Write((int)0); writer.Flush(); List <int> positions = new List <int>(); List <char[]> names = new List <char[]>(); List <int> sizes = new List <int>(); for (int i = 0; i < wad.Textures.Count; i++) { long position = stream.Position - startOffset; positions.Add((int)position); TextureByteIndexPaletteWithMipmaps texture; TextureLumpInfo textureLump; var t = wad.Textures[i]; if (t is TextureByteIndexPalette) { if (t is TextureByteIndexPaletteWithMipmaps) { texture = (TextureByteIndexPaletteWithMipmaps)t; } else { var tbip = (TextureByteIndexPalette)t; texture = tbip.GenerateMipmaps(TextureLumpInfo.MipmapOffsetsLength); } } else { //throw new NotImplementedException("Textures without byte palette are not supported yet"); var tbip = TextureByteIndexPalette.CreateFromBitmap(t); texture = tbip.GenerateMipmaps(TextureLumpInfo.MipmapOffsetsLength); } textureLump = new TextureLumpInfo(texture); textureLump.Save(writer); long length = stream.Position - position - startOffset; sizes.Add((int)length); } var global_wadEntry_position = stream.Position; stream.Position = global_textureLumpInfo_offset_position; writer.Write((int)(global_wadEntry_position - startOffset)); writer.Flush(); stream.Position = global_wadEntry_position; for (int i = 0; i < positions.Count; i++) { var position = positions[i]; var name = names[i]; var size = sizes[i]; var entry = new WadEntry((int)(position - startOffset), size, WadEntry.TextureType, name); entry.Write(writer); } }
private void SetEntryData(WadEntry e, BinaryReader br) { uint width, height, paletteSize; long textureDataOffset, paletteDataOffset; switch (e.Type) { case WadEntryType.Image: width = br.ReadUInt32(); height = br.ReadUInt32(); textureDataOffset = br.BaseStream.Position; br.BaseStream.Position += width * height; // Skip texture data paletteSize = br.ReadUInt16(); paletteDataOffset = br.BaseStream.Position; break; case WadEntryType.Texture: br.BaseStream.Position += 16; // Skip name width = br.ReadUInt32(); height = br.ReadUInt32(); textureDataOffset = br.BaseStream.Position + 16; var num = (int)(width * height); var skipMapData = (num / 4) + (num / 16) + (num / 64); br.BaseStream.Position += 16 + num + skipMapData; // Skip mipmap offsets, texture data, mipmap texture data paletteSize = br.ReadUInt16(); paletteDataOffset = br.BaseStream.Position; break; /* case WadEntryType.Font: width = br.ReadUInt32(); height = br.ReadUInt32(); textureDataOffset = br.BaseStream.Position + 8 + (256 * 4); br.BaseStream.Position += 8 + (256 * 4) + (width * height); // Skip font data, texture data paletteSize = br.ReadUInt16(); paletteDataOffset = br.BaseStream.Position; break;*/ default: throw new ArgumentOutOfRangeException(); } e.Width = width; e.Height = height; e.PaletteSize = paletteSize; e.TextureDataOffset = textureDataOffset; e.PaletteDataOffset = paletteDataOffset; }
public static void Load(WadFile wad, Stream stream) { if (wad == null) { throw new ArgumentNullException("wad"); } if (stream == null) { throw new ArgumentOutOfRangeException("stream"); } var reader = new BinaryReader(stream); var startOffset = stream.Position;// Position of start in stream (current - version) // Validate version uint version = reader.ReadUInt32(); if (version != Version) { throw new BspLib.Wad.Exceptions.WadVersionNotSupportedException(version); } // Header int num = reader.ReadInt32(); // Number of entries, not textures int offset = reader.ReadInt32(); var entries = new List <WadEntry>(); // Offset of entries // Often bedore end of file stream.Position = offset + startOffset; for (int i = 0; i < num; i++) { var entry = WadEntry.Read(reader); // Is a texture if (entry.Type == WadEntry.TextureType) { // Compressed if (entry.Compressed) { // Could not find how it works (no documentation). // In official github ( https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/utils/common/wadlib.c on line 301 ): // // F I X M E: do compression Console.Error.WriteLine("WadEntry ID={0}, Name='{1}' is compressed texture which is not supported. Skipping.", i, entry.Name_s); } // Not Compressed else { entries.Add(entry); } } // Not a texture else { Console.Error.WriteLine("WadEntry ID={0}, Name='{1}' has unknown / unsupported type 0x{2:X2}.", i, entry.Name_s, entry.Type); } } // Load all textures for (int i = 0; i < entries.Count; i++) { var entry = entries[i]; stream.Position = entry.PositionInFile + startOffset; //TODO Load entry throw new NotImplementedException("Loading entry is not implemented yet."); } }