Пример #1
0
 public ME3ExportEntry(ME3PCCObject pccFile, byte[] importData, uint exportOffset)
 {
     pccRef     = pccFile;
     info       = (byte[])importData.Clone();
     InfoOffset = exportOffset;
     hasChanged = false;
 }
Пример #2
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;
 }
Пример #3
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;
        }
Пример #4
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);
        }
Пример #5
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);
        }
Пример #6
0
 public ME3ExportEntry(ME3PCCObject pccFile, byte[] importData, uint exportOffset)
 {
     pccRef = pccFile;
     info = (byte[])importData.Clone();
     InfoOffset = exportOffset;
     hasChanged = false;
 }
Пример #7
0
 public ME3ImportEntry(ME3PCCObject pccFile, Stream importData)
 {
     pccRef = pccFile;
     data = new byte[ME3ImportEntry.byteSize];
     importData.Read(data, 0, data.Length);
 }
Пример #8
0
 public ME3ImportEntry(ME3PCCObject pccFile, Stream importData)
 {
     pccRef = pccFile;
     data   = new byte[ME3ImportEntry.byteSize];
     importData.Read(data, 0, data.Length);
 }
Пример #9
0
        public ME3SaltTexture2D(ME3PCCObject pccObj, int texIdx, String pathBioGame, uint hash = 0)
        {
            allPccs = new List<string>();
            hasChanged = false;
            Hash = hash;

            if (pccObj.isExport(texIdx) && (pccObj.Exports[texIdx].ClassName == className || pccObj.Exports[texIdx].ClassName == class2 || pccObj.Exports[texIdx].ClassName == class3))
            {
                Class = pccObj.Exports[texIdx].ClassName;
                ME3ExportEntry expEntry = pccObj.Exports[texIdx];
                properties = new Dictionary<string, SaltPropertyReader.Property>();
                byte[] rawData = (byte[])expEntry.Data.Clone();
                int propertiesOffset = SaltPropertyReader.detectStart(pccObj, rawData);
                headerData = new byte[propertiesOffset];
                Buffer.BlockCopy(rawData, 0, headerData, 0, propertiesOffset);
                pccOffset = expEntry.DataOffset;
                List<SaltPropertyReader.Property> tempProperties = SaltPropertyReader.getPropList(pccObj, rawData);
                texName = expEntry.ObjectName;
                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 = Textures.Methods.ParseFormat(pccObj.Names[property.Value.IntValue].Substring(3));
                            break;
                        case "TextureFileCacheName": arcName = property.Value.NameValue.Name; break;
                        case "LODGroup": LODGroup = property.Value.NameValue.Name; break;
                        case "None": dataOffset = (uint)(property.offsetval + property.Size); break;
                    }
                }
                if (!String.IsNullOrEmpty(arcName))
                    FullArcPath = GetTexArchive(pathBioGame);

                // if "None" property isn't found throws an exception
                if (dataOffset == 0)
                    throw new Exception("\"None\" property not found");
                else
                {
                    imageData = new byte[rawData.Length - dataOffset];
                    Buffer.BlockCopy(rawData, (int)dataOffset, imageData, 0, (int)(rawData.Length - dataOffset));
                }
            }
            else
                throw new Exception("Texture2D " + texIdx + " not found");

            pccExpIdx = texIdx;
            MemoryStream dataStream = new MemoryStream(imageData);  // FG: we will move forward with the memorystream (we are reading an export entry for a texture object data inside the pcc)
            numMipMaps = dataStream.ReadValueU32();                 // FG: 1st int32 (4 bytes / 32bits) is number of mipmaps
            uint count = numMipMaps;

            privateimgList = new List<ImageInfo>();
            ArcDataSize = 0;
            while (dataStream.Position < dataStream.Length && count > 0)
            {
                ImageInfo imgInfo = new ImageInfo();                            // FG: store properties in ImageInfo struct (code at top)
                imgInfo.storageType = (storage)dataStream.ReadValueS32();       // FG: 2nd int32 storage type (see storage types above in enum_struct)
                imgInfo.uncSize = dataStream.ReadValueS32();                    // FG: 3rd int32 uncompressed texture size
                imgInfo.cprSize = dataStream.ReadValueS32();                    // FG: 4th int32 compressed texture size
                imgInfo.offset = dataStream.ReadValueS32();                     // FG: 5th int32 texture offset
                if (imgInfo.storageType == storage.pccSto)
                {
                    //imgInfo.offset = (int)(pccOffset + dataOffset); // saving pcc offset as relative to exportdata offset, not absolute
                    imgInfo.offset = (int)dataStream.Position; // saving pcc offset as relative to exportdata offset, not absolute
                    //MessageBox.Show("Pcc class offset: " + pccOffset + "\nimages data offset: " + imgInfo.offset.ToString());
                    dataStream.Seek(imgInfo.uncSize, SeekOrigin.Current);       // FG: if local storage, texture data follows, so advance datastream to after uncompressed_size (pcc storage type only)
                }
                else if (imgInfo.storageType == storage.arcCpr || imgInfo.storageType == storage.arcUnc)
                {
                    ArcDataSize += imgInfo.uncSize;
                }
                imgInfo.imgSize = new ImageSize(dataStream.ReadValueU32(), dataStream.ReadValueU32());  // FG: 6th & 7th [or nth and (nth + 1) if local] int32 are width x height
                privateimgList.Add(imgInfo);                                                                   // FG: A salty's favorite, add the struct to a list<struct>
                count--;
            }


            // save what remains
            int remainingBytes = (int)(dataStream.Length - dataStream.Position);
            footerData = new byte[remainingBytes];
            dataStream.Read(footerData, 0, footerData.Length);


            dataStream.Dispose();
        }
Пример #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;
     }
 }
Пример #11
0
        public ME3Texture2D(ME3PCCObject pccObj, int texIdx)
        {
            pccRef = pccObj;
            // check if texIdx is an Export index and a Texture2D class
            if (pccObj.isExport(texIdx) && (pccObj.Exports[texIdx].ClassName == className))
            {
                ME3ExportEntry expEntry = pccObj.Exports[texIdx];
                properties = new Dictionary<string, PropertyReader.Property>();
                byte[] rawData = (byte[])expEntry.Data.Clone();
                int propertiesOffset = PropertyReader.detectStart(pccObj, rawData);
                headerData = new byte[propertiesOffset];
                Buffer.BlockCopy(rawData, 0, headerData, 0, propertiesOffset);
                pccOffset = (uint)expEntry.DataOffset;
                List<PropertyReader.Property> tempProperties = PropertyReader.getPropList(pccObj, rawData);
                texName = expEntry.ObjectName;
                for (int i = 0; i < tempProperties.Count; i++)
                {
                    PropertyReader.Property property = tempProperties[i];
                    if (!properties.ContainsKey(pccObj.Names[property.Name]))
                        properties.Add(pccObj.Names[property.Name], property);

                    switch (pccObj.Names[property.Name])
                    {
                        case "Format": texFormat = pccObj.Names[property.Value.IntValue].Substring(3); break;
                        case "TextureFileCacheName": arcName = pccObj.Names[property.Value.IntValue]; break;
                        case "LODGroup": LODGroup = pccObj.Names[property.Value.IntValue]; 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");
                else
                {
                    imageData = new byte[rawData.Length - dataOffset];
                    Buffer.BlockCopy(rawData, (int)dataOffset, imageData, 0, (int)(rawData.Length - dataOffset));
                }
            }
            else
                throw new Exception("Texture2D " + texIdx + " not found");

            pccExpIdx = texIdx;
            MemoryStream dataStream = new MemoryStream(imageData);
            numMipMaps = dataStream.ReadValueU32();
            uint count = numMipMaps;

            privateImageList = new List<ImageInfo>();
            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)(pccOffset + dataOffset); // saving pcc offset as relative to exportdata offset, not absolute
                    imgInfo.offset = (int)dataStream.Position; // saving pcc offset as relative to exportdata offset, not absolute
                    //MessageBox.Show("Pcc class offset: " + pccOffset + "\nimages data offset: " + imgInfo.offset.ToString());
                    dataStream.Seek(imgInfo.uncSize, SeekOrigin.Current);
                }
                imgInfo.imgSize = new ImageSize(dataStream.ReadValueU32(), dataStream.ReadValueU32());
                imgList.Add(imgInfo);
                count--;
            }

            // save what remains
            /*int remainingBytes = (int)(dataStream.Length - dataStream.Position);
            footerData = new byte[remainingBytes];
            dataStream.Read(footerData, 0, footerData.Length);*/
        }
Пример #12
0
        //unused
        private void replaceImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int n = listBox1.SelectedIndex;
            if (n <= 0)
                return;

            if (pcc.Exports[n].ClassName != "Texture2D")
                MessageBox.Show("Not a texture.");
            else
            {
                using (OpenFileDialog ofd = new OpenFileDialog())
                {
                    ofd.Filter = "DirectX images|*.dds";
                    if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        string path = Path.GetDirectoryName(pcc.pccFileName);
                        ME3PCCObject temp = new ME3PCCObject(pcc.pccFileName);
                        ME3SaltTexture2D tex2D = new ME3SaltTexture2D(temp, n, path);
                        string test = tex2D.imgList.Max(t => t.imgSize).ToString();
                        ImageFile im = KFreonLib.Textures.Creation.LoadAKImageFile(null, ofd.FileName);
                        tex2D.replaceImage(test, im, path);

                        ME3ExportEntry expEntry = temp.Exports[tex2D.pccExpIdx];
                        expEntry.SetData(tex2D.ToArray(expEntry.DataOffset, temp));
                        temp.saveToFile(temp.pccFileName);
                    }
                }
            }
            // Reload pcc?
        }
Пример #13
0
        private void TV1_DoubleClick(object sender, EventArgs e)
        {
            TreeNode t = TV1.SelectedNode;
            if (t == null || t.Parent == null)
                return;
            Println("Loading " + t.Text + " ...");

            string DLCName = t.Parent.Text;
            try
            {
                if (DLCName == mainPCCFolder)
                {
                    currentPCC = ME3Directory.cookedPath + t.Text;
                    pcc = new ME3PCCObject(currentPCC);
                }
                else
                {
                    return;
                }

                GeneratePccTree();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error:\n" + ex.Message);
            }
        }
Пример #14
0
 public void LoadFile(string s)
 {
     try
     {
         if (!File.Exists(s))
             return;
         pcc = new ME3PCCObject(s);
         currentPCC = s;
         GeneratePccTree();
     }
     catch (Exception ex)
     {
         MessageBox.Show("Error:\n" + ex.Message);
     }
 }
Пример #15
0
        private void CreateFromPCCDiffButton_Click(object sender, EventArgs e)
        {
            // KFreon: This is all just renamed stuff from WV's work. No credit to me.


            // KFreon: Get pcc's
            IPCCObject basePCC = null;
            IPCCObject modifiedPCC = null;
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.Filter = "PCC Files|*.pcc";
                ofd.Title = "Select base (unmodified) pcc";
                if (ofd.ShowDialog() != DialogResult.OK)
                    return;

                basePCC = new ME3PCCObject(ofd.FileName);

                ofd.Title = "Select modified pcc";
                if (ofd.ShowDialog() != DialogResult.OK)
                    return;

                modifiedPCC = new ME3PCCObject(ofd.FileName);
            }


            // KFreon: Compare PCC's and build script
            string loc = Path.GetDirectoryName(Application.ExecutablePath);
            string script = File.ReadAllText(loc + "\\exec\\JobTemplate_Binary2.txt");

            if (basePCC.ExportCount != modifiedPCC.ExportCount)
                throw new NotImplementedException("This is apparently not implemented yet.");

            // KFreon: Set pcc name
            var bits = basePCC.pccFileName.Split('\\');
            script.Replace("**m1**", bits.Last());

            if (basePCC.NameCount != modifiedPCC.NameCount)
            {
                StringBuilder names = new StringBuilder();
                foreach (var name in modifiedPCC.Names)
                    if (!basePCC.Names.Contains(name))
                        names.AppendLine("AddName(\"" + name + "\");");
                script = script.Replace("**m2**", names.ToString());
            }
            else
                script = script.Replace("**m2**", "\\ No names to add");

            StringBuilder exports = new StringBuilder();
            using(MemoryStream data = new MemoryStream())
            {
                for (int i = 0; i < basePCC.ExportCount; i++)
                {
                    if (!basePCC.Exports[i].Data.SequenceEqual(modifiedPCC.Exports[i].Data))
                    {
                        int offset = (int)data.Position;
                        data.WriteBytes(modifiedPCC.Exports[i].Data);
                        exports.AppendLine("ReplaceData(" + i + ", " + offset + ", " + modifiedPCC.Exports[i].Data.Length + ");");
                    }
                }
                script = script.Replace("**m3**", exports.ToString());

                ModJob job = new ModJob();
                job.data = data.ToArray();
                job.Name = "PCC Replacement Job for " + bits.Last();
                job.Script = script;
                KFreonLib.Scripting.ModMaker.JobList.Add(job);
            }

            Refresh();
        }
Пример #16
0
        public void CreateJobsFromPCCDiff(string basePCCName, string modPCCName)
        {
            // KFreon: This is all just renamed stuff from WV's work. No credit to me.
            StatusUpdater.UpdateText("Comparing PCC's...");


            // KFreon: Get pcc's
            IPCCObject basePCC = new ME3PCCObject(basePCCName);
            IPCCObject modifiedPCC = new ME3PCCObject(modPCCName);


            // KFreon: Compare PCC's and build script
            string loc = Path.GetDirectoryName(Application.ExecutablePath);
            string script = File.ReadAllText(loc + "\\exec\\JobTemplate_Binary2.txt");

            // KFreon: Set pcc name
            var bits = modifiedPCC.pccFileName.Split('\\').ToList();
            string filename = bits.Last();

            int index = bits.IndexOf("DLC");
            if (index > 0)
            {
                var dlcpaths = bits.GetRange(index, bits.Count - index);
                filename = string.Join("\\", dlcpaths);
            }


            // KFreon: Filename must contain CookedPCConsole
            if (!filename.Contains("cookedpcconsole", StringComparison.OrdinalIgnoreCase))
                filename = Path.Combine("CookedPCConsole", filename);

            filename = filename.Replace("\\\\", "\\").Replace("\\", "\\\\"); // KFreon: Need to not end up with \\\\\\\\\\\ or something, so chances are the only thing it would have at this stage is \\\\ so reset that to \\ then expand to \\\\.
            script = script.Replace("**m2**", filename);


            if (basePCC.NameCount != modifiedPCC.NameCount)
            {
                StringBuilder names = new StringBuilder();
                foreach (var name in modifiedPCC.Names)
                    if (!basePCC.Names.Contains(name))
                        names.AppendLine("names.Add(\"" + name + "\");" + Environment.NewLine);
                script = script.Replace("// **KF_NAMES", names.ToString());
            }

            int jobCount = 0;
            for (int i = 0; i < basePCC.ExportCount; i++)
            {
                if (modifiedPCC.Exports.Count == i)  // KFreon: Not adding Exports just yet.
                    break;


                if (!basePCC.Exports[i].Data.SequenceEqual(modifiedPCC.Exports[i].Data))
                {
                    ModJob job = new ModJob();
                    job.OriginalScript = script.Replace("**m1**", i.ToString());
                    job.Script = job.OriginalScript;

                    job.data = modifiedPCC.Exports[i].Data;
                    job.Name = "Binary Replacement Job for " + bits.Last();

                    job.ExpIDs = new List<int>();
                    job.ExpIDs.Add(i);

                    job.OrigExpIDs = new List<int>();
                    job.OrigExpIDs.Add(i);

                    job.PCCs = new List<string>();
                    job.OrigPCCs = new List<string>();
                    job.OrigPCCs.Add(modifiedPCC.pccFileName);
                    job.PCCs.Add(modifiedPCC.pccFileName);
                    job.Texname = basePCC.Exports[i].ObjectName;
                    KFreonLib.Scripting.ModMaker.JobList.Add(job);
                    jobCount++;
                }
            }


            if (jobCount > 0)
            {
                StatusUpdater.UpdateText("Created Job.");
            }
            else
            {
                StatusUpdater.UpdateText("No differences found!");
            }
            MainProgBar.ChangeProgressBar(1, 1);
            ExternalRefresh();
        }
Пример #17
0
        public void CopyImgList(ME3SaltTexture2D inTex, ME3PCCObject pcc)
        {
            imageData = inTex.imageData;
            privateimgList = inTex.privateimgList;
            numMipMaps = inTex.numMipMaps;

            //Copy Properties
            byte[] buff;
            using (MemoryStream tempMem = new MemoryStream())
            {
                tempMem.WriteBytes(headerData);
                for (int i = 0; i < inTex.properties.Count; i++)
                {
                    SaltPropertyReader.Property prop = inTex.properties.ElementAt(i).Value;

                    if (prop.Name == "UnpackMin")
                    {
                        for (int j = 0; j < inTex.UnpackNum; j++)
                        {
                            tempMem.WriteValueS64(pcc.addName2(prop.Name));
                            tempMem.WriteValueS64(pcc.addName2(prop.TypeVal.ToString()));
                            tempMem.WriteValueS32(prop.Size);
                            tempMem.WriteValueS32(j);
                            tempMem.WriteValueF32(prop.Value.FloatValue);
                        }
                        continue;
                    }

                    tempMem.WriteValueS64(pcc.addName2(prop.Name));

                    if (prop.Name == "None")
                        continue;


                    tempMem.WriteValueS64(pcc.addName2(prop.TypeVal.ToString()));
                    tempMem.WriteValueS64(prop.Size);

                    switch (prop.TypeVal)
                    {
                        case SaltPropertyReader.Type.FloatProperty:
                            tempMem.WriteValueF32(prop.Value.FloatValue);
                            break;
                        case SaltPropertyReader.Type.IntProperty:
                            tempMem.WriteValueS32(prop.Value.IntValue);
                            break;
                        case SaltPropertyReader.Type.NameProperty:
                            tempMem.WriteValueS64(pcc.addName2(prop.Value.StringValue));
                            // Heff: Modified to handle name references.
                            //var index = pcc.addName2(prop.Value.StringValue);
                            //tempMem.WriteValueS32(index);
                            //tempMem.WriteValueS32(prop.Value.NameValue.count);
                            break;
                        case SaltPropertyReader.Type.ByteProperty:
                            tempMem.WriteValueS64(pcc.addName2(prop.Value.StringValue));
                            tempMem.WriteValueS32(pcc.addName2(prop.Value.String2));
                            byte[] footer = new byte[4];
                            Buffer.BlockCopy(prop.raw, prop.raw.Length - 4, footer, 0, 4);
                            tempMem.WriteBytes(footer);
                            break;
                        case SaltPropertyReader.Type.BoolProperty:
                            tempMem.WriteValueBoolean(prop.Value.Boolereno);
                            break;
                        case SaltPropertyReader.Type.StructProperty:
                            tempMem.WriteValueS64(pcc.addName2(prop.Value.StringValue));
                            for (int k = 0; k < prop.Size; k++)
                                tempMem.WriteByte((byte)prop.Value.Array[k].IntValue);
                            break;
                        default:
                            throw new NotImplementedException("Property type: " + prop.TypeVal + ", not yet implemented. TELL ME ABOUT THIS!");
                    }
                }
                buff = tempMem.ToArray();
            }

            properties = new Dictionary<string, SaltPropertyReader.Property>();

            List<SaltPropertyReader.Property> tempProperties = SaltPropertyReader.ReadProp(pcc, buff, headerData.Length);
            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 = Textures.Methods.ParseFormat(pcc.Names[property.Value.IntValue].Substring(3));
                        break;
                    case "TextureFileCacheName": arcName = property.Value.NameValue.Name; break;
                    case "LODGroup": LODGroup = property.Value.NameValue.Name; 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");
        }
Пример #18
0
 public ME3ImportEntry(ME3PCCObject pccFile, byte[] importData)
 {
     pccRef = pccFile;
     data = (byte[])importData.Clone();
 }
Пример #19
0
        public byte[] ToArray(uint pccExportDataOffset, ME3PCCObject pcc)
        {
            using (MemoryStream tempStream = new MemoryStream())
            {
                tempStream.WriteBytes(headerData);

                // Whilst testing get rid of this
                // Heff: Seems like the shadowmap was the best solution in most cases,
                // adding an exception for known problematic animated textures for now.
                // (See popup in tpftools)
                if (properties.ContainsKey("LODGroup"))
                    properties["LODGroup"].Value.String2 = "TEXTUREGROUP_Shadowmap";
                else
                {
                    tempStream.WriteValueS64(pcc.addName2("LODGroup"));
                    tempStream.WriteValueS64(pcc.addName2("ByteProperty"));
                    tempStream.WriteValueS64(8);
                    tempStream.WriteValueS64(pcc.addName2("TextureGroup"));
                    tempStream.WriteValueS64(pcc.addName2("TEXTUREGROUP_Shadowmap"));
                }

                foreach (KeyValuePair<string, SaltPropertyReader.Property> kvp in properties)
                {
                    SaltPropertyReader.Property prop = kvp.Value;

                    if (prop.Name == "UnpackMin")
                    {
                        for (int i = 0; i < UnpackNum; i++)
                        {
                            tempStream.WriteValueS64(pcc.addName2(prop.Name));
                            tempStream.WriteValueS64(pcc.addName2(prop.TypeVal.ToString()));
                            tempStream.WriteValueS32(prop.Size);
                            tempStream.WriteValueS32(i);
                            tempStream.WriteValueF32(prop.Value.FloatValue);
                        }
                        continue;
                    }

                    tempStream.WriteValueS64(pcc.addName2(prop.Name));

                    if (prop.Name == "None")
                        continue;

                    tempStream.WriteValueS64(pcc.addName2(prop.TypeVal.ToString()));
                    tempStream.WriteValueS64(prop.Size);

                    switch (prop.TypeVal)
                    {
                        case SaltPropertyReader.Type.FloatProperty:
                            tempStream.WriteValueF32(prop.Value.FloatValue);
                            break;
                        case SaltPropertyReader.Type.IntProperty:
                            tempStream.WriteValueS32(prop.Value.IntValue);
                            break;
                        case SaltPropertyReader.Type.NameProperty:
                            tempStream.WriteValueS64(pcc.addName2(prop.Value.StringValue));
                            // Heff: Modified to handle name references.
                            //var nameIndex = pcc.addName2(prop.Value.StringValue);
                            //tempStream.WriteValueS32(nameIndex);
                            //tempStream.WriteValueS32(prop.Value.NameValue.count);
                            break;
                        case SaltPropertyReader.Type.ByteProperty:
                            tempStream.WriteValueS64(pcc.addName2(prop.Value.StringValue));
                            tempStream.WriteValueS64(pcc.addName2(prop.Value.String2));
                            // Heff: Modified to handle name references.
                            //var valueIndex = pcc.addName2(prop.Value.String2);
                            //tempStream.WriteValueS32(valueIndex);
                            //tempStream.WriteValueS32(prop.Value.NameValue.count);

                            //tempStream.WriteValueS32(pcc.addName2(prop.Value.String2));
                            //byte[] footer = new byte[4];
                            //Buffer.BlockCopy(prop.raw, prop.raw.Length - 4, footer, 0, 4);
                            //tempStream.WriteBytes(footer);
                            break;
                        case SaltPropertyReader.Type.BoolProperty:
                            tempStream.WriteValueBoolean(prop.Value.Boolereno);
                            break;
                        case SaltPropertyReader.Type.StructProperty:
                            tempStream.WriteValueS64(pcc.addName2(prop.Value.StringValue));
                            for (int i = 0; i < prop.Size; i++)
                                tempStream.WriteByte((byte)prop.Value.Array[i].IntValue);
                            break;
                        default:
                            throw new NotImplementedException("Property type: " + prop.TypeVal + ", not yet implemented. TELL ME ABOUT THIS!");
                    }
                }

                //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;

                tempStream.WriteValueU32(numMipMaps);
                foreach (ImageInfo imgInfo in privateimgList)
                {
                    tempStream.WriteValueS32((int)imgInfo.storageType);
                    tempStream.WriteValueS32(imgInfo.uncSize);
                    tempStream.WriteValueS32(imgInfo.cprSize);
                    if (imgInfo.storageType == storage.pccSto)
                    {
                        tempStream.WriteValueS32((int)(imgInfo.offset + pccExportDataOffset + dataOffset));
                        tempStream.Write(imageData, imgInfo.offset, imgInfo.uncSize);
                    }
                    else
                        tempStream.WriteValueS32(imgInfo.offset);
                    tempStream.WriteValueU32(imgInfo.imgSize.width);
                    tempStream.WriteValueU32(imgInfo.imgSize.height);
                }
                //// Texture2D footer, 24 bytes size - changed to 20
                //tempStream.Write(imageData, imageData.Length - 20, 20);
                tempStream.WriteBytes(footerData);
                return tempStream.ToArray();
            }

            #region Unused Code
            /*
            bool lodExists = false;
            foreach (KeyValuePair<string, PropertyReader.Property> kvp in properties)
            {
                PropertyReader.Property property = kvp.Value;
                if (kvp.Key == "LODGroup")
                {
                    lodExists = true;
                    break;
                }
            }

            MemoryStream buffer = new MemoryStream();
            buffer.Write(headerData, 0, headerData.Length);

            if (lodExists)
            {
                // extracting values from LODGroup Property
                PropertyReader.Property LODGroup = properties["LODGroup"];
                string textureGroupName = pcc.Names[LODGroup.Value.IntValue];
                bool nameExists = false;
                string newTextureGroupName = "TEXTUREGROUP_Shadowmap";
                if (String.Compare(newTextureGroupName, textureGroupName) != 0)
                {
                    textureGroupName = newTextureGroupName;
                    if (!pcc.Names.Exists(name => name == newTextureGroupName))
                        pcc.Names.Add(newTextureGroupName);
                    using (MemoryStream rawStream = new MemoryStream(LODGroup.raw))
                    {
                        rawStream.Seek(32, SeekOrigin.Begin);
                        rawStream.WriteValueS32(pcc.Names.FindIndex(name => name == newTextureGroupName));
                        rawStream.WriteValueS32(0);
                        properties["LODGroup"].raw = rawStream.ToArray();
                    }
                }
                else
                    nameExists = true;
                //MemoryStream buffer = new MemoryStream();
                //buffer.Write(headerData, 0, headerData.Length);
                foreach (KeyValuePair<string, PropertyReader.Property> kvp in properties)
                {
                    PropertyReader.Property property = kvp.Value;

                    if (kvp.Key == "LODBias")
                        continue;
                    if (kvp.Key == "InternalFormatLODBias")
                        continue;
                    if (kvp.Key == "LODGroup" && nameExists == false)
                    {
                        int name;
                        if (!nameExists)
                            name = pcc.Names.Count - 1;                 //Warranty Voiders Name redirect hack^^
                        else
                            name = LODGroup.Value.IntValue;
                        ME3_HR_Patch.Helper.BitConverter.IsLittleEndian = true;
                        byte[] buff = ME3_HR_Patch.Helper.BitConverter.GetBytes(name);
                        for (int i = 0; i < 4; i++)
                            property.raw[i + 24] = buff[i];
                    }
                    buffer.Write(property.raw, 0, property.raw.Length);
                    if (kvp.Key == "UnpackMin")
                    {
                        buffer.Write(property.raw, 0, property.raw.Length);
                        buffer.Write(property.raw, 0, property.raw.Length);
                    }
                }
            }
            else
            {
                //MemoryStream buffer = new MemoryStream();
                //buffer.Write(headerData, 0, headerData.Length);
                int lodID = pcc.findName("LODGroup");
                if (lodID == -1)
                {
                    pcc.addName("LODGroup");
                    lodID = pcc.Names.Count - 1;
                }
                buffer.WriteBytes(ME3_HR_Patch.Helper.BitConverter.GetBytes(lodID));
                buffer.WriteBytes(ME3_HR_Patch.Helper.BitConverter.GetBytes((int)0));
                lodID = pcc.findName("ByteProperty");
                buffer.WriteBytes(ME3_HR_Patch.Helper.BitConverter.GetBytes(lodID));
                buffer.WriteBytes(ME3_HR_Patch.Helper.BitConverter.GetBytes((int)0));
                //Write an int
                buffer.WriteBytes(ME3_HR_Patch.Helper.BitConverter.GetBytes((int)8));
                buffer.WriteBytes(ME3_HR_Patch.Helper.BitConverter.GetBytes((int)0));

                lodID = pcc.findName("TextureGroup");
                if (lodID == -1)
                {
                    pcc.addName("TextureGroup");
                    lodID = pcc.Names.Count - 1;
                }
                buffer.WriteBytes(ME3_HR_Patch.Helper.BitConverter.GetBytes(lodID));
                buffer.WriteBytes(ME3_HR_Patch.Helper.BitConverter.GetBytes((int)0));

                lodID = pcc.findName("TEXTUREGROUP_Shadowmap");
                if (lodID == -1)
                {
                    pcc.addName("TEXTUREGROUP_Shadowmap");
                    lodID = pcc.Names.Count - 1;
                }
                buffer.WriteBytes(ME3_HR_Patch.Helper.BitConverter.GetBytes(lodID));
                buffer.WriteBytes(ME3_HR_Patch.Helper.BitConverter.GetBytes((int)0));

                foreach (KeyValuePair<string, PropertyReader.Property> kvp in properties)
                {
                    PropertyReader.Property property = kvp.Value;

                    if (kvp.Key == "LODBias")
                        continue;
                    if (kvp.Key == "InternalFormatLODBias")
                        continue;
                    if (kvp.Key == "LODGroup")
                    {
                        int name = pcc.Names.Count - 1;                 //Warranty Voiders Name redirect hack^^
                        ME3_HR_Patch.Helper.BitConverter.IsLittleEndian = true;
                        byte[] buff = ME3_HR_Patch.Helper.BitConverter.GetBytes(name);
                        for (int i = 0; i < 4; i++)
                            property.raw[i + 24] = buff[i];
                    }
                    buffer.Write(property.raw, 0, property.raw.Length);
                    if (kvp.Key == "UnpackMin")
                    {
                        buffer.Write(property.raw, 0, property.raw.Length);
                        buffer.Write(property.raw, 0, property.raw.Length);
                    }
                }
            }

            buffer.WriteValueU32(numMipMaps);
            foreach (ImageInfo imgInfo in imgList)
            {
                buffer.WriteValueS32((int)imgInfo.storageType);
                buffer.WriteValueS32(imgInfo.uncSize);
                buffer.WriteValueS32(imgInfo.cprSize);
                if (imgInfo.storageType == storage.pccSto)
                {
                    buffer.WriteValueS32((int)(imgInfo.offset + pccExportDataOffset + dataOffset));
                    buffer.Write(imageData, imgInfo.offset, imgInfo.uncSize);
                }
                else
                    buffer.WriteValueS32(imgInfo.offset);
                buffer.WriteValueU32(imgInfo.imgSize.width);
                buffer.WriteValueU32(imgInfo.imgSize.height);
            }
            // Texture2D footer, 24 bytes size
            buffer.Write(imageData, imageData.Length - 24, 24);
            byte[] rawData = buffer.ToArray();
            return rawData;
            */
            #endregion
        }
Пример #20
0
 public ME3ImportEntry(ME3PCCObject pccFile, byte[] importData)
 {
     pccRef = pccFile;
     data   = (byte[])importData.Clone();
 }