Inheritance: IPCCObject
示例#1
0
 /// <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;
 }
示例#2
0
        /// <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;
        }
示例#3
0
        /// <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);
        }
示例#4
0
        /// <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);
        }
示例#5
0
        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);
        }
示例#6
0
        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;
                }
            }
        }
示例#7
0
 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;
 }
示例#8
0
 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;
 }
示例#9
0
        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();
        }
示例#10
0
 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;
     }
 }