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); } }
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); }
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); } }
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); } } } } }
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)); } }
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); }
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); }
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); }
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."); } }
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[]); } }
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(); }
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; } }
protected void loadPaletteData(aBinaryReader reader, int entrycount, long tlutoffset) { reader.Goto(tlutoffset); mBasePalette = new bloPalette(mTlutFormat, mTransparency, entrycount, reader); attachPalette(mBasePalette); }
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"); } } } }
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); }
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(); }
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; } } }
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); } } } }
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)); } }
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); }
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(); }
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); }