示例#1
0
        public static void pack_baa(string projectDir, jBAAProjectFile project, string fileName)
        {
            if (fileName == null)
            {
                fileName = project.originalFile;
            }

            var blockStrm  = File.OpenWrite(fileName);
            var blockWrite = new BeBinaryWriter(blockStrm);

            Console.WriteLine("Prewriting BAA header data");
            // Prewrite header data so it's length is absolute
            blockWrite.Write(libJAudio.Loaders.JA_BAALoader.BAA_Header);
            for (int i = 0; i < project.includes.Length; i++)
            {
                var w  = project.includes[i];
                var sz = baa_GetSectionHeaderInfo(w);
                blockWrite.Write(w.hash);
                for (int k = 0; k < sz.size; k++)
                {
                    blockWrite.Write((int)0x00);
                }
            }
            blockWrite.Write(libJAudio.Loaders.JA_BAALoader.BAA_Footer);
            blockWrite.Flush();
            var head_anchor = 4L; // Start past the AA_<
            var tail_anchor = blockWrite.BaseStream.Position;

            Console.WriteLine($"Header ends at 0x{tail_anchor:X}");
            Console.WriteLine($"-> Project has {project.includes.Length} includes.");
            Console.WriteLine("-> Building project...");
            for (int i = 0; i < project.includes.Length; i++)
            {
                var dep  = project.includes[i];                           // load include
                var data = File.ReadAllBytes($"{projectDir}/{dep.path}"); // read include data
                Console.WriteLine($"->\t{projectDir}/{dep.path}\tL:0x{data.Length:X} added.");
                var sPos = tail_anchor;                                   // set start pos to tail anchor
                blockWrite.Write(data);                                   // sprawl data into file
                while ((blockWrite.BaseStream.Position & 0xF) != 8)
                {
                    blockWrite.Write((byte)0x00);
                    blockWrite.Flush();
                }
                var ePos = blockWrite.BaseStream.Position;              // store end position
                tail_anchor = ePos;                                     // set tail anchor to end pos
                blockWrite.BaseStream.Position = head_anchor;           // jump to head anchor
                baa_PackSection((int)sPos, (int)ePos, dep, blockWrite); // write section header
                head_anchor = blockWrite.BaseStream.Position;           // update head anchor.
                blockWrite.BaseStream.Position = tail_anchor;           // reseek to tail anchor.
                // repeat :)
            }

            Console.WriteLine($"-> Flushing into {fileName}");
            blockWrite.Flush();
            blockStrm.Flush();
            blockWrite.Close();
            blockStrm.Close();
            Console.WriteLine("Done.");
        }
示例#2
0
        private static byte[] WriteStrings(ref BinaryReaderBE reader, List <string> strings)
        {
            long           strCount     = reader.ReadInt64();
            long           newStrLength = 0;
            MemoryStream   temp         = new MemoryStream();
            BeBinaryWriter tempWriter   = new BeBinaryWriter(temp);

            tempWriter.Write(strCount);
            for (int i = 0; i < strCount; i++)
            {
                int oldStrLength = reader.ReadInt32();
                if (oldStrLength != 0)
                {
                    string lineStr = strings[i];
                    for (int k = 0; k < ArchiveConfig.OriginalChars.Length; k++)
                    {
                        lineStr = lineStr.Replace(ArchiveConfig.ReplaceChars[k], ArchiveConfig.OriginalChars[k]);
                    }
                    long strLength = lineStr.Length ^ 0xFFFFFFFF;
                    tempWriter.Write((Int32)strLength);
                    byte[] str = Encoding.Unicode.GetBytes(lineStr);
                    tempWriter.Write(str);
                    tempWriter.Write(new byte[2]);
                    newStrLength += 4 + str.Length + 2;
                    if (oldStrLength < 0)
                    {
                        oldStrLength = Math.Abs(oldStrLength) * 2;
                    }
                    reader.BaseStream.Position += oldStrLength;
                }
                else
                {
                    tempWriter.Write(new byte[4]);
                }
            }
            tempWriter.Close();
            return(temp.ToArray());
        }
示例#3
0
        public static void unpack(string barc, string outdir)
        {
            if (!Directory.Exists(outdir))
            {
                Directory.CreateDirectory(outdir);
            }

            var schemastm = File.OpenWrite(outdir + "\\schema.bin");
            var schemawt  = new BeBinaryWriter(schemastm);
            var barcstm   = File.OpenRead(barc);
            var barcread  = new BeBinaryReader(barcstm);

            schemawt.Write((int)barcstm.Length);

            var bhead = barcread.ReadUInt64(); // Should be BARC.

            if (bhead != 0x2D2D2D2D42415243)
            {
                Console.WriteLine("!!!! BARC header didn't match! 0x{0:X}!=0x2D2D2D2D42415243", bhead);
                return;
            }
            barcread.ReadInt32(); // skip
            var count = barcread.ReadInt32();

            schemawt.Write(count);
            var ARCFile = util.readBARCStringWE(barcread);

            schemawt.Write(ARCFile);
            var vread = File.OpenRead(ARCFile);

            addr_history = new bool[vread.Length * 3];
            seq_map      = new int[vread.Length * 3];
            var names = new string[count];

            for (int i = 0; i < count; i++)
            {
                var seqname = util.readBARCStringWE(barcread);
                var outname = string.Format("{0:D6}.bms", i);
                names[i] = outname + " = " + seqname;
                barcread.ReadUInt32();
                barcread.ReadUInt32(); // Idk, but im sure as hell not using these for this app.
                var offset = barcread.ReadUInt32();
                if (addr_history[offset])
                {
                    var bx  = File.OpenWrite(outdir + "\\" + outname);
                    var bxw = new BeBinaryWriter(bx);
                    bxw.Write(0xAFBFCFDF);
                    bxw.Write(seq_map[offset]);
                    barcread.ReadUInt32(); // just to keep aligned.
                    Console.WriteLine("Alias.");
                    continue;
                }
                addr_history[offset] = true;
                seq_map[offset]      = i;
                var size     = barcread.ReadUInt32();
                var filedata = new byte[size];
                vread.Position = offset;
                vread.Read(filedata, 0, (int)size);
                File.WriteAllBytes(outdir + "\\" + outname, filedata);
            }

            File.WriteAllLines(outdir + "\\names.txt", names);
            schemawt.Close();
            schemastm.Close();
        }
示例#4
0
        public static void pack_aaf(string projectDir, jAAFProjectFile project, string fileName)
        {
            if (fileName == null)
            {
                fileName = project.originalFile;
            }

            var blockStrm  = File.OpenWrite(fileName);
            var blockWrite = new BeBinaryWriter(blockStrm);


            Console.WriteLine("Prewriting AAF header data");

            for (int i = 0; i < project.includes.Length; i++)
            {
                var w  = project.includes[i];
                var sz = aaf_GetSectionHeaderInfo(w);
                switch (w.type)
                {
                case "INSTRUMENT_CLUSTER":
                    Console.WriteLine("INST CLUSTER.");
                    blockWrite.Write(2);
                    for (int k = 0; k < project.banks.Length; k++)
                    {
                        blockWrite.Write((int)0x01); // Offset
                        blockWrite.Write((int)0x02); // Size
                        blockWrite.Write((int)0x03); // Flags
                    }
                    blockWrite.Write((int)0x00);     // Cluster end indicator.
                    break;

                case "WAVE_CLUSTER":
                    blockWrite.Write(3);
                    for (int k = 0; k < project.waves.Length; k++)
                    {
                        blockWrite.Write((int)0x04); // Offset
                        blockWrite.Write((int)0x05); // Size
                        blockWrite.Write((int)0x06); // Flags
                    }
                    blockWrite.Write((int)0x00);     // Cluster end indicator.
                    break;

                default:
                    blockWrite.Write(w.hash);
                    for (int k = 0; k < sz.size; k++)
                    {
                        blockWrite.Write((int)0x00);
                    }
                    break;
                }
            }

            while ((blockWrite.BaseStream.Position % 32) != 0)
            {
                blockWrite.Write((byte)0x00); // oh god im sorry
                blockWrite.Flush();
            }

            //blockWrite.Flush();
            //Environment.Exit(0);

            var head_anchor = 0L;
            var tail_anchor = blockWrite.BaseStream.Position;

            Console.WriteLine($"Header ends at 0x{tail_anchor:X}");
            Console.WriteLine($"-> Project has {project.includes.Length} includes.");
            Console.WriteLine("-> Building project...");
            for (int i = 0; i < project.includes.Length; i++)
            {
                var dep = project.includes[i]; // load include
                switch (dep.type)
                {
                case "INSTRUMENT_CLUSTER":
                    blockWrite.BaseStream.Position = head_anchor;
                    blockWrite.Write((int)2);     // Cluster end indicator.
                    head_anchor = blockWrite.BaseStream.Position;
                    blockWrite.BaseStream.Position = tail_anchor;

                    for (int k = 0; k < project.banks.Length; k++)
                    {
                        var waveDep  = project.banks[k];
                        var waveData = File.ReadAllBytes($"{projectDir}/{waveDep.path}"); // read include data
                        Console.WriteLine($"->\t{projectDir}/{waveDep.path}\t(bnk)L:0x{waveData.Length:X} added.");
                        var startPos = tail_anchor;                                       // set start pos to tail anchor
                        blockWrite.Write(waveData);                                       // sprawl data into file

                        while ((blockWrite.BaseStream.Position % 32) != 0)
                        {
                            blockWrite.Write((byte)0x00);     // oh god im sorry
                            blockWrite.Flush();
                        }
                        var endPos = waveData.Length;                 // store end position
                        tail_anchor = blockWrite.BaseStream.Position; // set tail anchor to end pos
                        blockWrite.BaseStream.Position = head_anchor; // jump to head anchor
                        blockWrite.Write((int)startPos);
                        blockWrite.Write((int)endPos);
                        blockWrite.Write((int)waveDep.flags);
                        head_anchor = blockWrite.BaseStream.Position;     // update head anchor.
                        blockWrite.BaseStream.Position = tail_anchor;     // reseek to tail anchor.
                    }
                    blockWrite.BaseStream.Position = head_anchor;
                    blockWrite.Write((int)0x00);     // Cluster end indicator.
                    head_anchor = blockWrite.BaseStream.Position;
                    blockWrite.BaseStream.Position = tail_anchor;
                    continue;

                case "WAVE_CLUSTER":
                {
                    blockWrite.BaseStream.Position = head_anchor;
                    blockWrite.Write((int)3);         // Cluster end indicator.
                    head_anchor = blockWrite.BaseStream.Position;
                    blockWrite.BaseStream.Position = tail_anchor;
                    for (int k = 0; k < project.waves.Length; k++)
                    {
                        var waveDep  = project.waves[k];
                        var waveData = File.ReadAllBytes($"{projectDir}/{waveDep.path}"); // read include data
                        Console.WriteLine($"->\t{projectDir}/{waveDep.path}\t(wsy)L:0x{waveData.Length:X} added.");
                        var startPos = tail_anchor;                                       // set start pos to tail anchor
                        blockWrite.Write(waveData);                                       // sprawl data into file

                        while ((blockWrite.BaseStream.Position % 32) != 0)
                        {
                            blockWrite.Write((byte)0x00);         // oh god im sorry
                            blockWrite.Flush();
                        }
                        var endPos = waveData.Length;                 // store end position
                        tail_anchor = blockWrite.BaseStream.Position; // set tail anchor to end pos
                        blockWrite.BaseStream.Position = head_anchor; // jump to head anchor
                        blockWrite.Write((int)startPos);
                        blockWrite.Write((int)endPos);
                        blockWrite.Write((int)waveDep.flags);
                        head_anchor = blockWrite.BaseStream.Position;         // update head anchor.
                        blockWrite.BaseStream.Position = tail_anchor;         // reseek to tail anchor.
                    }
                    blockWrite.BaseStream.Position = head_anchor;
                    blockWrite.Write((int)0x00);         // Cluster end indicator.
                    head_anchor = blockWrite.BaseStream.Position;
                    blockWrite.BaseStream.Position = tail_anchor;
                    continue;
                }
                }


                var data = File.ReadAllBytes($"{projectDir}/{dep.path}"); // read include data
                Console.WriteLine($"->\t{projectDir}/{dep.path}\tL:0x{data.Length:X} added.");
                var sPos = tail_anchor;                                   // set start pos to tail anchor
                blockWrite.Write(data);                                   // sprawl data into file
                while ((blockWrite.BaseStream.Position & 0xF) != 0)
                {
                    blockWrite.Write((byte)0x00); // oh god im sorry
                    blockWrite.Flush();
                }
                var ePos = blockWrite.BaseStream.Position;                     // store end position
                tail_anchor = ePos;                                            // set tail anchor to end pos
                blockWrite.BaseStream.Position = head_anchor;                  // jump to head anchor
                aaf_PackSection((int)sPos, (int)data.Length, dep, blockWrite); // write section header
                head_anchor = blockWrite.BaseStream.Position;                  // update head anchor.
                blockWrite.BaseStream.Position = tail_anchor;                  // reseek to tail anchor.
                // repeat :)
            }

            Console.WriteLine($"-> Flushing into {fileName}");
            blockWrite.Flush();
            blockStrm.Flush();
            blockWrite.Close();
            blockStrm.Close();
            Console.WriteLine("Done.");
        }
示例#5
0
        public static void encodeAPCM4(PCM16WAV wav, string fileOutput)
        {
            int[] last   = new int[6];
            int[] penult = new int[6];

            FileStream fOutput = null;

            try
            {
                fOutput = File.Open(fileOutput, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            } catch (Exception E) { cmdarg.assert($"Failed to create {fileOutput} for writing. ({E.Message})"); }

            if (fOutput == null)
            {
                cmdarg.assert("How did you get in here? File handle was null.");
            }

            BeBinaryWriter bw = new BeBinaryWriter(fOutput); // create writer.


            var isLoop = false;

            if (wav.sampler.loops != null)
            {
                isLoop = true;
            }

            bw.Write(STRM_HEAD);
            bw.Write((int)0x00000000); // Temporary length.
            bw.Write((ushort)0x0);     // ADPCM format.
            bw.Write((ushort)wav.bitsPerSample);
            bw.Write((ushort)wav.channels);
            bw.Write(isLoop ? (ushort)0xFFFF : (ushort)0x0000);
            bw.Write(wav.sampleRate);
            //Console.WriteLine(wav.sampleCount);
            bw.Write(wav.sampleCount);
            bw.Write(isLoop ? wav.sampler.loops[0].dwStart : 0);
            bw.Write(isLoop ? wav.sampler.loops[0].dwEnd   : 0);
            bw.Write(STRM_LENGTH);
            bw.Write(0);
            bw.Write(0x7F000000); // wat.
            for (int i = 0; i < 0x14; i++)
            {
                bw.Write((byte)0x00);
            }
            bw.Flush();

            Dictionary <int, short[]> wavTracks = new Dictionary <int, short[]>();

            for (int i = 0; i < wav.channels; i++)
            {
                wavTracks[i] = new short[wav.sampleCount];
            }



            var tpcm_l = 0;

            for (int i = 0; i < wav.sampleCount; i++)
            {
                for (int j = 0; j < wav.channels; j++)
                {
                    var pootis = wav.buffer[i * wav.channels + j];
                    wavTracks[j][tpcm_l] = pootis;
                }
                tpcm_l++;
            }


            var frames_per_block = (0x2760 / 0x9); // 9 byte frames.
            var remaining_frames = wav.sampleCount / 16;
            var blocks_total     = ((wav.sampleCount / 16) / frames_per_block) + 1;

            var bufferRemaining = (wav.sampleCount / 16) * 9;

            Console.WriteLine(bufferRemaining);


            var total_sample_offset = 0;

            for (int blk = 0; blk < blocks_total; blk++)
            {
                util.consoleProgress("Rendering ", blk + 1, blocks_total, true);
                bw.Write(BLCK_HEAD);
                bw.Write(bufferRemaining >= 0x2760 ? 0x2760 : bufferRemaining);

                for (int i = 0; i < last.Length; i++)
                {
                    bw.Write((short)last[i]);
                    bw.Write((short)penult[i]);
                }

                for (int chn = 0; chn < wav.channels; chn++)
                {
                    for (int frm = 0; frm < frames_per_block; frm++)
                    {
                        short[] wavIn        = new short[16];
                        byte[]  adpcmOut     = new byte[9];
                        var     wavFP        = wavTracks[chn];
                        var     hist0        = last[chn];
                        var     hist1        = penult[chn];
                        var     sampleOffset = total_sample_offset + frm * 16;
                        //Console.WriteLine(sampleOffset);
                        for (int k = 0; k < 16; k++)
                        {
                            if ((sampleOffset + k) >= wavFP.Length)
                            {
                                break;
                            }
                            wavIn[k] = wavFP[sampleOffset + k];
                        }
                        bananapeel.Pcm16toAdpcm4(wavIn, adpcmOut, ref hist0, ref hist1);
                        last[chn]   = hist0;
                        penult[chn] = hist1;
                        for (int k = 0; k < 9; k++)
                        {
                            bw.Write(adpcmOut[k]);
                        }
                    }
                }
                total_sample_offset += frames_per_block * 16;


                bufferRemaining -= bufferRemaining >= 0x2760 ? 0x2760 : bufferRemaining;
            }
            var bop = bw.BaseStream.Position;

            bw.BaseStream.Position = 4;
            bw.Write((int)(bop - 0x40));

            bw.Flush();
            bw.Close();
        }
示例#6
0
 public void Dispose()
 {
     bw.Close();
     bw.Dispose();
 }
示例#7
0
        private static byte[] Reimport(byte[] input, Dictionary <string, List <string> > data)
        {
            MemoryStream   result      = new MemoryStream();
            MemoryStream   inputStream = new MemoryStream(input);
            BinaryReaderBE reader      = new BinaryReaderBE(inputStream);
            BeBinaryWriter writer      = new BeBinaryWriter(result);

            if (reader.ReadUInt32() == ArchiveConfig.Signature)
            {
                reader.BaseStream.Position = ArchiveConfig.CompressionTypeOffset;
                uint compressType = reader.ReadUInt32();
                switch (compressType)
                {
                case 0:
                    reader.BaseStream.Position = ArchiveConfig.TableOffset;

                    uint     nameCount     = reader.ReadUInt32();
                    uint     nameOffset    = reader.ReadUInt32();
                    uint     exportCount   = reader.ReadUInt32();
                    uint     exportOffset  = reader.ReadUInt32();
                    uint     importCount   = reader.ReadUInt32();
                    uint     importOffset  = reader.ReadUInt32();
                    uint     emptyOffset   = reader.ReadUInt32();
                    uint     unknownOffset = reader.ReadUInt32();
                    long     emptyBytes    = unknownOffset - emptyOffset;
                    string[] nameTable     = new string[nameCount];
                    reader.BaseStream.Position = nameOffset;
                    for (int i = 0; i < nameCount; i++)
                    {
                        uint strLength = reader.ReadUInt32();
                        nameTable[i] = Encoding.UTF8.GetString(reader.ReadBytes((int)strLength - 1));
                        reader.BaseStream.Position += 9;
                    }
                    string[] nameImport = new string[importCount];
                    reader.BaseStream.Position = importOffset;
                    for (int i = 0; i < importCount; i++)
                    {
                        reader.BaseStream.Position += 20;
                        uint index = reader.ReadUInt32();
                        nameImport[i] = nameTable[(int)index];
                        reader.BaseStream.Position += 4;
                    }

                    reader.BaseStream.Position = 0;
                    writer.Write(reader.ReadBytes((int)exportOffset));     //header

                    long          bytesChanged = 0;
                    List <byte[]> newData      = new List <byte[]>();
                    long          current      = exportOffset;
                    for (int i = 0; i < exportCount; i++)
                    {
                        MemoryStream   newRealData = new MemoryStream();
                        BeBinaryWriter writerData  = new BeBinaryWriter(newRealData);
                        reader.BaseStream.Position = current;
                        long start     = reader.BaseStream.Position;
                        uint indexType = (uint)reader.ReadInt32() ^ 0xFFFFFFFF;
                        reader.BaseStream.Position += 8;
                        uint   nameIndex  = reader.ReadUInt32();
                        uint   suffixName = reader.ReadUInt32();
                        string name       = nameTable[(int)nameIndex];
                        if (suffixName != 0)
                        {
                            name += $"_{suffixName}";
                        }
                        reader.BaseStream.Position += 12;
                        uint size      = reader.ReadUInt32();
                        uint offset    = reader.ReadUInt32();
                        long newOffset = offset + bytesChanged;
                        reader.BaseStream.Position += 4;
                        if (reader.ReadUInt32() > 0)
                        {
                            reader.BaseStream.Position += 4;
                        }
                        reader.BaseStream.Position += 20;
                        long headerLength = reader.BaseStream.Position - start;
                        current = reader.BaseStream.Position;
                        reader.BaseStream.Position = offset;
                        long stringBytesChanged = 0;

                        if (nameImport[indexType] == "Sqex03DataMessage")
                        {
                            uint order = reader.ReadUInt32();
                            writerData.Write(order);
                            while (true)
                            {
                                int    nameIDIndex = reader.ReadInt32();
                                string nameID      = nameTable[nameIDIndex];
                                writerData.Write(nameIDIndex);
                                if (nameID == "None")
                                {
                                    writerData.Write(new byte[4]);
                                    break;
                                }
                                long   classIDIndex = reader.ReadInt64();
                                string classID      = nameTable[classIDIndex];
                                writerData.Write(classIDIndex);
                                if (classID == "IntProperty")
                                {
                                    writerData.Write(reader.ReadBytes(16));
                                }
                                else if (classID == "ArrayProperty")
                                {
                                    long lengthProperty = reader.ReadInt64();
                                    if (nameID == "m_String")
                                    {
                                        List <string> strings;
                                        if (data.TryGetValue(name, out strings))
                                        {
                                            byte[] temp         = WriteStrings(ref reader, strings);
                                            long   newStrLength = temp.Length - 4;
                                            writerData.Write(newStrLength);
                                            writerData.Write(temp);
                                            stringBytesChanged += newStrLength - lengthProperty;
                                        }
                                        else
                                        {
                                            writerData.Write(lengthProperty);
                                            writerData.Write(reader.ReadBytes((int)lengthProperty + 4));
                                        }
                                    }
                                    else if (nameID == "m_Name")
                                    {
                                        List <string> strings;
                                        if (data.TryGetValue($"{name}_Name", out strings))
                                        {
                                            byte[] temp         = WriteStrings(ref reader, strings);
                                            long   newStrLength = temp.Length - 4;
                                            writerData.Write(newStrLength);
                                            writerData.Write(temp);
                                            stringBytesChanged += newStrLength - lengthProperty;
                                        }
                                        else
                                        {
                                            writerData.Write(lengthProperty);
                                            writerData.Write(reader.ReadBytes((int)lengthProperty + 4));
                                        }
                                    }
                                    else
                                    {
                                        writerData.Write(lengthProperty);
                                        writerData.Write(reader.ReadBytes((int)(lengthProperty + 4)));
                                    }
                                }
                            }
                        }
                        else
                        {
                            writerData.Write(reader.ReadBytes((int)size));
                        }
                        writerData.Close();
                        newData.Add(newRealData.ToArray());
                        reader.BaseStream.Position = start;
                        writer.Write(reader.ReadBytes(32));
                        if (stringBytesChanged != 0)
                        {
                            writer.Write((uint)(size + stringBytesChanged));
                            bytesChanged += stringBytesChanged;
                            reader.BaseStream.Position += 4;
                        }
                        else
                        {
                            writer.Write(reader.ReadBytes(4));
                        }
                        writer.Write((uint)newOffset);
                        reader.BaseStream.Position += 4;
                        writer.Write(reader.ReadBytes((int)headerLength - 40));
                    }
                    writer.Write(new byte[emptyBytes]);
                    foreach (byte[] dataMessage in newData)
                    {
                        writer.Write(dataMessage);
                    }
                    writer.Write(new byte[4]);
                    break;

                case 1:
                    byte[] decompressedData = Decompress(input, (uint)reader.BaseStream.Position);
                    return(Reimport(decompressedData, data));

                default:
                    throw new Exception("The file has an unsupported compression type.");
                }
            }
            else
            {
                throw new Exception("The file is not a Drakengard 3 (Unreal 3) file.");
            }
            reader.Close();
            writer.Close();
            return(result.ToArray());
        }