Beispiel #1
0
        public static byte[] Chunk(List <byte[]> input, string name)
        {
            var ms = new MemoryStream();

            byte[] scratch = new byte[4];
            ms.Write(scratch, 0, 2);
            ms.Write(BitConverter.GetBytes(input.Count - 1), 0, 4);
            int offset = 0x2A;
            int count  = 0;

            // Writes the section headers
            foreach (var s in input)
            {
                EndianMethods.WriteInt(ms, offset);
                offset += 4;
                offset += s.Length;
                count++;
            }
            count = 0;

            // Writes the section contents
            foreach (var s in input)
            {
                EndianMethods.WriteInt(ms, s.Length);
                ms.Write(s, 0, s.Length);
                count++;
            }

            // Re-encodes the data as LZSS format
            ms.Position = 0;
            var compress = new MemoryStream();

            Lzs.Encode(ms, compress);

            // Container for our compressed data, will pass this back to be appended to flevel
            byte[] data = new byte[compress.Length + 28];

            // Adds field name 20bytes as a header
            byte[] nameBytes = Encoding.ASCII.GetBytes(name);
            Array.Resize(ref nameBytes, 24);
            int z = 0;

            while (z < 24)
            {
                data[z] = nameBytes[z];
                z++;
            }

            // Writes in encoded data - Offset to avoid losing the field title header
            compress.Position = 0;
            compress.Read(data, 28, (int)compress.Length);

            // Updates the field header for file length; jumps from byte after header to start of next field's name
            EndianMethods.WriteInt(data, 20, (int)compress.Length + 4);
            EndianMethods.WriteInt(data, 24, (int)compress.Length + 0);

            return(data);
        }
Beispiel #2
0
        // Method that chunks an flevel then re-assembles it
        void bw_Compress(object sender, DoWorkEventArgs e)
        {
            ExtractArgs ea = (ExtractArgs)e.Argument;

            using (var fs = new FileStream(ea.Input, FileMode.Open))
            {
                var           df     = FF7Files.LoadLGP(fs, ea.Input);
                int           file   = 0;
                List <byte[]> chunks = new List <byte[]>();
                //string flev = Path.Combine(ea.Output, Path.GetFileName("flevel.lgp"));
                string flev = Directory.GetCurrentDirectory() + "\\PC\\Output File\\flevel.lgp";

                // Apply ToC and CRC to the new flevel
                byte[] addStart = new byte[23301];
                fs.Position = 0;
                fs.Read(addStart, 0, addStart.Length);
                using (var appendStart = new FileStream(flev, FileMode.Append))
                {
                    appendStart.Write(addStart, 0, addStart.Length);
                    appendStart.Close();
                }

                int   tocPointer  = 36;     // Holds pointer location for where to write new offset for ToC
                ulong fieldOffset = 0x5B05; // Holds offset value to write into tocPointer
                int   fieldCount  = 0;      // Counts fields
                foreach (var item in df.Items)
                {
                    (sender as BackgroundWorker).ReportProgress(100 * file++ / df.Items.Count);
                    // This route is for field files
                    if (Path.GetExtension(item.Name).Length == 0 &&
                        item.Name != "maplist"
                        // These files 'shrink' when included; seem functional but excluded for now
                        && item.Name != "blackbgb" &&
                        item.Name != "frcyo" &&
                        item.Name != "fship_4" &&
                        item.Name != "las0_8" &&
                        item.Name != "las2_1" &&
                        item.Name != "uutai1"
                        )
                    {
                        byte[] ff = new byte[item.Length - 24];
                        fs.Position = item.Start + 24;
                        fs.Read(ff, 0, ff.Length);
                        chunks = FieldFile.Unchunk(ff);

                        // >>>>
                        // Can adjust the uncompressed chunks here if need be before they go to recompression
                        // Randomisation tasks should be called here, triggered based on section #
                        // >>>>

                        // If using consistent allocation of models, then that logic should be done somewhere here so
                        // that all fields passing through have access to the newly assigned HRC strings and can pass
                        // them through to the rando logic.

                        // Sends Field Script chunk of field to be randomised
                        if (chkItems.Checked)
                        {
                            chunks[0] = FieldScript.ChangeItemsMateria(chunks[0], item.Name);
                        }

                        // Sends Model Loader chunk of field to be randomised
                        if (chkModels.Checked)
                        {
                            chunks[2] = ModelLoader.SwapFieldModels(chunks[2]);
                        }

                        // Recompresses the chunks into a field
                        var field = FieldFile.Chunk(chunks, item.Name);

                        // Skip the first ToC offset as this won't change
                        if (fieldCount != 0)
                        {
                            // Adds field length to pointer so we know where next section starts
                            tocPointer += 27;
                            byte[] byteOffset = EndianMethods.GetLittleEndianConvert(fieldOffset);
                            using (Stream stream = File.Open(flev, FileMode.Open))
                            {
                                stream.Position = tocPointer;
                                stream.Write(byteOffset, 0, 4);
                            }
                        }

                        // Takes the size of the chunked field; used to determine next offset for ToC
                        fieldOffset += (ulong)field.Length;
                        fieldCount++;

                        // Writes it into the new flevel
                        using (var stream = new FileStream(flev, FileMode.Append))
                        {
                            stream.Write(field, 0, field.Length);
                        }
                    }
                    // This route is for non-field files
                    else
                    {
                        byte[] field = new byte[item.Length];
                        fs.Position = item.Start;
                        fs.Read(field, 0, field.Length);

                        // Adds field length to pointer so we know where next section starts
                        tocPointer += 27;
                        byte[] byteOffset = EndianMethods.GetLittleEndianConvert(fieldOffset);
                        using (Stream stream = File.Open(flev, FileMode.Open))
                        {
                            stream.Position = tocPointer;
                            stream.Write(byteOffset, 0, 4);
                        }
                        // Takes the size of the misc file
                        fieldOffset += (ulong)field.Length;
                        fieldCount++;

                        // Writes it into the new flevel
                        using (var stream = new FileStream(flev, FileMode.Append))
                        {
                            stream.Write(field, 0, field.Length);
                        }
                    }
                }
                // Adds the final terminating string to the flevel
                byte[] terminate = new byte[] { 0x46, 0x49, 0x4E, 0x41, 0x4C, 0x20, 0x46, 0x41, 0x4E, 0x54, 0x41, 0x53, 0x59, 0x37 };
                using (var finalStream = new FileStream(flev, FileMode.Append))
                {
                    finalStream.Write(terminate, 0, terminate.Length);
                }
            }
        }