예제 #1
0
        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));
            }
        }
예제 #2
0
파일: ChunkItem.cs 프로젝트: gstack/Shockky
 public static ChunkItem Read(ref ShockwaveReader input, AfterBurnerMapEntry entry)
 {
     if (entry.IsCompressed)
     {
         return(input.ReadCompressedChunk(entry));
     }
     else
     {
         return(Read(ref input, entry.Header));
     }
 }
예제 #3
0
        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);
            }
        }
예제 #4
0
        //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);
        }
예제 #5
0
        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));
            }
        }
예제 #6
0
        public InitialLoadSegmentChunk ReadInitialLoadSegment(AfterBurnerMapEntry ilsEntry)
        {
            _input.Position += ilsEntry.Offset;

            return(Read(_input, ilsEntry.Header) as InitialLoadSegmentChunk);
        }