private void ReadInitialLoadSegment(ref ShockwaveReader input, AfterBurnerMapEntry[] entries, Dictionary <int, ChunkItem> chunks) { //First entry in the AfterBurnerMap must be ILS. AfterBurnerMapEntry ilsEntry = entries[0]; input.Advance(ilsEntry.Offset); //TODO: this shouldn't be here ReadOnlySpan <byte> compressedData = input.ReadBytes(ilsEntry.Length); Span <byte> decompressedData = ilsEntry.DecompressedLength <= 1024 ? stackalloc byte[ilsEntry.DecompressedLength] : new byte[ilsEntry.DecompressedLength]; ZLib.Decompress(compressedData, decompressedData); ShockwaveReader ilsReader = new ShockwaveReader(decompressedData, input.IsBigEndian); while (ilsReader.IsDataAvailable) { int id = ilsReader.Read7BitEncodedInt(); AfterBurnerMapEntry entry = entries.FirstOrDefault(e => e.Id == id); //TODO: Chunk entries as dictionary if (entry == null) { break; } chunks.Add(id, Read(ref ilsReader, entry.Header)); } }
public static ChunkItem Read(ref ShockwaveReader input, AfterBurnerMapEntry entry) { if (entry.IsCompressed) { return(input.ReadCompressedChunk(entry)); } else { return(Read(ref input, entry.Header)); } }
public AfterburnerMapChunk(ref ShockwaveReader input, ChunkHeader header) : base(header) { input.ReadByte(); Remnants.Enqueue(input.Read7BitEncodedInt()); using var deflaterInput = CreateDeflateReader(ref input); Remnants.Enqueue(deflaterInput.Read7BitEncodedInt()); Remnants.Enqueue(deflaterInput.Read7BitEncodedInt()); Entries = new AfterBurnerMapEntry[deflaterInput.Read7BitEncodedInt()]; for (int i = 0; i < Entries.Length; i++) { Entries[i] = new AfterBurnerMapEntry(deflaterInput); } }
//TODO: Tidy up more. public IDictionary <int, ChunkItem> ReadChunks(ref ShockwaveReader input, AfterBurnerMapEntry[] entries) { int chunkStart = input.Position; var chunks = new Dictionary <int, ChunkItem>(entries.Length); ReadInitialLoadSegment(ref input, entries, chunks); for (int i = 1; i < entries.Length; i++) { AfterBurnerMapEntry entry = entries[i]; if (entry.Offset == -1) { continue; } input.Position = chunkStart + entry.Offset; chunks.Add(entry.Id, Read(ref input, entry)); } return(chunks); }
public void ReadChunks(List <AfterBurnerMapEntry> entries, Action <ChunkItem> callback) { int ilsChunkCount = entries.Count(e => e.Offset == -1); for (int i = 0; i < ilsChunkCount; i++) { if (_input.Position >= Header.Length) { break; } int id = _input.Read7BitEncodedInt(); AfterBurnerMapEntry entry = entries.FirstOrDefault(e => e.Header.Id == id); if (entry == null) { break; //TODO: } entry.Header.Offset = _input.Position; callback?.Invoke(Read(_input, entry.Header)); } }
public InitialLoadSegmentChunk ReadInitialLoadSegment(AfterBurnerMapEntry ilsEntry) { _input.Position += ilsEntry.Offset; return(Read(_input, ilsEntry.Header) as InitialLoadSegmentChunk); }