/// <summary> /// /// </summary> /// <param name="file"></param> /// <param name="stream"></param> /// <param name="WhichGame"></param> /// <returns></returns> public static IPCCObject CreatePCCObject(string file, MemoryTributary stream, int WhichGame) { IPCCObject pcc; if (WhichGame == 1) pcc = new ME1PCCObject(file, stream); else if (WhichGame == 2) pcc = new ME2PCCObject(file, stream); else if (WhichGame == 3) pcc = new ME3PCCObject(file, stream); else { DebugOutput.PrintLn("WHAT HAVE YOU DONE!! PCCObject creation failed!"); return null; } return pcc; }
/// <summary> /// Creates a PCCObject from a file. /// </summary> /// <param name="file">PCC file to create object from.</param> /// <param name="WhichGame">Game version.</param> /// <returns>IPCCObject from file.</returns> public static IPCCObject CreatePCCObject(string file, int WhichGame) { IPCCObject pcc; // KFreon: Use different methods for each game. if (WhichGame == 1) pcc = new ME1PCCObject(file); else if (WhichGame == 2) pcc = new ME2PCCObject(file); else if (WhichGame == 3) pcc = new ME3PCCObject(file); else { DebugOutput.PrintLn("WHAT HAVE YOU DONE!! PCCObject creation failed!"); return null; } return pcc; }
/// <summary> /// /// </summary> /// <param name="file"></param> /// <param name="stream"></param> /// <param name="WhichGame"></param> /// <returns></returns> public static IPCCObject CreatePCCObject(string file, MemoryStream stream, int WhichGame) { IPCCObject pcc; if (WhichGame == 1) { pcc = new ME1PCCObject(file, stream); } else if (WhichGame == 2) { pcc = new ME2PCCObject(file, stream); } else if (WhichGame == 3) { pcc = new ME3PCCObject(file, stream); } else { DebugOutput.PrintLn("WHAT HAVE YOU DONE!! PCCObject creation failed!"); return(null); } return(pcc); }
/// <summary> /// Creates a PCCObject from a file. /// </summary> /// <param name="file">PCC file to create object from.</param> /// <param name="WhichGame">Game version.</param> /// <returns>IPCCObject from file.</returns> public static IPCCObject CreatePCCObject(string file, int WhichGame) { IPCCObject pcc; // KFreon: Use different methods for each game. if (WhichGame == 1) { pcc = new ME1PCCObject(file); } else if (WhichGame == 2) { pcc = new ME2PCCObject(file); } else if (WhichGame == 3) { pcc = new ME3PCCObject(file); } else { DebugOutput.PrintLn("WHAT HAVE YOU DONE!! PCCObject creation failed!"); return(null); } return(pcc); }
public ME2Texture2D(ME2PCCObject pcc, int pccExpID, String pathBioGame) { ME2ExportEntry exp = pcc.Exports[pccExpID]; if (String.Compare(exp.ClassName, className) != 0 && String.Compare(exp.ClassName, class2) != 0 && String.Compare(exp.ClassName, class3) != 0) { throw new FormatException("Export is not a texture"); } Class = exp.ClassName; exportOffset = exp.DataOffset; FullPackage = exp.PackageFullName; texName = exp.ObjectName; pccFileName = pcc.pccFileName; allPccs = new List<string>(); allPccs.Add(pcc.pccFileName); properties = new Dictionary<string, SaltPropertyReader.Property>(); byte[] rawData = (byte[])exp.Data.Clone(); Compression = "No Compression"; int propertiesOffset = SaltPropertyReader.detectStart(pcc, rawData); headerData = new byte[propertiesOffset]; Buffer.BlockCopy(rawData, 0, headerData, 0, propertiesOffset); pccOffset = (uint)exp.DataOffset; UnpackNum = 0; List<SaltPropertyReader.Property> tempProperties = SaltPropertyReader.getPropList(pcc, rawData); for (int i = 0; i < tempProperties.Count; i++) { SaltPropertyReader.Property property = tempProperties[i]; if (property.Name == "UnpackMin") UnpackNum++; if (!properties.ContainsKey(property.Name)) properties.Add(property.Name, property); switch (property.Name) { case "Format": texFormat = property.Value.StringValue; break; case "TextureFileCacheName": arcName = property.Value.StringValue; break; case "LODGroup": LODGroup = property.Value.StringValue; break; case "CompressionSettings": Compression = property.Value.StringValue; break; case "None": dataOffset = (uint)(property.offsetval + property.Size); break; } } // if "None" property isn't found throws an exception if (dataOffset == 0) throw new Exception("\"None\" property not found"); if (!String.IsNullOrEmpty(arcName)) FullArcPath = GetTexArchive(pathBioGame); imageData = new byte[rawData.Length - dataOffset]; Buffer.BlockCopy(rawData, (int)dataOffset, imageData, 0, (int)(rawData.Length - dataOffset)); //DebugOutput.PrintLn("ImageData size = " + imageData.Length); pccExpIdx = pccExpID; MemoryStream dataStream = new MemoryStream(imageData); privateimgList = new List<ImageInfo>(); dataStream.ReadValueU32(); //Current position in pcc numMipMaps = dataStream.ReadValueU32(); uint count = numMipMaps; ArcDataSize = 0; //DebugOutput.PrintLn(numMipMaps + " derp"); while (dataStream.Position < dataStream.Length && count > 0) { ImageInfo imgInfo = new ImageInfo(); imgInfo.storageType = (storage)dataStream.ReadValueS32(); imgInfo.uncSize = dataStream.ReadValueS32(); imgInfo.cprSize = dataStream.ReadValueS32(); imgInfo.offset = dataStream.ReadValueS32(); if (imgInfo.storageType == storage.pccSto) { imgInfo.offset = (int)dataStream.Position; dataStream.Seek(imgInfo.uncSize, SeekOrigin.Current); } else if (imgInfo.storageType == storage.arcCpr || imgInfo.storageType == storage.arcUnc) { ArcDataSize += imgInfo.uncSize; } imgInfo.imgSize = new ImageSize(dataStream.ReadValueU32(), dataStream.ReadValueU32()); if (privateimgList.Exists(img => img.imgSize == imgInfo.imgSize)) { uint width = imgInfo.imgSize.width; uint height = imgInfo.imgSize.height; if (width == 4 && privateimgList.Exists(img => img.imgSize.width == width)) width = privateimgList.Last().imgSize.width / 2; if (width == 0) width = 1; if (height == 4 && privateimgList.Exists(img => img.imgSize.height == height)) height = privateimgList.Last().imgSize.height / 2; if (height == 0) height = 1; imgInfo.imgSize = new ImageSize(width, height); if (privateimgList.Exists(img => img.imgSize == imgInfo.imgSize)) throw new Exception("Duplicate image size found"); } privateimgList.Add(imgInfo); count--; //DebugOutput.PrintLn("ImgInfo no: " + count + ", Storage Type = " + imgInfo.storageType + ", offset = " + imgInfo.offset); } // Grab the rest for the footer footerData = new byte[dataStream.Length - dataStream.Position]; footerData = dataStream.ReadBytes(footerData.Length); }
public void CopyImgList(ME2Texture2D inTex, ME2PCCObject pcc) { numMipMaps = inTex.numMipMaps; if (properties.ContainsKey("NeverStream") && properties["NeverStream"].Value.IntValue == 1) { imageData = null; GC.Collect(); // store images as pccSto format privateimgList = new List<ImageInfo>(); MemoryStream tempData = new MemoryStream(); for (int i = 0; i < inTex.privateimgList.Count; i++) { ImageInfo newImg = new ImageInfo(); ImageInfo replaceImg = inTex.privateimgList[i]; newImg.storageType = storage.pccSto; newImg.uncSize = replaceImg.uncSize; newImg.cprSize = replaceImg.uncSize; newImg.imgSize = replaceImg.imgSize; newImg.offset = (int)(tempData.Position); if (replaceImg.storageType == storage.arcCpr) { string archivePath = inTex.FullArcPath; if (!File.Exists(archivePath)) throw new FileNotFoundException("Texture archive not found in " + archivePath); using (FileStream archiveStream = File.OpenRead(archivePath)) { archiveStream.Seek(replaceImg.offset, SeekOrigin.Begin); SaltLZOHelper lzohelp = new SaltLZOHelper(); tempData.WriteBytes(lzohelp.DecompressTex(archiveStream, replaceImg.offset, replaceImg.uncSize, replaceImg.cprSize)); } } else if (replaceImg.storageType == storage.pccSto) { byte[] buffer = new byte[newImg.cprSize]; Buffer.BlockCopy(inTex.imageData, replaceImg.offset, buffer, 0, buffer.Length); tempData.WriteBytes(buffer); } else throw new NotImplementedException("Copying from non package stored texture no available"); privateimgList.Add(newImg); } for (int i = 0; i < privateimgList.Count; i++) { ImageInfo tempinfo = privateimgList[i]; if (inTex.privateimgList[i].storageType == storage.empty) tempinfo.storageType = storage.empty; privateimgList[i] = tempinfo; } imageData = tempData.ToArray(); tempData.Close(); tempData = null; GC.Collect(); } else { imageData = inTex.imageData; privateimgList = inTex.privateimgList; } // add properties "TextureFileCacheName" and "TFCFileGuid" if they are missing, if (!properties.ContainsKey("TextureFileCacheName") && inTex.properties.ContainsKey("TextureFileCacheName")) { SaltPropertyReader.Property none = properties["None"]; properties.Remove("None"); SaltPropertyReader.Property property = new SaltPropertyReader.Property(); property.TypeVal = SaltPropertyReader.Type.NameProperty; property.Name = "TextureFileCacheName"; property.Size = 8; SaltPropertyReader.PropertyValue value = new SaltPropertyReader.PropertyValue(); value.StringValue = "Textures"; property.Value = value; properties.Add("TextureFileCacheName", property); arcName = value.StringValue; if (!properties.ContainsKey("TFCFileGuid")) { SaltPropertyReader.Property guidprop = new SaltPropertyReader.Property(); guidprop.TypeVal = SaltPropertyReader.Type.StructProperty; guidprop.Name = "TFCFileGuid"; guidprop.Size = 16; SaltPropertyReader.PropertyValue guid = new SaltPropertyReader.PropertyValue(); guid.len = guidprop.Size; guid.StringValue = "Guid"; guid.IntValue = pcc.AddName(guid.StringValue); guid.Array = new List<SaltPropertyReader.PropertyValue>(); for (int i = 0; i < 4; i++) guid.Array.Add(new SaltPropertyReader.PropertyValue()); guidprop.Value = guid; properties.Add("TFCFileGuid", guidprop); } properties.Add("None", none); } // copy specific properties from inTex for (int i = 0; i < inTex.properties.Count; i++) { SaltPropertyReader.Property prop = inTex.properties.ElementAt(i).Value; switch (prop.Name) { case "TextureFileCacheName": arcName = prop.Value.StringValue; properties["TextureFileCacheName"].Value.StringValue = arcName; break; case "TFCFileGuid": SaltPropertyReader.Property GUIDProp = properties["TFCFileGuid"]; for (int l = 0; l < 4; l++) { SaltPropertyReader.PropertyValue tempVal = GUIDProp.Value.Array[l]; tempVal.IntValue = prop.Value.Array[l].IntValue; GUIDProp.Value.Array[l] = tempVal; } break; case "MipTailBaseIdx": properties["MipTailBaseIdx"].Value.IntValue = prop.Value.IntValue; break; case "SizeX": properties["SizeX"].Value.IntValue = prop.Value.IntValue; break; case "SizeY": properties["SizeY"].Value.IntValue = prop.Value.IntValue; break; } } }
public void ChangeTexFormat(string newFormat, ME2PCCObject pcc) { SaltPropertyReader.Property prop = properties["Format"]; Int64 formatID = (Int64)pcc.AddName(newFormat); byte[] buff = BitConverter.GetBytes(formatID); Buffer.BlockCopy(buff, 0, prop.raw, 24, sizeof(Int64)); prop.Value.StringValue = pcc.Names[(int)formatID]; properties["Format"] = prop; texFormat = properties["Format"].Value.StringValue; }
public void ChangeCompression(string newComp, ME2PCCObject pcc) { if (!properties.ContainsKey("CompressionSettings")) { throw new KeyNotFoundException("Texture doesn't have a compression property"); } SaltPropertyReader.Property prop = properties["CompressionSettings"]; Int64 comp = (Int64)pcc.AddName(newComp); byte[] buff = BitConverter.GetBytes(comp); Buffer.BlockCopy(buff, 0, prop.raw, 24, sizeof(Int64)); prop.Value.StringValue = pcc.Names[(int)comp]; properties["CompressionSettings"] = prop; Compression = properties["CompressionSettings"].Value.StringValue; }
public byte[] ThisToArray(uint pccExportDataOffset, ME2PCCObject pcc) { MemoryStream buffer = new MemoryStream(); buffer.Write(headerData, 0, headerData.Length); if (properties.ContainsKey("LODGroup")) { properties["LODGroup"].Value.StringValue = "TEXTUREGROUP_LightAndShadowMap"; properties["LODGroup"].Value.String2 = pcc.Names[0]; } else { buffer.WriteValueS64(pcc.AddName("LODGroup")); buffer.WriteValueS64(pcc.AddName("ByteProperty")); buffer.WriteValueS64(8); buffer.WriteValueS64(pcc.AddName("TEXTUREGROUP_LightAndShadowMap")); } int count = 0; foreach (KeyValuePair<string, SaltPropertyReader.Property> kvp in properties) { SaltPropertyReader.Property prop = kvp.Value; if (prop.Name == "UnpackMin") { for (int j = 0; j < UnpackNum; j++) { buffer.WriteValueS64(pcc.AddName(prop.Name)); buffer.WriteValueS64(pcc.AddName(prop.TypeVal.ToString())); buffer.WriteValueS32(prop.Size); buffer.WriteValueS32(j); buffer.WriteValueF32(prop.Value.FloatValue, Endian.Little); } continue; } buffer.WriteValueS64(pcc.AddName(prop.Name)); if (prop.Name == "None") { for (int j = 0; j < 12; j++) buffer.WriteByte(0); } else { buffer.WriteValueS64(pcc.AddName(prop.TypeVal.ToString())); buffer.WriteValueS64(prop.Size); switch (prop.TypeVal) { case SaltPropertyReader.Type.IntProperty: buffer.WriteValueS32(prop.Value.IntValue); break; case SaltPropertyReader.Type.BoolProperty: buffer.WriteValueS32(prop.Value.IntValue); break; case SaltPropertyReader.Type.NameProperty: buffer.WriteValueS64(pcc.AddName(prop.Value.StringValue)); // Heff: Modified to handle name references. //var index = pcc.AddName(prop.Value.StringValue); //buffer.WriteValueS32(index); //buffer.WriteValueS32(prop.Value.NameValue.count); break; case SaltPropertyReader.Type.StrProperty: buffer.WriteValueS32(prop.Value.StringValue.Length + 1); foreach (char c in prop.Value.StringValue) buffer.WriteByte((byte)c); buffer.WriteByte(0); break; case SaltPropertyReader.Type.StructProperty: string strVal = prop.Value.StringValue; if (prop.Name.ToLowerInvariant().Contains("guid")) strVal = "Guid"; buffer.WriteValueS64(pcc.AddName(strVal)); foreach (SaltPropertyReader.PropertyValue value in prop.Value.Array) buffer.WriteValueS32(value.IntValue); break; case SaltPropertyReader.Type.ByteProperty: buffer.WriteValueS32(pcc.AddName(prop.Value.StringValue)); buffer.WriteValueS32(pcc.AddName(prop.Value.String2)); break; case SaltPropertyReader.Type.FloatProperty: buffer.WriteValueF32(prop.Value.FloatValue, Endian.Little); break; default: throw new FormatException("unknown property"); } } } buffer.WriteValueS32((int)buffer.Position + (int)pccExportDataOffset); //Remove empty textures List<ImageInfo> tempList = new List<ImageInfo>(); foreach (ImageInfo imgInfo in privateimgList) { if (imgInfo.storageType != storage.empty) tempList.Add(imgInfo); } privateimgList = tempList; numMipMaps = (uint)privateimgList.Count; buffer.WriteValueU32(numMipMaps); foreach (ImageInfo imgInfo in privateimgList) { buffer.WriteValueS32((int)imgInfo.storageType); buffer.WriteValueS32(imgInfo.uncSize); buffer.WriteValueS32(imgInfo.cprSize); if (imgInfo.storageType == storage.pccSto) { buffer.WriteValueS32((int)(buffer.Position + pccExportDataOffset)); buffer.Write(imageData, imgInfo.offset, imgInfo.uncSize); } else buffer.WriteValueS32(imgInfo.offset); if (imgInfo.imgSize.width < 4) buffer.WriteValueU32(4); else buffer.WriteValueU32(imgInfo.imgSize.width); if (imgInfo.imgSize.height < 4) buffer.WriteValueU32(4); else buffer.WriteValueU32(imgInfo.imgSize.height); } buffer.WriteBytes(footerData); return buffer.ToArray(); }
public void LoadPcc(IPCCObject pcc, string path) { switch (pcc.GameVersion) { case 1: pcc = new ME1PCCObject(path); break; case 2: pcc = new ME2PCCObject(path); break; case 3: pcc = new ME3PCCObject(path); break; } }