Пример #1
0
        void countBlock(aBinaryReader reader)
        {
            reader.Goto(0x20u);
            for (var i = 0u; i < mFontHeader.blockCount; ++i)
            {
                var blockStart = reader.Position;
                var typeID     = reader.Read32();
                var size       = reader.Read32();
                switch (typeID)
                {
                case cINF1: break;

                case cWID1: ++mWidthCount; break;

                case cMAP1: ++mMapCount; break;

                case cGLY1: ++mGlyphCount; break;

                default: {
                    Debug.Fail("Unknown data block.");
                    break;
                }
                }
                reader.Goto(blockStart + size);
            }
        }
Пример #2
0
        void LoadRiffBlock()
        {
            switch (mReader.ReadString(4))
            {
            case "RIFF": break;

            case "RIFX": mReader.Endianness = Endianness.Big; break;

            default: mareep.WriteError("WAV: could not find 'RIFF'."); break;
            }

            mSize = mReader.ReadS32();

            if (mReader.ReadString(4) != "WAVE")
            {
                mareep.WriteError("WAV: could not find 'WAVE'.");
            }

            var fmt  = false;
            var data = false;

            while ((mReader.Position - 8) < mSize)
            {
                var id    = mReader.ReadString(4);
                var size  = mReader.ReadS32();
                var start = mReader.Position;

                switch (id)
                {
                case "fmt ": fmt = true; LoadFmtBlock(size); break;

                case "data": data = true; LoadDataBlock(size); break;
                }

                mReader.Goto(start + size);
            }

            if (!fmt)
            {
                mareep.WriteError("WAV: missing 'fmt ' chunk.");
            }
            else if (!data)
            {
                mareep.WriteError("WAV: missing 'data' chunk.");
            }

            // calculate sample count here to ensure fmt has been loaded
            mSampleCount = (mDataSize / mBlockAlign);
        }
Пример #3
0
        void setBlock(aBinaryReader reader)
        {
            int widthBlocks = 0;
            int glyphBlocks = 0;
            int mapBlocks   = 0;

            reader.Goto(0x20u);
            for (uint i = 0; i < mFontHeader.blockCount; ++i)
            {
                var blockStart = reader.Position;
                var typeID     = reader.Read32();
                var size       = reader.Read32();
                switch (typeID)
                {
                case cINF1: {
                    mInfoBlock     = new InfoBlock(reader);
                    mDecoderMethod = sAboutEncoding[(int)mInfoBlock.fontType];
                    break;
                }

                case cWID1: {
                    mWidthBlocks[widthBlocks++] = new WidthBlock(reader);
                    break;
                }

                case cGLY1: {
                    mGlyphBlocks[glyphBlocks++] = new GlyphBlock(reader);
                    break;
                }

                case cMAP1: {
                    mMapBlocks[mapBlocks] = new MapBlock(reader);
                    int firstChar = mMapBlocks[mapBlocks].firstChar;
                    if (mFirstChar > firstChar)
                    {
                        mFirstChar = firstChar;
                    }
                    ++mapBlocks;
                    break;
                }

                default: {
                    Debug.Fail("Unknown data block.");
                    break;
                }
                }
                reader.Goto(blockStart + size);
            }
        }
Пример #4
0
        void WriteSdta()
        {
            mWriter.WriteString("LIST");
            mWriter.WriteS32(CalculateSmplSize() + 12);

            mWriter.WriteString("sdta");

            mWriter.WriteString("smpl");
            mWriter.WriteS32(CalculateSmplSize());

            foreach (var waveGroup in mWaveBank)
            {
                var archiveFileName = Path.Combine(mInputDirectory, waveGroup.ArchiveFileName);

                using (var instream = mareep.OpenFile(archiveFileName)) {
                    var reader = new aBinaryReader(instream, Endianness.Big);

                    mareep.WriteSeparator('-');
                    mareep.WriteMessage("{0} ({1} wave(s))\n", waveGroup.ArchiveFileName, waveGroup.Count);

                    foreach (var wave in waveGroup)
                    {
                        reader.Goto(wave.WaveStart);
                        var data  = reader.Read8s(wave.WaveSize);
                        var mixer = new RawWaveMixer(new MemoryStream(data), wave.Format);
                        mixer.Write(WaveFormat.Pcm16, mWriter);

                        for (var i = 0; i < 92; i++)
                        {
                            mWriter.WriteS8(0);
                        }
                    }
                }
            }
        }
Пример #5
0
        void DoExtractWsys()
        {
            if (mAafInPath == null)
            {
                mareep.WriteError("CHARGE: missing -init-data-file parameter");
            }

            if (mOutput == null)
            {
                mareep.WriteError("CHARGE: missing -output parameter");
            }

            if (mTarget == null)
            {
                mareep.WriteError("CHARGE: missing -target parameter");
            }

            int index;

            if (!Int32.TryParse(mTarget, out index))
            {
                mareep.WriteError("CHARGE: bad target {0}", mTarget);
            }

            using (Stream stream = mareep.OpenFile(mAafInPath)) {
                mareep.WriteMessage("Scanning AAF header...\n");
                aBinaryReader reader = new aBinaryReader(stream, Endianness.Big);
                int           offset, size;

                if (!ReadAafHeader(reader, 3, index, out offset, out size))
                {
                    mareep.WriteError("CHARGE: failed to find wave bank data\n");
                }

                reader.Goto(offset);

                if (reader.ReadS32() != 0x57535953)                   // 'WSYS'
                {
                    mareep.WriteError("CHARGE: could not find 'WSYS' header");
                }

                mareep.WriteMessage("Found wave bank data {0} (0x{1:X6}, 0x{2:X6})\n", index, offset, size);
                mareep.WriteMessage("Extracting wave bank data...\n");
                reader.Goto(offset);
                WriteFileData(mOutput, reader.Read8s(size));
            }
        }
Пример #6
0
        public override void load(Stream stream)
        {
            var reader = new aBinaryReader(stream, Endianness.Big);

            reader.PushAnchor();
            mFormat       = (gxTlutFormat)reader.Read8();
            mTransparency = reader.Read8();
            mEntryCount   = reader.Read16();
            reader.Goto(0x20);
            loadPaletteData(reader);
        }
Пример #7
0
        protected override WaveBank DoTransform(WaveBank obj)
        {
            if (obj == null)
            {
                return(null);
            }

            if (!Directory.Exists(mWaveDirectory))
            {
                mareep.WriteMessage("Creating directory '{0}'...\n", mWaveDirectory);
                Directory.CreateDirectory(mWaveDirectory);
            }

            mareep.WriteMessage("Transferring waves...\n");
            var extension = (mExtractWav ? "wav" : "raw");

            foreach (var waveGroup in obj)
            {
                var archiveFileName    = Path.Combine(mBankDirectory, waveGroup.ArchiveFileName);
                var archiveNoExtension = Path.GetFileNameWithoutExtension(waveGroup.ArchiveFileName);

                using (var input = mareep.OpenFile(archiveFileName)) {
                    var reader = new aBinaryReader(input, Endianness.Big);

                    mareep.WriteSeparator('-');
                    mareep.WriteMessage("{0} ({1} wave(s))\n", waveGroup.ArchiveFileName, waveGroup.Count);

                    foreach (var wave in waveGroup)
                    {
                        wave.FileName = String.Format("{0}_{1:D5}.{2}.{3}", archiveNoExtension, wave.WaveId, wave.Format.ToLowerString(), extension);
                        string waveFileName = Path.Combine(mWaveDirectory, wave.FileName);

                        using (var output = mareep.CreateFile(waveFileName)) {
                            reader.Goto(wave.WaveStart);
                            var data = reader.Read8s(wave.WaveSize);

                            if (mExtractWav)
                            {
                                ExtractWav(wave, data, output);
                            }
                            else
                            {
                                ExtractRaw(wave, data, output);
                            }
                        }

                        mareep.WriteMessage(" #{0:X4} {1} {2} {3}Hz {4} samples\n", wave.WaveId, mareep.ConvertKey(wave.RootKey), wave.Format.ToLowerString(), (int)wave.SampleRate, wave.SampleCount);
                    }
                }
            }

            return(obj);
        }
Пример #8
0
        static bool ReadBarcHeader(aBinaryReader reader, string seq, int count, out int index, out int offset, out int size)
        {
            index = ConvertSeqNameToIndex(seq);
            long start = reader.Position;

            offset = 0;
            size   = 0;

            if (index > 0)
            {
                if (index >= count)
                {
                    return(false);
                }

                reader.Goto(start + 32 * index + 24);
                offset = reader.ReadS32();
                size   = reader.ReadS32();
                return(true);
            }

            for (int i = 0; i < count; ++i)
            {
                reader.Goto(start + 32 * i);
                string name = reader.ReadString <aZSTR>();

                if (name.Equals(seq, StringComparison.InvariantCultureIgnoreCase))
                {
                    reader.Goto(start + 32 * i + 24);
                    offset = reader.ReadS32();
                    size   = reader.ReadS32();
                    index  = i;
                    return(true);
                }
            }

            return(false);
        }
Пример #9
0
        protected void LoadMidi(Stream stream)
        {
            mReader = new aBinaryReader(stream, Endianness.Big, Encoding.ASCII);
            mReader.PushAnchor();
            mTracks = new List <TrackChunkInfo>();

            var mthd   = false;
            var tracks = 0;

            while (!mReader.IsAtEndOfStream)
            {
                if (mReader.BytesRemaining < 8)
                {
                    mareep.WriteWarning("MIDI: incomplete chunk at file end.\n");
                    break;
                }

                var id    = mReader.ReadString(4);
                var size  = mReader.ReadS32();
                var start = mReader.Position;

                switch (id)
                {
                case "MThd": mthd = true; LoadMThd(size); break;

                case "MTrk": ++tracks; LoadMTrk(size); break;
                }

                mReader.Goto(start + size);
            }

            if (!mthd)
            {
                mareep.WriteError("MIDI: missing header chunk.");
            }

            if (tracks != mTrackCount)
            {
                mareep.WriteWarning("MIDI: track count mismatch (header says {0}, found {1}).\n", mTrackCount, tracks);
                mTrackCount = tracks;
            }

            if (mFormat == 0 && mTrackCount != 1)
            {
                mareep.WriteWarning("MIDI: format-0 requires a single track.");
            }
        }
Пример #10
0
        protected void loadImageData(aBinaryReader reader, long texoffset)
        {
            if (texoffset == 0)
            {
                texoffset = 32;
            }
            reader.Goto(texoffset);
            var data = bloImage.loadImageData(reader, mWidth, mHeight, mFormat);

            if (data is aRGBA[])
            {
                mImageData   = (data as aRGBA[]);
                mPaletteData = null;
            }
            else if (data is short[])
            {
                mImageData   = new aRGBA[mWidth * mHeight];
                mPaletteData = (data as short[]);
            }
        }
Пример #11
0
        public void load(aBinaryReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }
            reader.PushAnchor();
            var entryCount  = reader.ReadS32();
            var fieldCount  = reader.ReadS32();
            var entryOffset = reader.Read32();
            var entrySize   = reader.ReadS32();

            mFields = new jmpField[fieldCount];
            for (var i = 0; i < fieldCount; ++i)
            {
                mFields[i].hash    = reader.Read32();
                mFields[i].bitmask = reader.Read32();
                mFields[i].start   = reader.Read16();
                mFields[i].shift   = reader.Read8();
                mFields[i].type    = (jmpValueType)reader.Read8();
            }
            mEntries = new jmpValue[entryCount, fieldCount];
            for (var entry = 0; entry < entryCount; ++entry)
            {
                for (var field = 0; field < fieldCount; ++field)
                {
                    reader.Goto(entryOffset + (entrySize * entry) + mFields[field].start);
                    switch (mFields[field].type)
                    {
                    case jmpValueType.INTEGER: mEntries[entry, field] = (int)((reader.ReadS32() & mFields[field].bitmask) >> mFields[field].shift); break;

                    case jmpValueType.FLOAT: mEntries[entry, field] = reader.ReadF32(); break;

                    case jmpValueType.STRING: mEntries[entry, field] = reader.ReadString <aCSTR>(0x20); break;
                    }
                }
            }
            reader.PopAnchor();
        }
Пример #12
0
        void PerformStreamToWav(Stream instream, Stream outstream)
        {
            var reader = new aBinaryReader(instream, Endianness.Big);
            var writer = new aBinaryWriter(outstream, Endianness.Little);

            var streamDataSize = reader.ReadS32();
            var sampleCount    = reader.ReadS32();
            var sampleRate     = reader.Read16();
            var dataSize       = (sampleCount * 4);
            var format         = (StreamFormat)reader.Read16();

            writer.WriteString("RIFF");
            writer.WriteS32(36 + dataSize);
            writer.WriteString("WAVE");
            writer.WriteString("fmt ");
            writer.WriteS32(16);
            writer.WriteS16(1);              // format
            writer.Write16(2);               // channel count
            writer.WriteS32(sampleRate);
            writer.WriteS32(sampleRate * 4); // byte rate
            writer.Write16(4);               // block align
            writer.Write16(16);              // bit depth
            writer.WriteString("data");
            writer.WriteS32(dataSize);

            reader.Goto(32);

            switch (format)
            {
            case StreamFormat.Pcm: DecodeStreamPcm(reader, writer, sampleCount); break;

            case StreamFormat.Adpcm: DecodeStreamAdpcm(reader, writer, sampleCount); break;

            default: mareep.WriteError("AFC: Unknown format '{0}' in header.", (int)format); break;
            }
        }
Пример #13
0
 protected void loadPaletteData(aBinaryReader reader, int entrycount, long tlutoffset)
 {
     reader.Goto(tlutoffset);
     mBasePalette = new bloPalette(mTlutFormat, mTransparency, entrycount, reader);
     attachPalette(mBasePalette);
 }
Пример #14
0
        void DoReplaceSeq()
        {
            if (mAafInPath == null)
            {
                mareep.WriteError("CHARGE: missing -init-data-file parameter");
            }

            if (mArcInPath == null)
            {
                mareep.WriteError("CHARGE: missing -seq-data-file parameter");
            }

            byte[] arc_data = ReadFileData(mArcInPath);

            if (mInput == null)
            {
                mareep.WriteError("CHARGE: missing -input parameter");
            }

            byte[] seq_data = ReadFileData(mInput);

            if (mTarget == null)
            {
                mareep.WriteError("CHARGE: missing -target parameter");
            }

            byte[] barc_data = null;

            using (Stream input = mareep.OpenFile(mAafInPath)) {
                mareep.WriteMessage("Scanning AAF header...\n");
                aBinaryReader reader = new aBinaryReader(input, Endianness.Big);
                int           offset, size;

                if (!ReadAafHeader(reader, 4, 0, out offset, out size))
                {
                    mareep.WriteError("CHARGE: failed to find sequence info block");
                }

                reader.Goto(offset);

                if (reader.ReadS32() != 0x42415243)                   // 'BARC'
                {
                    mareep.WriteError("CHARGE: could not find 'BARC' header");
                }

                reader.Goto(offset + 12);
                int count = reader.ReadS32();
                barc_data = new byte[32 + 32 * count];
                reader.Goto(offset + 32);
                int index, old_offset, old_size;

                mareep.WriteMessage("Found sequence info data (0x{0:X6}, 0x{1:X6}), {2} sequence(s)\n", offset, size, count);
                mareep.WriteMessage("Scanning sequence list...\n");

                if (!ReadBarcHeader(reader, mTarget, count, out index, out old_offset, out old_size))
                {
                    mareep.WriteError("CHARGE: could not find sequence {0}", mTarget);
                }

                mareep.WriteMessage("Found sequence {0} (0x{1:X6}, 0x{2:X6})\n", index, offset, size);

                int new_offset, new_size = ((seq_data.Length + 31) & ~31);
                int difference = (new_size - old_size);
                reader.Goto(offset + 16);

                using (Stream arc_stream = mareep.CreateFile(mArcOutPath))
                    using (MemoryStream barc_stream = new MemoryStream(barc_data, true)) {
                        mareep.WriteMessage("Writing new sequence data...\n");
                        aBinaryWriter arc_writer  = new aBinaryWriter(arc_stream);
                        aBinaryWriter barc_writer = new aBinaryWriter(barc_stream, Endianness.Big);
                        barc_writer.WriteS32(0x42415243);                 // 'BARC'
                        barc_writer.WriteS32(0x2D2D2D2D);                 // '----'
                        barc_writer.WriteS32(0);
                        barc_writer.WriteS32(count);
                        barc_writer.Write8s(reader.Read8s(16));

                        for (int i = 0; i < count; ++i)
                        {
                            barc_writer.Write8s(reader.Read8s(14));
                            barc_writer.WriteS16(reader.ReadS16());
                            barc_writer.WriteS32(reader.ReadS32());
                            barc_writer.WriteS32(reader.ReadS32());
                            offset     = reader.ReadS32();
                            size       = reader.ReadS32();
                            new_offset = offset;

                            if (offset > old_offset)
                            {
                                new_offset += difference;
                            }

                            arc_writer.Goto(new_offset);

                            if (i == index)
                            {
                                arc_writer.Write8s(seq_data);
                                arc_writer.WritePadding(32, 0);
                                size = new_size;
                            }
                            else
                            {
                                arc_writer.Write8s(arc_data, offset, size);
                            }

                            barc_writer.WriteS32(new_offset);
                            barc_writer.WriteS32(size);
                        }
                    }

                reader.Goto(0);

                using (Stream output = mareep.CreateFile(mAafOutPath)) {
                    mareep.WriteMessage("Writing new AAF file...\n");
                    aBinaryWriter writer = new aBinaryWriter(output, Endianness.Big);

                    if (!WriteAafHeader(reader, writer, 4, 0, barc_data))
                    {
                        mareep.WriteError("CHARGE: failed to write aaf file");
                    }
                }
            }
        }
Пример #15
0
        static bool WriteAafHeader(aBinaryReader reader, aBinaryWriter writer, int id, int index, byte[] data)
        {
            long reader_base = reader.Position;
            long writer_base = writer.Position;
            int  old_offset, old_size;

            if (!ReadAafHeader(reader, id, index, out old_offset, out old_size))
            {
                return(false);
            }

            int difference = (data.Length - old_size);

            reader.Goto(reader_base);
            int section;

            while ((section = reader.ReadS32()) != 0)
            {
                bool has_vnum = (section == 2 || section == 3);
                writer.WriteS32(section);
                int offset, size;
                int i = 0;

                while ((offset = reader.ReadS32()) != 0)
                {
                    size = reader.ReadS32();

                    if (offset > old_offset)
                    {
                        offset += difference;
                    }

                    writer.Keep();
                    writer.Goto(writer_base + offset);

                    if (section == id && i == index)
                    {
                        writer.Write8s(data);
                        size = data.Length;
                    }
                    else
                    {
                        reader.Keep();
                        reader.Goto(reader_base + offset);
                        writer.Write8s(reader.Read8s(size));
                        reader.Back();
                    }

                    writer.Back();
                    writer.WriteS32(offset);
                    writer.WriteS32(size);

                    if (has_vnum)
                    {
                        writer.WriteS32(reader.ReadS32());
                    }

                    ++i;
                }

                writer.WriteS32(0);
            }

            writer.WriteS32(0);
            writer.Goto(writer.Length);
            writer.WritePadding(32, 0);
            return(true);
        }
Пример #16
0
        static void Main(string[] arguments)
        {
            Message("doomwadcorrupter v{0} arookas", new Version(0, 1, 12));
            Separator();
            if (arguments == null || arguments.Length < 2)
            {
                Message("Usage: doomwadcorrupter <input.wad> <output.wad> [options]");
                Message();
                Message("Options:");
                Message("    -start <value>");
                Message("    -end <value>");
                Message("    -inc <value>");
                Message("    -mode <type> [<value>]");
                Message("    -skip <filter> [<filter> [...]]");
                Message("    -only <filter> [<filter> [...]]");
                Message("    -zdoom");
                Message();
                Message("For more detailed instructions, refer to the official repo page.");
                Pause();
                Exit(false);
            }
            var inputWAD  = arguments[0];
            var outputWAD = arguments[1];

            cmd     = new aCommandLine(arguments.Skip(2).ToArray());
            options = new CorrupterOptions(cmd);
            DisplayOptions(inputWAD, outputWAD);

            int lumpCount;
            var lumpsCorrupted = 0;
            var lumpsSkipped   = 0;
            var bytesCorrupted = 0;

            rnd = new Random((uint)options.CorruptSeed);
            var timeTaken = Stopwatch.StartNew();

            using (var instream = OpenWAD(inputWAD)) {
                var reader = new aBinaryReader(instream, Endianness.Little, Encoding.ASCII);

                // header
                var wadType = reader.ReadString(4);

                if (wadType != "IWAD" && wadType != "PWAD")
                {
                    Error("Input file is not a DOOM WAD.");
                }

                lumpCount = reader.ReadS32();
                var directoryOffset = reader.ReadS32();

                // directory
                reader.Goto(directoryOffset);
                var lumps = aCollection.Initialize(lumpCount, () => new Lump(reader));

                using (var outstream = CreateWAD(outputWAD)) {
                    var writer = new aBinaryWriter(outstream, Endianness.Little, Encoding.ASCII);
                    // header
                    writer.WriteString(wadType);
                    writer.WriteS32(lumpCount);
                    writer.WriteS32(directoryOffset);

                    // data
                    var corruptBuff = new byte[options.Increment];
                    var startBuff   = new byte[options.Start];
                    var ns          = LumpNamespace.Global;

                    foreach (var lump in lumps)
                    {
                        reader.Goto(lump.Start);
                        writer.Goto(lump.Start);
                        CheckNamespaceMarker(lump, ref ns);
                        if (options.Filter.IsCorruptable(lump.Name, ns) && !(options.ZDOOM && IsZDOOMLump(lump.Name)))
                        {
                            ++lumpsCorrupted;
                            var i   = options.Start;
                            var end = options.End ?? lump.Length;
                            if (i > 0)
                            {
                                var count = (int)System.Math.Min(lump.Length, i);
                                reader.Read(startBuff, count);
                                writer.Write8s(startBuff, count);
                            }
                            while (i < lump.Length && i < end)
                            {
                                Status("Corrupting '{0}'... (0x{1:X8} / 0x{2:X8})", lump.Name, i, lump.Length);
                                var count = (int)System.Math.Min(lump.Length - i, options.Increment);
                                reader.Read(corruptBuff, count);
                                CorruptByte(ref corruptBuff[0], options.CorruptMode, options.CorruptValue);
                                writer.Write8s(corruptBuff, count);
                                ++bytesCorrupted;
                                i += count;
                            }
                        }
                        else
                        {
                            ++lumpsSkipped;
                            writer.Write8s(reader.Read8s(lump.Length));
                        }
                    }

                    // directory
                    writer.Goto(directoryOffset);
                    foreach (var lump in lumps)
                    {
                        Status("Writing lump directory for '{0}'...", lump.Name);
                        lump.ToStream(writer);
                    }
                }
            }

            timeTaken.Stop();
            Status("Finished corrupting.");
            Message();
            Separator();
            Message("                       Files : {0}", lumpCount);
            Message("             Files corrupted : {0}", lumpsCorrupted);
            Message("               Files skipped : {0}", lumpsSkipped);
            Message("Bytes mercilessly sacrificed : {0}", bytesCorrupted);
            Message("                  Time taken : {0}", timeTaken.Elapsed.ToString("g"));
            Message("                 Finished at : {0}", DateTime.Now.ToString("HH:mm:ss tt"));
            Pause();
        }
Пример #17
0
        protected override void CalculateHistoryAdpcm2(int sample, out int last, out int penult)
        {
            last   = 0;
            penult = 0;

            var frame = (sample / 16);

            if (frame == 0)
            {
                return;
            }

            switch (mFormat)
            {
            case WaveFormat.Pcm8: {
                var adpcm2 = new byte[5];
                var pcm16 = new short[16];
                int _last = 0, _penult = 0;

                mReader.Goto(0);

                for (var i = 0; i < frame; ++i)
                {
                    for (var j = 0; j < 16; ++j)
                    {
                        pcm16[j] = 0;

                        if ((i * 16 + j) < mSampleCount)
                        {
                            Waveform.Pcm8toPcm16(mReader.ReadS8(), out pcm16[j]);
                        }
                    }

                    Waveform.Pcm16toAdpcm2(pcm16, adpcm2, ref _last, ref _penult);
                    Waveform.Adpcm2toPcm16(adpcm2, pcm16, ref last, ref penult);
                }

                break;
            }

            case WaveFormat.Pcm16: {
                var adpcm2 = new byte[5];
                var pcm16 = new short[16];
                int _last = 0, _penult = 0;

                mReader.Goto(0);

                for (var i = 0; i < frame; ++i)
                {
                    for (var j = 0; j < 16; ++j)
                    {
                        pcm16[j] = 0;

                        if ((i * 16 + j) < mSampleCount)
                        {
                            pcm16[j] = mReader.ReadS16();
                        }
                    }

                    Waveform.Pcm16toAdpcm2(pcm16, adpcm2, ref _last, ref _penult);
                    Waveform.Adpcm2toPcm16(adpcm2, pcm16, ref last, ref penult);
                }

                break;
            }

            case WaveFormat.Adpcm2: {
                var pcm16 = new short[16];

                mReader.Goto(0);

                for (var i = 0; i < frame; ++i)
                {
                    Waveform.Adpcm2toPcm16(mReader.Read8s(5), pcm16, ref last, ref penult);
                }

                break;
            }

            case WaveFormat.Adpcm4: {
                var adpcm2 = new byte[5];
                var pcm16 = new short[16];
                int last1 = 0, penult1 = 0;
                int last2 = 0, penult2 = 0;

                mReader.Goto(0);

                for (var i = 0; i < frame; ++i)
                {
                    Waveform.Adpcm4toPcm16(mReader.Read8s(9), pcm16, ref last1, ref penult1);
                    Waveform.Pcm16toAdpcm2(pcm16, adpcm2, ref last2, ref penult2);
                    Waveform.Adpcm2toPcm16(adpcm2, pcm16, ref last, ref penult);
                }

                break;
            }
            }
        }
Пример #18
0
        static bool loadBlo1(bloPane parent, aBinaryReader reader)
        {
            bloPane lastPane = parent;

            for (;;)
            {
                long start  = reader.Position;
                uint typeID = reader.Read32();
                long length = reader.Read32();
                long end    = (start + length);

                switch (typeID)
                {
                case cPAN1: {
                    lastPane = new bloPane();
                    lastPane.load(parent, reader, bloFormat.Blo1);
                    if (reader.Position != end)
                    {
                        Console.WriteLine(">>> Bad '{0}' section at {1:X6} (header size {2:X6} actual size {3:X6})", idToString(typeID), start, length, (reader.Position - start));
                        reader.Goto(end);
                    }
                    break;
                }

                case cPIC1: {
                    lastPane = new bloPicture();
                    lastPane.load(parent, reader, bloFormat.Blo1);
                    if (reader.Position != end)
                    {
                        Console.WriteLine(">>> Bad '{0}' section at {1:X6} (header size {2:X6} actual size {3:X6})", idToString(typeID), start, length, (reader.Position - start));
                        reader.Goto(end);
                    }
                    break;
                }

                case cWIN1: {
                    lastPane = new bloWindow();
                    lastPane.load(parent, reader, bloFormat.Blo1);
                    if (reader.Position != end)
                    {
                        Console.WriteLine(">>> Bad '{0}' section at {1:X6} (header size {2:X6} actual size {3:X6})", idToString(typeID), start, length, (reader.Position - start));
                        reader.Goto(end);
                    }
                    break;
                }

                case cTBX1: {
                    lastPane = new bloTextbox();
                    lastPane.load(parent, reader, bloFormat.Blo1);
                    reader.Goto(end);
                    break;
                }

                case cBGN1: {
                    reader.Goto(end);
                    if (!loadBlo1(lastPane, reader))
                    {
                        return(false);
                    }
                    break;
                }

                case cEND1: {
                    reader.Goto(end);
                    return(true);
                }

                case cEXT1: {
                    // we should skip to the end of this section just in case,
                    // but SMS doesn't so to keep compatibility neither do we
                    return(true);
                }

                default: {
                    Console.WriteLine(">>> Unknown '{0}' section at {1:X6} (size {2:X6})", idToString(typeID), start, length);
                    return(false);
                }
                }
            }
        }
Пример #19
0
        static void Main(string[] arguments)
        {
            Message("doomwadcorrupter v{0} arookas", new Version(0, 1, 12));
            Separator();
            if (arguments == null || arguments.Length < 2) {
                Message("Usage: doomwadcorrupter <input.wad> <output.wad> [options]");
                Message();
                Message("Options:");
                Message("    -start <value>");
                Message("    -end <value>");
                Message("    -inc <value>");
                Message("    -mode <type> [<value>]");
                Message("    -skip <filter> [<filter> [...]]");
                Message("    -only <filter> [<filter> [...]]");
                Message("    -zdoom");
                Message();
                Message("For more detailed instructions, refer to the official repo page.");
                Pause();
                Exit(false);
            }
            var inputWAD = arguments[0];
            var outputWAD = arguments[1];
            cmd = new aCommandLine(arguments.Skip(2).ToArray());
            options = new CorrupterOptions(cmd);
            DisplayOptions(inputWAD, outputWAD);

            int lumpCount;
            var lumpsCorrupted = 0;
            var lumpsSkipped = 0;
            var bytesCorrupted = 0;
            rnd = new Random((uint)options.CorruptSeed);
            var timeTaken = Stopwatch.StartNew();
            using (var instream = OpenWAD(inputWAD)) {
                var reader = new aBinaryReader(instream, Endianness.Little, Encoding.ASCII);

                // header
                var wadType = reader.ReadString(4);

                if (wadType != "IWAD" && wadType != "PWAD") {
                    Error("Input file is not a DOOM WAD.");
                }

                lumpCount = reader.ReadS32();
                var directoryOffset = reader.ReadS32();

                // directory
                reader.Goto(directoryOffset);
                var lumps = aCollection.Initialize(lumpCount, () => new Lump(reader));

                using (var outstream = CreateWAD(outputWAD)) {
                    var writer = new aBinaryWriter(outstream, Endianness.Little, Encoding.ASCII);
                    // header
                    writer.WriteString(wadType);
                    writer.WriteS32(lumpCount);
                    writer.WriteS32(directoryOffset);

                    // data
                    var corruptBuff = new byte[options.Increment];
                    var startBuff = new byte[options.Start];
                    var ns = LumpNamespace.Global;

                    foreach (var lump in lumps) {
                        reader.Goto(lump.Start);
                        writer.Goto(lump.Start);
                        CheckNamespaceMarker(lump, ref ns);
                        if (options.Filter.IsCorruptable(lump.Name, ns) && !(options.ZDOOM && IsZDOOMLump(lump.Name))) {
                            ++lumpsCorrupted;
                            var i = options.Start;
                            var end = options.End ?? lump.Length;
                            if (i > 0) {
                                var count = (int)System.Math.Min(lump.Length, i);
                                reader.Read(startBuff, count);
                                writer.Write8s(startBuff, count);
                            }
                            while (i < lump.Length && i < end) {
                                Status("Corrupting '{0}'... (0x{1:X8} / 0x{2:X8})", lump.Name, i, lump.Length);
                                var count = (int)System.Math.Min(lump.Length - i, options.Increment);
                                reader.Read(corruptBuff, count);
                                CorruptByte(ref corruptBuff[0], options.CorruptMode, options.CorruptValue);
                                writer.Write8s(corruptBuff, count);
                                ++bytesCorrupted;
                                i += count;
                            }
                        }
                        else {
                            ++lumpsSkipped;
                            writer.Write8s(reader.Read8s(lump.Length));
                        }
                    }

                    // directory
                    writer.Goto(directoryOffset);
                    foreach (var lump in lumps) {
                        Status("Writing lump directory for '{0}'...", lump.Name);
                        lump.ToStream(writer);
                    }
                }
            }

            timeTaken.Stop();
            Status("Finished corrupting.");
            Message();
            Separator();
            Message("                       Files : {0}", lumpCount);
            Message("             Files corrupted : {0}", lumpsCorrupted);
            Message("               Files skipped : {0}", lumpsSkipped);
            Message("Bytes mercilessly sacrificed : {0}", bytesCorrupted);
            Message("                  Time taken : {0}", timeTaken.Elapsed.ToString("g"));
            Message("                 Finished at : {0}", DateTime.Now.ToString("HH:mm:ss tt"));
            Pause();
        }
Пример #20
0
        void DoExtractSeq()
        {
            if (mAafInPath == null)
            {
                mareep.WriteError("CHARGE: missing -init-data-file parameter");
            }

            if (mArcInPath == null)
            {
                mareep.WriteError("CHARGE: missing -seq-data-file parameter");
            }

            if (mOutput == null)
            {
                mareep.WriteError("CHARGE: missing -output parameter");
            }

            if (mTarget == null)
            {
                mareep.WriteError("CHARGE: missing -target parameter");
            }

            int offset, size;

            using (Stream stream = mareep.OpenFile(mAafInPath)) {
                mareep.WriteMessage("Scanning AAF header...\n");
                aBinaryReader reader = new aBinaryReader(stream, Endianness.Big);

                if (!ReadAafHeader(reader, 4, 0, out offset, out size))
                {
                    mareep.WriteError("CHARGE: failed to find sequence info data");
                }

                reader.Goto(offset);

                if (reader.ReadS32() != 0x42415243)                   // 'BARC'
                {
                    mareep.WriteError("CHARGE: could not find 'BARC' header");
                }

                reader.Goto(offset + 12);
                int count = reader.ReadS32();
                reader.Goto(offset + 32);
                int index;

                mareep.WriteMessage("Found sequence info data (0x{0:X6}, 0x{1:X6}), {2} sequence(s)\n", offset, size, count);
                mareep.WriteMessage("Scanning sequence list...\n");

                if (!ReadBarcHeader(reader, mTarget, count, out index, out offset, out size))
                {
                    mareep.WriteError("CHARGE: could not find sequence {0}", mTarget);
                }

                mareep.WriteMessage("Found sequence {0} (0x{1:X6}, 0x{2:X6})\n", index, offset, size);
            }

            mareep.WriteMessage("Extracting sequence data...\n");

            using (Stream stream = mareep.OpenFile(mArcInPath)) {
                aBinaryReader reader = new aBinaryReader(stream);
                reader.Goto(offset);
                WriteFileData(mOutput, reader.Read8s(size));
            }
        }
Пример #21
0
        protected override WaveBank DoTransform(WaveBank obj)
        {
            if (obj != null)
            {
                return(obj);
            }

            mReader.Keep();
            mReader.PushAnchor();

            if (mReader.Read32() != WSYS)
            {
                mareep.WriteError("WSYS: could not find header.");
            }

            var size = mReader.ReadS32();

            mReader.Step(8);             // unused
            var winfOffset = mReader.ReadS32();
            var wbctOffset = mReader.ReadS32();

            mareep.WriteMessage("WSYS: header found, size {0:F1} KB\n", ((double)size / 1024.0d));

            var waveBank = new WaveBank();

            waveBank.Name = mName;

            mReader.Goto(winfOffset);

            if (mReader.Read32() != WINF)
            {
                mareep.WriteError("WSYS: could not find WINF at 0x{0:X6}.", winfOffset);
            }

            var waveGroupCount = mReader.ReadS32();

            if (waveGroupCount < 0)
            {
                mareep.WriteError("WSYS: bad wave-group count '{0}' in WINF.", waveGroupCount);
            }

            mareep.WriteMessage("WSYS: WINF found, {0} wave group(s).\n", waveGroupCount);

            var waveGroupOffsets = mReader.ReadS32s(waveGroupCount);

            mReader.Goto(wbctOffset);

            if (mReader.Read32() != WBCT)
            {
                mareep.WriteError("WSYS: could not find WBCT at 0x{0:X6}.", wbctOffset);
            }

            mReader.Step(4);             // unused

            var sceneCount = mReader.ReadS32();

            if (sceneCount != waveGroupCount)
            {
                mareep.WriteError("WSYS: WINF count ({0}) does not match WBCT count ({1}).", waveGroupCount, sceneCount);
            }

            var sceneOffsets = mReader.ReadS32s(sceneCount);

            for (var i = 0; i < waveGroupCount; ++i)
            {
                mReader.Goto(waveGroupOffsets[i]);

                var archiveName   = mReader.ReadString <aCSTR>(112);
                var waveInfoCount = mReader.ReadS32();

                if (waveInfoCount < 0)
                {
                    mareep.WriteError("WSYS: bad wave count '{0}' in wave group #{1}.", waveInfoCount, i);
                }

                var waveInfoOffsets = mReader.ReadS32s(waveInfoCount);

                mReader.Goto(sceneOffsets[i]);

                if (mReader.Read32() != SCNE)
                {
                    mareep.WriteError("WSYS: could not find SCNE at 0x{0:X6}.", sceneOffsets[i]);
                }

                mReader.Step(8);                 // unused
                var cdfOffset = mReader.ReadS32();
                mReader.Goto(cdfOffset);

                if (mReader.Read32() != C_DF)
                {
                    mareep.WriteError("WSYS: could not find C-DF at 0x{0:X6}.", cdfOffset);
                }

                var waveidCount = mReader.ReadS32();

                if (waveidCount != waveInfoCount)
                {
                    mareep.WriteError("WSYS: C-DF count ({0}) does not match wave-info count ({1}).", waveidCount, waveInfoCount);
                }

                var waveidOffsets = mReader.ReadS32s(waveidCount);

                var waveGroup = new WaveGroup();
                waveGroup.ArchiveFileName = archiveName;

                for (var j = 0; j < waveInfoCount; ++j)
                {
                    var wave = new Wave();

                    mReader.Goto(waveidOffsets[j]);

                    var waveid = (mReader.ReadS32() & 0xFFFF);
                    wave.WaveId = waveid;

                    mReader.Goto(waveInfoOffsets[j]);
                    mReader.Step(1);                     // unknown

                    var format = (WaveFormat)mReader.Read8();

                    if (!format.IsDefined())
                    {
                        mareep.WriteError("WSYS: group #{0}: wave #{1}: bad format '{2}'.", i, j, (byte)format);
                    }
                    else
                    {
                        wave.Format = format;
                    }

                    var key = mReader.Read8();

                    if (key < 0 || key > 127)
                    {
                        mareep.WriteError("WSYS: group #{0}: wave #{1}: bad root key '{2}'.", i, j, key);
                    }
                    else
                    {
                        wave.RootKey = key;
                    }

                    mReader.Step(1);                     // alignment

                    var sampleRate = mReader.ReadF32();

                    if (sampleRate < 0.0f)
                    {
                        mareep.WriteError("WSYS: group #{0}: wave #{1}: bad sample rate '{2:F1}'.", i, j, sampleRate);
                    }
                    else
                    {
                        wave.SampleRate = sampleRate;
                    }

                    var waveStart = mReader.ReadS32();

                    if (waveStart < 0)
                    {
                        mareep.WriteError("WSYS: group #{0}: wave #{1}: bad wave start '{2}'.", i, j, waveStart);
                    }
                    else
                    {
                        wave.WaveStart = waveStart;
                    }

                    var waveSize = mReader.ReadS32();

                    if (waveSize < 0)
                    {
                        mareep.WriteError("WSYS: group #{0}: wave #{1}: bad wave size '{1}'.", i, j, waveSize);
                    }
                    else
                    {
                        wave.WaveSize = waveSize;
                    }

                    wave.Loop = (mReader.Read32() != 0);

                    var loopStart = mReader.ReadS32();

                    if (loopStart < 0)
                    {
                        mareep.WriteError("WSYS: group #{0}: wave #{1}: bad loop start '{2}'.", i, j, loopStart);
                    }
                    else
                    {
                        wave.LoopStart = loopStart;
                    }

                    var loopEnd = mReader.ReadS32();

                    if (loopEnd < 0)
                    {
                        mareep.WriteError("WSYS: group #{0}: wave #{1}: bad loop end '{2}'.", i, j, loopEnd);
                    }
                    else
                    {
                        wave.LoopEnd = loopEnd;
                    }

                    var sampleCount = mReader.ReadS32();
                    wave.SampleCount = mareep.CalculateSampleCount(format, waveSize);

                    if (loopStart > loopEnd)
                    {
                        mareep.WriteWarning("WSYS: group #{0}: wave #{1}: loop start '{2}' is greater than loop end '{3}'.\n", i, j, loopStart, loopEnd);
                    }

                    if (loopStart > wave.SampleCount)
                    {
                        mareep.WriteWarning("WSYS: group #{0}: wave #{1}: loop start '{2}' is greater than sample count '{3}'.\n", i, j, loopStart, wave.SampleCount);
                    }

                    if (loopEnd > wave.SampleCount)
                    {
                        mareep.WriteWarning("WSYS: group #{0}: wave #{1}: loop end '{2}' is greater than sample count '{3}'.\n", i, j, loopEnd, wave.SampleCount);
                    }

                    wave.HistoryLast   = mReader.ReadS16();
                    wave.HistoryPenult = mReader.ReadS16();

                    // rest of the fields are unknown or runtime

                    waveGroup.Add(wave);
                }

                waveBank.Add(waveGroup);
            }

            mReader.PopAnchor();
            mReader.Back();

            return(waveBank);
        }
Пример #22
0
        static void WriteText(uint ofs)
        {
            byte command;

            sReader.Keep();
            sReader.Goto(sTextOffset + ofs);
            var maxofs = 0u;

            do
            {
                var pos = sReader.Position - sTextOffset;
                command = sReader.Read8();
                sWriter.Write("  {0:X8} {1}", pos, sCommandNames[command]);
                var nextofs = 0u;
                switch (command)
                {
                case 0x00: sWriter.Write(" {0}", sReader.ReadS32()); break;

                case 0x01: sWriter.Write(" {0}", sReader.ReadF32()); break;

                case 0x02: {
                    var data  = sReader.ReadS32();
                    var value = FetchDataValue(data);
                    sWriter.Write(" {0} # \"{1}\"", data, value);
                    break;
                }

                case 0x03: sWriter.Write(" ${0:X8}", sReader.Read32()); break;

                case 0x04: WriteVar(); break;

                case 0x06: WriteVar(); break;

                case 0x07: WriteVar(); break;

                case 0x0D: {
                    sReader.Read8();                             // TSpcInterp skips this byte
                    WriteVar();
                    break;
                }

                case 0x1C: {
                    var dest   = sReader.Read32();
                    var args   = sReader.ReadS32();
                    var symbol = FetchSymbol(i => i.Data == dest);
                    if (symbol != null)
                    {
                        sWriter.Write(" {0}, {1}", FetchSymbolName(symbol), args);
                    }
                    else
                    {
                        sWriter.Write(" ${0:X8}, {1}", dest, args);
                    }
                    break;
                }

                case 0x1D: sWriter.Write(" {0}, {1}", FetchSymbolName(FetchSymbol(sReader.ReadS32())), sReader.ReadS32()); break;

                case 0x1E: sWriter.Write(" {0}", sReader.ReadS32()); break;

                case 0x1F: sWriter.Write(" {0}", sReader.ReadS32()); break;

                case 0x22: nextofs = WriteJmp(ofs); break;

                case 0x23: nextofs = WriteJmp(ofs); break;
                }
                sWriter.WriteLine();
                if (nextofs > maxofs)
                {
                    maxofs = nextofs;
                }
            } while (!IsReturnCommand(command) || sReader.Position <= sTextOffset + maxofs);
            sWriter.WriteLine();
            sReader.Back();
        }
Пример #23
0
        static bool WriteAafHeader(aBinaryReader reader, aBinaryWriter writer, int id, int index, byte[] data)
        {
            long reader_base = reader.Position;
            long writer_base = writer.Position;
            int  old_offset, old_size;

            if (!ReadAafHeader(reader, id, index, out old_offset, out old_size))
            {
                return(false);
            }

            int difference = (data.Length - old_size);

            mareep.WriteMessage("Entry size difference: {0} byte(s)\n", difference);
            int danger_level = 0;

            reader.Goto(reader_base);
            int section;

            while ((section = reader.ReadS32()) != 0)
            {
                if (danger_level++ > 1000)
                {
                    mareep.WriteError("CHARGE: malformed AAF file (endless loop detected)");
                }

                bool has_vnum = (section == 2 || section == 3);
                writer.WriteS32(section);
                int offset, size;
                int i = 0;

                while ((offset = reader.ReadS32()) != 0)
                {
                    if (danger_level++ > 1000)
                    {
                        mareep.WriteError("CHARGE: malformed AAF file (endless loop detected)");
                    }

                    size = reader.ReadS32();
                    int new_offset = offset;

                    if (new_offset > old_offset)
                    {
                        new_offset += difference;
                    }

                    writer.Keep();
                    writer.Goto(writer_base + new_offset);

                    if (section == id && i == index)
                    {
                        writer.Write8s(data);
                        size = data.Length;
                    }
                    else
                    {
                        reader.Keep();
                        reader.Goto(reader_base + offset);
                        writer.Write8s(reader.Read8s(size));
                        reader.Back();
                    }

                    writer.Back();
                    writer.WriteS32(new_offset);
                    writer.WriteS32(size);

                    if (has_vnum)
                    {
                        writer.WriteS32(reader.ReadS32());
                    }

                    ++i;
                }

                writer.WriteS32(0);
            }

            writer.WriteS32(0);
            writer.Goto(writer.Length);
            writer.WritePadding(32, 0);
            return(true);
        }